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;
|
| | | }
|
| | | }
|
| | | }
|
| | | */
|