JsonParserByLeo/Src/DLL/Parser.hpp

161 lines
7.5 KiB
C++

2026-10-19 07:28:49 -05:00
//+------------------------------------------------------------------+
//| 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 \
2026-10-19 09:16:24 -05:00
| uint64_t(m_index[sp] - start) << TSN_SBL_BIT_STR_LEN(TSN_SBL_SLEN_KEY) \
2026-10-19 07:28:49 -05:00
| uint64_t(start) << TSN_SBL_BIT_STR_START; \
m_cinta_pos++; /* slot del hash (se llena en el JIT) */ \
2026-10-19 09:16:24 -05:00
m_pos = m_index[++sp]; \
sp++; /*Ahora mismo apunta al siguiente*/ \
2026-10-19 07:28:49 -05:00
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)
2026-10-19 13:26:09 -05:00
// 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))
2026-10-19 07:28:49 -05:00
//--- 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) \
}
2026-10-19 13:26:09 -05:00
//---
#define TSN_JSON_IN_BEAK goto json_switch_start;
2026-10-19 07:28:49 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
extern "C" __declspec(dllexport)
// array ya allocado tambein raw solo hace falta rellenar
bool __stdcall JsonParserResolve(
2026-10-19 10:49:05 -05:00
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
2026-10-19 07:28:49 -05:00
const int len, // tamaño de raw
const uint64_t jit_enabled, // valor del 2do slot de los objetos (JIT habilitado o no)
//--- salida
2026-10-19 10:49:05 -05:00
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
2026-10-19 07:28:49 -05:00
); // retorna true en caso de exito, false de lo contrario..
//+------------------------------------------------------------------+