| //+------------------------------------------------------------------+
|
| //| Parser.hpp |
|
| //| Copyright 2026, Niquel Mendoza. |
|
| //| https://www.mql5.com/ |
|
| //+------------------------------------------------------------------+
|
|
|
| //+------------------------------------------------------------------+
|
| //| Pre-Defines |
|
| //+------------------------------------------------------------------+
|
| #pragma once
|
| #define TSNPARSERIN_CPP_DLL
|
| #define TSN_TARGET_AVX2
|
|
|
| //+------------------------------------------------------------------+
|
| //| Includes |
|
| //+------------------------------------------------------------------+
|
| //--- Tipos estilo mql5 (antes de los includes de la lib)
|
| #include <cstdint>
|
| #include <climits>
|
| using ulong = uint64_t;
|
| using uint = uint32_t;
|
| using uchar = uint8_t;
|
| using ushort = uint16_t;
|
|
|
| //--- Includes extra
|
| #include "..\\..\\..\\BasesParserSLan\\Src\\BaseClass\\Def.mqh"
|
| #include "..\\..\\..\\BasesParserSLan\\Src\\Utils\\Number.mqh"
|
| #include "..\\JsonCore\\JsonDefines.mqh"
|
| #include <cstdio>
|
| #include <cstring>
|
|
|
| //--- Definiciones base
|
| #if defined(TSN_TARGET_AVX512)
|
| #include <immintrin.h>
|
| // kernel con __m512i, _mm512_*, 1 carga de 64 bytes
|
|
|
| #elif defined(TSN_TARGET_AVX2)
|
| #include <immintrin.h>
|
| // kernel con __m256i, _mm256_*, 2 cargas de 32 bytes (lo que ya armamos)
|
|
|
| #elif defined(TSN_TARGET_SSE42)
|
| #include <immintrin.h>
|
| // kernel con __m128i, _mm_*, 4 cargas de 16 bytes
|
|
|
| #else
|
| #error "Debes definir TSN_TARGET_AVX512, TSN_TARGET_AVX2 o TSN_TARGET_SSE42"
|
| #endif
|
|
|
| #include <cstdarg>
|
|
|
| //--- mascaras
|
| #define TSNTABLES_MASK_IMPARES_F (0xAAAAAAAAAAAAAAAA)
|
| #define TSNTABLES_MASK_PARES_F (0x5555555555555555)
|
|
|
| //+------------------------------------------------------------------+
|
| //| Macros |
|
| //+------------------------------------------------------------------+
|
| //---
|
| #define TSN_JSON_AUMENT curr_count++;
|
|
|
| //--- finish basico
|
| #define TSN_JSON_FINISH_B \
|
| *out_cinta_pos = m_cinta_pos; \
|
| *out_pos = m_pos;
|
|
|
| //--- Escribir las salidas basicas + (aqui macro ud especifica el ultimo error) (util para retruan false)
|
| #define TSN_JSON_ON_FINISH_WOUT(ERR) \
|
| *out_last_err = (ERR); \
|
| TSN_JSON_FINISH_B
|
|
|
| //--- nota: esta funcion uncaite setea el error y redirige al punto comun (defualt)
|
| #define TSN_JSON_FAIL(ERR) \
|
| *out_last_err = (ERR); \
|
| goto json_err;
|
|
|
| //--- make string (numeros que ya no se pueden representar bien)
|
| #define JSONPARSERBYLEO_NUM_MAKE_STRING \
|
| m_cinta[m_cinta_pos++] = JSON_VTYPE_STRING \
|
| | uint64_t(m_pos - start) << TSN_SBL_BIT_STR_LEN(TSN_SBL_SLEN_STR) \
|
| | uint64_t(start) << TSN_SBL_BIT_STR_START;
|
|
|
| //--- clave: start = inicio (luego del "), sp apunta al " de cierre
|
| #define TSN_JSON_PARSE_KEY \
|
| m_cinta[m_cinta_pos++] = JSON_VTYPE_KEY \
|
| | uint64_t(m_index[sp] - start) << TSN_SBL_BIT_STR_LEN(TSN_SBL_SLEN_KEY) \
|
| | uint64_t(start) << TSN_SBL_BIT_STR_START; \
|
| m_cinta_pos++; /* slot del hash (se llena en el JIT) */ \
|
| m_pos = m_index[++sp]; \
|
| sp++; /*Ahora mismo apunta al siguiente*/ \
|
| if(m_raw[m_pos++] != ':') \
|
| { \
|
| TSN_JSON_FAIL(TSN_JSON_ERR_MALFODERD_KEY_EXPECTED_DOS_PUNTOS) \
|
| }
|
|
|
| //--- Se usa solo luego de un cor ini aqui peuden ir " [ { t\f\n (1-9\-) ]
|
| #define TSN_JSON_NEXT_COR_INI \
|
| { \
|
| uchar _c = m_raw[m_pos]; \
|
| while(_c < 33) \
|
| _c = m_raw[++m_pos]; \
|
| m_next = g_table_json_tokens[_c]; \
|
| if(((1 << m_next) & TSN_JSON_F_VAL_COR) == 0) \
|
| { \
|
| TSN_JSON_FAIL(TSN_JSON_ERR_MALFORDMED_JSON_AFTER_COR_INI) \
|
| } \
|
| }
|
|
|
| //--- Luego de una coma en array \ luego de una key (el valor)
|
| // Luego de una , y KEY siempre siempre valor
|
| #define TSN_JSON_NEXT_VALUE_COMM_KEY \
|
| { \
|
| uchar _c = m_raw[m_pos]; \
|
| while(_c < 33) \
|
| _c = m_raw[++m_pos]; \
|
| m_next = g_table_json_tokens[_c]; \
|
| if(((1 << m_next) & TSN_JSON_F_ALL_I_VAL) == 0) \
|
| { \
|
| TSN_JSON_FAIL(TSN_JSON_ERR_MALFORDMED_JSON_FIND_VAL) \
|
| } \
|
| }
|
|
|
| //--- Luego de un valor (solo estructurales)
|
| // Salta a json_after_value (en el bucle principal): ahi se mira directo el caracter
|
| // (',' o el cierre esperado) sin pasar por tabla\flags\switch.
|
| // Ahora mismo solo mira (no suma sp como tal), eso lo hace cada estrucutral.. en su case
|
| #define JSONPARSERBYLEO_GOTO_AFTERVALUE goto json_after_value;
|
|
|
| //--- Cierre esperado segun el tipo del padre (T: 0=arr, 1=obj)
|
| // ']' = 93 y '}' = 125 = ']' + 32
|
| #define TSN_JSON_MAKE_CLOSER(T) uchar(']' + ((T) << 5))
|
|
|
| //--- Para hacer un compare con un literal
|
| #define JSONPARSERBYLEO_CHEK_LITERAL(MACRO, ERR) \
|
| uint value; \
|
| std::memcpy(&value, m_raw + m_pos, sizeof(value)); \
|
| if(value != MACRO) \
|
| { \
|
| TSN_JSON_FAIL(ERR) \
|
| }
|
|
|
| //---
|
| #define TSN_JSON_IN_BEAK goto json_switch_start;
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| extern "C" __declspec(dllexport)
|
| // array ya allocado tambein raw solo hace falta rellenar
|
| bool __stdcall JsonParserResolve(
|
| const uint8_t* __restrict m_raw, // datos de entrada
|
| uint64_t* __restrict m_cinta, // cinta de datos
|
| int* __restrict m_index, // array de indices structurales
|
| const int len, // tamaño de raw
|
| const uint64_t jit_enabled, // valor del 2do slot de los objetos (JIT habilitado o no)
|
|
|
| //--- salida
|
| int* __restrict out_last_err, // ultimo err
|
| int* __restrict out_cinta_pos, // posicion actul en la cinta
|
| int* __restrict out_pos // ultima posicion en la lecutra de raw
|
| ); // retorna true en caso de exito, false de lo contrario..
|
| //+------------------------------------------------------------------+
|