2026-08-03 09:20:10 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Parser.cpp |
|
|
|
|
|
//| Copyright 2026, Niquel Mendoza. |
|
|
|
|
|
//| https://www.mql5.com/ |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
|
2026-08-03 11:26:12 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Pre-Defines |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-08-03 09:20:10 -05:00
|
|
|
#pragma once
|
2026-08-03 11:26:12 -05:00
|
|
|
#define TSNPARSERIN_CPP_DLL
|
|
|
|
|
#define TSN_TARGET_AVX2
|
2026-08-03 09:20:10 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-08-03 11:26:12 -05:00
|
|
|
//| Includes |
|
2026-08-03 09:20:10 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-08-03 12:14:49 -05:00
|
|
|
//--- Includes extra
|
|
|
|
|
#include "..\\..\\..\\BasesParserSLan\\Src\\Def.mqh"
|
|
|
|
|
#include "..\\JsonDefines.mqh"
|
2026-08-03 15:01:11 -05:00
|
|
|
#include <cstdio>
|
2026-08-03 09:20:10 -05:00
|
|
|
|
|
|
|
|
//--- 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 <nmmintrin.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
|
|
|
|
|
|
2026-08-26 19:48:01 -05:00
|
|
|
#include <cstdarg>
|
2026-08-03 11:26:12 -05:00
|
|
|
|
2026-08-03 09:20:10 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
using ulong = uint64_t;
|
|
|
|
|
using uchar = uint8_t;
|
|
|
|
|
|
|
|
|
|
//--- mascaras
|
|
|
|
|
#define TSNTABLES_MASK_IMPARES_F (0xAAAAAAAAAAAAAAAA)
|
|
|
|
|
#define TSNTABLES_MASK_PARES_F (0x5555555555555555)
|
|
|
|
|
|
2026-08-03 12:14:49 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
// Defines especificos para avanzar
|
|
|
|
|
//--- Se usa solo luego de un cor ini aqui peuden ir " [ { t\f\n (1-9\-) ]
|
|
|
|
|
#define TSN_JSON_NEXT_COR_INI \
|
|
|
|
|
while(true) \
|
|
|
|
|
{ \
|
2026-08-03 15:01:11 -05:00
|
|
|
const uchar _c = m_raw[(*m_pos)];\
|
2026-08-03 12:14:49 -05:00
|
|
|
if(_c < 33) \
|
|
|
|
|
{ \
|
2026-08-03 15:01:11 -05:00
|
|
|
(*m_pos)++; \
|
2026-08-03 12:14:49 -05:00
|
|
|
continue; \
|
|
|
|
|
} \
|
|
|
|
|
m_next = g_table_json_tokens[_c];\
|
|
|
|
|
if(((1 << m_next) & TSN_JSON_F_VAL_COR) == 0)\
|
|
|
|
|
{ \
|
2026-08-03 15:01:11 -05:00
|
|
|
*m_last_err= TSN_JSON_ERR_MALFORDMED_JSON; \
|
2026-08-03 12:14:49 -05:00
|
|
|
return false; \
|
|
|
|
|
}\
|
|
|
|
|
break; \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Luego de una coma en array
|
|
|
|
|
// Luego de una , y KEY siempre siempre valor
|
|
|
|
|
#define TSN_JSON_NEXT_VALUE_COMM_KEY \
|
|
|
|
|
while(true) \
|
|
|
|
|
{ \
|
2026-08-03 15:01:11 -05:00
|
|
|
const uchar _c = m_raw[(*m_pos)];\
|
2026-08-03 12:14:49 -05:00
|
|
|
if(_c < 33) \
|
|
|
|
|
{ \
|
2026-08-03 15:01:11 -05:00
|
|
|
(*m_pos)++; \
|
2026-08-03 12:14:49 -05:00
|
|
|
continue; \
|
|
|
|
|
} \
|
|
|
|
|
m_next = g_table_json_tokens[_c];\
|
|
|
|
|
if(((1 << m_next) & TSN_JSON_F_ALL_I_VAL) == 0)\
|
|
|
|
|
{ \
|
2026-08-03 15:01:11 -05:00
|
|
|
*m_last_err= TSN_JSON_ERR_MALFORDMED_JSON; \
|
2026-08-03 12:14:49 -05:00
|
|
|
return false; \
|
|
|
|
|
}\
|
|
|
|
|
break; \
|
|
|
|
|
}
|
2026-08-03 15:01:11 -05:00
|
|
|
|
2026-08-03 11:26:12 -05:00
|
|
|
#define JSONPARSERBYLEO_FULL_NEXT \
|
2026-08-03 15:01:11 -05:00
|
|
|
(*m_pos) = m_index[sp++]; \
|
|
|
|
|
m_next = g_table_json_tokens[m_raw[(*m_pos)]];\
|
2026-08-03 11:26:12 -05:00
|
|
|
if(((1 << m_next) & m_stak_curr_state) == 0)\
|
|
|
|
|
{\
|
2026-08-03 15:01:11 -05:00
|
|
|
*m_last_err = TSN_JSON_ERR_MALFORDMED_JSON;\
|
2026-08-03 11:26:12 -05:00
|
|
|
return false;\
|
|
|
|
|
}
|
2026-08-26 19:48:01 -05:00
|
|
|
|
|
|
|
|
//--- macro para parsear numeros
|
|
|
|
|
#define JSONPARSERBYLEO_PARSE_NUMBER(mask) \
|
|
|
|
|
int64_t v = 0;\
|
|
|
|
|
uchar ch = m_raw[(*m_pos)] ^ '0';\
|
|
|
|
|
while(true) \
|
|
|
|
|
{ \
|
|
|
|
|
v = (v << 3) + (v << 1) + ch; \
|
|
|
|
|
(*m_pos)++; \
|
|
|
|
|
ch = m_raw[(*m_pos)] ^ '0'; \
|
|
|
|
|
if(ch < 10) \
|
|
|
|
|
continue; \
|
|
|
|
|
else \
|
|
|
|
|
if(ch == 30 || (ch | 0x20) == 117) \
|
|
|
|
|
{ \
|
|
|
|
|
double val = double(v); \
|
|
|
|
|
if(ch == 30) \
|
|
|
|
|
{ \
|
|
|
|
|
(*m_pos)++; \
|
|
|
|
|
int64_t frac_int = 0; \
|
|
|
|
|
int fract_digits = 0; \
|
|
|
|
|
while(true) \
|
|
|
|
|
{ \
|
|
|
|
|
const uchar c = m_raw[(*m_pos)] ^ '0'; \
|
|
|
|
|
if(c > 9) \
|
|
|
|
|
break; \
|
|
|
|
|
frac_int = (frac_int << 3) + (frac_int << 1) + c; \
|
|
|
|
|
fract_digits++; \
|
|
|
|
|
(*m_pos)++; \
|
|
|
|
|
} \
|
|
|
|
|
val += frac_int * g_Exp10[fract_digits]; \
|
|
|
|
|
} \
|
|
|
|
|
if((m_raw[(*m_pos)] | 0x20) == 'e') \
|
|
|
|
|
{ \
|
|
|
|
|
(*m_pos)++; \
|
|
|
|
|
bool exp_sign = true; \
|
|
|
|
|
uchar _c = m_raw[(*m_pos)]; \
|
|
|
|
|
if(_c == '-') \
|
|
|
|
|
{ \
|
|
|
|
|
exp_sign = false; \
|
|
|
|
|
(*m_pos)++; \
|
|
|
|
|
} \
|
|
|
|
|
else \
|
|
|
|
|
if(_c == '+') \
|
|
|
|
|
{ \
|
|
|
|
|
(*m_pos)++; \
|
|
|
|
|
} \
|
|
|
|
|
_c = m_raw[(*m_pos)] ^ '0'; \
|
|
|
|
|
int exp_val = 0; \
|
|
|
|
|
while(true) \
|
|
|
|
|
{ \
|
|
|
|
|
exp_val = (exp_val << 3) + (exp_val << 1) + _c; \
|
|
|
|
|
(*m_pos)++; \
|
|
|
|
|
_c = m_raw[(*m_pos)] ^ '0'; \
|
|
|
|
|
if(_c > 9) \
|
|
|
|
|
break; \
|
|
|
|
|
} \
|
|
|
|
|
val *= (exp_sign) ? g_Pow10[exp_val] : g_Exp10[exp_val]; \
|
|
|
|
|
} \
|
2026-08-28 08:28:32 -05:00
|
|
|
TsnBitInterprete bit; \
|
2026-08-26 19:48:01 -05:00
|
|
|
bit.double_value = val; \
|
|
|
|
|
bit.long_value ^= (mask & (1LL << 63)); \
|
|
|
|
|
m_cinta[(*m_cinta_pos)++] = JSON_VTYPE_REAL; \
|
|
|
|
|
m_cinta[(*m_cinta_pos)++] = bit.long_value; \
|
|
|
|
|
break; \
|
|
|
|
|
} \
|
|
|
|
|
else \
|
|
|
|
|
{ \
|
|
|
|
|
m_cinta[(*m_cinta_pos)++] = JSON_VTYPE_INTEGER; \
|
|
|
|
|
m_cinta[(*m_cinta_pos)++] = (v ^ mask) - mask; \
|
|
|
|
|
break; \
|
|
|
|
|
} \
|
|
|
|
|
}
|
2026-08-03 11:26:12 -05:00
|
|
|
|
2026-08-03 12:14:49 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-08-03 10:47:54 -05:00
|
|
|
extern "C" __declspec(dllexport)
|
|
|
|
|
// array ya allocado tambein raw solo hace falta rellenar
|
2026-08-03 12:14:49 -05:00
|
|
|
bool __stdcall JsonParserResolve(const uint8_t * m_raw, const int len, int* m_last_err, int* m_cinta_pos,
|
2026-08-26 19:48:01 -05:00
|
|
|
int* m_pos, const int m_offset, int64_t * m_cinta, int* m_index);
|
|
|
|
|
//+------------------------------------------------------------------+
|