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)
|
2026-09-18 14:11:09 -05:00 | | | #include <immintrin.h>
|
2026-08-03 09:20:10 -05:00 | | | // 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-09-18 14:11:09 -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;
|
2026-09-18 14:11:09 -05:00 | | | using ushort = uint16_t;
|
2026-08-03 09:20:10 -05:00 | | |
|
| | | //--- mascaras
|
| | | #define TSNTABLES_MASK_IMPARES_F (0xAAAAAAAAAAAAAAAA)
|
| | | #define TSNTABLES_MASK_PARES_F (0x5555555555555555)
|
| | |
|
2026-08-03 12:14:49 -05:00 | | | //+------------------------------------------------------------------+
|
2026-09-18 14:11:09 -05:00 | | | //| Macros |
|
2026-08-03 12:14:49 -05:00 | | | //+------------------------------------------------------------------+
|
2026-09-18 14:11:09 -05:00 | | | //---
|
| | | #define TSN_JSON_AUMENT m_stak_num[m_stak_curr]++;
|
| | |
|
| | | //--- Al terminar el parseo qeu hacer
|
| | | #define TSN_JSON_ON_FINISH \
|
| | | *m_cinta_pos = cinta_pos; \
|
| | | *m_pos = pos;
|
| | |
|
| | | //--- clave
|
| | | #define TSN_JSON_PARSE_KEY \
|
| | | pos = m_index[sp++]; \
|
| | | m_cinta[cinta_pos++] = (int64_t)JSON_VTYPE_KEY \
|
| | | | int64_t(pos - start) << TSN_SBL_BIT_STR_LEN \
|
| | | | int64_t(start) << TSN_SBL_BIT_STR_START; \
|
| | | pos = m_index[sp++]; \
|
| | | if(m_raw[pos++] != ':') \
|
| | | { \
|
| | | *m_last_err = TSN_JSON_ERR_MALFODERD_KEY_EXPECTED_DOS_PUNTOS; \
|
| | | TSN_JSON_ON_FINISH \
|
| | | return false; \
|
2026-08-03 12:14:49 -05:00 | | | }
|
| | |
|
2026-09-18 14:11:09 -05:00 | | | //--- Se usa solo luego de un cor ini aqui peuden ir " [ { t\f\n (1-9\-) ]
|
| | | #define TSN_JSON_NEXT_COR_INI \
|
| | | while(true) \
|
| | | { \
|
| | | const uchar _c = m_raw[pos]; \
|
| | | if(_c < 33) \
|
| | | { \
|
| | | pos++; \
|
| | | continue; \
|
| | | } \
|
| | | m_next = g_table_json_tokens[_c]; \
|
| | | if(((1 << m_next) & TSN_JSON_F_VAL_COR) == 0) \
|
| | | { \
|
| | | *m_last_err = TSN_JSON_ERR_MALFORDMED_JSON_AFTER_COR_INI; \
|
| | | TSN_JSON_ON_FINISH \
|
| | | return false; \
|
| | | } \
|
| | | break; \
|
| | | }
|
| | |
|
2026-08-03 12:14:49 -05:00 | | | //--- Luego de una coma en array
|
| | | // Luego de una , y KEY siempre siempre valor
|
2026-09-18 14:11:09 -05:00 | | | #define TSN_JSON_NEXT_VALUE_COMM_KEY \
|
| | | while(true) \
|
| | | { \
|
| | | const uchar _c = m_raw[pos]; \
|
| | | if(_c < 33) \
|
| | | { \
|
| | | pos++; \
|
| | | continue; \
|
| | | } \
|
| | | m_next = g_table_json_tokens[_c]; \
|
| | | if(((1 << m_next) & TSN_JSON_F_ALL_I_VAL) == 0) \
|
| | | { \
|
| | | *m_last_err = TSN_JSON_ERR_MALFORDMED_JSON_FIND_VAL; \
|
| | | TSN_JSON_ON_FINISH \
|
| | | return false; \
|
| | | } \
|
| | | break; \
|
| | | }
|
2026-08-03 15:01:11 -05:00 | | |
|
2026-09-18 14:11:09 -05:00 | | | #define JSONPARSERBYLEO_FULL_NEXT \
|
| | | pos = m_index[sp++]; \
|
| | | m_next = g_table_json_tokens[m_raw[pos]]; \
|
| | | if(((1 << m_next) & m_stak_curr_state) == 0) \
|
| | | { \
|
| | | *m_last_err = TSN_JSON_ERR_MALFORDMED_JSON_AFTER_VAL; \
|
| | | TSN_JSON_ON_FINISH \
|
| | | return false; \
|
2026-08-03 11:26:12 -05:00 | | | }
|
2026-09-18 14:11:09 -05:00 | | |
|
2026-08-26 19:48:01 -05:00 | | | //--- macro para parsear numeros
|
2026-09-18 14:11:09 -05:00 | | | #define JSONPARSERBYLEO_PARSE_NUMBER(SING) \
|
| | | int64_t v = 0; \
|
| | | uchar ch = m_raw[pos] ^ '0'; \
|
| | | while(true) \
|
| | | { \
|
| | | v = (v << 3) + (v << 1) + ch; \
|
| | | pos++; \
|
| | | ch = m_raw[pos] ^ '0'; \
|
| | | if(ch < 10) \
|
| | | continue; \
|
| | | else \
|
| | | if(ch == 30 || (ch | 0x20) == 117) \
|
| | | { \
|
| | | double val = double(v); \
|
| | | if(ch == 30) \
|
| | | { \
|
| | | pos++; \
|
| | | int64_t frac_int = 0; \
|
| | | ushort fract_digits = 0; \
|
| | | while(true) \
|
| | | { \
|
| | | ch = m_raw[pos] ^ '0'; \
|
| | | if(ch > 9) \
|
| | | break; \
|
| | | frac_int = (frac_int << 3) + (frac_int << 1) + ch; \
|
| | | fract_digits++; \
|
| | | pos++; \
|
| | | } \
|
| | | val += frac_int * g_Exp10[fract_digits]; \
|
| | | } \
|
| | | if((ch | 0x20) == 117) \
|
| | | { \
|
| | | pos++; \
|
| | | bool exp_sign = true; \
|
| | | ch = m_raw[pos] ^ '0'; \
|
| | | if(ch > 9) \
|
| | | { \
|
| | | if(ch == 29) \
|
| | | exp_sign = false; \
|
| | | pos++; \
|
| | | ch = m_raw[pos] ^ '0'; \
|
| | | } \
|
| | | ushort exp_val = 0; \
|
| | | while(true) \
|
| | | { \
|
| | | exp_val = (exp_val << 3) + (exp_val << 1) + ch; \
|
| | | pos++; \
|
| | | ch = m_raw[pos] ^ '0'; \
|
| | | if(ch > 9) \
|
| | | break; \
|
| | | } \
|
| | | val *= (exp_sign) ? g_Pow10[exp_val] : g_Exp10[exp_val]; \
|
| | | } \
|
| | | TsnBitInterprete bit; \
|
| | | bit.double_value = val; \
|
| | | m_cinta[cinta_pos++] = JSON_VTYPE_REAL; \
|
| | | m_cinta[cinta_pos++] = SING(bit.long_value); \
|
| | | break; \
|
| | | } \
|
| | | else \
|
| | | { \
|
| | | m_cinta[cinta_pos++] = JSON_VTYPE_INTEGER; \
|
| | | m_cinta[cinta_pos++] = SING(v); \
|
| | | break; \
|
| | | } \
|
2026-08-26 19:48:01 -05:00 | | | }
|
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-09-18 14:11:09 -05:00 | | | bool __stdcall JsonParserResolve(
|
| | | const uint8_t* m_raw, // datos de entrada
|
| | | int64_t* m_cinta, // cinta de datos
|
| | | int* m_index, // array de indices structurales
|
| | | const int len, // tamaño de raw
|
| | | const int m_offset, // offset de inicio para pos
|
| | |
|
| | | //--- salida
|
| | | int* m_last_err, // ultimo err
|
| | | int* m_cinta_pos, // posicion actul en la cinta
|
| | | int* m_pos // ultima posicion en la lecutra de raw
|
| | | ); // retorna true en caso de exito, false de lo contrario..
|
2026-08-26 19:48:01 -05:00 | | | //+------------------------------------------------------------------+
|