JsonParserByLeo/Src/DLL/Old.mqh

1266 lines
38 KiB
MQL5
Raw Permalink Normal View History

2026-08-03 12:14:54 -05:00
/*
//---
m_stak_curr = -1;
//m_stak_curr_state = -1;
//m_stak_curr = -1;
m_last_err = TSN_JSON_NOT_ERR;
//m_next = TSN_JSON_TOK_INVALID;
m_pos = m_offset;
m_cinta_pos = 0;
m_tables_size = 0;
// m_index_s = 0;
// Tomar un chunk aplicar swar y luego compactralo y añadirlo
#define TSNTABLES_SWAR_HAS_2(mask) (~((mask | TSNTABLES_SWAR_HI) - TSNTABLES_SWAR_LO) & ~mask & TSNTABLES_SWAR_HI)
#define JSONPARSERBYLEO_MAKE_HAS_X(v, p, MASK, COMPACTED) \
const ulong x_##p##v = chunk##v ^ MASK;\
ulong has_##p##v = TSNTABLES_SWAR_HAS_2(x_##p##v);\
COMPACTED |= TSNTABLES_COMPACT_UL_F(has_##p##v) << ((v-1) << 3);
// cargar un chunk
#define JSONPARSERBYLEO_LOAD_CHUNK(v) \
ulong chunk##v = (ulong)m_raw[m_pos++]\
| (ulong)m_raw[m_pos++] << 8\
| (ulong)m_raw[m_pos++] << 16\
| (ulong)m_raw[m_pos++] << 24\
| (ulong)m_raw[m_pos++] << 32\
| (ulong)m_raw[m_pos++] << 40\
| (ulong)m_raw[m_pos++] << 48 \
| (ulong)m_raw[m_pos++] << 56;
// tabla de chars validos (strucutrales)
const uchar g_tsn_jsonparser_t[16] =
{
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, ':', '{',
',', '}', 0, 0
};
#define JSONPARSERBYLEO_FULL_NEXT \
m_pos = m_index[sp++]; \
m_next = g_table_json_tokens[m_raw[m_pos]];\
if(((1 << m_next) & m_stak_curr_state) == 0)\
{\
m_last_err = TSN_JSON_ERR_MALFORDMED_JSON;\
return false;\
}
template <typename T>
string ToBits(T v)
{
string str = "";
for(int i = (sizeof(T) << 3) - 1 ; i >= 0; i--)
{
str += string(uchar((v & (1ULL << i)) == 0 ? 0 : 1));
}
return str;
}
do
{
//---
const int locked = m_pos; // Actual de aqui luego caluremos offsets
//--- Load 64 chars
JSONPARSERBYLEO_LOAD_CHUNK(1)
JSONPARSERBYLEO_LOAD_CHUNK(2)
JSONPARSERBYLEO_LOAD_CHUNK(3)
JSONPARSERBYLEO_LOAD_CHUNK(4)
JSONPARSERBYLEO_LOAD_CHUNK(5)
JSONPARSERBYLEO_LOAD_CHUNK(6)
JSONPARSERBYLEO_LOAD_CHUNK(7)
JSONPARSERBYLEO_LOAD_CHUNK(8)
//---
ulong compacted_bs = 0;
JSONPARSERBYLEO_MAKE_HAS_X(1, bs, TSNTABLES_SWAR_MASK_BACK_SLASH, compacted_bs)
JSONPARSERBYLEO_MAKE_HAS_X(2, bs, TSNTABLES_SWAR_MASK_BACK_SLASH, compacted_bs)
JSONPARSERBYLEO_MAKE_HAS_X(3, bs, TSNTABLES_SWAR_MASK_BACK_SLASH, compacted_bs)
JSONPARSERBYLEO_MAKE_HAS_X(4, bs, TSNTABLES_SWAR_MASK_BACK_SLASH, compacted_bs)
JSONPARSERBYLEO_MAKE_HAS_X(5, bs, TSNTABLES_SWAR_MASK_BACK_SLASH, compacted_bs)
JSONPARSERBYLEO_MAKE_HAS_X(6, bs, TSNTABLES_SWAR_MASK_BACK_SLASH, compacted_bs)
JSONPARSERBYLEO_MAKE_HAS_X(7, bs, TSNTABLES_SWAR_MASK_BACK_SLASH, compacted_bs)
JSONPARSERBYLEO_MAKE_HAS_X(8, bs, TSNTABLES_SWAR_MASK_BACK_SLASH, compacted_bs)
//---
ulong compacted_qt = 0;
JSONPARSERBYLEO_MAKE_HAS_X(1, qt, TSNTABLES_SWAR_MASK_COMILLA, compacted_qt)
JSONPARSERBYLEO_MAKE_HAS_X(2, qt, TSNTABLES_SWAR_MASK_COMILLA, compacted_qt)
JSONPARSERBYLEO_MAKE_HAS_X(3, qt, TSNTABLES_SWAR_MASK_COMILLA, compacted_qt)
JSONPARSERBYLEO_MAKE_HAS_X(4, qt, TSNTABLES_SWAR_MASK_COMILLA, compacted_qt)
JSONPARSERBYLEO_MAKE_HAS_X(5, qt, TSNTABLES_SWAR_MASK_COMILLA, compacted_qt)
JSONPARSERBYLEO_MAKE_HAS_X(6, qt, TSNTABLES_SWAR_MASK_COMILLA, compacted_qt)
JSONPARSERBYLEO_MAKE_HAS_X(7, qt, TSNTABLES_SWAR_MASK_COMILLA, compacted_qt)
JSONPARSERBYLEO_MAKE_HAS_X(8, qt, TSNTABLES_SWAR_MASK_COMILLA, compacted_qt)
//---
compacted_bs &= ~prev_scape;
// Print("compacted_bs (crudo, antes de resta):");
// Print(ToBits(compacted_bs));
// Print("Prevs: ");
// Print(ToBits(prev_in_string));
// Print(ToBits(prev_scape));
// Print("QT");
// Print(ToBits(compacted_qt));
//---
const ulong prev = (((compacted_bs << 1) | TSNTABLES_MASK_IMPARES_F) - compacted_bs) ^ TSNTABLES_MASK_IMPARES_F;
const ulong escaped = prev ^ compacted_bs;
prev_scape = (prev & compacted_bs) >> 63;
ulong qt_final = compacted_qt & ~escaped;
const ulong quoted_pos = qt_final;
//Print("QT Final");
// Print(ToBits(qt_final));
//--- Ahora lo que hacemos es un xor "desencanodoad" la idea es 1 en donde es "in string"
// y 0 dodne nolo es
qt_final ^= qt_final << 1;
//Print(ToBits(qt_final));
qt_final ^= qt_final << 2;
// Print(ToBits(qt_final));
qt_final ^= qt_final << 4;
// Print(ToBits(qt_final));
qt_final ^= qt_final << 8;
//Print(ToBits(qt_final));
qt_final ^= qt_final << 16;
// Print(ToBits(qt_final));
qt_final ^= qt_final << 32;
// Print(ToBits(qt_final));
//---
const ulong in_string = qt_final ^ prev_in_string;
//---
chunk1 |= 0x2020202020202020;
chunk2 |= 0x2020202020202020;
chunk3 |= 0x2020202020202020;
chunk4 |= 0x2020202020202020;
chunk5 |= 0x2020202020202020;
chunk6 |= 0x2020202020202020;
chunk7 |= 0x2020202020202020;
chunk8 |= 0x2020202020202020;
//---
ulong result = 0;
result |= ulong(g_tsn_jsonparser_t[chunk1 & 0xF] == (chunk1 & 0xff));
result |= ulong(g_tsn_jsonparser_t[(chunk1 >> 8) & 0xF] == ((chunk1 >> 8) & 0xff)) << 1;
result |= ulong(g_tsn_jsonparser_t[(chunk1 >> 16) & 0xF] == ((chunk1 >> 16) & 0xff)) << 2;
result |= ulong(g_tsn_jsonparser_t[(chunk1 >> 24) & 0xF] == ((chunk1 >> 24) & 0xff)) << 3;
result |= ulong(g_tsn_jsonparser_t[(chunk1 >> 32) & 0xF] == ((chunk1 >> 32) & 0xff)) << 4;
result |= ulong(g_tsn_jsonparser_t[(chunk1 >> 40) & 0xF] == ((chunk1 >> 40) & 0xff)) << 5;
result |= ulong(g_tsn_jsonparser_t[(chunk1 >> 48) & 0xF] == ((chunk1 >> 48) & 0xff)) << 6;
result |= ulong(g_tsn_jsonparser_t[(chunk1 >> 56) & 0xF] == ((chunk1 >> 56) & 0xff)) << 7;
result |= ulong(g_tsn_jsonparser_t[chunk2 & 0xF] == (chunk2 & 0xff)) << 8;
result |= ulong(g_tsn_jsonparser_t[(chunk2 >> 8) & 0xF] == ((chunk2 >> 8) & 0xff)) << 9;
result |= ulong(g_tsn_jsonparser_t[(chunk2 >> 16) & 0xF] == ((chunk2 >> 16) & 0xff)) << 10;
result |= ulong(g_tsn_jsonparser_t[(chunk2 >> 24) & 0xF] == ((chunk2 >> 24) & 0xff)) << 11;
result |= ulong(g_tsn_jsonparser_t[(chunk2 >> 32) & 0xF] == ((chunk2 >> 32) & 0xff)) << 12;
result |= ulong(g_tsn_jsonparser_t[(chunk2 >> 40) & 0xF] == ((chunk2 >> 40) & 0xff)) << 13;
result |= ulong(g_tsn_jsonparser_t[(chunk2 >> 48) & 0xF] == ((chunk2 >> 48) & 0xff)) << 14;
result |= ulong(g_tsn_jsonparser_t[(chunk2 >> 56) & 0xF] == ((chunk2 >> 56) & 0xff)) << 15;
result |= ulong(g_tsn_jsonparser_t[chunk3 & 0xF] == (chunk3 & 0xff)) << 16;
result |= ulong(g_tsn_jsonparser_t[(chunk3 >> 8) & 0xF] == ((chunk3 >> 8) & 0xff)) << 17;
result |= ulong(g_tsn_jsonparser_t[(chunk3 >> 16) & 0xF] == ((chunk3 >> 16) & 0xff)) << 18;
result |= ulong(g_tsn_jsonparser_t[(chunk3 >> 24) & 0xF] == ((chunk3 >> 24) & 0xff)) << 19;
result |= ulong(g_tsn_jsonparser_t[(chunk3 >> 32) & 0xF] == ((chunk3 >> 32) & 0xff)) << 20;
result |= ulong(g_tsn_jsonparser_t[(chunk3 >> 40) & 0xF] == ((chunk3 >> 40) & 0xff)) << 21;
result |= ulong(g_tsn_jsonparser_t[(chunk3 >> 48) & 0xF] == ((chunk3 >> 48) & 0xff)) << 22;
result |= ulong(g_tsn_jsonparser_t[(chunk3 >> 56) & 0xF] == ((chunk3 >> 56) & 0xff)) << 23;
result |= ulong(g_tsn_jsonparser_t[chunk4 & 0xF] == (chunk4 & 0xff)) << 24;
result |= ulong(g_tsn_jsonparser_t[(chunk4 >> 8) & 0xF] == ((chunk4 >> 8) & 0xff)) << 25;
result |= ulong(g_tsn_jsonparser_t[(chunk4 >> 16) & 0xF] == ((chunk4 >> 16) & 0xff)) << 26;
result |= ulong(g_tsn_jsonparser_t[(chunk4 >> 24) & 0xF] == ((chunk4 >> 24) & 0xff)) << 27;
result |= ulong(g_tsn_jsonparser_t[(chunk4 >> 32) & 0xF] == ((chunk4 >> 32) & 0xff)) << 28;
result |= ulong(g_tsn_jsonparser_t[(chunk4 >> 40) & 0xF] == ((chunk4 >> 40) & 0xff)) << 29;
result |= ulong(g_tsn_jsonparser_t[(chunk4 >> 48) & 0xF] == ((chunk4 >> 48) & 0xff)) << 30;
result |= ulong(g_tsn_jsonparser_t[(chunk4 >> 56) & 0xF] == ((chunk4 >> 56) & 0xff)) << 31;
result |= ulong(g_tsn_jsonparser_t[chunk5 & 0xF] == (chunk5 & 0xff)) << 32;
result |= ulong(g_tsn_jsonparser_t[(chunk5 >> 8) & 0xF] == ((chunk5 >> 8) & 0xff)) << 33;
result |= ulong(g_tsn_jsonparser_t[(chunk5 >> 16) & 0xF] == ((chunk5 >> 16) & 0xff)) << 34;
result |= ulong(g_tsn_jsonparser_t[(chunk5 >> 24) & 0xF] == ((chunk5 >> 24) & 0xff)) << 35;
result |= ulong(g_tsn_jsonparser_t[(chunk5 >> 32) & 0xF] == ((chunk5 >> 32) & 0xff)) << 36;
result |= ulong(g_tsn_jsonparser_t[(chunk5 >> 40) & 0xF] == ((chunk5 >> 40) & 0xff)) << 37;
result |= ulong(g_tsn_jsonparser_t[(chunk5 >> 48) & 0xF] == ((chunk5 >> 48) & 0xff)) << 38;
result |= ulong(g_tsn_jsonparser_t[(chunk5 >> 56) & 0xF] == ((chunk5 >> 56) & 0xff)) << 39;
result |= ulong(g_tsn_jsonparser_t[chunk6 & 0xF] == (chunk6 & 0xff)) << 40;
result |= ulong(g_tsn_jsonparser_t[(chunk6 >> 8) & 0xF] == ((chunk6 >> 8) & 0xff)) << 41;
result |= ulong(g_tsn_jsonparser_t[(chunk6 >> 16) & 0xF] == ((chunk6 >> 16) & 0xff)) << 42;
result |= ulong(g_tsn_jsonparser_t[(chunk6 >> 24) & 0xF] == ((chunk6 >> 24) & 0xff)) << 43;
result |= ulong(g_tsn_jsonparser_t[(chunk6 >> 32) & 0xF] == ((chunk6 >> 32) & 0xff)) << 44;
result |= ulong(g_tsn_jsonparser_t[(chunk6 >> 40) & 0xF] == ((chunk6 >> 40) & 0xff)) << 45;
result |= ulong(g_tsn_jsonparser_t[(chunk6 >> 48) & 0xF] == ((chunk6 >> 48) & 0xff)) << 46;
result |= ulong(g_tsn_jsonparser_t[(chunk6 >> 56) & 0xF] == ((chunk6 >> 56) & 0xff)) << 47;
result |= ulong(g_tsn_jsonparser_t[chunk7 & 0xF] == (chunk7 & 0xff)) << 48;
result |= ulong(g_tsn_jsonparser_t[(chunk7 >> 8) & 0xF] == ((chunk7 >> 8) & 0xff)) << 49;
result |= ulong(g_tsn_jsonparser_t[(chunk7 >> 16) & 0xF] == ((chunk7 >> 16) & 0xff)) << 50;
result |= ulong(g_tsn_jsonparser_t[(chunk7 >> 24) & 0xF] == ((chunk7 >> 24) & 0xff)) << 51;
result |= ulong(g_tsn_jsonparser_t[(chunk7 >> 32) & 0xF] == ((chunk7 >> 32) & 0xff)) << 52;
result |= ulong(g_tsn_jsonparser_t[(chunk7 >> 40) & 0xF] == ((chunk7 >> 40) & 0xff)) << 53;
result |= ulong(g_tsn_jsonparser_t[(chunk7 >> 48) & 0xF] == ((chunk7 >> 48) & 0xff)) << 54;
result |= ulong(g_tsn_jsonparser_t[(chunk7 >> 56) & 0xF] == ((chunk7 >> 56) & 0xff)) << 55;
result |= ulong(g_tsn_jsonparser_t[chunk8 & 0xF] == (chunk8 & 0xff)) << 56;
result |= ulong(g_tsn_jsonparser_t[(chunk8 >> 8) & 0xF] == ((chunk8 >> 8) & 0xff)) << 57;
result |= ulong(g_tsn_jsonparser_t[(chunk8 >> 16) & 0xF] == ((chunk8 >> 16) & 0xff)) << 58;
result |= ulong(g_tsn_jsonparser_t[(chunk8 >> 24) & 0xF] == ((chunk8 >> 24) & 0xff)) << 59;
result |= ulong(g_tsn_jsonparser_t[(chunk8 >> 32) & 0xF] == ((chunk8 >> 32) & 0xff)) << 60;
result |= ulong(g_tsn_jsonparser_t[(chunk8 >> 40) & 0xF] == ((chunk8 >> 40) & 0xff)) << 61;
result |= ulong(g_tsn_jsonparser_t[(chunk8 >> 48) & 0xF] == ((chunk8 >> 48) & 0xff)) << 62;
result |= ulong(g_tsn_jsonparser_t[(chunk8 >> 56) & 0xF] == ((chunk8 >> 56) & 0xff)) << 63;
// [ " " : 20, " 20" : 20 ]
// 1 000
//Print("Estructural");
//Print(ToBits(result));
//Print("In string");
//Print(ToBits(in_string));
//---
prev_in_string = ulong(int64_t(in_string) >> 63); // cast para forazr el >> con 1unos (Aritmetico)
ulong structural = (result & ~in_string) | quoted_pos;
//---
//Print("Final");
//Print(ToBits(structural));
//--- iteracion
while(structural != 0)
{
2026-08-27 13:40:38 -05:00
const ulong flag = TSNTABLES_BIT_DEJAR_SOLO_MINUS_SIG_BYTE(structural);
m_index[m_index_s++] = locked + TSNTABLES_CTZ_64_GET_BIT(flag);
2026-08-03 12:14:54 -05:00
//Print(CharToString(m_raw[m_index[m_index_s - 1]]));
structural &= (structural - 1);
}
}
while((m_pos + 64) < m_len);
//----
m_index_s = JsonParserResolve(m_raw, m_len, m_index);
int sp = 0;
m_pos = m_index[sp]; // Posicion
m_next = g_table_json_tokens[m_raw[m_pos]]; // primer
while(true)
{
switch(m_next)
{
case TSN_JSON_TOK_NUMBER:
{
//---
long v = 0;
//--- Validamos signo
long mask = 0;
uchar ch = m_raw[m_pos];
if(ch == '-')
{
mask = -1;
m_pos++; // Ahora en numero
ch = m_raw[m_pos];
}
//---
ch ^= '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++;
long 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];
}
//--- 10e50.02500140
if((m_raw[m_pos] | 0x20) == 'e') // e or 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];
}
//---
static BitInterpreter bit;
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; // Fin
}
}
//---
JSONPARSERBYLEO_FULL_NEXT
break;
}
//---
case TSN_JSON_TOK_STRING:
{
//---
//TSN_JSON_RESERVAR(2)
//---
const int start = m_index[sp++] + 1; // luego del "
m_pos = m_index[sp++]; // justo en "
//---
m_cinta[m_cinta_pos++] = JSON_VTYPE_STRING
| long(m_pos - start) << TSN_SBL_BIT_STR_LEN
| long(start) << TSN_SBL_BIT_STR_START;
//---
JSONPARSERBYLEO_FULL_NEXT
//---
break;
}
case TSN_JSON_TOK_BOOL_TRUE:
{
//TSN_JSON_RESERVAR(1)
// t r u e W
// [-4] [-3] [-2] [-1] [0]
m_pos += 4;
// 5 | 1 << TSN_SBL_BIT_START_BOOL(4) = 21
m_cinta[m_cinta_pos++] = 21;
//---
JSONPARSERBYLEO_FULL_NEXT
break;
}
case TSN_JSON_TOK_BOOL_FALSE:
{
//TSN_JSON_RESERVAR(1)
// f a l s e W
// [] [-4] [-3] [-2 ] [-1] [0]
m_pos += 5;
m_cinta[m_cinta_pos++] = JSON_VTYPE_BOOLEAN;
//---
JSONPARSERBYLEO_FULL_NEXT
break;
}
case TSN_JSON_TOK_NULL:
{
//TSN_JSON_RESERVAR(1)
// n u l l W
// [-4][-3][-2][-1][]
//---
m_pos += 4;
m_cinta[m_cinta_pos++] = JSON_VTYPE_NULL;
//---
JSONPARSERBYLEO_FULL_NEXT
break;
}
case TSN_JSON_TOK_COMMA:
{
//---
m_stak_num[m_stak_curr]++;
//---
m_pos++;
//---
if(m_stak_curr_state == TSN_JSON_CTX_IN_OBJ)
{
//---
const int start = m_index[sp++] + 1; // luego del "
m_pos = m_index[sp++]; // justo en "
//Print("start: " , start, " len: " , (m_pos - start));
//---
m_cinta[m_cinta_pos++] = (long)JSON_VTYPE_KEY
| long(m_pos - start) << TSN_SBL_BIT_STR_LEN
| long(start) << TSN_SBL_BIT_STR_START;
// Print(EnumToString(ENUM_JSON_VTYPE(m_cinta[m_cinta_pos - 1] & 0xf)));
//---
m_pos = m_index[sp++];
if(m_raw[m_pos++] != ':')
{
m_last_err = TSN_JSON_ERR_MALFODERD_KEY_EXPECTED_DOS_PUNTOS;
return false;
}
// Ahora si buscamos valor
}
TSN_JSON_NEXT_VALUE_COMM_KEY
break;
}
case TSN_JSON_TOK_LLAVE_INI:
{
//---
sp++;
//TSN_JSON_RESERVAR(1)
m_cinta[m_cinta_pos] = JSON_VTYPE_OBJ;
//---
m_stak_curr++;
m_stak_curr_state = TSN_JSON_CTX_IN_OBJ;
m_stak_state[m_stak_curr] = TSN_JSON_CTX_IN_OBJ;
m_stak_num[m_stak_curr] = 0;
m_stak_pos[m_stak_curr] = m_cinta_pos++;
//---
m_cinta[m_cinta_pos++] = m_pos++;
//---
m_pos = m_index[sp++];
if(m_raw[m_pos] == '}')
{
m_next = TSN_JSON_TOK_LLAVE_END;
}
else
{
const int start = ++m_pos;
m_pos = m_index[sp++]; // justo en "
//--- Capturamos
m_cinta[m_cinta_pos++] = JSON_VTYPE_KEY
| long(m_pos - start) << TSN_SBL_BIT_STR_LEN
| long(start) << TSN_SBL_BIT_STR_START;
//---
m_pos = m_index[sp++];
if(m_raw[m_pos++] != ':')
{
m_last_err = TSN_JSON_ERR_MALFODERD_KEY_EXPECTED_DOS_PUNTOS;
return false;
}
// Ahora a buscar valor
TSN_JSON_NEXT_VALUE_COMM_KEY
}
//---
break;
}
case TSN_JSON_TOK_COR_INI:
{
//---
sp++;
//TSN_JSON_RESERVAR(1)
m_cinta[m_cinta_pos] = JSON_VTYPE_ARR;
//---
m_stak_curr++;
m_stak_curr_state = TSN_JSON_CTX_IN_ARR;
m_stak_state[m_stak_curr] = TSN_JSON_CTX_IN_ARR;
m_stak_num[m_stak_curr] = 0;
m_stak_pos[m_stak_curr] = m_cinta_pos++;
//---
m_cinta[m_cinta_pos++] = m_pos++;
//Print(CharToString(m_raw[m_pos]));
//---
const int n = m_index[sp];
if(m_raw[n] != ']')
{
TSN_JSON_NEXT_COR_INI
}
else
{
sp++;
m_pos = n;
m_next = TSN_JSON_TOK_LLAVE_END;
}
//---
break;
}
// tema de ends ya lo scaa en next el sp
case TSN_JSON_TOK_LLAVE_END:
case TSN_JSON_TOK_COR_END:
{
//---
//sp++;
//---
if(m_cinta_pos > m_stak_pos[m_stak_curr] + 2) // [a][a][v][c]
{
m_stak_num[m_stak_curr]++;
}
//---
const int lp = m_stak_pos[m_stak_curr];
m_cinta[lp] |= long(m_stak_num[m_stak_curr]) << TSN_SBL_BIT_START_NUM_EL | long(m_cinta_pos - lp) << TSN_SBL_BIT_START_NUM_C;
m_cinta[lp + 1] |= long(m_pos) << TSN_JSON_BIT_END_T;
//---
//m_stak_curr--;
//---
if(--m_stak_curr < 0)
return true;
//---
m_stak_curr_state = m_stak_state[m_stak_curr];
//---
m_pos++;
//---
JSONPARSERBYLEO_FULL_NEXT
//---
break;
}
//---
default:
{
m_last_err = TSN_JSON_ERR_INVALID_CHAR;
return false;
}
}
}
}
#endif // JSONPARSERBYLEO_DLL
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CJsonParser::Parse()
{
//---
m_stak_curr = -1;
//m_stak_curr_state = -1;
//m_stak_curr = -1;
m_last_err = TSN_JSON_NOT_ERR;
//m_next = TSN_JSON_TOK_INVALID;
m_pos = m_offset;
m_cinta_pos = 0;
m_tables_size = 0;
//--- Inicial
const uchar _f_c = m_raw[m_pos];
if(_f_c == '{')
{
m_next = TSN_JSON_TOK_LLAVE_INI;
}
else
if(_f_c == '[')
{
m_next = TSN_JSON_TOK_COR_INI;
}
else
{
m_pos++;
while(true)
{
const uchar _f__c = m_raw[m_pos];
if(_f__c < 33)
{
m_pos++;
continue;
}
//---
if(_f__c == '{')
{
m_next = TSN_JSON_TOK_LLAVE_INI;
}
else
if(_f__c == '[')
{
m_next = TSN_JSON_TOK_COR_INI;
}
else
{
m_next = TSN_JSON_TOK_INVALID;
}
break;
}
}
//--- Bucle
while(true)
{
switch(m_next)
{
case TSN_JSON_TOK_NUMBER:
{
//---
long v = 0;
//--- Validamos signo
long mask = 0;
uchar ch = m_raw[m_pos];
if(ch == '-')
{
mask = -1;
m_pos++; // Ahora en numero
ch = m_raw[m_pos];
}
//---
ch ^= '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++;
long 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];
}
//--- 10e50.02500140
if((m_raw[m_pos] | 0x20) == 'e') // e or 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];
}
//---
static BitInterpreter bit;
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; // Fin
}
}
//--- no hago el m_pos++ dado que ahora mismo estamo en el seg char
TSN_JSON_NEXT_NO_NEXT_KEY
break;
}
//---
case TSN_JSON_TOK_STRING:
{
//---
//TSN_JSON_RESERVAR(2)
//---
const int start = ++m_pos;
//---
#ifndef JSONPARSERBYLEO_DESACTIVE_SWAR
//--- Pase inicial 8 en 8
while(true)
{
// PrintFormat("Analizando: '%s'", CharArrayToString(m_raw, m_pos, 8));
const ulong chunk = (ulong)m_raw[m_pos]
| (ulong)m_raw[m_pos + 1] << 8
| (ulong)m_raw[m_pos + 2] << 16
| (ulong)m_raw[m_pos + 3] << 24
| (ulong)m_raw[m_pos + 4] << 32
| (ulong)m_raw[m_pos + 5] << 40
| (ulong)m_raw[m_pos + 6] << 48
| (ulong)m_raw[m_pos + 7] << 56;
//---
const ulong x_bs = chunk ^ TSNTABLES_SWAR_MASK_BACK_SLASH;
ulong has_bs = TSNTABLES_SWAR_HAS(x_bs);
const ulong x_qt = chunk ^ TSNTABLES_SWAR_MASK_COMILLA;
const ulong has_qt = TSNTABLES_SWAR_HAS(x_qt);
//---
if((has_bs | has_qt) == 0) // Caso comun. .. ninguno de los dos.. continuamos..
{
m_pos += 8;
if((m_pos + 7) >= m_len) // Ultimas 8 posicinoes son " " asi que seria invalido ya..
{
m_last_err = TSN_JSON_ERR_STRING_NOT_CLOSED;
return false;
}
continue;
}
//---
if(has_bs == 0) // Si not iene bs (pero confirmamos que no es 0)
// Entonces no tirne bs pero si qt salimos de una..
{
2026-08-27 13:40:38 -05:00
const ulong flag_real = TSNTABLES_BIT_DEJAR_SOLO_MINUS_SIG_BYTE(has_qt);
2026-08-03 12:14:54 -05:00
//---
2026-08-27 13:40:38 -05:00
m_pos += TSNTABLES_CTZ_64_GET_BYTE(flag_real);
2026-08-03 12:14:54 -05:00
m_cinta[m_cinta_pos++] = JSON_VTYPE_STRING
| long(m_pos - start) << TSN_SBL_BIT_STR_LEN
| long(start) << TSN_SBL_BIT_STR_START;
m_pos++; // Luego del "
break;
}
//--- Hay bs si o si pero tambien puede haber "
const uchar compacted_bs = TSNTABLES_COMPACT_UL(has_bs);
const uchar prev = (((compacted_bs << 1) | TSNTABLES_MASK_IMPARES) - compacted_bs) ^ TSNTABLES_MASK_IMPARES;
const uchar escaped = prev ^ compacted_bs;
//---
const uchar compacted_qt = TSNTABLES_COMPACT_UL(has_qt);
const uchar qt_final = compacted_qt & ~escaped;
//Print("nada");
//---
if(qt_final != 0) // Hay un qt real de cierre
{
// Avanzamos y cerramos..
2026-08-27 13:40:38 -05:00
m_pos += g_tsntables_table_ctz_i8[qt_final];
2026-08-03 12:14:54 -05:00
m_cinta[m_cinta_pos++] = JSON_VTYPE_STRING
| long(m_pos - start) << TSN_SBL_BIT_STR_LEN
| long(start) << TSN_SBL_BIT_STR_START;
m_pos++; // Luego del "
break;
}
else
{
m_pos += 8;
// Print(CharToString(m_raw[m_pos]));
// escape
if(((prev & compacted_bs) >> 7U) != 0) // Overflow el ultimo char es \ y el siguiente escapa
{
//Print("siuu");
m_pos++; // Uno mas.. luego del currend
}
// No hay ... o es escapado en caso exista
if((m_pos + 7) >= m_len) // Ultimas 8 posicinoes son " " asi que seria invalido ya..
{
m_last_err = TSN_JSON_ERR_STRING_NOT_CLOSED;
return false;
}
}
}
#else // JSONPARSERBYLEO_DESACTIVE_SWAR
//--- Char por char
do
{
const uchar c = m_raw[m_pos];
//---
if(c == '\\')
{
m_pos += 2;
continue;
}
if(c == '"')
{
// STRING 1 slot: [tipo(4)|len(28low)|start(32high)]
m_cinta[m_cinta_pos++] = JSON_VTYPE_STRING | long(m_pos - start) << TSN_SBL_BIT_STR_LEN |
long(start) << TSN_SBL_BIT_STR_START;
// curr_end = INT_MAX;
m_pos++;
break;
}
//---
m_pos++;
}
while(m_pos < m_len);
#endif // JSONPARSERBYLEO_DESACTIVE_SWAR
//---
TSN_JSON_NEXT_NO_NEXT_KEY
//---
break;
}
case TSN_JSON_TOK_BOOL_TRUE:
{
//TSN_JSON_RESERVAR(1)
// t r u e W
// [-4] [-3] [-2] [-1] [0]
m_pos += 4;
// 5 | 1 << TSN_SBL_BIT_START_BOOL(4) = 21
m_cinta[m_cinta_pos++] = 21;
//---
TSN_JSON_NEXT_NO_NEXT_KEY
break;
}
case TSN_JSON_TOK_BOOL_FALSE:
{
//TSN_JSON_RESERVAR(1)
// f a l s e W
// [] [-4] [-3] [-2 ] [-1] [0]
m_pos += 5;
m_cinta[m_cinta_pos++] = JSON_VTYPE_BOOLEAN;
//---
TSN_JSON_NEXT_NO_NEXT_KEY
break;
}
case TSN_JSON_TOK_NULL:
{
//TSN_JSON_RESERVAR(1)
// n u l l W
// [-4][-3][-2][-1][]
//---
m_pos += 4;
m_cinta[m_cinta_pos++] = JSON_VTYPE_NULL;
//---
TSN_JSON_NEXT_NO_NEXT_KEY
break;
}
case TSN_JSON_TOK_COMMA:
{
//---
m_stak_num[m_stak_curr]++;
//---
m_pos++;
//---
if(m_stak_curr_state == TSN_JSON_CTX_IN_OBJ)
{
TSN_JSON_NEXT_ESPECIFIC_DO('"', TSN_JSON_TOK_KEY)
}
else
{
TSN_JSON_NEXT_VALUE_COMM_KEY
}
break;
}
case TSN_JSON_TOK_LLAVE_INI:
{
//TSN_JSON_RESERVAR(1)
m_cinta[m_cinta_pos] = JSON_VTYPE_OBJ;
//---
m_stak_curr++;
m_stak_curr_state = TSN_JSON_CTX_IN_OBJ;
m_stak_state[m_stak_curr] = TSN_JSON_CTX_IN_OBJ;
m_stak_num[m_stak_curr] = 0;
m_stak_pos[m_stak_curr] = m_cinta_pos++;
//---
m_cinta[m_cinta_pos++] = m_pos++;
//---
TSN_JSON_NEXT_LLAVE_INI
//---
break;
}
case TSN_JSON_TOK_COR_INI:
{
//TSN_JSON_RESERVAR(1)
m_cinta[m_cinta_pos] = JSON_VTYPE_ARR;
//---
m_stak_curr++;
m_stak_curr_state = TSN_JSON_CTX_IN_ARR;
m_stak_state[m_stak_curr] = TSN_JSON_CTX_IN_ARR;
m_stak_num[m_stak_curr] = 0;
m_stak_pos[m_stak_curr] = m_cinta_pos++;
//---
m_cinta[m_cinta_pos++] = m_pos++;
//---
TSN_JSON_NEXT_COR_INI
//---
break;
}
case TSN_JSON_TOK_LLAVE_END:
case TSN_JSON_TOK_COR_END:
{
//---
if(m_cinta_pos > m_stak_pos[m_stak_curr] + 2) // [a][a][v][c]
{
m_stak_num[m_stak_curr]++;
}
//---
const int lp = m_stak_pos[m_stak_curr];
m_cinta[lp] |= long(m_stak_num[m_stak_curr]) << TSN_SBL_BIT_START_NUM_EL | long(m_cinta_pos - lp) << TSN_SBL_BIT_START_NUM_C;
m_cinta[lp + 1] |= long(m_pos) << TSN_JSON_BIT_END_T;
//---
//m_stak_curr--;
//---
if(--m_stak_curr < 0)
return true;
//---
m_stak_curr_state = m_stak_state[m_stak_curr];
//---
m_pos++;
//---
TSN_JSON_NEXT_NO_NEXT_KEY
//---
break;
}
case TSN_JSON_TOK_KEY:
{
const int start = ++m_pos;
//---
#ifndef JSONPARSERBYLEO_ACTIVE_SWAR_KEYS
//--- Pase inicial 8 en 8
while(true)
{
// "asdasdasd".........."
// PrintFormat("Analizando: '%s'", CharArrayToString(m_raw, m_pos, 8));
const ulong chunk = (ulong)m_raw[m_pos]
| (ulong)m_raw[m_pos + 1] << 8
| (ulong)m_raw[m_pos + 2] << 16
| (ulong)m_raw[m_pos + 3] << 24
| (ulong)m_raw[m_pos + 4] << 32
| (ulong)m_raw[m_pos + 5] << 40
| (ulong)m_raw[m_pos + 6] << 48
| (ulong)m_raw[m_pos + 7] << 56;
//---
#ifdef JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
const ulong x_bs = chunk ^ TSNTABLES_SWAR_MASK_BACK_SLASH;
ulong has_bs = TSNTABLES_SWAR_HAS(x_bs);
#endif // JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
const ulong x_qt = chunk ^ TSNTABLES_SWAR_MASK_COMILLA;
const ulong has_qt = TSNTABLES_SWAR_HAS(x_qt);
//---
#ifdef JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
if((has_bs | has_qt) == 0) // Caso comun. .. ninguno de los dos.. continuamos..
{
m_pos += 8;
if((m_pos + 7) >= m_len) // Ultimas 8 posicinoes son " " asi que seria invalido ya..
{
m_last_err = TSN_JSON_ERR_KEY_NOT_CLOSED;
return false;
}
continue;
}
#else // JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
if(has_qt == 0) // Caso comun. .. ninguno de los dos.. continuamos..
{
m_pos += 8;
if((m_pos + 7) >= m_len) // Ultimas 8 posicinoes son " " asi que seria invalido ya..
{
m_last_err = TSN_JSON_ERR_KEY_NOT_CLOSED;
return false;
}
continue;
}
#endif
//---
#ifdef JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
if(has_bs == 0) // Si not iene bs (pero confirmamos que no es 0)
// Entonces no tirne bs pero si qt salimos de una..
{
#endif // JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
2026-08-27 13:40:38 -05:00
const ulong flag_real = TSNTABLES_BIT_DEJAR_SOLO_MINUS_SIG_BYTE(has_qt);
2026-08-03 12:14:54 -05:00
//---
2026-08-27 13:40:38 -05:00
m_pos += TSNTABLES_CTZ_64_GET_BYTE(flag_real);
2026-08-03 12:14:54 -05:00
m_cinta[m_cinta_pos++] = JSON_VTYPE_KEY
| long(m_pos - start) << TSN_SBL_BIT_STR_LEN
| long(start) << TSN_SBL_BIT_STR_START;
m_pos++; // Luego del "
break;
#ifdef JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
}
//---
const uchar compacted_bs = TSNTABLES_COMPACT_UL(has_bs);
const uchar prev = (((compacted_bs << 1) | TSNTABLES_MASK_IMPARES) - compacted_bs) ^ TSNTABLES_MASK_IMPARES;
const uchar escaped = prev ^ compacted_bs;
//---
const uchar compacted_qt = TSNTABLES_COMPACT_UL(has_qt);
const uchar qt_final = compacted_qt & ~escaped;
//---
if(qt_final != 0) // Hay un qt real de cierre
{
// Avanzamos y cerramos..
2026-08-27 13:40:38 -05:00
m_pos += g_tsntables_table_ctz_i8[qt_final];
2026-08-03 12:14:54 -05:00
m_cinta[m_cinta_pos++] = JSON_VTYPE_STRING
| long(m_pos - start) << TSN_SBL_BIT_STR_LEN
| long(start) << TSN_SBL_BIT_STR_START;
m_pos++; // Luego del "
break;
}
else
{
m_pos += 8;
// Print(CharToString(m_raw[m_pos]));
if(((prev & compacted_bs) >> 7U) != 0) // Overflow el ultimo char es \ y el siguiente escapa
{
//Print("siuu");
m_pos++; // Uno mas.. luego del currend
}
// No hay ... o es escapado en caso exista
if((m_pos + 7) >= m_len) // Ultimas 8 posicinoes son " " asi que seria invalido ya..
{
m_last_err = TSN_JSON_ERR_KEY_NOT_CLOSED;
return false;
}
}
#endif // JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
}
#else // JSONPARSERBYLEO_ACTIVE_SWAR_KEYS
//--- Char por char
while(true)
{
#ifdef JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
const uchar c = m_raw[m_pos];
if(c == '\\')
{
m_pos += 2;
continue;
}
if(c == '"')
{
m_cinta[m_cinta_pos++] = JSON_VTYPE_KEY
| long(m_pos - start) << TSN_SBL_BIT_STR_LEN
| long(start) << TSN_SBL_BIT_STR_START;
// curr_end = INT_MAX;
m_pos++;
break;
}
#else // JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
if(m_raw[m_pos] == '"')
{
m_cinta[m_cinta_pos++] = JSON_VTYPE_KEY
| long(m_pos - start) << TSN_SBL_BIT_STR_LEN
| long(start) << TSN_SBL_BIT_STR_START;
// curr_end = INT_MAX;
m_pos++;
break;
}
#endif // JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
//---
m_pos++;
if(m_pos >= m_len)
{
m_last_err = TSN_JSON_ERR_KEY_NOT_CLOSED;
return false;
}
}
#endif // JSONPARSERBYLEO_ACTIVE_SWAR_KEYS
//--- Find :
while(true)
{
//---
if(m_raw[m_pos] == ':')
break;
//---
m_pos++;
if(m_pos >= m_len)
{
m_last_err = TSN_JSON_ERR_MALFODERD_KEY_EXPECTED_DOS_PUNTOS;
return false;
}
}
//---
m_pos++; // Luego del
//--- Buscamos valor
TSN_JSON_NEXT_VALUE_COMM_KEY
//---
break;
}
default:
{
m_last_err = TSN_JSON_ERR_INVALID_CHAR;
return false;
}
}
}
*/