2026-08-24 13:05:37 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| RSP.mqh |
|
|
|
|
|
//| Copyright 2026, Niquel Mendoza |
|
|
|
|
|
//| https://www.mql5.com |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#property copyright "Copyright 2026, Niquel Mendoza"
|
|
|
|
|
#property link "https://www.mql5.com"
|
|
|
|
|
#property strict
|
|
|
|
|
|
|
|
|
|
#ifndef CRYPTOBYLEO_RSPPARSER_RSP_MQH
|
|
|
|
|
#define CRYPTOBYLEO_RSPPARSER_RSP_MQH
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#include "Def.mqh"
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
namespace TSN
|
|
|
|
|
{
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
class CRSPParser : public CBaseLanFormat
|
|
|
|
|
{
|
2026-08-24 22:33:45 -05:00
|
|
|
public:
|
|
|
|
|
int m_root_values;
|
|
|
|
|
|
2026-08-24 13:05:37 -05:00
|
|
|
private:
|
2026-08-24 21:32:18 -05:00
|
|
|
//--- last err
|
2026-08-24 13:05:37 -05:00
|
|
|
ENUM_RSPPARSER_LAST_ERR m_last_err;
|
2026-08-24 21:32:18 -05:00
|
|
|
|
|
|
|
|
//--- parseo
|
2026-08-24 13:05:37 -05:00
|
|
|
int m_prev_start_v;
|
|
|
|
|
|
|
|
|
|
// el ultimo valor esta entre [] osea meta
|
|
|
|
|
bool m_last_meta;
|
|
|
|
|
|
|
|
|
|
// mascara de fin
|
|
|
|
|
#ifndef RSPDATA_DESACTIVE_SWAR
|
|
|
|
|
ulong m_last_val_mask;
|
|
|
|
|
#else
|
|
|
|
|
uchar m_last_val_char;
|
|
|
|
|
#endif // RSPDATA_DESACTIVE_SWAR
|
2026-08-24 22:33:45 -05:00
|
|
|
|
2026-08-24 13:05:37 -05:00
|
|
|
public:
|
2026-08-24 15:46:14 -05:00
|
|
|
CRSPParser(void);
|
2026-08-24 13:05:37 -05:00
|
|
|
~CRSPParser(void) {}
|
|
|
|
|
|
2026-08-24 22:07:20 -05:00
|
|
|
//---
|
|
|
|
|
__forceinline void CorrectPadding() { CorrectPadingInternal('\n', 8); }
|
|
|
|
|
|
2026-08-24 13:05:37 -05:00
|
|
|
//---
|
|
|
|
|
bool AutoParseByFileExt(const int file_ext_type);
|
|
|
|
|
int AssingFile(const string& file_name, const bool comon_flag);
|
|
|
|
|
|
2026-08-24 21:32:18 -05:00
|
|
|
//--
|
|
|
|
|
// verifica si una clave esta limpia
|
|
|
|
|
// En caso no lo este ejeucta la limpiza ahi mismo
|
|
|
|
|
void VerifyCleanKey(const int cur, const int start, int& len);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
bool KeysEqual(const string &str, const int curr);
|
|
|
|
|
bool StrEquals(const string &str, const int curr) const;
|
|
|
|
|
|
2026-08-24 13:05:37 -05:00
|
|
|
//---
|
2026-08-24 15:46:14 -05:00
|
|
|
__forceinline ENUM_RSPPARSER_LAST_ERR LastErr() const { return m_last_err; }
|
2026-08-24 13:05:37 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
bool Parse();
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
void ErrorInfo(bool with_avanze = false) const;
|
2026-08-24 22:07:20 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
bool SaveCompiled(const string & file_name_out, const bool out_common_flag) const;
|
|
|
|
|
bool SaveCompiled(const string & file_name_out, const bool out_common_flag, const string & file_name_data, const bool data_common_flag) const;
|
2026-08-24 22:33:45 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
void PrintCintaTypes(const int start, const int num) const;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
CRSPNode GetRoot();
|
2026-08-24 13:05:37 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-08-24 15:46:14 -05:00
|
|
|
CRSPParser::CRSPParser()
|
|
|
|
|
:
|
|
|
|
|
#ifndef RSPDATA_DESACTIVE_SWAR
|
|
|
|
|
m_last_val_mask(TSNTABLES_SWAR_MASK_NEW_LINE)
|
|
|
|
|
#else // RSPDATA_DESACTIVE_SWAR
|
|
|
|
|
m_last_val_char('\n')
|
|
|
|
|
#endif // RSPDATA_DESACTIVE_SWAR
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-24 22:07:20 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CRSPParser::AutoParseByFileExt(const int file_ext_type)
|
|
|
|
|
{
|
|
|
|
|
switch(file_ext_type)
|
|
|
|
|
{
|
|
|
|
|
case TSN_SLF_RAW_FILE:
|
|
|
|
|
{
|
|
|
|
|
CorrectPadding(); // Auto
|
|
|
|
|
return Parse();
|
|
|
|
|
}
|
|
|
|
|
case TSN_SLF_RAW_EMBEBED:
|
|
|
|
|
{
|
|
|
|
|
return m_cinta_pos > 0 && m_len > 0;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
m_last_err = RSPPARSER_LAST_ERR_INVALID_EXT_FILE;
|
|
|
|
|
m_pos = 0;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-24 21:32:18 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CRSPParser::StrEquals(const string &str, const int curr) const
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
// m_cinta[m_cinta_pos++] = long(m_pos - 1) | long(start) << TSN_JSON_BIT_STR_START_END;
|
|
|
|
|
const int start = int(m_cinta[curr] >> TSN_SBL_BIT_STR_START);
|
|
|
|
|
const int len = int((m_cinta[curr] >> TSN_SBL_BIT_STR_LEN) & TSN_SBL_BIT_STR_MASK_LEN);
|
|
|
|
|
//PrintFormat("Exact = '%s', other = '%s'", CharArrayToString(m_raw, start, len), str);
|
|
|
|
|
|
|
|
|
|
const int l = StringLen(str);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
if(l != len)
|
|
|
|
|
return false;
|
|
|
|
|
for(int i = 0; i < l; i++)
|
|
|
|
|
{
|
|
|
|
|
if(str[i] != m_raw[start + i])
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void CRSPParser::VerifyCleanKey(const int cur, const int start, int& len)
|
|
|
|
|
{
|
|
|
|
|
const int k = cur + 1; // kpos+1
|
|
|
|
|
if(((m_cinta[k] >> RSPDATA_BITSTART_ISKEY_CLEAN) & RSPDATA_MASK_META_IS) == 0)
|
|
|
|
|
{
|
|
|
|
|
int j = (start + len) - 1;
|
|
|
|
|
while(j >= start && m_raw[j] < 33)
|
|
|
|
|
{
|
|
|
|
|
j--;
|
|
|
|
|
}
|
|
|
|
|
len = (j - start) + 1;
|
2026-08-24 22:42:17 -05:00
|
|
|
m_cinta[cur] = long(RSPDATA_TYPE_PLAIN_KEY)
|
|
|
|
|
| long(len) << TSN_SBL_BIT_STR_LEN
|
|
|
|
|
| long(start) << TSN_SBL_BIT_STR_START;
|
|
|
|
|
|
2026-08-24 21:32:18 -05:00
|
|
|
m_cinta[k] |= RSPDATA_BITSTART_ISKEY_CLEAN_F;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CRSPParser::KeysEqual(const string &str, const int curr)
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
const int start = int(m_cinta[curr] >> TSN_SBL_BIT_STR_START);
|
|
|
|
|
int len = int((m_cinta[curr] >> TSN_SBL_BIT_STR_LEN) & TSN_SBL_BIT_STR_MASK_LEN);
|
|
|
|
|
//---
|
|
|
|
|
VerifyCleanKey(curr, start, len);
|
|
|
|
|
//---
|
|
|
|
|
const int l = StringLen(str);
|
|
|
|
|
//---
|
|
|
|
|
if(l != len)
|
|
|
|
|
return false;
|
|
|
|
|
//---
|
|
|
|
|
for(int i = 0; i < l; i++)
|
|
|
|
|
if(str[i] != m_raw[start + i])
|
|
|
|
|
return false;
|
|
|
|
|
//---
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-24 15:46:14 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
// luego de un valor buscar key
|
|
|
|
|
// el |1 lo hacemos para acitvar el bit 1 cosa uqe aumenta en 1 el valor base del token
|
|
|
|
|
// En el enum estan definidos de tal forma qeu si le aumentmos 1 para value=key (ahora es key)
|
|
|
|
|
// y los demas tambien
|
|
|
|
|
// coment aunenta en uno ahora es comentp
|
|
|
|
|
// lo que tambien aumenta es cor que pasa a ser corp
|
|
|
|
|
// e invalid pasa a (fuera) de rango (defualt en NEXTT)
|
|
|
|
|
// maxima velocidad sin branches
|
|
|
|
|
#define TSN_RSPPARSER_NEXTV \
|
|
|
|
|
while(true) \
|
|
|
|
|
{ \
|
|
|
|
|
if(m_pos >= m_len) \
|
|
|
|
|
{ \
|
|
|
|
|
return true; \
|
|
|
|
|
} \
|
|
|
|
|
const uchar cfasd = m_raw[m_pos]; \
|
|
|
|
|
if(cfasd < 33) \
|
|
|
|
|
{ \
|
|
|
|
|
m_pos++; \
|
|
|
|
|
continue; \
|
|
|
|
|
} \
|
|
|
|
|
m_next = g_tsn_rsp_t_to_tokesn[cfasd]|1; \
|
2026-08-24 22:33:45 -05:00
|
|
|
break;\
|
2026-08-24 15:46:14 -05:00
|
|
|
}
|
2026-08-24 13:05:37 -05:00
|
|
|
|
2026-08-25 08:22:06 -05:00
|
|
|
//---
|
|
|
|
|
#define RSPDATA_PARSE_FIND_CHAR_UNROLLED_8(CH) \
|
|
|
|
|
if(m_raw[m_pos] == CH)\
|
|
|
|
|
break;\
|
|
|
|
|
m_pos++;\
|
|
|
|
|
if(m_raw[m_pos] == CH)\
|
|
|
|
|
break;\
|
|
|
|
|
m_pos++;\
|
|
|
|
|
if(m_raw[m_pos] == CH)\
|
|
|
|
|
break;\
|
|
|
|
|
m_pos++;\
|
|
|
|
|
if(m_raw[m_pos] == CH)\
|
|
|
|
|
break;\
|
|
|
|
|
m_pos++;\
|
|
|
|
|
if(m_raw[m_pos] == CH)\
|
|
|
|
|
break;\
|
|
|
|
|
m_pos++;\
|
|
|
|
|
if(m_raw[m_pos] == CH)\
|
|
|
|
|
break;\
|
|
|
|
|
m_pos++;\
|
|
|
|
|
if(m_raw[m_pos] == CH)\
|
|
|
|
|
break;\
|
|
|
|
|
m_pos++;\
|
|
|
|
|
if(m_raw[m_pos] == CH)\
|
|
|
|
|
break; \
|
|
|
|
|
m_pos++;
|
|
|
|
|
|
2026-08-24 13:05:37 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CRSPParser::Parse(void)
|
|
|
|
|
{
|
|
|
|
|
//---
|
2026-08-24 15:46:14 -05:00
|
|
|
m_pos = m_offset;
|
2026-08-24 22:33:45 -05:00
|
|
|
m_cinta_pos = 0;
|
2026-08-24 13:05:37 -05:00
|
|
|
m_last_meta = false;
|
2026-08-24 15:46:14 -05:00
|
|
|
m_last_err = RSPPARSER_LAST_ERR_NOT;
|
2026-08-24 22:33:45 -05:00
|
|
|
m_root_values = 0;
|
2026-08-24 13:05:37 -05:00
|
|
|
|
2026-08-24 15:46:14 -05:00
|
|
|
//--- Initial
|
|
|
|
|
while(true)
|
|
|
|
|
{
|
|
|
|
|
const uchar _c = m_raw[m_pos];
|
|
|
|
|
if(_c < 33)
|
|
|
|
|
{
|
|
|
|
|
m_pos++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
m_next = g_tsn_rsp_t_to_tokesn[_c] | 1;
|
2026-08-24 22:33:45 -05:00
|
|
|
break;
|
2026-08-24 15:46:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Iter
|
2026-08-24 13:05:37 -05:00
|
|
|
while(true)
|
|
|
|
|
{
|
|
|
|
|
switch(m_next)
|
|
|
|
|
{
|
2026-08-24 15:46:14 -05:00
|
|
|
//---
|
|
|
|
|
case RSPDATA_TOK_TYPE_VALUE:
|
|
|
|
|
{
|
|
|
|
|
// m_prev_start_v = start del key qeu este ultimo nos definio para este valor
|
|
|
|
|
#ifndef RSPDATA_DESACTIVE_SWAR
|
|
|
|
|
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 ^ m_last_val_mask;
|
|
|
|
|
const ulong has_x = TSNTABLES_SWAR_HAS(x);
|
|
|
|
|
if(has_x == 0)
|
|
|
|
|
{
|
|
|
|
|
m_pos += 8;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
if((m_pos + 7) >= m_len)
|
|
|
|
|
{
|
|
|
|
|
m_last_err = RSPPARSER_LAST_ERR_SE_BUSCABA_FIN_V;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
// Si hay \n
|
|
|
|
|
const ulong flag = TSNTABLES_SWAR_64_DEJAR_SOLO_MINUS_SIG_BYTE(has_x);
|
|
|
|
|
m_pos += TSNTABLES_SWAR_64_GET_BYTE(flag); // Ahora mismo en \n
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
m_last_val_mask = TSNTABLES_SWAR_MASK_NEW_LINE;
|
2026-08-25 08:22:06 -05:00
|
|
|
|
|
|
|
|
|
2026-08-24 15:46:14 -05:00
|
|
|
#else // RSPDATA_DESACTIVE_SWAR
|
2026-08-25 08:22:06 -05:00
|
|
|
while(true)
|
2026-08-24 15:46:14 -05:00
|
|
|
{
|
2026-08-25 08:22:06 -05:00
|
|
|
RSPDATA_PARSE_FIND_CHAR_UNROLLED_8(m_last_val_char)
|
|
|
|
|
//---
|
|
|
|
|
if((m_pos + 7) >= m_len)
|
|
|
|
|
{
|
|
|
|
|
m_last_err = RSPPARSER_LAST_ERR_SE_BUSCABA_FIN_V;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2026-08-24 15:46:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
m_last_val_char = '\n';
|
|
|
|
|
#endif // RSPDATA_DESACTIVE_SWAR
|
|
|
|
|
// Ahora mismo en \n
|
2026-08-25 08:22:06 -05:00
|
|
|
|
|
|
|
|
|
2026-08-24 15:46:14 -05:00
|
|
|
//---
|
|
|
|
|
m_cinta[m_cinta_pos++] = long(RSPDATA_TYPE_PLAIN_VALUE) | long(m_pos - m_prev_start_v) << TSN_SBL_BIT_STR_LEN
|
|
|
|
|
| long(m_prev_start_v) << TSN_SBL_BIT_STR_START;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
m_pos++; // Luiego del \n
|
2026-08-24 22:33:45 -05:00
|
|
|
m_root_values++;
|
2026-08-24 15:46:14 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
TSN_RSPPARSER_NEXTV
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
2026-08-24 13:05:37 -05:00
|
|
|
case RSPDATA_TOK_TYPE_KEY:
|
|
|
|
|
{
|
|
|
|
|
// ahora mismo justo en kstart
|
|
|
|
|
const int start = m_pos++;
|
2026-08-25 08:22:06 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
// Por deqfecto desactivo en priomedio als key no superan los 8 chars ahi
|
|
|
|
|
// asi que no hay mucho beneficio
|
|
|
|
|
#ifdef RSPDATA_PARSER_KEY_ACTIVE_SWAR
|
2026-08-24 13:05:37 -05:00
|
|
|
while(true)
|
|
|
|
|
{
|
|
|
|
|
//Print(CharArrayToString(m_raw, m_pos, 7));
|
|
|
|
|
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_IGUAL;
|
|
|
|
|
const ulong has_x = TSNTABLES_SWAR_HAS(x);
|
|
|
|
|
if(has_x == 0)
|
|
|
|
|
{
|
|
|
|
|
m_pos += 8;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
if((m_pos + 7) >= m_len)
|
|
|
|
|
{
|
|
|
|
|
m_last_err = RSPPARSER_LAST_ERR_SE_BUSCABA_EQ;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
// Si hay =
|
|
|
|
|
const ulong flag = TSNTABLES_SWAR_64_DEJAR_SOLO_MINUS_SIG_BYTE(has_x);
|
|
|
|
|
m_pos += TSNTABLES_SWAR_64_GET_BYTE(flag);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2026-08-25 08:22:06 -05:00
|
|
|
#else // RSPDATA_PARSER_KEY_ACTIVE_SWAR
|
|
|
|
|
while(true)
|
2026-08-24 13:05:37 -05:00
|
|
|
{
|
2026-08-25 08:22:06 -05:00
|
|
|
RSPDATA_PARSE_FIND_CHAR_UNROLLED_8('=')
|
|
|
|
|
//---
|
|
|
|
|
if((m_pos + 7) >= m_len)
|
|
|
|
|
{
|
|
|
|
|
m_last_err = RSPPARSER_LAST_ERR_SE_BUSCABA_EQ;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2026-08-24 13:05:37 -05:00
|
|
|
}
|
2026-08-25 08:22:06 -05:00
|
|
|
#endif // RSPDATA_PARSER_KEY_ACTIVE_SWAR
|
2026-08-24 13:05:37 -05:00
|
|
|
// Ahora mismo justo en =
|
|
|
|
|
m_cinta[m_cinta_pos++] = long(RSPDATA_TYPE_PLAIN_KEY)
|
|
|
|
|
| long(m_pos - start) << TSN_SBL_BIT_STR_LEN
|
|
|
|
|
| long(start) << TSN_SBL_BIT_STR_START;
|
|
|
|
|
|
|
|
|
|
// ahora toca meta
|
|
|
|
|
m_cinta[m_cinta_pos++] = long(RSPDATA_TYPE_META) | long(m_last_meta) << TSN_SBL_BIT_START_ENDTYPE;
|
2026-08-24 15:46:14 -05:00
|
|
|
|
2026-08-24 13:05:37 -05:00
|
|
|
//--- avanzamos
|
|
|
|
|
m_pos++; // Ahora toca value
|
|
|
|
|
m_prev_start_v = m_pos;
|
2026-08-25 08:22:06 -05:00
|
|
|
m_last_meta = false;
|
2026-08-24 21:32:18 -05:00
|
|
|
|
2026-08-24 13:05:37 -05:00
|
|
|
//--- Ahora buscamos el valor
|
|
|
|
|
while(true)
|
|
|
|
|
{
|
|
|
|
|
const uchar f = m_raw[m_pos];
|
|
|
|
|
if(f < 33)
|
|
|
|
|
{
|
|
|
|
|
if(f == '\n')
|
|
|
|
|
{
|
|
|
|
|
// No habai nada estamos en\n entonces 0
|
|
|
|
|
m_cinta[m_cinta_pos++] = long(RSPDATA_TYPE_PLAIN_VALUE) | long(0) << TSN_SBL_BIT_STR_LEN
|
|
|
|
|
| long(start) << TSN_SBL_BIT_STR_START;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
TSN_RSPPARSER_NEXTV
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
m_pos++;
|
|
|
|
|
if(m_pos >= m_len) // o en todo caso fin
|
|
|
|
|
{
|
|
|
|
|
m_cinta[m_cinta_pos++] = long(RSPDATA_TYPE_PLAIN_VALUE) | long(0) << TSN_SBL_BIT_STR_LEN
|
|
|
|
|
| long(start) << TSN_SBL_BIT_STR_START;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
m_prev_start_v++; // nada avanzamos..
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Justo aqui nos detenemos. Vemos que sigue comentario o valor
|
2026-08-24 15:46:14 -05:00
|
|
|
// Valor raw tal cual (sin 1 asi que el value es vlaue ya no se pasa a key)
|
2026-08-24 13:05:37 -05:00
|
|
|
m_next = g_tsn_rsp_t_to_tokesn[f];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//--- [ ]
|
|
|
|
|
case RSPDATA_TOK_TYPE_COR:
|
2026-08-24 15:46:14 -05:00
|
|
|
case RSPDATA_TOK_TYPE_COR_P:
|
2026-08-24 13:05:37 -05:00
|
|
|
{
|
|
|
|
|
m_pos++; // luego del cor
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
m_last_meta = true;
|
|
|
|
|
|
|
|
|
|
// saltar ws
|
|
|
|
|
while(true)
|
|
|
|
|
{
|
|
|
|
|
if(m_raw[m_pos] < 33)
|
|
|
|
|
continue;
|
2026-08-24 22:33:45 -05:00
|
|
|
break;
|
2026-08-24 13:05:37 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// camibamos las mcaras para que en vez de \n sea ] fin de valor
|
|
|
|
|
#ifndef RSPDATA_DESACTIVE_SWAR
|
2026-08-24 15:46:14 -05:00
|
|
|
m_last_val_mask = TSNTABLES_SWAR_MASK_COR_END;
|
2026-08-24 13:05:37 -05:00
|
|
|
#else
|
|
|
|
|
m_last_val_char = ']';
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// ahora mismo ene l primer char de key
|
|
|
|
|
m_next = RSPDATA_TOK_TYPE_KEY;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case RSPDATA_TOK_TYPE_COMMENT:
|
2026-08-24 15:46:14 -05:00
|
|
|
case RSPDATA_TOK_TYPE_COMMENT_P:
|
2026-08-24 13:05:37 -05:00
|
|
|
{
|
|
|
|
|
m_pos++; // Siguiente..
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
#ifndef RSPDATA_DESACTIVE_SWAR
|
|
|
|
|
while(true)
|
|
|
|
|
{
|
|
|
|
|
//Print(CharArrayToString(m_raw, m_pos, 7));
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
//--- Check
|
|
|
|
|
if((m_pos + 7) >= m_len)
|
|
|
|
|
{
|
|
|
|
|
m_last_err = RSPPARSER_LAST_ERR_SE_BUSCABA_FIN_DE_LINEA;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
// Si hay \n
|
|
|
|
|
const ulong flag = TSNTABLES_SWAR_64_DEJAR_SOLO_MINUS_SIG_BYTE(has_x);
|
|
|
|
|
m_pos += TSNTABLES_SWAR_64_GET_BYTE(flag); // Ahora mismo en \n+1 \n[aqui]
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#else // RSPDATA_DESACTIVE_SWAR
|
2026-08-25 08:22:06 -05:00
|
|
|
while(true)
|
2026-08-24 13:05:37 -05:00
|
|
|
{
|
2026-08-25 08:22:06 -05:00
|
|
|
RSPDATA_PARSE_FIND_CHAR_UNROLLED_8('\n')
|
|
|
|
|
//---
|
|
|
|
|
if((m_pos + 7) >= m_len)
|
|
|
|
|
{
|
|
|
|
|
m_last_err = RSPPARSER_LAST_ERR_SE_BUSCABA_FIN_DE_LINEA;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2026-08-24 13:05:37 -05:00
|
|
|
}
|
|
|
|
|
#endif // RSPDATA_DESACTIVE_SWAR
|
|
|
|
|
//---
|
|
|
|
|
m_pos++;
|
|
|
|
|
// Si o si sigue key
|
|
|
|
|
TSN_RSPPARSER_NEXTV
|
|
|
|
|
break;
|
|
|
|
|
}
|
2026-08-24 15:46:14 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case RSPDATA_TOK_INVALID:
|
|
|
|
|
{
|
|
|
|
|
m_last_err = RSPPARSER_LAST_ERR_INVALID_TOKEN;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-24 13:05:37 -05:00
|
|
|
//---
|
|
|
|
|
default:
|
2026-08-24 15:46:14 -05:00
|
|
|
m_last_err = RSPPARSER_LAST_ERR_INVALID_NEXTT;
|
2026-08-24 13:05:37 -05:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-24 15:46:14 -05:00
|
|
|
}
|
2026-08-24 13:05:37 -05:00
|
|
|
|
2026-08-24 22:07:20 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
int CRSPParser::AssingFile(const string &file_name, const bool comon_flag)
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(FileGetExtension(file_name) == RSPPARSER_TAPECACHE_EXT) // jsontp tape cache
|
|
|
|
|
{
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
const int fh = FileOpen(file_name, FILE_BIN | FILE_ANSI | (comon_flag ? FILE_COMMON : 0) | FILE_READ);
|
|
|
|
|
if(fh == INVALID_HANDLE)
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
// Metadata (cinta\yaml)
|
|
|
|
|
m_cinta_pos = FileReadInteger(fh); // Nota que cuadno se guarda se hace con el tamaño exacto
|
|
|
|
|
m_cinta_reserve = m_cinta_pos; // Mismo tamaño
|
|
|
|
|
const int type = FileReadInteger(fh); // Tipo ()
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
if(type == TSN_SLF_RAW_EMBEBED)
|
|
|
|
|
{
|
|
|
|
|
m_len = FileReadInteger(fh);
|
|
|
|
|
m_offset = FileReadInteger(fh);
|
|
|
|
|
FileReadArray(fh, m_cinta, 0, m_cinta_pos); // Total
|
|
|
|
|
// Yaml embebido (aqui no hace falta hacer nada ya todo esta hecho.. osea lo de encoding etc..)
|
|
|
|
|
FileReadArray(fh, m_raw, 0, m_len);
|
|
|
|
|
}
|
|
|
|
|
else // Dir
|
|
|
|
|
{
|
|
|
|
|
const bool common = bool(FileReadInteger(fh, CHAR_VALUE));
|
|
|
|
|
const int file_name_len = FileReadInteger(fh);
|
|
|
|
|
if(AssingFile(FileReadString(fh, file_name_len), common) == TSN_SLF_EXT_TYPE_CACHE_FILE)
|
|
|
|
|
{
|
|
|
|
|
FileClose(fh);
|
|
|
|
|
return -1; // fallo
|
|
|
|
|
}
|
|
|
|
|
FileReadArray(fh, m_cinta, 0, m_cinta_pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
FileClose(fh);
|
|
|
|
|
return TSN_SLF_EXT_TYPE_CACHE_FILE;
|
|
|
|
|
}
|
|
|
|
|
else // Ninguno de los dos... json normal O jsonasm
|
|
|
|
|
{
|
|
|
|
|
const int l = (int)FileLoad(file_name, m_raw, (comon_flag ? FILE_COMMON : 0));
|
|
|
|
|
if(l == -1)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
m_len = l;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
NormalizeUft();
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return TSN_SLF_EXT_TYPE_FILE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//--- Ambos
|
|
|
|
|
// 4 bytes: m_cinta_pos
|
|
|
|
|
// 4 bytes: type
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
bool CRSPParser::SaveCompiled(const string & file_name_out, const bool out_common_flag) const
|
|
|
|
|
{
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
const int fh = FileOpen(file_name_out, FILE_BIN | (out_common_flag ? FILE_COMMON : 0) | FILE_WRITE | FILE_ANSI);
|
|
|
|
|
if(fh == INVALID_HANDLE)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Comun
|
|
|
|
|
FileWriteInteger(fh, m_cinta_pos);
|
|
|
|
|
FileWriteInteger(fh, TSN_SLF_RAW_EMBEBED);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
// 4 bytes: len
|
|
|
|
|
// 4 bytes: offset
|
|
|
|
|
// array: cinta
|
|
|
|
|
// array yaml
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
FileWriteInteger(fh, m_len);
|
|
|
|
|
FileWriteInteger(fh, m_offset);
|
|
|
|
|
FileWriteArray(fh, m_cinta, 0, m_cinta_pos);
|
|
|
|
|
FileWriteArray(fh, m_raw, 0, m_len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
FileClose(fh);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CRSPParser::SaveCompiled(const string & file_name_out, const bool out_common_flag,
|
|
|
|
|
const string & file_name_data, const bool data_common_flag) const
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
::ResetLastError();
|
|
|
|
|
const int fh = FileOpen(file_name_out, FILE_BIN | (out_common_flag ? FILE_COMMON : 0) | FILE_WRITE | FILE_ANSI);
|
|
|
|
|
if(fh == INVALID_HANDLE)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--- Comun
|
|
|
|
|
FileWriteInteger(fh, m_cinta_pos);
|
|
|
|
|
FileWriteInteger(fh, TSN_SLF_RAW_FILE);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
// 1 bytes: comon
|
|
|
|
|
// 4 bytes: len
|
|
|
|
|
// string: name_file
|
|
|
|
|
// array: cinta
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
FileWriteInteger(fh, data_common_flag, CHAR_VALUE);
|
|
|
|
|
const int len = StringLen(file_name_data);
|
|
|
|
|
FileWriteInteger(fh, len);
|
|
|
|
|
FileWriteString(fh, file_name_data, len);
|
|
|
|
|
FileWriteArray(fh, m_cinta, 0, m_cinta_pos);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
FileClose(fh);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-24 22:33:45 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void CRSPParser::ErrorInfo(bool with_avanze = false) const
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
void CRSPParser::PrintCintaTypes(const int start, const int num) const
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
int p = fmax(start, 0);
|
|
|
|
|
const int end = (num == WHOLE_ARRAY || (p + num) > m_cinta_pos) ? m_cinta_pos : (p + num);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
while(p < end)
|
|
|
|
|
{
|
|
|
|
|
const ENUM_RSPDATA_TYPE tipo = ENUM_RSPDATA_TYPE(m_cinta[p] & TSN_SBL_BIT_MASK_TYPE);
|
|
|
|
|
string text = "[" + (string)p + "] " + EnumToString(tipo) + " | ";
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
switch(tipo)
|
|
|
|
|
{
|
|
|
|
|
case RSPDATA_TYPE_PLAIN_KEY:
|
|
|
|
|
{
|
|
|
|
|
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 += "start=" + (string)s + " len=" + (string)slen + " key=\"" + CharArrayToString(m_raw, s, slen) + "\"";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case RSPDATA_TYPE_PLAIN_VALUE:
|
|
|
|
|
{
|
|
|
|
|
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 += "start=" + (string)s + " len=" + (string)slen + " val=\"" + CharArrayToString(m_raw, s, slen) + "\"";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case RSPDATA_TYPE_META:
|
|
|
|
|
{
|
|
|
|
|
static BitInterpreter un;
|
|
|
|
|
un.long_value = m_cinta[p + 1];
|
|
|
|
|
text += StringFormat("is_cor=%s is_val_cleaned=%s is_key_cleaned=%s",
|
|
|
|
|
(((m_cinta[p] >> TSN_SBL_BIT_START_ENDTYPE) & RSPDATA_MASK_META_IS) != 0 ? "true" : "false"),
|
|
|
|
|
(((m_cinta[p] >> RSPDATA_BITSTART_ISVAL_CLEAN) & RSPDATA_MASK_META_IS) != 0 ? "true" : "false"),
|
|
|
|
|
(((m_cinta[p] >> RSPDATA_BITSTART_ISKEY_CLEAN) & RSPDATA_MASK_META_IS) != 0 ? "true" : "false")
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Print(text);
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2026-08-24 13:05:37 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#endif // CRYPTOBYLEO_RSPPARSER_RSP_MQH
|