//+------------------------------------------------------------------+ //| Parser.cpp | //| Copyright 2026, Niquel Mendoza. | //| https://www.mql5.com/ | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Pre-Defines | //+------------------------------------------------------------------+ #pragma once #define TSNPARSERIN_CPP_DLL #define TSN_TARGET_AVX2 //+------------------------------------------------------------------+ //| Includes | //+------------------------------------------------------------------+ //--- Includes extra #include "..\\..\\..\\BasesParserSLan\\Src\\Def.mqh" #include "..\\JsonDefines.mqh" #include //--- Definiciones base #if defined(TSN_TARGET_AVX512) #include // kernel con __m512i, _mm512_*, 1 carga de 64 bytes #elif defined(TSN_TARGET_AVX2) #include // kernel con __m256i, _mm256_*, 2 cargas de 32 bytes (lo que ya armamos) #elif defined(TSN_TARGET_SSE42) #include // 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 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ using ulong = uint64_t; using uchar = uint8_t; using ushort = uint16_t; //--- mascaras #define TSNTABLES_MASK_IMPARES_F (0xAAAAAAAAAAAAAAAA) #define TSNTABLES_MASK_PARES_F (0x5555555555555555) //+------------------------------------------------------------------+ //| Macros | //+------------------------------------------------------------------+ //--- #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; \ } //--- 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; \ } //--- Luego de una coma en array // Luego de una , y KEY siempre siempre valor #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; \ } #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; \ } //--- macro para parsear numeros #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; \ } \ } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ extern "C" __declspec(dllexport) // array ya allocado tambein raw solo hace falta rellenar 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.. //+------------------------------------------------------------------+