869 lines
24 KiB
MQL5
869 lines
24 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[512];
|
|
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:
|
|
{
|
|
//---
|
|
static BitInterpreter 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;
|
|
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
|
|
const ulong flag_real = TSNTABLES_SWAR_64_DEJAR_SOLO_MINUS_SIG_BYTE(has_qt);
|
|
|
|
//---
|
|
m_pos += TSNTABLES_SWAR_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);
|
|
// Aislamos los bits donde empeizan las rachas de \
|
|
const uchar starts = compacted_bs & ~(compacted_bs << 1);
|
|
// sumas especiifca para impar
|
|
const ushort sum_impar_wide = (ushort)compacted_bs + ushort(starts & TSNTABLES_MASK_IMPARES);
|
|
// Obtenemos finales de ambos...
|
|
const uchar end_par = (compacted_bs + (starts & TSNTABLES_MASK_PARES)) & ~compacted_bs;
|
|
const uchar end_impar = uchar(sum_impar_wide & 0xFF) & ~compacted_bs;
|
|
// Ahora ya sabemos donde esta los finaes impares..
|
|
const uchar end_final = (end_impar & TSNTABLES_MASK_PARES) | (end_par & TSNTABLES_MASK_IMPARES);
|
|
const uchar compacted_qt = TSNTABLES_COMPACT_UL(has_qt);
|
|
const uchar qt_final = compacted_qt & ~end_final;
|
|
//Print("nada");
|
|
|
|
//---
|
|
if(qt_final != 0) // Hay un qt real de cierre
|
|
{
|
|
// Avanzamos y cerramos..
|
|
m_pos += g_table_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((sum_impar_wide & 0x100) != 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
|
|
|
|
//---
|
|
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;
|
|
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
|
|
}
|
|
}
|
|
|
|
|
|
//---
|
|
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;
|
|
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..
|
|
{
|
|
const ulong flag_real = TSNTABLES_SWAR_64_DEJAR_SOLO_MINUS_SIG_BYTE(has_qt);
|
|
|
|
//---
|
|
m_pos += TSNTABLES_SWAR_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);
|
|
// Aislamos los bits donde empeizan las rachas de \
|
|
const uchar starts = compacted_bs & ~(compacted_bs << 1);
|
|
// sumas especiifca para impar
|
|
const ushort sum_impar_wide = (ushort)compacted_bs + ushort(starts & TSNTABLES_MASK_IMPARES);
|
|
// Obtenemos finales de ambos...
|
|
const uchar end_par = (compacted_bs + (starts & TSNTABLES_MASK_PARES)) & ~compacted_bs;
|
|
const uchar end_impar = uchar(sum_impar_wide & 0xFF) & ~compacted_bs;
|
|
// Ahora ya sabemos donde esta los finaes impares..
|
|
const uchar end_final = (end_impar & TSNTABLES_MASK_PARES) | (end_par & TSNTABLES_MASK_IMPARES);
|
|
const uchar compacted_qt = TSNTABLES_COMPACT_UL(has_qt);
|
|
const uchar qt_final = compacted_qt & ~end_final;
|
|
//Print("nada");
|
|
|
|
//---
|
|
if(qt_final != 0) // Hay un qt real de cierre
|
|
{
|
|
// Avanzamos y cerramos..
|
|
m_pos += g_table_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((sum_impar_wide & 0x100) != 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
|
|
//--- 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
|
|
|
|
|
|
//---
|
|
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_MALFORDMED_JSON;
|
|
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
|
|
//---
|
|
int curr_end = m_pos + 8;
|
|
while(curr_end <= m_len)
|
|
{
|
|
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 = curr_end;
|
|
curr_end += 8;
|
|
continue;
|
|
}
|
|
|
|
//---
|
|
break;
|
|
}
|
|
#endif // JSONPARSERBYLEO_DESACTIVE_SWAR_IN_FIND_NL
|
|
do
|
|
{
|
|
if(m_raw[m_pos] == '\n')
|
|
break;
|
|
|
|
m_pos++;
|
|
}
|
|
while(m_pos < m_len);
|
|
|
|
// 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_MALFORDMED_JSON;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//---End
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
#endif // JSONPARSERBYLEO_SRC_JSONASM_MQH
|