809 lines
22 KiB
MQL5
809 lines
22 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| JsonAsm.mqh |
| |
//| Copyright 2026, Niquel Mendoza. |
| |
//| https://www.mql5.com/ |
| |
//+------------------------------------------------------------------+
| |
#property copyright "Copyright 2026, Niquel Mendoza."
| |
#property link "https://www.mql5.com/"
| |
#property strict
| |
| |
#ifndef JSONPARSERBYLEO_SRC_JSONASM_MQH
| |
#define JSONPARSERBYLEO_SRC_JSONASM_MQH
| |
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
#include "JsonParser.mqh"
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
namespace TSN
| |
{
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
int CJsonParser::ToJsonAsm(uchar& text[]) const
| |
{
| |
//---
| |
int p = 0; // Lectura de cinta
| |
int w = 0; // Escritura en text
| |
| |
//---
| |
ArrayResize(text, (m_len << 1));
| |
| |
//--- Pila de posiciones de "muerte" (en slots de cinta) de cada ARR/OBJ abierto
| |
int end_stack[JSONPARSERBYLEO_MAX_STACK];
| |
int stack_curr = -1;
| |
| |
//---
| |
while(p < m_cinta_pos)
| |
{
| |
//---
| |
const ENUM_JSON_VTYPE tipo = ENUM_JSON_VTYPE(m_cinta[p] & 0xF);
| |
| |
//---
| |
switch(tipo)
| |
{
| |
//---
| |
case JSON_VTYPE_KEY:
| |
{
| |
// KEY 1 slot: [tipo(4)|len(28low)|start(32high)] (igual que STRING)
| |
const int s = int(m_cinta[p] >> TSN_SBL_BIT_STR_START);
| |
const int slen = int((m_cinta[p] >> TSN_SBL_BIT_STR_LEN) & TSN_SBL_BIT_STR_MASK_LEN);
| |
| |
text[w++] = 'K';
| |
text[w++] = ' ';
| |
text[w++] = '"';
| |
w += ArrayCopy(text, m_raw, w, s, slen);
| |
text[w++] = '"';
| |
text[w++] = '\n';
| |
break;
| |
}
| |
| |
//---
| |
case JSON_VTYPE_OBJ:
| |
case JSON_VTYPE_ARR:
| |
{
| |
text[w++] = tipo == JSON_VTYPE_ARR ? 'A' : 'O';
| |
text[w++] = ' ';
| |
text[w++] = '\n';
| |
| |
//--- num_c = slots de cinta que ocupa este contenedor completo (incluyéndose a sí mismo)
| |
const int num_c = int(m_cinta[p] >> TSN_SBL_BIT_START_NUM_C);
| |
| |
//--- Apilamos dónde "muere" este nivel, no cuántos elementos le faltan
| |
stack_curr++;
| |
end_stack[stack_curr] = p + num_c;
| |
break;
| |
}
| |
| |
case JSON_VTYPE_INTEGER:
| |
{
| |
text[w++] = 'R';
| |
text[w++] = ' ';
| |
long num = m_cinta[p + 1];
| |
if(num == 0)
| |
{
| |
text[w++] = '0';
| |
}
| |
else
| |
{
| |
w += StringToCharArray(string(num), text, w, WHOLE_ARRAY, CP_UTF8) - 1;
| |
}
| |
| |
//---
| |
text[w++] = '\n';
| |
text[w++] = '-';
| |
text[w++] = '\n';
| |
break;
| |
}
| |
| |
//---
| |
case JSON_VTYPE_REAL:
| |
{
| |
//---
| |
TsnBitInterprete bit;
| |
bit.long_value = m_cinta[p + 1];
| |
double num = bit.double_value;
| |
| |
//---
| |
text[w++] = 'R';
| |
text[w++] = ' ';
| |
w += StringToCharArray(string(num), text, w, WHOLE_ARRAY, CP_UTF8) - 1;
| |
| |
//---
| |
text[w++] = '\n';
| |
text[w++] = '-';
| |
text[w++] = '\n';
| |
break;
| |
}
| |
| |
//--
| |
case JSON_VTYPE_BOOLEAN:
| |
{
| |
text[w++] = bool((m_cinta[p] >> TSN_SBL_BIT_START_ENDTYPE) & 1) ? 'T' : 'F';
| |
text[w++] = '\n';
| |
text[w++] = '-';
| |
text[w++] = '\n';
| |
break;
| |
}
| |
| |
//---
| |
case JSON_VTYPE_STRING:
| |
{
| |
const int s = int(m_cinta[p] >> TSN_SBL_BIT_STR_START);
| |
const int slen = int((m_cinta[p] >> TSN_SBL_BIT_STR_LEN) & TSN_SBL_BIT_STR_MASK_LEN);
| |
| |
//---
| |
text[w++] = 'S';
| |
text[w++] = ' ';
| |
text[w++] = '"';
| |
w += ArrayCopy(text, m_raw, w, s, slen);
| |
text[w++] = '"';
| |
text[w++] = '\n';
| |
text[w++] = '-';
| |
text[w++] = '\n';
| |
break;
| |
}
| |
| |
//---
| |
case JSON_VTYPE_NULL:
| |
{
| |
text[w++] = 'N';
| |
text[w++] = '\n';
| |
text[w++] = '-';
| |
text[w++] = '\n';
| |
break;
| |
}
| |
}
| |
| |
//---
| |
p += GetStepPure(p);
| |
| |
//--- Cerramos en cascada todos los niveles cuya posición de muerte ya alcanzamos.
| |
// Esto reemplaza tanto el manejo de "vacío" como la cascada de pops: ya no hace
| |
// falta tocar nada dentro de cada case.
| |
while(stack_curr >= 0 && p == end_stack[stack_curr])
| |
{
| |
text[w++] = 'P';
| |
text[w++] = ' ';
| |
text[w++] = '\n';
| |
| |
//---
| |
stack_curr--;
| |
| |
//---
| |
if(stack_curr >= 0)
| |
{
| |
text[w++] = '-';
| |
text[w++] = ' ';
| |
text[w++] = '\n';
| |
}
| |
}
| |
}
| |
| |
//---
| |
return ArrayResize(text, w);
| |
}
| |
| |
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
bool CJsonParser::ParseAssembly(void)
| |
{
| |
//--- Variables init
| |
m_cinta_pos = 0;
| |
m_pos = m_offset;
| |
m_last_err = TSN_JSON_NOT_ERR;
| |
m_next = TSN_JSON_TOKEN_ASM_ITER;
| |
m_stak_curr = -1;
| |
| |
//---
| |
while(true)
| |
{
| |
switch(m_next)
| |
{
| |
//---
| |
case JSON_VTYPE_KEY:
| |
{
| |
//---
| |
m_pos += 2;
| |
| |
//---
| |
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;
| |
continue;
| |
}
| |
#else // JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
| |
if(has_qt == 0) // Caso comun. .. ninguno de los dos.. continuamos..
| |
{
| |
m_pos += 8;
| |
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
| |
const ulong flag_real = TSNTABLES_BIT_DEJAR_SOLO_MINUS_SIG_BYTE(has_qt);
| |
| |
//---
| |
m_pos += TSNTABLES_CTZ_64_GET_BYTE(flag_real);
| |
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
| |
}
| |
| |
//--- 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) // Hay un qt real de cierre
| |
{
| |
// Avanzamos y cerramos..
| |
m_pos += g_tsntables_table_ctz_i8[qt_final];
| |
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
| |
}
| |
}
| |
#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++;
| |
}
| |
#endif // JSONPARSERBYLEO_ACTIVE_SWAR_KEYS
| |
| |
//---
| |
m_next = TSN_JSON_TOKEN_ASM_ITER;
| |
break;
| |
}
| |
| |
//---
| |
case JSON_VTYPE_OBJ: // OBJ [COUNT] [STEP]
| |
{
| |
| |
//---
| |
m_cinta[m_cinta_pos] = JSON_VTYPE_OBJ;
| |
| |
//---
| |
m_stak_curr++;
| |
m_stak_num[m_stak_curr] = 0;
| |
m_stak_pos[m_stak_curr] = m_cinta_pos++;
| |
| |
//---
| |
m_cinta[m_cinta_pos++] = m_pos++;
| |
| |
//---
| |
m_next = TSN_JSON_TOKEN_ASM_ITER;
| |
| |
//---
| |
break;
| |
}
| |
| |
//---
| |
case JSON_VTYPE_ARR: // ARR [COUNT] [STEP]
| |
{
| |
| |
//---
| |
m_cinta[m_cinta_pos] = JSON_VTYPE_ARR;
| |
| |
//---
| |
m_stak_curr++;
| |
m_stak_num[m_stak_curr] = 0;
| |
m_stak_pos[m_stak_curr] = m_cinta_pos++;
| |
| |
//---
| |
m_cinta[m_cinta_pos++] = m_pos++;
| |
| |
//---
| |
m_next = TSN_JSON_TOKEN_ASM_ITER;
| |
| |
//---
| |
break;
| |
}
| |
| |
//---
| |
case JSON_VTYPE_INTEGER:
| |
case JSON_VTYPE_REAL: // REAL [Valor]
| |
{
| |
//---
| |
m_pos += 2;
| |
| |
//---
| |
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;
| |
ushort fract_digits = 0;
| |
//---
| |
while(true)
| |
{
| |
ch = m_raw[m_pos] ^ '0';
| |
if(ch > 9)
| |
break;
| |
frac_int = (frac_int << 3) + (frac_int << 1) + ch;
| |
fract_digits++;
| |
m_pos++;
| |
}
| |
| |
//---
| |
val += frac_int * g_Exp10[fract_digits];
| |
}
| |
| |
//--- 10e50.02500140
| |
if((ch | 0x20) == 117) // e or E
| |
{
| |
bool exp_sign = true;
| |
ch = m_raw[++m_pos] ^ '0';
| |
if(ch > 9)
| |
{
| |
if(ch == 29)
| |
exp_sign = false;
| |
ch = m_raw[++m_pos] ^ '0';
| |
}
| |
| |
//---
| |
ushort exp_val = 0;
| |
| |
//---
| |
while(true)
| |
{
| |
exp_val = (exp_val << 3) + (exp_val << 1) + ch;
| |
ch = m_raw[++m_pos] ^ '0';
| |
if(ch > 9)
| |
break;
| |
}
| |
| |
//---
| |
val *= (exp_sign) ? g_Pow10[exp_val] : g_Exp10[exp_val];
| |
}
| |
| |
//---
| |
TsnBitInterprete 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
| |
}
| |
}
| |
| |
| |
//---
| |
m_next = TSN_JSON_TOKEN_ASM_ITER;
| |
break;
| |
}
| |
| |
//---
| |
case JSON_VTYPE_BOOLEAN: // TRUE (solo...)
| |
{
| |
//---
| |
m_pos++;
| |
// 5 | 1 << TSN_SBL_BIT_START_BOOL(4) = 21
| |
m_cinta[m_cinta_pos++] = 21;
| |
| |
//---
| |
m_next = TSN_JSON_TOKEN_ASM_ITER;
| |
break;
| |
}
| |
| |
//---
| |
case JSON_VTYPE_STRING:
| |
{
| |
//---
| |
m_pos += 2; // S[][Aqui]
| |
| |
//---
| |
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;
| |
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..
| |
{
| |
const ulong flag_real = TSNTABLES_BIT_DEJAR_SOLO_MINUS_SIG_BYTE(has_qt);
| |
| |
//---
| |
m_pos += TSNTABLES_CTZ_64_GET_BYTE(flag_real);
| |
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) // Hay un qt real de cierre
| |
{
| |
// Avanzamos y cerramos..
| |
m_pos += g_tsntables_table_ctz_i8[qt_final];
| |
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
| |
}
| |
}
| |
}
| |
| |
#else
| |
//--- Char por char
| |
while(true)
| |
{
| |
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++;
| |
}
| |
#endif // JSONPARSERBYLEO_DESACTIVE_SWAR
| |
| |
| |
//---
| |
m_next = TSN_JSON_TOKEN_ASM_ITER;
| |
break;
| |
}
| |
| |
//---
| |
case JSON_VTYPE_NULL:
| |
{
| |
m_cinta[m_cinta_pos++] = JSON_VTYPE_NULL;
| |
m_pos++;
| |
m_next = TSN_JSON_TOKEN_ASM_ITER;
| |
break;
| |
}
| |
| |
//---
| |
case TSN_JSON_TOKEN_ASM_BOOL_FALSE: // FALSE [value=1\0]
| |
{
| |
//---
| |
m_pos++;
| |
m_cinta[m_cinta_pos++] = JSON_VTYPE_BOOLEAN;
| |
| |
//---
| |
m_next = TSN_JSON_TOKEN_ASM_ITER;
| |
break;
| |
}
| |
| |
//---
| |
case TSN_JSON_TOKEN_ASM_INVALID: //
| |
{
| |
//Print("Err: ", m_next, " Pos: ", m_raw[m_pos]);
| |
m_last_err = TSN_JSON_ERR_INVALID_CHAR;
| |
return false;
| |
}
| |
| |
//---
| |
case TSN_JSON_TOKEN_ASM_POP:
| |
{
| |
| |
//---
| |
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;
| |
//---
| |
//PrintFormat("Stack curr %d | Size = %d | Num %d | LP %d - Cinta pos %d", m_stak_curr, m_stak_size, m_stak_num[m_stak_curr], lp, m_cinta_pos);
| |
| |
//---
| |
m_stak_curr--;
| |
m_pos++; // Luego del P
| |
| |
//---
| |
if(m_stak_curr < 0)
| |
{
| |
return true;
| |
}
| |
| |
//---
| |
m_next = TSN_JSON_TOKEN_ASM_ITER;
| |
break;
| |
}
| |
| |
//---
| |
case TSN_JSON_TOKEN_ASM_ADD_EL:
| |
{
| |
m_stak_num[m_stak_curr]++;
| |
m_pos++;
| |
m_next = TSN_JSON_TOKEN_ASM_ITER;
| |
break;
| |
}
| |
| |
| |
//---
| |
case TSN_JSON_TOKEN_ASM_ITER:
| |
{
| |
// JUSTO luego del \n
| |
//---
| |
while(true)
| |
{
| |
//---
| |
const uchar c = m_raw[m_pos];
| |
if(c < 33)
| |
{
| |
m_pos++;
| |
if(m_pos >= m_len)
| |
{
| |
m_last_err = TSN_JSON_ERR_MALFOMED_LEN_SUPERADO;
| |
return false;
| |
}
| |
continue;
| |
}
| |
| |
//---
| |
m_next = g_tsn_jsonasm_char_to_token[c];
| |
break;
| |
}
| |
| |
//---
| |
break;
| |
}
| |
| |
//---
| |
case TSN_JSON_TOKEN_ASM_SALTAR_NL:
| |
{
| |
//---
| |
#ifdef JSONPARSERBYLEO_ACTIVE_SWAR_IN_FIND_NL
| |
| |
//---
| |
while(true)
| |
{
| |
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 = chunk ^ TSNTABLES_SWAR_MASK_NEW_LINE;
| |
const ulong has_x = TSNTABLES_SWAR_HAS(x);
| |
| |
//---
| |
if(has_x == 0)
| |
{
| |
m_pos += 8;
| |
continue;
| |
}
| |
| |
//---
| |
const ulong flag_real = TSNTABLES_BIT_DEJAR_SOLO_MINUS_SIG_BYTE(has_x);
| |
m_pos += TSNTABLES_CTZ_64_GET_BYTE(flag_real); // ya en \n
| |
| |
//---
| |
break;
| |
}
| |
#else // JSONPARSERBYLEO_ACTIVE_SWAR_IN_FIND_NL
| |
while(true)
| |
{
| |
if(m_raw[m_pos] == '\n')
| |
break;
| |
m_pos++;
| |
}
| |
#endif // JSONPARSERBYLEO_ACTIVE_SWAR_IN_FIND_NL
| |
| |
// En caso supere el len haciendo esto
| |
//Print("Char: ", m_raw[m_pos]);
| |
m_pos++; // Luego del \n
| |
| |
//---
| |
m_next = TSN_JSON_TOKEN_ASM_ITER;
| |
break;
| |
}
| |
| |
default:
| |
{
| |
// Print("Err: " , m_next);
| |
m_last_err = TSN_JSON_ERR_INVALID_CHAR;
| |
return false;
| |
}
| |
}
| |
}
| |
}
| |
| |
| |
//---End
| |
}
| |
//+------------------------------------------------------------------+
| |
#endif // JSONPARSERBYLEO_SRC_JSONASM_MQH
|