2026-07-24 07:27:55 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-06-02 21:23:50 -05:00 | | | | //| JsonParser.mqh |
|
| | | | //| Copyright 2026, Niquel Mendoza. |
|
2026-10-08 13:39:44 -05:00 | | | | //| https://www.mql5.com |
|
2026-06-02 21:23:50 -05:00 | | | | //+------------------------------------------------------------------+
|
| | | | #property copyright "Copyright 2026, Niquel Mendoza."
|
2026-10-08 13:39:44 -05:00 | | | | #property link "https://www.mql5.com"
|
2026-06-02 21:23:50 -05:00 | | | | #property strict
|
| | | |
|
2026-10-08 13:39:44 -05:00 | | | | #ifndef JSONPARSERBYLEO_SRC_JSONCORE_JSONPARSER_MQH
|
| | | | #define JSONPARSERBYLEO_SRC_JSONCORE_JSONPARSER_MQH
|
2026-06-02 21:23:50 -05:00 | | | |
|
| | | | //+------------------------------------------------------------------+
|
| | | | //| |
|
| | | | //+------------------------------------------------------------------+
|
2026-10-03 17:00:34 -05:00 | | | | #include "JsonDefines.mqh"
|
2026-06-02 21:23:50 -05:00 | | | |
|
2026-08-03 09:31:58 -05:00 | | | | //---
|
| | | | #ifdef JSONPARSERBYLEO_DLL
|
2026-10-19 07:27:55 -05:00 | | | | #include "..\\DLL\\Main.mqh"
|
2026-08-03 09:31:58 -05:00 | | | | #endif // JSONPARSERBYLEO_DLL
|
| | | |
|
2026-06-02 21:23:50 -05:00 | | | | //+------------------------------------------------------------------+
|
| | | | //| |
|
| | | | //+------------------------------------------------------------------+
|
| | | | namespace TSN
|
| | | | {
|
| | | | //+------------------------------------------------------------------+
|
| | | | //| |
|
| | | | //+------------------------------------------------------------------+
|
2026-07-19 07:41:52 -05:00 | | | | class CJsonParser : public CBaseStructuredLan
|
2026-06-02 21:23:50 -05:00 | | | | {
|
2026-08-04 08:01:50 -05:00 | | | | protected:
|
2026-06-02 21:23:50 -05:00 | | | | //---
|
2026-08-03 09:31:58 -05:00 | | | | #ifdef JSONPARSERBYLEO_DLL
|
| | | | int m_index[];
|
| | | | int m_index_r;
|
| | | | #endif // JSONPARSERBYLEO_DLL
|
| | | |
|
2026-06-02 21:23:50 -05:00 | | | | //---
|
| | | | ENUM_TSN_JSON_LAST_ERR m_last_err;
|
2026-07-19 07:41:52 -05:00 | | | |
|
| | | | //---
|
| | | | int CalcRegType(const string& file_name) override final;
|
2026-09-30 07:39:54 -05:00 | | | |
|
2026-06-02 21:23:50 -05:00 | | | | public:
|
2026-08-03 09:31:58 -05:00 | | | | CJsonParser(void);
|
2026-06-02 21:23:50 -05:00 | | | | ~CJsonParser(void) {}
|
| | | |
|
2026-10-08 21:46:49 -05:00 | | | | //--- Correct padding
|
2026-06-03 08:32:38 -05:00 | | | | // Para data raw se puede usar el json uchar directamtne
|
2026-09-18 14:11:09 -05:00 | | | | void CorrectPadding();
|
2026-08-03 09:31:58 -05:00 | | | | #ifdef JSONPARSERBYLEO_DLL
|
2026-09-18 14:11:09 -05:00 | | | | void CorrectPaddingSimd();
|
2026-08-03 09:31:58 -05:00 | | | | #endif // JSONPARSERBYLEO_DLL
|
2026-06-03 07:50:45 -05:00 | | | |
|
2026-10-08 21:46:49 -05:00 | | | | //--- Parseo
|
| | | | bool AutoParseByFileExt(const int file_ext_type);
|
2026-06-18 09:48:36 -05:00 | | | | bool Parse();
|
2026-08-03 09:31:58 -05:00 | | | | #ifdef JSONPARSERBYLEO_DLL
|
2026-09-18 14:11:09 -05:00 | | | | __forceinline bool ParseSimd();
|
2026-08-03 09:31:58 -05:00 | | | | #endif // JSONPARSERBYLEO_DLL
|
2026-09-18 14:11:09 -05:00 | | | |
|
2026-10-01 08:25:33 -05:00 | | | | //--- Errores
|
2026-06-03 07:50:45 -05:00 | | | | __forceinline ENUM_TSN_JSON_LAST_ERR LastErr() const { return m_last_err; }
|
2026-09-30 07:39:54 -05:00 | | | | void CatchErr();
|
2026-10-03 17:00:34 -05:00 | | | | void ErrorInfo(const string header = "");
|
2026-06-03 07:50:45 -05:00 | | | |
|
2026-10-08 21:46:49 -05:00 | | | | //--- Config
|
2026-10-08 13:39:44 -05:00 | | | | void Options(const uint f);
|
| | | |
|
2026-10-01 08:25:33 -05:00 | | | | //--- Step
|
2026-06-02 22:52:39 -05:00 | | | | __forceinline int GetStep(const int idx) const;
|
2026-06-03 07:50:45 -05:00 | | | | __forceinline int GetStepPure(const int idx) const;
|
| | | |
|
2026-06-03 18:53:05 -05:00 | | | |
|
2026-10-08 13:39:44 -05:00 | | | | //--- GetRoot
|
| | | | CJsonNode GetRoot();
|
| | | |
|
2026-10-01 08:25:33 -05:00 | | | | //--- Info
|
2026-06-18 08:36:18 -05:00 | | | | void PrintCintaTypes(const int start, const int num) const;
|
2026-06-03 07:50:45 -05:00 | | | |
|
2026-10-08 21:46:49 -05:00 | | | | //--- Node
|
2026-10-08 20:25:09 -05:00 | | | | void NodeHashing(int curr, const int obj_count, const int bend, int& table_pos);
|
2026-10-01 08:25:33 -05:00 | | | | bool SerializeToDom(CDomNodeBase* root, CDomNodeManager* manager, int cur, const int end);
|
2026-07-11 16:31:27 -05:00 | | | |
|
2026-10-08 21:46:49 -05:00 | | | |
|
| | | | //--- Strings\Keys
|
2026-10-06 08:01:09 -05:00 | | | | // uso en get value o exatcion
|
2026-10-08 13:39:44 -05:00 | | | | template<typename TKey>
|
2026-10-08 21:46:49 -05:00 | | | | __forceinline string GetRawAsStr(int idx) const
|
| | | | {
|
| | | | return CharArrayToString(m_raw, TSN_SBL_CLS_STR_START(idx, int), TSN_SBL_CLS_STR_LEN(idx, (2 - sizeof(TKey)), int));
|
| | | | }
|
2026-10-08 13:39:44 -05:00 | | | | template<typename TKey>
|
2026-10-08 21:46:49 -05:00 | | | | __forceinline int GetRawAsUArr(int idx, uchar &res[], int pos = 0) const
|
| | | | {
|
| | | | return ArrayCopy(res, m_raw, pos, TSN_SBL_CLS_STR_START(idx, int), TSN_SBL_CLS_STR_LEN(idx, (2 - sizeof(TKey)), int));
|
| | | | }
|
2026-10-08 21:07:14 -05:00 | | | | template<typename TKey>
|
2026-10-08 21:46:49 -05:00 | | | | __forceinline bool GetStrAsStr(int idx, string &res) const
|
| | | | {
|
| | | | return CBSFLUnescape::MakeString<CJsonParser>(m_raw,
|
| | | | TSN_SBL_CLS_STR_START(idx, int),
|
| | | | TSN_SBL_CLS_STR_LEN(idx, (2 - sizeof(TKey)), int), res);
|
| | | | }
|
2026-10-08 21:07:14 -05:00 | | | | template<typename TKey>
|
2026-10-08 21:46:49 -05:00 | | | | __forceinline int GetStrAsUArr(int idx, uchar &res[], int pos = 0) const
|
| | | | {
|
| | | | return CBSFLUnescape::MakeUArray<CJsonParser, BSFL_UE_SURROGATES>(m_raw,
|
| | | | TSN_SBL_CLS_STR_START(idx, int),
|
| | | | TSN_SBL_CLS_STR_LEN(idx, (2 - sizeof(TKey)), int), res, pos);
|
| | | | }
|
2026-10-06 08:01:09 -05:00 | | | |
|
| | | |
|
2026-10-08 20:25:09 -05:00 | | | | //--- Funciones para node (interno de uso interno)
|
2026-09-30 07:39:54 -05:00 | | | | template <typename T>
|
| | | | void ToArray(int cur, T& out_arr[], const int end) const;
|
| | | | template <typename T>
|
| | | | bool ExistInArray(int cur, const T val, const uint flags, const int end) const;
|
| | | | template <typename T>
|
| | | | bool ExistInArrayHomogeneo(int cur, const T val, const int end) const;
|
2026-10-08 13:39:44 -05:00 | | | | __forceinline int NodeAt(int cur, const int index) const;
|
| | | | int NodeFindByHashFvn1A64(const ulong kh, int cur, const int end);
|
| | | | __forceinline int NodeObjAtSlow(int cur, const int index) const;
|
| | | | int NodeKeyToPositionSlow(const ulong kh, int cur, const int end);
|
| | | | int NodeGetKeys(int cur, string &keys[], const int end) const;
|
2026-10-01 08:25:33 -05:00 | | | |
|
2026-10-08 21:46:49 -05:00 | | | | //--- Print error general
|
2026-10-03 17:00:34 -05:00 | | | | static void PrintError(const string& header, const uchar& buf[], const int len,
|
| | | | int col, int line, ENUM_TSN_JSON_LAST_ERR err, string& salida, bool print = true);
|
| | | |
|
2026-07-26 16:46:05 -05:00 | | | | //--- Tablas generales
|
2026-09-30 07:39:54 -05:00 | | | | static const string s_dtype_to_str[JSON_VTYPE_TOTAL];
|
2026-10-05 21:58:00 -05:00 | | | | // unescape
|
| | | | static const uchar s_unescape_table[256];
|
| | | | // escape
|
| | | | static const uchar s_escape_table[256];
|
2026-10-08 13:39:44 -05:00 | | | | static string s_str;
|
2026-07-26 16:46:05 -05:00 | | | | };
|
| | | |
|
2026-08-03 09:31:58 -05:00 | | | | //+------------------------------------------------------------------+
|
| | | | //| |
|
| | | | //+------------------------------------------------------------------+
|
| | | | CJsonParser::CJsonParser(void)
|
| | | | {
|
2026-10-19 13:26:09 -05:00 | | | | m_next = TSN_JSON_TOK_INVALID + 1; // Apunta a un valor invalido
|
| | | | // Estro para que en caso se usa parse simd (no de errores "fantasma" dado que m_next no se usa ahi)
|
2026-08-03 09:31:58 -05:00 | | | | #ifdef JSONPARSERBYLEO_DLL
|
| | | | m_index_r = ArrayResize(m_index, 256, 256);
|
| | | | #endif // JSONPARSERBYLEO_DLL
|
| | | | }
|
| | | |
|
2026-07-26 16:46:05 -05:00 | | | | //+------------------------------------------------------------------+
|
| | | | //| |
|
| | | | //+------------------------------------------------------------------+
|
2026-10-08 13:39:44 -05:00 | | | | void CJsonParser::Options(const uint f)
|
2026-07-26 16:46:05 -05:00 | | | | {
|
2026-10-08 13:39:44 -05:00 | | | | m_jit_enabled = (f & BSFL_OPT_F_ENABLE_JIT) != 0 ? TSN_SBL_BIT_JIT_INITIAL_V : TSN_SBL_BIT_JIT_INV_VAL;
|
| | | | }
|
2026-09-18 14:11:09 -05:00 | | | |
|
| | | | //+------------------------------------------------------------------+
|
| | | | //| |
|
| | | | //+------------------------------------------------------------------+
|
| | | | #ifdef JSONPARSERBYLEO_DLL
|
| | | | void CJsonParser::CorrectPaddingSimd()
|
| | | | {
|
| | | | //---
|
| | | | const int new_len = m_len + 64;
|
| | | | ArrayResize(m_raw, new_len);
|
| | | |
|
| | | | //---
|
| | | | int i = m_len;
|
| | | | m_raw[i++] = ' ';
|
| | | | m_raw[i++] = '^'; // para cor ini para que falle bien..
|
| | | | // esto es para el caso de " no cerrado o { asi tal cual.. entonces ahi
|
| | | | // porzariamos a econnotrar un "" el cual ya lo manejaria y seria invalido
|
| | | | m_raw[i++] = '"';
|
| | | | m_raw[i++] = ' ';
|
| | | | m_raw[i++] = '"';
|
| | | | // esto es para el key... los dos primeors eran para que no de fuera de rango en index..
|
| | | | // en caso tengos un { asi tal cual... ecnontrar una key... pero luego le sigue : pero ahora pondmores
|
| | | | // , asi que == ':' fallaria retornando false, lo neceismtos dado que , se procesa como estrucuutra en la dll
|
| | | | m_raw[i++] = ',';
|
| | | |
|
| | | | //---
|
| | | | for(; i < new_len; i++)
|
| | | | m_raw[i] = ' '; // vacio
|
| | | |
|
| | | | //--- Reservamos
|
| | | | if(m_len > m_cinta_reserve)
|
| | | | {
|
2026-09-25 08:00:04 -05:00 | | | | m_cinta_reserve = m_len;
|
2026-09-18 14:11:09 -05:00 | | | | ArrayResize(m_cinta, m_len);
|
| | | | }
|
| | | |
|
| | | | //---
|
2026-09-25 08:00:04 -05:00 | | | | if(m_len > m_index_r)
|
2026-09-18 14:11:09 -05:00 | | | | {
|
2026-09-25 08:00:04 -05:00 | | | | m_index_r = m_len;
|
2026-09-18 14:11:09 -05:00 | | | | ArrayResize(m_index, m_index_r);
|
| | | | }
|
| | | | }
|
| | | | #endif // JSONPARSERBYLEO_DLL
|
| | | |
|
2026-10-08 13:39:44 -05:00 | | | | // {"a":0}
|
2026-09-18 14:11:09 -05:00 | | | | //+------------------------------------------------------------------+
|
| | | | void CJsonParser::CorrectPadding()
|
| | | | {
|
| | | | //---
|
2026-09-30 07:39:54 -05:00 | | | | //const int new_len = ;
|
2026-09-25 08:00:04 -05:00 | | | | ArrayResize(m_raw, m_len + 11);
|
2026-09-18 14:11:09 -05:00 | | | |
|
| | | | //--- Rellenamos
|
| | | | // esto es por el escapado. caso borde donde el json su ultimo char sea \ y avanze ++
|
| | | | // entonces con esto apaleamos eso..
|
| | | | m_raw[m_len] = ' ';
|
| | | | // este caracter es invalido por lo que en casos donde haya [ (sin mas asi tal cual)
|
| | | | // como no tenemos chekeos de rango entonces se tompara con este daond un error de malformacion
|
| | | | m_raw[m_len + 1] = '^';
|
| | | | m_raw[m_len + 2] = '"';
|
| | | | // justo luego 8 caracteres
|
| | | | m_raw[m_len + 3] = '\n'; // en una key invalida cargara a paritr de aqui 7 caracterres mas..
|
| | | | m_raw[m_len + 4] = '"'; // esto para poder encontrar el cierre de key... aparte en asm
|
| | | | // un token " asi suelto no es valido asi que daria error en caso haya un ; asi no mas.. sin \n (lo enocnr)
|
| | | | // igual por el padding pero luego avnazar a " pero este como tal no es token valido
|
2026-10-03 11:47:17 -05:00 | | | | // invalidos para que sigmoas si un valor esta fuera de rango como un string o algo asi
|
| | | | // falle aqui....
|
| | | | m_raw[m_len + 5] = '^'; //
|
2026-10-02 22:01:54 -05:00 | | | | m_raw[m_len + 6] = '^';
|
| | | | m_raw[m_len + 7] = '^';
|
| | | | m_raw[m_len + 8] = '^';
|
| | | | m_raw[m_len + 9] = '^';
|
| | | | m_raw[m_len + 10] = '^';
|
2026-09-18 14:11:09 -05:00 | | | |
|
| | | | //--- Reservamos
|
| | | | if(m_len > m_cinta_reserve)
|
| | | | {
|
| | | | m_cinta_reserve = m_len;
|
| | | | ArrayResize(m_cinta, m_len);
|
| | | | }
|
| | | | }
|
| | | |
|
2026-06-20 13:57:50 -05:00 | | | | //+------------------------------------------------------------------+
|
| | | | //| |
|
| | | | //+------------------------------------------------------------------+
|
2026-10-08 13:39:44 -05:00 | | | | // ponemos el jit attemp en vlao rinvalido, y table size le hacemos un pop..
|
| | | | #define BASESPARSERSAN_NODEHASHING_FINISH_ERR \
|
| | | | m_cinta[lock] = TSN_SBL_BIT_JIT_INV_VAL; \
|
| | | | m_tables_size--;
|
| | | |
|
| | | | //---
|
2026-10-08 20:25:09 -05:00 | | | | void CJsonParser::NodeHashing(int curr, const int obj_count, const int bend, int& table_pos)
|
2026-06-20 13:57:50 -05:00 | | | | {
|
2026-09-23 15:25:08 -05:00 | | | | //--- inicial
|
| | | | BASESPARSERSLAN_START_NODE_HASH(table_pos, curr)
|
2026-06-20 13:57:50 -05:00 | | | |
|
| | | | //---
|
| | | | m_tables[table_pos].table_size = obj_count; // Numero de objetos
|
| | | |
|
2026-10-08 13:39:44 -05:00 | | | | //--- 4 siempre dado que menos no se permite..
|
2026-06-28 18:47:50 -05:00 | | | | m_pfh.MaxValSeed(m_max_att++);
|
2026-10-08 13:39:44 -05:00 | | | | m_pfh.InitAlg(obj_count, 0.70, 4);
|
2026-06-20 13:57:50 -05:00 | | | |
|
| | | | //---
|
2026-06-21 20:08:59 -05:00 | | | | ArrayResize(m_tables[table_pos].pos_arr, obj_count);
|
2026-06-20 13:57:50 -05:00 | | | |
|
| | | | //--- Obtnemos las posiciones de incio
|
2026-06-24 17:20:42 -05:00 | | | | ulong keys_h[];
|
2026-06-28 18:47:50 -05:00 | | | | int posiciones[];
|
2026-06-24 17:20:42 -05:00 | | | | ArrayResize(keys_h, obj_count);
|
2026-06-28 18:47:50 -05:00 | | | | ArrayResize(posiciones, obj_count);
|
2026-06-24 17:20:42 -05:00 | | | | int pos_c = 0;
|
2026-10-08 13:39:44 -05:00 | | | | const int lock = curr + 1;
|
| | | | curr += TSN_SBL_SLOT_OBJ_SIZE; // Ahora en key
|
2026-06-24 17:20:42 -05:00 | | | |
|
| | | | //---
|
2026-06-20 13:57:50 -05:00 | | | | while(curr < bend)
|
| | | | {
|
| | | | //---
|
2026-06-24 17:20:42 -05:00 | | | | m_tables[table_pos].pos_arr[pos_c] = curr; // Assing
|
2026-06-20 13:57:50 -05:00 | | | |
|
| | | | //---
|
2026-10-08 13:39:44 -05:00 | | | | const ulong v = m_cinta[curr];
|
| | | | ulong hash;
|
| | | | if(TSN_SBL_KEY_HAS_ISN_HASH(v)) // no tiene hash
|
2026-06-24 17:20:42 -05:00 | | | | {
|
2026-10-08 13:39:44 -05:00 | | | | int i = int(v >> TSN_SBL_BIT_STR_START);
|
| | | | if(!CBSFLUnescape::MakeHash<CJsonParser>(m_raw, i, m_len, hash))
|
| | | | {
|
| | | | BASESPARSERSAN_NODEHASHING_FINISH_ERR
|
2026-10-08 20:25:09 -05:00 | | | | return;
|
2026-10-08 13:39:44 -05:00 | | | | }
|
| | | | m_cinta[curr] |= TSN_SBL_KEY_FLAG_HASH; // lo ponemos como valido...
|
| | | | m_cinta[curr + TSN_SBL_KEY_OFF_HASH] = hash; // para reproducibildiad
|
2026-06-24 17:20:42 -05:00 | | | | }
|
2026-10-08 13:39:44 -05:00 | | | | else
|
| | | | hash = m_cinta[curr + TSN_SBL_KEY_OFF_HASH]; // en la siguiente posicion esta el hash lo obtenemos tal cual
|
2026-06-20 13:57:50 -05:00 | | | |
|
2026-06-24 17:20:42 -05:00 | | | | //---
|
2026-10-08 13:39:44 -05:00 | | | | keys_h[pos_c] = hash;
|
2026-06-28 18:47:50 -05:00 | | | | posiciones[pos_c] = pos_c;
|
| | | | pos_c++;
|
2026-06-20 13:57:50 -05:00 | | | |
|
| | | | //---
|
2026-10-08 13:39:44 -05:00 | | | | curr += TSN_SBL_KEYSLOT_SIZE; // salta KEY
|
2026-06-24 17:20:42 -05:00 | | | | curr += GetStep(curr); // salta VAL
|
| | | | }
|
2026-06-20 13:57:50 -05:00 | | | |
|
2026-10-08 13:39:44 -05:00 | | | | //--- assing de tamaños
|
2026-06-28 18:47:50 -05:00 | | | | const int fn = m_pfh.m_final_table_size;
|
2026-10-08 13:39:44 -05:00 | | | | m_tables[table_pos].sizes = BSFL_T_PACK(m_pfh.m_buckets_size_last, m_pfh.m_final_table_size_last);
|
2026-07-28 21:39:04 -05:00 | | | |
|
2026-10-08 13:39:44 -05:00 | | | | //--- resize de arrays iniciales
|
2026-06-28 18:47:50 -05:00 | | | | ArrayResize(m_tables[table_pos].pos_index, fn);
|
| | | | ArrayResize(m_tables[table_pos].key_hash, fn);
|
| | | | ArrayInitialize(m_tables[table_pos].key_hash, 0ULL);
|
2026-06-20 13:57:50 -05:00 | | | |
|
| | | | //---
|
2026-09-25 08:00:04 -05:00 | | | | if(m_pfh.RunWValue(keys_h, posiciones, m_tables[table_pos].seeds, m_tables[table_pos].pos_index, m_tables[table_pos].key_hash))
|
2026-10-08 20:25:09 -05:00 | | | | return;
|
2026-09-25 08:00:04 -05:00 | | | |
|
| | | | //----
|
2026-10-08 13:39:44 -05:00 | | | | BASESPARSERSAN_NODEHASHING_FINISH_ERR
|
2026-10-08 20:25:09 -05:00 | | | | return;
|
2026-06-20 13:57:50 -05:00 | | | | }
|
2026-06-24 17:20:42 -05:00 | | | |
|
2026-07-19 07:41:52 -05:00 | | | | //+------------------------------------------------------------------+
|
| | | | //| |
|
| | | | //+------------------------------------------------------------------+
|
| | | | int CJsonParser::CalcRegType(const string& file_name)
|
| | | | {
|
| | | | return (int)JPBL_HashExt(file_name);
|
| | | | }
|
| | | |
|
2026-06-18 09:48:36 -05:00 | | | |
|
| | | |
|
2026-06-21 21:51:52 -05:00 | | | | //+------------------------------------------------------------------+
|
| | | | //| |
|
| | | | //+------------------------------------------------------------------+
|
| | | | bool CJsonParser::AutoParseByFileExt(const int file_ext_type)
|
| | | | {
|
| | | | switch(file_ext_type)
|
| | | | {
|
2026-07-19 07:41:52 -05:00 | | | | case TSN_SLF_RAW_FILE:
|
2026-06-21 21:51:52 -05:00 | | | | {
|
2026-07-19 07:41:52 -05:00 | | | | CorrectPadding(); // Auto
|
2026-06-21 21:51:52 -05:00 | | | | return Parse();
|
| | | | }
|
2026-07-19 07:41:52 -05:00 | | | | case TSN_SLF_RAW_EMBEBED:
|
2026-06-21 21:51:52 -05:00 | | | | {
|
2026-07-19 07:41:52 -05:00 | | | | return m_cinta_pos > 0 && m_len > 0;
|
2026-06-21 21:51:52 -05:00 | | | | }
|
| | | | default:
|
| | | | {
|
| | | | m_last_err = TSN_JSON_ERR_INVALID_EXT_FILE;
|
| | | | m_pos = 0;
|
| | | | return false;
|
| | | | }
|
| | | | }
|
| | | | }
|
2026-06-18 09:48:36 -05:00 | | | |
|
2026-06-02 21:23:50 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-08-02 16:49:10 -05:00 | | | | //| Macros de avanze |
|
2026-06-02 21:23:50 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-10-08 19:54:46 -05:00 | | | | //--- para aumtenar el numero de elementos.
|
| | | | #define TSN_JSON_AUMENT curr_count++;
|
2026-09-30 07:39:54 -05:00 | | | |
|
2026-10-02 22:01:54 -05:00 | | | | //--- Generico
|
| | | | // Luego de un valor siempre , o su fin
|
| | | | // 1 en la tabl to token es INVALID (dara error..de malformed..)
|
| | | | // Este se usa luego de un valor.. la idea es que luego de un valor "" numero t\f\n ] }
|
| | | | // tiene que haber o un }] o en todo caso , de continuacino solo eso...
|
| | | | #define TSN_JSON_NEXT_NO_NEXT_KEY \
|
| | | | uchar _c = m_raw[m_pos]; \
|
| | | | while(_c < 33) { _c = m_raw[++m_pos]; } \
|
| | | | m_next = g_table_json_tokens[_c]; \
|
2026-10-18 12:41:33 -05:00 | | | | if(((1 << m_next) & curr_state) == 0) \
|
2026-10-02 22:01:54 -05:00 | | | | { \
|
| | | | m_last_err= TSN_JSON_ERR_MALFORDMED_JSON_AFTER_VAL; \
|
| | | | return false; \
|
2026-10-03 11:47:17 -05:00 | | | | }
|
2026-10-02 22:01:54 -05:00 | | | |
|
2026-06-20 13:57:50 -05:00 | | | | //--- Luego de una coma en array
|
| | | | // Luego de una , y KEY siempre siempre valor
|
2026-09-30 07:39:54 -05:00 | | | | #define TSN_JSON_NEXT_VALUE_COMM_KEY \
|
| | | | uchar _c; \
|
| | | | while((_c=m_raw[++m_pos])<33) {} \
|
| | | | m_next = g_table_json_tokens[_c]; \
|
| | | | if(((1 << m_next) & TSN_JSON_F_ALL_I_VAL) == 0) \
|
| | | | { \
|
2026-09-18 14:11:09 -05:00 | | | | m_last_err= TSN_JSON_ERR_MALFORDMED_JSON_FIND_VAL; \
|
2026-09-30 07:39:54 -05:00 | | | | return false; \
|
| | | | }
|
| | | |
|
2026-10-08 20:25:09 -05:00 | | | | //--- unrolled find key
|
| | | | #define TSN_JSON_FINDKEY_FINAL_U4 \
|
| | | | if(m_raw[m_pos] == '"') \
|
| | | | break; \
|
| | | | m_pos++; \
|
| | | | if(m_raw[m_pos] == '"') \
|
| | | | break; \
|
| | | | m_pos++; \
|
| | | | if(m_raw[m_pos] == '"') \
|
| | | | break; \
|
| | | | m_pos++; \
|
| | | | if(m_raw[m_pos] == '"') \
|
| | | | break; \
|
| | | | m_pos++;
|
2026-08-03 09:31:58 -05:00 | | | |
|
2026-10-17 15:35:59 -05:00 | | | | //--- unrooled find normal
|
| | | | #define JSONPARSERBYLEO_FIND_FINAL_STR_IT \
|
| | | | if((c = m_raw[m_pos]) == '"') \
|
| | | | break; \
|
| | | | m_pos += (c == '\\') + 1; \
|
| | | | if((c = m_raw[m_pos]) == '"') \
|
| | | | break; \
|
| | | | m_pos += (c == '\\') + 1; \
|
| | | | if((c = m_raw[m_pos]) == '"') \
|
| | | | break; \
|
| | | | m_pos += (c == '\\') + 1; \
|
| | | | if((c = m_raw[m_pos]) == '"') \
|
| | | | break; \
|
| | | | m_pos += (c == '\\') + 1;
|
| | | |
|
| | | |
|
2026-08-26 19:48:01 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-09-30 07:39:54 -05:00 | | | | //| Parseo de numeros |
|
2026-08-26 19:48:01 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-09-30 07:39:54 -05:00 | | | | //--- make string
|
2026-10-08 13:39:44 -05:00 | | | | #define JSONPARSERBYLEO_NUM_MAKE_STRING m_cinta[m_cinta_pos++] = JSON_VTYPE_STRING \
|
| | | | | ulong(m_pos - start) << TSN_SBL_BIT_STR_LEN(TSN_SBL_SLEN_STR) \
|
| | | | | ulong(start) << TSN_SBL_BIT_STR_START;
|
2026-09-30 07:39:54 -05:00 | | | |
|
2026-08-02 12:33:47 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-08-03 15:01:11 -05:00 | | | | //| Parse con simd |
|
2026-08-02 12:33:47 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-10-19 13:26:09 -05:00 | | | | // m_last_err = TSN_JSON_NOT_ERR; quizas no hague falta dado qeu en la DLL siemrpe se stea con noterr o eso
|
2026-08-03 09:31:58 -05:00 | | | | #ifdef JSONPARSERBYLEO_DLL
|
2026-09-18 14:11:09 -05:00 | | | | __forceinline bool CJsonParser::ParseSimd()
|
2026-06-02 21:23:50 -05:00 | | | | {
|
2026-08-03 15:01:11 -05:00 | | | | //--- Iniciales
|
2026-10-19 13:26:09 -05:00 | | | | m_pos = m_offset;
|
2026-07-12 18:24:34 -05:00 | | | | m_tables_size = 0;
|
2026-09-18 14:11:09 -05:00 | | | | return JsonParserResolve(m_raw,
|
| | | | m_cinta,
|
| | | | m_index,
|
| | | | m_len,
|
2026-10-19 07:27:55 -05:00 | | | | m_jit_enabled,
|
2026-09-18 14:11:09 -05:00 | | | | (int&)m_last_err,
|
| | | | m_cinta_pos,
|
| | | | m_pos
|
| | | | );
|
2026-08-02 16:49:10 -05:00 | | | | }
|
2026-08-03 09:31:58 -05:00 | | | | #endif // JSONPARSERBYLEO_DLL
|
| | | |
|
2026-08-03 15:01:11 -05:00 | | | |
|
2026-08-26 19:48:01 -05:00 | | | |
|
2026-08-02 16:49:10 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-08-03 15:01:11 -05:00 | | | | //| Parse normal |
|
2026-08-02 16:49:10 -05:00 | | | | //+------------------------------------------------------------------+
|
| | | | bool CJsonParser::Parse()
|
| | | | {
|
| | | | //---
|
| | | | m_last_err = TSN_JSON_NOT_ERR;
|
| | | | m_pos = m_offset;
|
| | | | m_cinta_pos = 0;
|
| | | | m_tables_size = 0;
|
| | | |
|
2026-10-08 19:54:46 -05:00 | | | | //---
|
| | | | uint curr_state = 0;
|
| | | | uint curr_count = 0;
|
| | | | uint curr_padre = 0;
|
| | | |
|
2026-08-02 16:49:10 -05:00 | | | | //--- 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;
|
2026-10-18 12:41:33 -05:00 | | | | else // No easy
|
2026-08-02 16:49:10 -05:00 | | | | {
|
2026-10-08 19:54:46 -05:00 | | | | uchar __c = m_raw[++m_pos];
|
| | | | while(__c < 33)
|
| | | | __c = m_raw[++m_pos];
|
| | | |
|
| | | | //---
|
| | | | if(__c == '{')
|
| | | | m_next = TSN_JSON_TOK_LLAVE_INI;
|
| | | | else
|
| | | | if(__c == '[')
|
| | | | m_next = TSN_JSON_TOK_COR_INI;
|
2026-10-18 12:41:33 -05:00 | | | | else // Single value
|
2026-08-02 16:49:10 -05:00 | | | | {
|
2026-10-08 19:54:46 -05:00 | | | | m_next = TSN_JSON_TOK_INVALID;
|
2026-08-02 16:49:10 -05:00 | | | | }
|
| | | | }
|
| | | |
|
| | | | //--- Bucle
|
| | | | while(true)
|
| | | | {
|
| | | | switch(m_next)
|
| | | | {
|
2026-08-26 19:48:01 -05:00 | | | | //---
|
| | | | case TSN_JSON_TOK_NUMBER_NEG:
|
2026-08-02 16:49:10 -05:00 | | | | {
|
2026-09-30 07:39:54 -05:00 | | | | //--- solo 3 varaibles nada mas en general (garantizado)
|
| | | | long v = 0;
|
2026-10-08 13:39:44 -05:00 | | | | const uint start = m_pos;
|
2026-09-30 07:39:54 -05:00 | | | | uchar ch = m_raw[++m_pos] ^ '0';
|
2026-08-02 16:49:10 -05:00 | | | | //---
|
2026-09-30 07:39:54 -05:00 | | | | switch(0)
|
| | | | {
|
| | | | default: // scope con psoiblidad de break.
|
| | | | {
|
| | | | //--- primera iteracion sin cheking
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_PARSE_NUM_U1(v)
|
2026-09-30 07:39:54 -05:00 | | | | //--- Interesante: sigue siendo cero pero me pide mas digitios ?¿
|
| | | | if(!v)
|
| | | | {
|
| | | | m_last_err = TSN_JSON_ERR_LEADING_ZEROS;
|
| | | | m_next = TSN_JSON_TOK_INVALID;
|
| | | | continue;
|
| | | | }
|
| | | | //--- 19 iteraciones maximo
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_PARSE_NUM_UNROLLED_17(v)
|
2026-10-01 13:36:22 -05:00 | | | | STRCONV_TOV_ALG(v, ch)
|
2026-09-30 07:39:54 -05:00 | | | | if((ch = m_raw[++m_pos] ^ '0') > 9)
|
| | | | {
|
| | | | if(v > 0)
|
| | | | break;
|
| | | | }
|
| | | | else // aun es valido asi que seguimos saltando el numero completo (parte entera) (pero ya sabmeos que es invalido)
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_NUM_SKIP_NUMBER
|
2026-09-30 07:39:54 -05:00 | | | | }
|
| | | | //--- revismoos si es dec, si lo es saltamos la parte dec
|
2026-10-02 22:01:54 -05:00 | | | | if(STRCONV_DECX_CH_IS_DEC(ch))
|
| | | | break;
|
| | | |
|
2026-09-30 07:39:54 -05:00 | | | | //--- pasamos a str y ya no caemos abajo de aqui:
|
| | | | JSONPARSERBYLEO_NUM_MAKE_STRING
|
| | | | TSN_JSON_AUMENT
|
| | | | TSN_JSON_NEXT_NO_NEXT_KEY
|
| | | | continue; // esto aplica a nivel de while
|
| | | | }
|
| | | | }
|
| | | | //--- vemos si decimal
|
2026-10-02 22:01:54 -05:00 | | | | if(STRCONV_DECX_CH_IS_DEC(ch))
|
2026-09-30 07:39:54 -05:00 | | | | {
|
| | | | long exponente = 0; // exponente
|
2026-10-08 13:39:44 -05:00 | | | | uint digitos = m_pos - start; // digitos que se van acomulando (parte ent + dec)
|
2026-10-02 22:01:54 -05:00 | | | | if(STRCONV_DECX_CH_IS_PDEC(ch))
|
2026-09-30 07:39:54 -05:00 | | | | {
|
2026-10-08 13:39:44 -05:00 | | | | uint ds = ++m_pos; // inicio
|
2026-09-30 07:39:54 -05:00 | | | | if((ch = m_raw[m_pos] ^ '0') > 9)
|
| | | | {
|
| | | | m_last_err = TSN_JSON_ERR_EXPECTED_NUMBER_AFECTER_DECIMALP;
|
| | | | return false;
|
| | | | }
|
| | | | while(true)
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | //DOMBASEUTIL_NUM_PROCCES_FIRST_DEC(v, ch, m_pos, ds, digitos)
|
| | | | DOMBASEUTIL_PARSE_NUM_UNROLLED_18(v)
|
| | | | DOMBASEUTIL_NUM_SKIP_NUMBER
|
2026-09-30 07:39:54 -05:00 | | | | break;
|
| | | | }
|
| | | | //---
|
| | | | ds = (m_pos - ds); // numero de digitos de la parte decimal
|
| | | | digitos += ds;
|
| | | | exponente -= ds;
|
| | | | }
|
2026-10-02 22:01:54 -05:00 | | | | if(STRCONV_DECX_CH_IS_E(ch)) //
|
2026-09-30 07:39:54 -05:00 | | | | {
|
| | | | bool exp_positivo = true;
|
| | | | ch = m_raw[++m_pos] ^ '0';
|
| | | | if(ch > 9)
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | if(STRCONV_DECX_CH_IS_MINUS(ch))
|
2026-09-30 07:39:54 -05:00 | | | | exp_positivo = false;
|
| | | | if((ch = m_raw[++m_pos] ^ '0') > 9)
|
| | | | {
|
| | | | m_last_err = TSN_JSON_ERR_EXPECTED_NUMBER_AFECTER_EXP;
|
| | | | return false; // sale
|
| | | | }
|
| | | | }
|
| | | | int expo = 0;
|
| | | | while(true) // siguimos acomulando en v
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_PARSE_NUM_U1(expo)
|
2026-09-30 07:39:54 -05:00 | | | | if(expo == 0) // leading zeros.. ahora mismo aun hay digitos pero el primero es 0..
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_PARSE_SKIP_LZ
|
2026-09-30 07:39:54 -05:00 | | | | } // pos apunta al curr no cero ch ya tiene su valor en caso sea 00000x (no numero) sale..
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_PARSE_NUM_UNROLLED_8(expo)
|
| | | | STRCONV_TOV_ALG(expo, ch)
|
2026-09-30 07:39:54 -05:00 | | | | if((ch = m_raw[++m_pos] ^ '0') > 9) // 10cimo digito
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | if(expo > 0) // es valido
|
2026-09-30 07:39:54 -05:00 | | | | break; // no ov
|
| | | | }
|
| | | | else // sigue saltamos todo lo que hya
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_NUM_SKIP_NUMBER
|
2026-09-30 07:39:54 -05:00 | | | | }
|
| | | | expo = INT_MAX;
|
2026-10-02 22:01:54 -05:00 | | | | break;
|
2026-09-30 07:39:54 -05:00 | | | | }
|
| | | | exponente += exp_positivo ? expo : -expo;
|
| | | | }
|
2026-10-02 22:01:54 -05:00 | | | | //--- 1 dado que start incluye el -
|
| | | | if(STRCONV_DOUBLE_SAFE_DBL_P(digitos, exponente, 1))
|
2026-09-30 07:39:54 -05:00 | | | | {
|
| | | | TsnBitInterprete bit;
|
2026-10-02 22:01:54 -05:00 | | | | bit.double_value = -STRCONV_TO_DOUBLE_ALG(exponente, v);
|
2026-09-30 07:39:54 -05:00 | | | | m_cinta[m_cinta_pos++] = JSON_VTYPE_REAL;
|
2026-10-08 13:39:44 -05:00 | | | | m_cinta[m_cinta_pos++] = bit.ulong_value;
|
2026-09-30 07:39:54 -05:00 | | | | }
|
| | | | else // make_string: numero grande o que ya no se peude representar con precision (a string)
|
| | | | {
|
| | | | JSONPARSERBYLEO_NUM_MAKE_STRING
|
| | | | }
|
| | | | }
|
| | | | else
|
| | | | {
|
| | | | m_cinta[m_cinta_pos++] = JSON_VTYPE_INTEGER;
|
| | | | m_cinta[m_cinta_pos++] = -v;
|
| | | | }
|
2026-08-02 16:49:10 -05:00 | | | | //---
|
2026-09-18 14:11:09 -05:00 | | | | TSN_JSON_AUMENT
|
2026-08-26 19:48:01 -05:00 | | | | TSN_JSON_NEXT_NO_NEXT_KEY
|
| | | | break;
|
| | | | }
|
2026-08-02 16:49:10 -05:00 | | | |
|
2026-08-26 19:48:01 -05:00 | | | | //---
|
2026-09-30 07:39:54 -05:00 | | | | case TSN_JSON_TOK_NUMBER:
|
2026-08-26 19:48:01 -05:00 | | | | {
|
| | | | //---
|
2026-10-08 13:39:44 -05:00 | | | | const uint start = m_pos;
|
2026-10-18 12:41:33 -05:00 | | | | // Primer valor
|
| | | | const uchar fc = m_raw[start] ^ '0';
|
| | | | ulong v = fc; // Tal cual sin mas..
|
| | | | // Segundo valor
|
| | | | uchar ch = m_raw[++m_pos] ^ '0';
|
2026-08-02 16:49:10 -05:00 | | | |
|
2026-09-30 07:39:54 -05:00 | | | | //---
|
| | | | switch(0)
|
| | | | {
|
| | | | default: // scope con psoiblidad de break.
|
| | | | {
|
| | | | //---
|
2026-10-18 12:41:33 -05:00 | | | | if(ch > 9) // Mayor
|
| | | | break;
|
| | | | if(!v) // LZ
|
2026-09-30 07:39:54 -05:00 | | | | {
|
| | | | m_last_err = TSN_JSON_ERR_LEADING_ZEROS;
|
| | | | m_next = TSN_JSON_TOK_INVALID;
|
| | | | continue;
|
| | | | }
|
| | | | //--- 19 iteraciones maximo
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_PARSE_NUM_UNROLLED_18(v)
|
2026-10-01 13:36:22 -05:00 | | | | STRCONV_TOV_ALG(v, ch)
|
2026-09-30 07:39:54 -05:00 | | | | if((ch = m_raw[++m_pos] ^ '0') > 9)
|
| | | | {
|
| | | | if(fc == 1 && v > LONG_MAX)
|
| | | | break;
|
| | | | }
|
| | | | else // aun es valido asi que seguimos saltando el numero completo (parte entera) (pero ya sabmeos que es invalido)
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_NUM_SKIP_NUMBER
|
2026-09-30 07:39:54 -05:00 | | | | }
|
2026-10-02 22:01:54 -05:00 | | | | //--- revismoos si es dec, si es asi lo mandamos para la funcion dec aqui solo big integer
|
| | | | if(STRCONV_DECX_CH_IS_DEC(ch))
|
| | | | break;
|
2026-09-30 07:39:54 -05:00 | | | | //--- pasamos a str y ya no caemos abajo de aqui:
|
| | | | JSONPARSERBYLEO_NUM_MAKE_STRING
|
| | | | TSN_JSON_AUMENT
|
| | | | TSN_JSON_NEXT_NO_NEXT_KEY
|
| | | | continue; // esto aplica a nivel de while
|
| | | | }
|
| | | | }
|
| | | | //--- vemos si decimal
|
2026-10-02 22:01:54 -05:00 | | | | if(STRCONV_DECX_CH_IS_DEC(ch)) // v por lo tanto llega bien aqui como entero unsigned valido
|
2026-09-30 07:39:54 -05:00 | | | | {
|
| | | | long exponente = 0; // exponente
|
2026-10-08 13:39:44 -05:00 | | | | uint digitos = m_pos - start; // digitos que se van acomulando (parte ent + dec)
|
2026-10-02 22:01:54 -05:00 | | | | if(STRCONV_DECX_CH_IS_PDEC(ch)) // punto decimal (tomar precuacion aqui si v puede dar overflow y voltear no hay chekeo)
|
2026-09-30 07:39:54 -05:00 | | | | {
|
2026-10-08 13:39:44 -05:00 | | | | uint ds = ++m_pos;
|
2026-09-30 07:39:54 -05:00 | | | | if((ch = m_raw[m_pos] ^ '0') > 9)
|
| | | | {
|
| | | | m_last_err = TSN_JSON_ERR_EXPECTED_NUMBER_AFECTER_DECIMALP;
|
| | | | return false;
|
| | | | }
|
| | | | while(true)
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | //DOMBASEUTIL_NUM_PROCCES_FIRST_DEC(v, ch, m_pos, ds, digitos)
|
| | | | DOMBASEUTIL_PARSE_NUM_UNROLLED_18(v)
|
| | | | DOMBASEUTIL_NUM_SKIP_NUMBER
|
2026-09-30 07:39:54 -05:00 | | | | break;
|
| | | | }
|
| | | | //---
|
| | | | ds = (m_pos - ds); // numero de digitos de la parte decimal
|
| | | | digitos += ds;
|
| | | | exponente -= ds;
|
| | | | }
|
2026-10-02 22:01:54 -05:00 | | | | if(STRCONV_DECX_CH_IS_E(ch)) //
|
2026-09-30 07:39:54 -05:00 | | | | {
|
| | | | bool exp_positivo = true;
|
| | | | ch = m_raw[++m_pos] ^ '0';
|
| | | | if(ch > 9)
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | if(STRCONV_DECX_CH_IS_MINUS(ch))
|
2026-09-30 07:39:54 -05:00 | | | | exp_positivo = false;
|
| | | | if((ch = m_raw[++m_pos] ^ '0') > 9)
|
| | | | {
|
| | | | m_last_err = TSN_JSON_ERR_EXPECTED_NUMBER_AFECTER_EXP;
|
| | | | return false; // sale
|
| | | | }
|
| | | | }
|
| | | | int expo = 0;
|
2026-10-02 22:01:54 -05:00 | | | | while(true)
|
2026-09-30 07:39:54 -05:00 | | | | {
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_PARSE_NUM_U1(expo)
|
2026-09-30 07:39:54 -05:00 | | | | if(expo == 0) // leading zeros.. ahora mismo aun hay digitos pero el primero es 0..
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_PARSE_SKIP_LZ
|
2026-09-30 07:39:54 -05:00 | | | | } // pos apunta al curr no cero ch ya tiene su valor en caso sea 00000x (no numero) sale..
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_PARSE_NUM_UNROLLED_8(expo)
|
| | | | STRCONV_TOV_ALG(expo, ch)
|
2026-09-30 07:39:54 -05:00 | | | | if((ch = m_raw[++m_pos] ^ '0') > 9) // 10cimo digito
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | if(expo > 0) // es valido
|
2026-09-30 07:39:54 -05:00 | | | | break; // no ov
|
| | | | }
|
| | | | else // sigue saltamos todo lo que hya
|
| | | | {
|
2026-10-02 22:01:54 -05:00 | | | | DOMBASEUTIL_NUM_SKIP_NUMBER
|
2026-09-30 07:39:54 -05:00 | | | | }
|
| | | | expo = INT_MAX;
|
2026-10-02 22:01:54 -05:00 | | | | break;
|
2026-09-30 07:39:54 -05:00 | | | | }
|
| | | | exponente += exp_positivo ? expo : -expo;
|
| | | | }
|
2026-10-02 22:01:54 -05:00 | | | | //---
|
| | | | if(STRCONV_DOUBLE_SAFE_DBL(digitos, exponente))
|
2026-09-30 07:39:54 -05:00 | | | | {
|
| | | | TsnBitInterprete bit;
|
2026-10-02 22:01:54 -05:00 | | | | bit.double_value = STRCONV_TO_DOUBLE_ALG(exponente, v);
|
2026-09-30 07:39:54 -05:00 | | | | m_cinta[m_cinta_pos++] = JSON_VTYPE_REAL;
|
2026-10-08 13:39:44 -05:00 | | | | m_cinta[m_cinta_pos++] = bit.ulong_value;
|
2026-09-30 07:39:54 -05:00 | | | | }
|
2026-10-02 22:01:54 -05:00 | | | | else
|
2026-09-30 07:39:54 -05:00 | | | | {
|
| | | | JSONPARSERBYLEO_NUM_MAKE_STRING
|
| | | | }
|
| | | | }
|
| | | | else
|
| | | | {
|
| | | | m_cinta[m_cinta_pos++] = JSON_VTYPE_UINTEGER;
|
2026-10-08 13:39:44 -05:00 | | | | m_cinta[m_cinta_pos++] = v;
|
2026-09-30 07:39:54 -05:00 | | | | }
|
| | | | //---
|
2026-09-18 14:11:09 -05:00 | | | | TSN_JSON_AUMENT
|
2026-08-02 16:49:10 -05:00 | | | | TSN_JSON_NEXT_NO_NEXT_KEY
|
| | | | break;
|
| | | | }
|
| | | |
|
| | | | //---
|
| | | | case TSN_JSON_TOK_STRING:
|
| | | | {
|
| | | | //---
|
2026-10-08 13:39:44 -05:00 | | | | const uint start = ++m_pos;
|
2026-08-02 16:49:10 -05:00 | | | |
|
| | | | //---
|
| | | | #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;
|
| | | | const ulong x_qt = chunk ^ TSNTABLES_SWAR_MASK_COMILLA;
|
2026-10-17 15:35:59 -05:00 | | | | ulong has_bs = TSNTABLES_SWAR_HAS(x_bs);
|
| | | | ulong has_qt = TSNTABLES_SWAR_HAS(x_qt);
|
2026-08-02 16:49:10 -05:00 | | | |
|
| | | | //---
|
2026-10-17 15:35:59 -05:00 | | | | if((has_bs | has_qt) == 0) // Fast path
|
2026-08-02 16:49:10 -05:00 | | | | {
|
| | | | m_pos += 8;
|
| | | | continue;
|
| | | | }
|
| | | |
|
| | | | //---
|
2026-10-18 12:41:33 -05:00 | | | | if(has_bs == 0) // Si not iene bs (pero confirmamos que no es 0) (Fast path)
|
2026-08-02 16:49:10 -05:00 | | | | {
|
2026-10-17 15:35:59 -05:00 | | | | const ulong flag_real = TSNTABLES_BIT_DEJAR_SOLO_MINUS_SIG_BYTE(has_qt);
|
2026-08-27 13:40:38 -05:00 | | | | m_pos += TSNTABLES_CTZ_64_GET_BYTE(flag_real);
|
2026-08-02 16:49:10 -05:00 | | | | m_cinta[m_cinta_pos++] = JSON_VTYPE_STRING
|
2026-10-08 13:39:44 -05:00 | | | | | ulong(m_pos - start) << TSN_SBL_BIT_STR_LEN(TSN_SBL_SLEN_STR)
|
| | | | | ulong(start) << TSN_SBL_BIT_STR_START;
|
2026-08-02 16:49:10 -05:00 | | | | m_pos++; // Luego del "
|
| | | | break;
|
| | | | }
|
| | | |
|
2026-10-17 15:35:59 -05:00 | | | | //--- Slow path
|
| | | | has_bs = TSNTABLES_SWAR_HAS_EXACT(x_bs);
|
| | | | has_qt = TSNTABLES_SWAR_HAS_EXACT(x_qt);
|
| | | |
|
2026-08-02 16:49:10 -05:00 | | | | //--- 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");
|
| | | |
|
| | | | //---
|
2026-09-18 14:11:09 -05:00 | | | | if(qt_final) // Hay un qt real de cierre
|
2026-08-02 16:49:10 -05:00 | | | | {
|
2026-09-18 14:11:09 -05:00 | | | | //---
|
2026-08-02 16:49:10 -05:00 | | | | // Avanzamos y cerramos..
|
2026-08-27 13:40:38 -05:00 | | | | m_pos += g_tsntables_table_ctz_i8[qt_final];
|
2026-08-02 16:49:10 -05:00 | | | | m_cinta[m_cinta_pos++] = JSON_VTYPE_STRING
|
2026-10-08 13:39:44 -05:00 | | | | | ulong(m_pos - start) << TSN_SBL_BIT_STR_LEN(TSN_SBL_SLEN_STR)
|
| | | | | ulong(start) << TSN_SBL_BIT_STR_START;
|
2026-09-18 14:11:09 -05:00 | | | |
|
| | | | //---
|
| | | | m_pos++;
|
2026-08-02 16:49:10 -05:00 | | | | break;
|
| | | | }
|
| | | | else
|
| | | | {
|
2026-10-17 15:35:59 -05:00 | | | | m_pos += 8;// + ((prev & compacted_bs) >> 7U);
|
2026-08-02 16:49:10 -05:00 | | | | // 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
|
| | | | }
|
| | | | }
|
| | | | }
|
2026-10-17 15:35:59 -05:00 | | | |
|
| | | |
|
2026-08-02 16:49:10 -05:00 | | | | #else // JSONPARSERBYLEO_DESACTIVE_SWAR
|
| | | | //--- Char por char
|
2026-10-17 15:35:59 -05:00 | | | | uchar c;
|
| | | | while(true) // Find unrrolled 20
|
2026-08-02 16:49:10 -05:00 | | | | {
|
2026-10-17 15:35:59 -05:00 | | | | JSONPARSERBYLEO_FIND_FINAL_STR_IT
|
| | | | JSONPARSERBYLEO_FIND_FINAL_STR_IT
|
| | | | JSONPARSERBYLEO_FIND_FINAL_STR_IT
|
| | | | JSONPARSERBYLEO_FIND_FINAL_STR_IT
|
| | | | JSONPARSERBYLEO_FIND_FINAL_STR_IT
|
2026-08-02 16:49:10 -05:00 | | | | }
|
2026-10-17 15:35:59 -05:00 | | | |
|
| | | | //---
|
| | | | m_cinta[m_cinta_pos++] = JSON_VTYPE_STRING | ulong(m_pos - start) << TSN_SBL_BIT_STR_LEN(TSN_SBL_SLEN_STR) |
|
| | | | ulong(start) << TSN_SBL_BIT_STR_START;
|
| | | | m_pos++;
|
2026-08-02 16:49:10 -05:00 | | | | #endif // JSONPARSERBYLEO_DESACTIVE_SWAR
|
| | | |
|
| | | | //---
|
2026-09-18 14:11:09 -05:00 | | | | TSN_JSON_AUMENT
|
2026-08-02 16:49:10 -05:00 | | | | TSN_JSON_NEXT_NO_NEXT_KEY
|
| | | |
|
| | | | //---
|
| | | | break;
|
| | | | }
|
2026-09-30 07:39:54 -05:00 | | | | case TSN_JSON_TOK_BOOL_TRUE:
|
2026-08-02 16:49:10 -05:00 | | | | {
|
2026-10-03 11:47:17 -05:00 | | | | const uint k = (uint)m_raw[++m_pos] | (uint)m_raw[++m_pos] << 8 | (uint)m_raw[++m_pos] << 16;
|
| | | | if(k != TSNJSON_VAL_TRUE)
|
2026-09-30 07:39:54 -05:00 | | | | return false;
|
2026-08-02 16:49:10 -05:00 | | | |
|
2026-09-30 07:39:54 -05:00 | | | | //---
|
| | | | m_pos++;
|
2026-10-08 19:54:46 -05:00 | | | | m_cinta[m_cinta_pos++] = (JSON_VTYPE_BOOLEAN | 1ULL << TSN_SBL_BIT_START_BOOL);
|
2026-08-02 16:49:10 -05:00 | | | |
|
| | | | //---
|
2026-09-18 14:11:09 -05:00 | | | | TSN_JSON_AUMENT
|
2026-08-02 16:49:10 -05:00 | | | | TSN_JSON_NEXT_NO_NEXT_KEY
|
| | | | break;
|
| | | | }
|
2026-09-30 07:39:54 -05:00 | | | | case TSN_JSON_TOK_BOOL_FALSE:
|
2026-08-02 16:49:10 -05:00 | | | | {
|
2026-10-03 11:47:17 -05:00 | | | | //const uint k = (uint)m_raw[++m_pos] | (uint)m_raw[++m_pos] << 8 | (uint)m_raw[++m_pos] << 16 | (uint)m_raw[++m_pos] << 24;
|
2026-09-30 07:39:54 -05:00 | | | | if(m_raw[++m_pos] != 'a' || m_raw[++m_pos] != 'l' || m_raw[++m_pos] != 's' || m_raw[++m_pos] != 'e')
|
| | | | return false;
|
| | | |
|
| | | | //---
|
| | | | m_pos++;
|
2026-08-02 16:49:10 -05:00 | | | | m_cinta[m_cinta_pos++] = JSON_VTYPE_BOOLEAN;
|
| | | |
|
| | | | //---
|
2026-09-18 14:11:09 -05:00 | | | | TSN_JSON_AUMENT
|
2026-08-02 16:49:10 -05:00 | | | | TSN_JSON_NEXT_NO_NEXT_KEY
|
| | | | break;
|
| | | | }
|
| | | | case TSN_JSON_TOK_NULL:
|
| | | | {
|
2026-10-03 11:47:17 -05:00 | | | | const uint k = (uint)m_raw[++m_pos] | (uint)m_raw[++m_pos] << 8 | (uint)m_raw[++m_pos] << 16;
|
| | | | if(k != TSNJSON_VAL_NULL)
|
2026-09-30 07:39:54 -05:00 | | | | return false;
|
2026-08-02 16:49:10 -05:00 | | | |
|
| | | | //---
|
2026-09-30 07:39:54 -05:00 | | | | m_pos++;
|
2026-08-02 16:49:10 -05:00 | | | | m_cinta[m_cinta_pos++] = JSON_VTYPE_NULL;
|
| | | |
|
| | | | //---
|
2026-09-18 14:11:09 -05:00 | | | | TSN_JSON_AUMENT
|
2026-08-02 16:49:10 -05:00 | | | | TSN_JSON_NEXT_NO_NEXT_KEY
|
| | | | break;
|
| | | | }
|
2026-09-30 07:39:54 -05:00 | | | | case TSN_JSON_TOK_COMMA:
|
2026-08-02 16:49:10 -05:00 | | | | {
|
2026-10-08 19:54:46 -05:00 | | | | if(curr_state == TSN_JSON_CTX_IN_OBJ)
|
2026-08-02 16:49:10 -05:00 | | | | {
|
2026-09-30 07:39:54 -05:00 | | | | while(m_raw[++m_pos] != '"') {}
|
| | | | m_next = TSN_JSON_TOK_KEY;
|
2026-08-02 16:49:10 -05:00 | | | | }
|
| | | | else
|
| | | | {
|
| | | | TSN_JSON_NEXT_VALUE_COMM_KEY
|
| | | | }
|
| | | | break;
|
| | | | }
|
2026-10-17 15:35:59 -05:00 | | | | case TSN_JSON_TOK_LLAVE_INI:
|
2026-08-02 16:49:10 -05:00 | | | | {
|
2026-10-08 19:54:46 -05:00 | | | | //--- guardar lo uqe tenaismos (numero de elementos) (+1 para contar este nuevo elemento)
|
| | | | m_cinta[curr_padre] = curr_count + 1;
|
| | | |
|
| | | | //--- nuevo, ahora guardamos la direccion de nuesto padre y la nuestar (rempalzao num el por mientas)
|
| | | | m_cinta[m_cinta_pos] = JSON_VTYPE_OBJ |
|
| | | | ulong(m_cinta_pos) << TSN_SBL_PARSE_START_CINTAPOS |
|
| | | | ulong(curr_padre) << TSN_SBL_BIT_START_NUM_C;
|
| | | | curr_padre = ++m_cinta_pos; // apunta al inicio + 1 (lo modificamos para count, ahora apunta aqui..)
|
| | | | m_cinta_pos++; // salta la posicion 1
|
| | | |
|
| | | | //--- reiniciamos los estados
|
| | | | curr_state = TSN_JSON_CTX_IN_OBJ;
|
| | | | curr_count = 0;
|
2026-08-02 16:49:10 -05:00 | | | |
|
2026-10-18 12:41:33 -05:00 | | | |
|
| | | | //---
|
| | | | uchar _c = m_raw[++m_pos];
|
| | | | while(_c < 33)
|
| | | | _c = m_raw[++m_pos];
|
| | | |
|
| | | | //---
|
| | | | if(_c == '"')
|
| | | | m_next = TSN_JSON_TOK_KEY;
|
| | | | else
|
2026-10-08 19:54:46 -05:00 | | | | if(_c == '}')
|
| | | | m_next = TSN_JSON_TOK_LLAVE_END;
|
2026-10-18 12:41:33 -05:00 | | | | else
|
| | | | {
|
2026-10-19 09:16:24 -05:00 | | | | m_last_err = TSN_JSON_ERR_MALFORDMED_JSON_AFTER_LLAVE_INI;
|
| | | | m_next = TSN_JSON_TOK_INVALID;
|
2026-10-08 19:54:46 -05:00 | | | | }
|
2026-10-18 12:41:33 -05:00 | | | |
|
2026-08-02 16:49:10 -05:00 | | | | //---
|
| | | | break;
|
| | | | }
|
| | | | case TSN_JSON_TOK_COR_INI:
|
| | | | {
|
2026-10-08 19:54:46 -05:00 | | | | //--- guardar lo uqe tenaismos (numero de elementos) (+1 para contar este nuevo elemento)
|
| | | | m_cinta[curr_padre] = curr_count + 1;
|
| | | |
|
| | | | //--- nuevo, ahora guardamos la direccion de nuesto padre y la nuestar (rempalzao num el por mientas)
|
| | | | m_cinta[m_cinta_pos] = JSON_VTYPE_ARR |
|
| | | | ulong(m_cinta_pos) << TSN_SBL_PARSE_START_CINTAPOS |
|
| | | | ulong(curr_padre) << TSN_SBL_BIT_START_NUM_C;
|
| | | | curr_padre = ++m_cinta_pos; // apunta al inicio + 1 (lo modificamos para count, ahora apunta aqui..)
|
| | | | m_cinta_pos++; // salta la posicion 1
|
| | | |
|
| | | | //--- reiniciamos los estados
|
| | | | curr_state = TSN_JSON_CTX_IN_ARR;
|
| | | | curr_count = 0;
|
| | | |
|
| | | | //--- Find
|
| | | | //- con el pre salta.. el [
|
2026-10-08 13:39:44 -05:00 | | | | uchar _c = m_raw[++m_pos];
|
2026-10-02 22:01:54 -05:00 | | | | while(_c < 33)
|
| | | | _c = m_raw[++m_pos];
|
2026-10-08 19:54:46 -05:00 | | | | //- check
|
2026-10-02 22:01:54 -05:00 | | | | m_next = g_table_json_tokens[_c];
|
| | | | if(((1 << m_next) & TSN_JSON_F_VAL_COR) == 0)
|
| | | | {
|
| | | | m_last_err = TSN_JSON_ERR_MALFORDMED_JSON_AFTER_COR_INI;
|
| | | | return false;
|
| | | | }
|
2026-10-03 11:47:17 -05:00 | | | |
|
2026-08-02 16:49:10 -05:00 | | | | //---
|
| | | | break;
|
| | | | }
|
| | | | case TSN_JSON_TOK_LLAVE_END:
|
| | | | {
|
2026-10-08 19:54:46 -05:00 | | | | //--- cacheamos el valor de cinta [curr_padre-1] = apunta a los datos
|
| | | | m_cinta[curr_padre] = m_jit_enabled; // le damos su valor final
|
| | | | const uint idata = --curr_padre;
|
| | | | const ulong v = m_cinta[idata];
|
| | | | // ahora si rehacemos el valor con todo ya listo.. (curr padre apunta a la posicion correcta)
|
| | | | m_cinta[idata] = JSON_VTYPE_OBJ | ulong(curr_count) << TSN_SBL_BIT_START_NUM_EL |
|
2026-10-08 20:25:09 -05:00 | | | | ulong(m_cinta_pos - ((v >> 1) & TSN_SBL_PARSE_MASK_CINTAPOS_S)) << TSN_SBL_BIT_START_NUM_C;
|
2026-08-02 16:49:10 -05:00 | | | |
|
2026-10-08 19:54:46 -05:00 | | | | curr_padre = uint(v >> TSN_SBL_BIT_START_NUM_C); // ahora obtenemos su padre..
|
2026-08-02 16:49:10 -05:00 | | | |
|
| | | | //---
|
2026-10-08 20:25:09 -05:00 | | | | if(curr_padre == idata) // dado que cur_padre apunta a la psocion 2.. [0][1 aqui] entonces con 1...
|
2026-10-08 19:54:46 -05:00 | | | | return true;
|
2026-08-02 16:49:10 -05:00 | | | |
|
| | | | //---
|
2026-10-08 19:54:46 -05:00 | | | | curr_count = (uint)m_cinta[curr_padre]; // le devolvemos..
|
| | | | curr_state = TSN_JSON_MAKE_STATE(m_cinta[curr_padre - 1] & TSN_SBL_PARSE_MASK_OA_T);
|
2026-08-02 16:49:10 -05:00 | | | | m_pos++;
|
| | | |
|
| | | | //---
|
| | | | TSN_JSON_NEXT_NO_NEXT_KEY
|
2026-10-08 19:54:46 -05:00 | | | | break;
|
| | | | }
|
| | | | case TSN_JSON_TOK_COR_END:
|
| | | | {
|
| | | | //--- cacheamos el valor de cinta [curr_padre-1] = apunta a los datos
|
| | | | const uint idata = --curr_padre;
|
| | | | const ulong v = m_cinta[idata];
|
| | | | // ahora si rehacemos el valor con todo ya listo.. (curr padre apunta a la posicion correcta)
|
| | | | m_cinta[idata] = JSON_VTYPE_ARR | ulong(curr_count) << TSN_SBL_BIT_START_NUM_EL |
|
2026-10-08 20:25:09 -05:00 | | | | ulong(m_cinta_pos - ((v >> 1) & TSN_SBL_PARSE_MASK_CINTAPOS_S)) << TSN_SBL_BIT_START_NUM_C;
|
2026-10-08 19:54:46 -05:00 | | | |
|
| | | | curr_padre = uint(v >> TSN_SBL_BIT_START_NUM_C); // ahora obtenemos su padre..
|
2026-08-02 16:49:10 -05:00 | | | |
|
| | | | //---
|
2026-10-08 20:25:09 -05:00 | | | | if(curr_padre == idata) // dado que cur_padre apunta a la psocion 2.. [0][1 aqui] entonces con 1...
|
2026-10-08 19:54:46 -05:00 | | | | return true;
|
| | | |
|
| | | | //---
|
| | | | curr_count = (uint)m_cinta[curr_padre]; // le devolvemos..
|
| | | | curr_state = TSN_JSON_MAKE_STATE(m_cinta[curr_padre - 1] & TSN_SBL_PARSE_MASK_OA_T);
|
| | | | m_pos++;
|
| | | |
|
| | | | //---
|
| | | | TSN_JSON_NEXT_NO_NEXT_KEY
|
2026-08-02 16:49:10 -05:00 | | | | break;
|
| | | | }
|
| | | | case TSN_JSON_TOK_KEY:
|
| | | | {
|
2026-10-08 13:39:44 -05:00 | | | | const uint start = ++m_pos;
|
2026-08-02 16:49:10 -05:00 | | | |
|
2026-06-20 13:57:50 -05:00 | | | | //--- Char por char
|
2026-10-03 11:47:17 -05:00 | | | | #ifdef JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
|
2026-06-20 13:57:50 -05:00 | | | | while(true)
|
| | | | {
|
2026-07-19 07:41:52 -05:00 | | | | const uchar c = m_raw[m_pos];
|
2026-06-20 13:57:50 -05:00 | | | | if(c == '\\')
|
| | | | {
|
| | | | m_pos += 2;
|
| | | | continue;
|
| | | | }
|
| | | | if(c == '"')
|
| | | | {
|
2026-06-20 14:18:38 -05:00 | | | | m_cinta[m_cinta_pos++] = JSON_VTYPE_KEY
|
2026-10-08 13:39:44 -05:00 | | | | | ulong(m_pos - start) << TSN_SBL_BIT_STR_LEN(TSN_SBL_SLEN_KEY)
|
| | | | | ulong(start) << TSN_SBL_BIT_STR_START;
|
2026-06-20 13:57:50 -05:00 | | | | m_pos++;
|
| | | | break;
|
| | | | }
|
2026-10-03 11:47:17 -05:00 | | | | m_pos++;
|
2026-06-04 17:26:20 -05:00 | | | | }
|
2026-10-03 11:47:17 -05:00 | | | | #else // JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS*/
|
| | | |
|
| | | | //---
|
2026-10-08 20:25:09 -05:00 | | | | while(true)
|
| | | | {
|
| | | | TSN_JSON_FINDKEY_FINAL_U4
|
| | | | TSN_JSON_FINDKEY_FINAL_U4
|
| | | | TSN_JSON_FINDKEY_FINAL_U4
|
| | | | TSN_JSON_FINDKEY_FINAL_U4
|
| | | | }
|
2026-10-03 17:00:34 -05:00 | | | |
|
2026-10-03 11:47:17 -05:00 | | | | //---
|
| | | | m_cinta[m_cinta_pos++] = JSON_VTYPE_KEY
|
2026-10-08 13:39:44 -05:00 | | | | | ulong(m_pos - start) << TSN_SBL_BIT_STR_LEN(TSN_SBL_SLEN_KEY)
|
| | | | | ulong(start) << TSN_SBL_BIT_STR_START;
|
2026-10-03 11:47:17 -05:00 | | | | m_pos++;
|
| | | | #endif // JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS
|
| | | |
|
2026-10-08 13:39:44 -05:00 | | | | //---
|
| | | | m_cinta_pos++; // hash ignoramos.
|
| | | |
|
2026-06-20 13:57:50 -05:00 | | | | //--- Find :
|
2026-10-18 12:41:33 -05:00 | | | | while(m_raw[m_pos] != ':')
|
2026-06-04 17:26:20 -05:00 | | | | {
|
2026-06-14 15:51:39 -05:00 | | | | //---
|
2026-10-18 12:41:33 -05:00 | | | | //if(m_raw[m_pos] == ':')
|
| | | | // break;
|
2026-06-04 17:26:20 -05:00 | | | |
|
2026-06-14 15:51:39 -05:00 | | | | //---
|
2026-06-20 13:57:50 -05:00 | | | | m_pos++;
|
2026-06-14 15:51:39 -05:00 | | | | if(m_pos >= m_len)
|
| | | | {
|
| | | | m_last_err = TSN_JSON_ERR_MALFODERD_KEY_EXPECTED_DOS_PUNTOS;
|
| | | | return false;
|
| | | | }
|
2026-06-04 17:26:20 -05:00 | | | | }
|
| | | |
|
| | | | //--- Buscamos valor
|
2026-06-20 13:57:50 -05:00 | | | | TSN_JSON_NEXT_VALUE_COMM_KEY
|
2026-06-02 21:23:50 -05:00 | | | |
|
| | | | //---
|
| | | | break;
|
| | | | }
|
| | | | default:
|
| | | | return false;
|
| | | | }
|
| | | | }
|
| | | | }
|
2026-06-20 13:57:50 -05:00 | | | |
|
2026-06-02 22:52:39 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-10-08 13:39:44 -05:00 | | | | //| GetStep |
|
2026-06-02 22:52:39 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-06-03 07:50:45 -05:00 | | | | __forceinline int CJsonParser::GetStepPure(const int idx) const
|
2026-06-02 22:52:39 -05:00 | | | | {
|
2026-09-30 07:39:54 -05:00 | | | | switch(int(m_cinta[idx] & TSN_SBL_BIT_MASK_TYPE))
|
2026-06-02 22:52:39 -05:00 | | | | {
|
2026-10-08 13:39:44 -05:00 | | | | case JSON_VTYPE_ARR:
|
2026-07-19 07:41:52 -05:00 | | | | case JSON_VTYPE_OBJ:
|
2026-09-30 07:39:54 -05:00 | | | | case JSON_VTYPE_UINTEGER:
|
2026-06-02 22:52:39 -05:00 | | | | case JSON_VTYPE_INTEGER:
|
| | | | case JSON_VTYPE_REAL:
|
| | | | return 2;
|
2026-06-03 07:50:45 -05:00 | | | | case JSON_VTYPE_BOOLEAN:
|
2026-06-02 22:52:39 -05:00 | | | | case JSON_VTYPE_STRING:
|
2026-06-03 07:50:45 -05:00 | | | | case JSON_VTYPE_NULL:
|
| | | | return 1;
|
2026-10-08 13:39:44 -05:00 | | | | case JSON_VTYPE_KEY:
|
| | | | return TSN_SBL_KEYSLOT_SIZE;
|
2026-09-23 15:25:08 -05:00 | | | | default:
|
| | | | return 1;
|
2026-06-03 07:50:45 -05:00 | | | | }
|
| | | | }
|
| | | |
|
| | | | //+------------------------------------------------------------------+
|
| | | | __forceinline int CJsonParser::GetStep(const int idx)
|
| | | | const
|
| | | | {
|
2026-08-28 11:16:09 -05:00 | | | | switch(int(m_cinta[idx] & TSN_SBL_BIT_MASK_TYPE))
|
2026-06-03 07:50:45 -05:00 | | | | {
|
2026-07-19 07:41:52 -05:00 | | | | case JSON_VTYPE_ARR:
|
2026-10-08 13:39:44 -05:00 | | | | case JSON_VTYPE_OBJ:
|
2026-07-19 07:41:52 -05:00 | | | | return int(m_cinta[idx] >> TSN_SBL_BIT_START_NUM_C);
|
2026-09-30 07:39:54 -05:00 | | | | case JSON_VTYPE_UINTEGER:
|
2026-06-03 07:50:45 -05:00 | | | | case JSON_VTYPE_INTEGER:
|
| | | | case JSON_VTYPE_REAL:
|
| | | | return 2;
|
2026-06-02 22:52:39 -05:00 | | | | case JSON_VTYPE_BOOLEAN:
|
2026-06-03 07:50:45 -05:00 | | | | case JSON_VTYPE_STRING:
|
2026-06-02 22:52:39 -05:00 | | | | case JSON_VTYPE_NULL:
|
| | | | return 1;
|
2026-10-08 13:39:44 -05:00 | | | | case JSON_VTYPE_KEY:
|
| | | | return TSN_SBL_KEYSLOT_SIZE;
|
2026-09-23 15:25:08 -05:00 | | | | default:
|
| | | | return 1;
|
2026-06-02 22:52:39 -05:00 | | | | }
|
| | | | }
|
| | | |
|
2026-06-03 07:50:45 -05:00 | | | |
|
| | | | //+------------------------------------------------------------------+
|
| | | | //| |
|
2026-07-19 13:56:15 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-10-01 08:25:33 -05:00 | | | | bool CJsonParser::SerializeToDom(CDomNodeBase *root, CDomNodeManager* manager, int cur, const int end)
|
2026-07-19 13:56:15 -05:00 | | | | {
|
| | | | //--- Temp
|
2026-10-01 08:25:33 -05:00 | | | | m_last_err = TSN_JSON_NOT_ERR;
|
2026-07-19 13:56:15 -05:00 | | | | CDomNodeBase* prev_value; // valolr qeu devuelve key
|
2026-08-27 13:56:43 -05:00 | | | | CDomNodeBase* current_container[JSONPARSERBYLEO_MAX_STACK]; // contenedor
|
| | | | int current_ends[JSONPARSERBYLEO_MAX_STACK];
|
2026-07-19 13:56:15 -05:00 | | | | int sp = 0;
|
| | | |
|
| | | | //--- Inicial
|
| | | | const int c = int((m_cinta[cur] >> TSN_SBL_BIT_START_NUM_EL) & TSN_SBL_BIT_MASK_NUM_EL);
|
| | | | if((m_cinta[cur]&TSN_SBL_BIT_MASK_TYPE) == JSON_VTYPE_OBJ)
|
| | | | root.NewObj(c);
|
| | | | else
|
| | | | root.NewArr(c);
|
2026-07-19 15:11:32 -05:00 | | | |
|
2026-07-19 13:56:15 -05:00 | | | | //---
|
| | | | current_container[0] = root;
|
| | | | current_ends[sp] = end;
|
| | | |
|
| | | | //---
|
| | | | cur += 2;
|
| | | |
|
| | | | //--- It
|
| | | | while(true)
|
| | | | {
|
| | | | //--- Check
|
2026-07-21 10:38:19 -05:00 | | | | while(cur >= current_ends[sp])
|
2026-07-19 13:56:15 -05:00 | | | | {
|
| | | | sp--; // Nivel menos
|
2026-07-19 15:11:32 -05:00 | | | | //Print("sp luego: ", sp);
|
| | | | if(sp < 0)
|
2026-10-01 08:25:33 -05:00 | | | | return true;
|
2026-07-19 13:56:15 -05:00 | | | | }
|
| | | | //---
|
| | | | const ENUM_JSON_VTYPE tipo = ENUM_JSON_VTYPE(m_cinta[cur] & TSN_SBL_BIT_MASK_TYPE);
|
2026-07-19 15:11:32 -05:00 | | | | //Print(EnumToString(tipo), " | ", cur, " | " , sp);
|
2026-07-19 13:56:15 -05:00 | | | | //---
|
| | | | switch(tipo)
|
| | | | {
|
2026-10-08 13:39:44 -05:00 | | | | case JSON_VTYPE_ARR:
|
2026-07-19 13:56:15 -05:00 | | | | {
|
2026-10-08 13:39:44 -05:00 | | | | const int count = int((m_cinta[cur] >> TSN_SBL_BIT_START_NUM_EL) & TSN_SBL_BIT_MASK_NUM_EL);
|
| | | | if(current_container[sp].m_type == JSON_VTYPE_ARR)
|
2026-07-19 13:56:15 -05:00 | | | | {
|
| | | | const int lock = sp++;
|
2026-07-19 15:11:32 -05:00 | | | | current_container[sp] = new CDomNodeBase(manager);
|
2026-10-08 13:39:44 -05:00 | | | | current_container[sp].NewArr(count);
|
2026-07-19 13:56:15 -05:00 | | | | current_container[lock].AddItem(current_container[sp]);
|
| | | | }
|
2026-10-08 13:39:44 -05:00 | | | | else // {key:[]}
|
2026-07-19 13:56:15 -05:00 | | | | {
|
| | | | sp++;
|
2026-10-08 13:39:44 -05:00 | | | | prev_value.NewArr(count);
|
2026-07-19 13:56:15 -05:00 | | | | current_container[sp] = prev_value;
|
| | | | }
|
| | | | current_ends[sp] = cur + int(m_cinta[cur] >> TSN_SBL_BIT_START_NUM_C);
|
| | | | break;
|
| | | | }
|
2026-10-08 13:39:44 -05:00 | | | | case JSON_VTYPE_OBJ:
|
2026-07-19 13:56:15 -05:00 | | | | {
|
2026-10-08 13:39:44 -05:00 | | | | const int count = (int((m_cinta[cur] >> TSN_SBL_BIT_START_NUM_EL) & TSN_SBL_BIT_MASK_NUM_EL)) << 1;
|
| | | | if(current_container[sp].m_type == JSON_VTYPE_ARR) // [{}]
|
2026-07-19 13:56:15 -05:00 | | | | {
|
| | | | const int lock = sp++;
|
2026-07-19 15:11:32 -05:00 | | | | current_container[sp] = new CDomNodeBase(manager);
|
2026-10-08 13:39:44 -05:00 | | | | current_container[sp].NewObj(count);
|
2026-07-19 13:56:15 -05:00 | | | | current_container[lock].AddItem(current_container[sp]);
|
| | | | }
|
2026-10-08 13:39:44 -05:00 | | | | else // {key:{}}
|
2026-07-19 13:56:15 -05:00 | | | | {
|
| | | | sp++;
|
2026-10-08 13:39:44 -05:00 | | | | prev_value.NewObj(count);
|
2026-07-19 13:56:15 -05:00 | | | | current_container[sp] = prev_value;
|
| | | | }
|
| | | | current_ends[sp] = cur + int(m_cinta[cur] >> TSN_SBL_BIT_START_NUM_C);
|
| | | | break;
|
| | | | }
|
2026-09-30 07:39:54 -05:00 | | | | case JSON_VTYPE_UINTEGER:
|
| | | | {
|
| | | | if(current_container[sp].m_type == JSON_VTYPE_ARR)
|
2026-10-08 21:07:14 -05:00 | | | | current_container[sp].AddItem(new CDomNodeBase(manager, m_cinta[cur + 1]));
|
2026-09-30 07:39:54 -05:00 | | | | else
|
2026-10-08 21:07:14 -05:00 | | | | prev_value = m_cinta[cur + 1];
|
2026-09-30 07:39:54 -05:00 | | | | break;
|
| | | | }
|
2026-07-19 13:56:15 -05:00 | | | | case JSON_VTYPE_INTEGER:
|
| | | | {
|
| | | | if(current_container[sp].m_type == JSON_VTYPE_ARR)
|
2026-10-08 21:07:14 -05:00 | | | | current_container[sp].AddItem(new CDomNodeBase(manager, (long)m_cinta[cur + 1]));
|
2026-07-19 13:56:15 -05:00 | | | | else
|
2026-10-08 21:07:14 -05:00 | | | | prev_value = (long)m_cinta[cur + 1];
|
2026-07-19 13:56:15 -05:00 | | | | break;
|
| | | | }
|
| | | | case JSON_VTYPE_REAL:
|
| | | | {
|
2026-08-28 08:28:32 -05:00 | | | | TsnBitInterprete un;
|
2026-10-08 13:39:44 -05:00 | | | | un.ulong_value = m_cinta[cur + 1];
|
2026-07-19 13:56:15 -05:00 | | | |
|
| | | | //---
|
| | | | if(current_container[sp].m_type == JSON_VTYPE_ARR)
|
2026-07-24 08:54:26 -05:00 | | | | current_container[sp].AddItem(new CDomNodeBase(manager, un.double_value));
|
2026-07-19 13:56:15 -05:00 | | | | else
|
| | | | prev_value = un.double_value;
|
| | | | break;
|
| | | | }
|
| | | | case JSON_VTYPE_BOOLEAN:
|
| | | | {
|
2026-10-08 19:54:46 -05:00 | | | | const bool v = (m_cinta[cur] >> TSN_SBL_BIT_START_BOOL) != 0;
|
2026-07-19 13:56:15 -05:00 | | | |
|
| | | | //---
|
| | | | if(current_container[sp].m_type == JSON_VTYPE_ARR)
|
2026-07-24 08:54:26 -05:00 | | | | current_container[sp].AddItem(new CDomNodeBase(manager, v));
|
2026-07-19 13:56:15 -05:00 | | | | else
|
| | | | prev_value = v;
|
| | | | break;
|
| | | | }
|
| | | | case JSON_VTYPE_STRING:
|
| | | | {
|
2026-10-08 13:39:44 -05:00 | | | | //---
|
| | | | const int s = TSN_SBL_CLS_STR_START(cur, int);
|
| | | | const int slen = TSN_SBL_CLS_STR_LEN(cur, TSN_SBL_SLEN_STR, int);
|
2026-07-19 13:56:15 -05:00 | | | |
|
| | | | //---
|
| | | | if(current_container[sp].m_type == JSON_VTYPE_ARR)
|
2026-10-01 08:25:33 -05:00 | | | | {
|
| | | | CDomNodeBase* ptr = new CDomNodeBase(TSN_SBL_BASE_TYPE_STR, manager);
|
| | | | current_container[sp].AddItem(ptr); // lo agregamos
|
| | | | const int idx = ptr.m_v.ix;
|
2026-10-08 13:39:44 -05:00 | | | | if(!JSONPBL_MAKESTRING(m_raw, s, slen, manager.m_string_stack[idx]))
|
2026-10-01 08:25:33 -05:00 | | | | {
|
2026-10-08 13:39:44 -05:00 | | | | m_pos = s;
|
2026-10-01 08:25:33 -05:00 | | | | m_last_err = TSN_JSON_ERR_IN_MATERIALIZE_STRING_PARSE_ERR;
|
| | | | return false;
|
| | | | }
|
| | | | }
|
2026-07-19 13:56:15 -05:00 | | | | else
|
2026-10-01 08:25:33 -05:00 | | | | {
|
| | | | prev_value.Type(TSN_SBL_BASE_TYPE_STR); // lo hacemos string
|
| | | | const int idx = prev_value.m_v.ix;
|
2026-10-08 13:39:44 -05:00 | | | | if(!JSONPBL_MAKESTRING(m_raw, s, slen, manager.m_string_stack[idx]))
|
2026-10-01 08:25:33 -05:00 | | | | {
|
2026-10-08 13:39:44 -05:00 | | | | m_pos = s;
|
2026-10-01 08:25:33 -05:00 | | | | m_last_err = TSN_JSON_ERR_IN_MATERIALIZE_STRING_PARSE_ERR;
|
| | | | return false;
|
| | | | }
|
| | | | }
|
2026-07-19 13:56:15 -05:00 | | | | break;
|
| | | | }
|
| | | | case JSON_VTYPE_NULL:
|
| | | | {
|
| | | | //---
|
| | | | if(current_container[sp].m_type == JSON_VTYPE_ARR)
|
2026-07-19 15:11:32 -05:00 | | | | current_container[sp].AddItem(new CDomNodeBase(manager));
|
2026-07-19 13:56:15 -05:00 | | | | else
|
| | | | prev_value.m_type = JSON_VTYPE_NULL;
|
| | | | break;
|
| | | | }
|
2026-10-08 13:39:44 -05:00 | | | | case JSON_VTYPE_KEY:
|
| | | | {
|
| | | | const int s = TSN_SBL_CLS_STR_START(cur, int);
|
| | | | const int slen = TSN_SBL_CLS_STR_LEN(cur, TSN_SBL_SLEN_KEY, int);
|
| | | | if(!JSONPBL_MAKESTRING(m_raw, s, slen, s_str))
|
| | | | {
|
| | | | m_pos = s;
|
| | | | m_last_err = TSN_JSON_ERR_IN_MATERIALIZE_STRING_PARSE_ERR;
|
| | | | return false;
|
| | | | }
|
| | | | prev_value = current_container[sp][s_str];
|
| | | | break;
|
| | | | }
|
2026-07-19 13:56:15 -05:00 | | | | default:
|
| | | | break;
|
| | | | }
|
| | | |
|
| | | | //---
|
| | | | cur += GetStepPure(cur);
|
| | | | }
|
2026-10-01 08:25:33 -05:00 | | | |
|
| | | | //---
|
| | | | return false;
|
2026-07-19 13:56:15 -05:00 | | | | }
|
| | | |
|
| | | | //+------------------------------------------------------------------+
|
| | | | //| |
|
2026-06-03 07:50:45 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-06-18 08:36:18 -05:00 | | | | void CJsonParser::PrintCintaTypes(const int start, const int num) const
|
2026-06-03 07:50:45 -05:00 | | | | {
|
2026-06-18 08:36:18 -05:00 | | | | //---
|
| | | | int p = fmax(start, 0);
|
| | | | const int end = (num == WHOLE_ARRAY || (p + num) > m_cinta_pos) ? m_cinta_pos : (p + num);
|
| | | |
|
2026-10-01 08:25:33 -05:00 | | | | //---
|
| | | | string text;
|
| | | | StringReserve(text, 256); // algo razonable.
|
| | | |
|
2026-06-18 08:36:18 -05:00 | | | | //---
|
| | | | while(p < end)
|
2026-06-03 07:50:45 -05:00 | | | | {
|
2026-07-19 07:41:52 -05:00 | | | | const ENUM_JSON_VTYPE tipo = ENUM_JSON_VTYPE(m_cinta[p] & TSN_SBL_BIT_MASK_TYPE);
|
2026-10-01 08:25:33 -05:00 | | | | text = "[" + (string)p + "] " + EnumToString(tipo) + " | ";
|
2026-06-03 15:48:09 -05:00 | | | |
|
| | | | //---
|
| | | | switch(tipo)
|
| | | | {
|
2026-10-08 13:39:44 -05:00 | | | | case JSON_VTYPE_ARR:
|
2026-07-19 07:41:52 -05:00 | | | | {
|
2026-10-08 13:39:44 -05:00 | | | | const int count = TSN_SBL_CLS_AO_NUM_EL(p, int);
|
| | | | const int num_c = TSN_SBL_CLS_AO_STEP(p, int);
|
| | | | text += "count=" + (string)count + " num_c=" + (string)num_c;
|
2026-07-19 07:41:52 -05:00 | | | | break;
|
| | | | }
|
| | | | case JSON_VTYPE_OBJ:
|
| | | | {
|
2026-10-08 13:39:44 -05:00 | | | | const int count = TSN_SBL_CLS_AO_NUM_EL(p, int);
|
| | | | const int num_c = TSN_SBL_CLS_AO_STEP(p, int);
|
| | | | const bool jit = TSN_SBL_CLS_OBJ_JIT(p + 1) != 0;
|
| | | | const ulong attemps = TSN_SBL_CLS_OBJ_JIT_ATTMP(p + 1);
|
| | | | text += "count=" + (string)count + " num_c=" + (string)num_c + " is_jit=" + (string)jit + " jit_attemps=" + (string)attemps;
|
2026-07-19 07:41:52 -05:00 | | | | break;
|
| | | | }
|
2026-09-30 07:39:54 -05:00 | | | | case JSON_VTYPE_UINTEGER:
|
| | | | {
|
| | | | text += "val=" + CValueToBuffer::ULLToStr(ulong(m_cinta[p + 1]));
|
| | | | break;
|
| | | | }
|
2026-06-03 15:48:09 -05:00 | | | | case JSON_VTYPE_INTEGER:
|
2026-07-19 07:41:52 -05:00 | | | | {
|
2026-06-03 15:48:09 -05:00 | | | | text += "val=" + (string)m_cinta[p + 1];
|
| | | | break;
|
2026-07-19 07:41:52 -05:00 | | | | }
|
2026-06-03 15:48:09 -05:00 | | | | case JSON_VTYPE_REAL:
|
2026-06-04 17:26:20 -05:00 | | | | {
|
2026-08-28 08:28:32 -05:00 | | | | TsnBitInterprete un;
|
2026-10-08 13:39:44 -05:00 | | | | un.ulong_value = m_cinta[p + 1];
|
2026-06-04 17:26:20 -05:00 | | | | text += "val=" + (string)un.double_value;
|
| | | | break;
|
| | | | }
|
2026-06-03 15:48:09 -05:00 | | | | case JSON_VTYPE_BOOLEAN:
|
2026-10-08 19:54:46 -05:00 | | | | text += "val=" + (string)(bool)((m_cinta[p] >> TSN_SBL_BIT_START_BOOL) & 1);
|
2026-06-03 15:48:09 -05:00 | | | | break;
|
| | | | case JSON_VTYPE_STRING:
|
2026-06-04 17:26:20 -05:00 | | | | {
|
2026-07-19 07:41:52 -05:00 | | | | const int s = int(m_cinta[p] >> TSN_SBL_BIT_STR_START);
|
2026-10-08 13:39:44 -05:00 | | | | const int slen = int((m_cinta[p] >> TSN_SBL_BIT_STR_LEN(TSN_SBL_SLEN_STR)) & TSN_SBL_BIT_STR_MASK_LEN(TSN_SBL_SLEN_STR));
|
2026-10-01 08:25:33 -05:00 | | | | //---
|
2026-10-08 13:39:44 -05:00 | | | | if(JSONPBL_MAKESTRING(m_raw, s, slen, s_str))
|
| | | | text += "start=" + (string)s + " len=" + (string)slen + " val=\"" + s_str + "\"";
|
2026-10-01 08:25:33 -05:00 | | | | else
|
| | | | text += "start=" + (string)s + " len=" + (string)slen + " val=Invalid";
|
2026-06-04 17:26:20 -05:00 | | | | break;
|
| | | | }
|
2026-06-03 15:48:09 -05:00 | | | | case JSON_VTYPE_NULL:
|
| | | | text += "null";
|
| | | | break;
|
2026-10-08 13:39:44 -05:00 | | | | case JSON_VTYPE_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_SLEN_KEY)) & TSN_SBL_BIT_STR_MASK_LEN(TSN_SBL_SLEN_KEY));
|
| | | | //---
|
| | | | if(JSONPBL_MAKESTRING(m_raw, s, slen, s_str))
|
| | | | text += "start=" + (string)s + " len=" + (string)slen + " val=\"" + s_str + "\"";
|
| | | | else
|
| | | | text += "start=" + (string)s + " len=" + (string)slen + " val=Invalid";
|
| | | | break;
|
| | | | }
|
2026-09-23 15:25:08 -05:00 | | | | //---
|
| | | | default:
|
| | | | break;
|
2026-06-03 15:48:09 -05:00 | | | | }
|
| | | |
|
| | | | Print(text);
|
2026-06-03 07:50:45 -05:00 | | | | p += GetStepPure(p);
|
| | | | }
|
| | | | }
|
| | | |
|
2026-10-01 08:25:33 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-10-08 13:39:44 -05:00 | | | | //| Errores |
|
2026-10-01 08:25:33 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-10-03 17:00:34 -05:00 | | | | static void CJsonParser::PrintError(const string& header, const uchar& buf[], const int len,
|
| | | | int col, int line, ENUM_TSN_JSON_LAST_ERR err, string& salida, bool print = true)
|
2026-10-01 08:25:33 -05:00 | | | | {
|
| | | | //---
|
2026-10-03 17:00:34 -05:00 | | | | string out = "";
|
| | | | out.Reserve(256);
|
2026-10-01 08:25:33 -05:00 | | | |
|
| | | | //---
|
2026-10-03 17:00:34 -05:00 | | | | if(header.Length())
|
| | | | out += "[" + header + "]\n";
|
2026-10-01 08:25:33 -05:00 | | | |
|
| | | | //---
|
2026-10-03 17:00:34 -05:00 | | | | out += StringFormat("JSON error at line %d, col %d:\n", line, col);
|
2026-10-01 08:25:33 -05:00 | | | |
|
| | | | //---
|
2026-10-03 17:00:34 -05:00 | | | | switch(err)
|
2026-10-01 08:25:33 -05:00 | | | | {
|
| | | | case TSN_JSON_ERR_INVALID_EXT_FILE:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Invalid file extension por JsonParserByLeo";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_INVALID_CHAR:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Invalid character found in json";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_MALFORDMED_JSON_AFTER_VAL:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Invalid character find in json, finding comma or context close (], })";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_MALFORDMED_JSON_AFTER_COR_INI:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Invalid character find in json, finding valid value after '['";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
2026-10-18 12:41:33 -05:00 | | | | case TSN_JSON_ERR_MALFORDMED_JSON_AFTER_LLAVE_INI:
|
| | | | out += "Invalid character find in json, finding valid value ['}' or '\"'] after '{'";
|
| | | | break;
|
2026-10-01 08:25:33 -05:00 | | | | case TSN_JSON_ERR_MALFORDMED_JSON_FIND_VAL:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Invalid character find in json, finding valid value";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_MALFODERD_KEY_EXPECTED_DOS_PUNTOS:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Invalid JSON key, One of two errors: \"Expected a ':' after a JSON key\" or \"Malformed JSON while searching for characters.\"";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_MALFOMED_LEN_SUPERADO:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Len has superated, but json are not closed, malformed json";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_JSON_NOT_FINISH:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Json read has finish but not closed in ] or }, malformed json";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_LEADING_ZEROS:
|
2026-10-03 17:00:34 -05:00 | | | | out += "A number in JSON notation cannot have leading zeros.";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_EXPECTED_NUMBER_AFECTER_EXP:
|
2026-10-03 17:00:34 -05:00 | | | | out += "A number was expected after the 'E' exponent; an invalid character was found.";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_EXPECTED_NUMBER_AFECTER_DECIMALP:
|
2026-10-03 17:00:34 -05:00 | | | | out += "A numeric value was expected after the decimal point.";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_MALFORMED_TRUE:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Malformed 'true' in json";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_MALFORMED_FALSE:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Malformed 'false' in json";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_MALFORMED_NULL:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Malformed 'null' in json";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_IN_MATERIALIZE_STRING_PARSE_ERR:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Error materializing string; possible causes include an invalid escape character or a malformed \\u sequence.";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_NOT_STRUCUTURAL_CHARS_FOUND:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Not structural character found in this json ({ | } | [ | ] | : | ,)";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | case TSN_JSON_ERR_INVALID_STATE_IN_PARSE_DOUBLE_E:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Invalid state for Json Sax Parsing, in parse double value";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | //---
|
| | | | default:
|
2026-10-03 17:00:34 -05:00 | | | | out += "Unknow error";
|
2026-10-01 08:25:33 -05:00 | | | | break;
|
| | | | }
|
| | | |
|
| | | | //---
|
2026-10-03 17:00:34 -05:00 | | | | CParserErrFormat::Format(len, buf, line, col, out, salida);
|
| | | |
|
| | | | //---
|
| | | | if(print)
|
| | | | Print(salida);
|
| | | | }
|
| | | |
|
| | | | //+------------------------------------------------------------------+
|
| | | | // Solo a que tener cuidado con true\false\null
|
| | | | // aparte tok invalid tambien dado que este ultimo retorna false
|
| | | | void CJsonParser::CatchErr()
|
| | | | {
|
| | | | //---
|
| | | | if(m_pos >= m_len)
|
| | | | m_pos = m_len - 1;
|
| | | |
|
| | | | //---
|
| | | | if(m_last_err != TSN_JSON_NOT_ERR)
|
| | | | return; // ya tiene valor no hace falta
|
| | | |
|
| | | | //---
|
| | | | switch(m_next)
|
2026-10-01 08:25:33 -05:00 | | | | {
|
2026-10-03 17:00:34 -05:00 | | | | case TSN_JSON_TOK_BOOL_TRUE:
|
| | | | m_last_err = TSN_JSON_ERR_MALFORMED_TRUE;
|
| | | | break;
|
| | | | case TSN_JSON_TOK_BOOL_FALSE:
|
| | | | m_last_err = TSN_JSON_ERR_MALFORMED_FALSE;
|
| | | | break;
|
| | | | case TSN_JSON_TOK_NULL:
|
| | | | m_last_err = TSN_JSON_ERR_MALFORMED_NULL;
|
| | | | break;
|
| | | | default:
|
| | | | {
|
2026-10-19 09:16:24 -05:00 | | | | if(m_next == TSN_JSON_TOK_INVALID) // Solo si es tok invalid (si no nada)
|
2026-10-03 17:00:34 -05:00 | | | | m_last_err = TSN_JSON_ERR_INVALID_CHAR;
|
| | | | break;
|
| | | | }
|
2026-10-01 08:25:33 -05:00 | | | | }
|
| | | | }
|
2026-07-11 16:31:27 -05:00 | | | |
|
2026-09-30 07:39:54 -05:00 | | | | //+------------------------------------------------------------------+
|
2026-10-03 17:00:34 -05:00 | | | | void CJsonParser::ErrorInfo(const string header = "")
|
| | | | {
|
| | | | //---
|
| | | | CatchErr();
|
| | | |
|
| | | | //---
|
| | | | if(m_last_err == TSN_JSON_NOT_ERR)
|
| | | | return;
|
| | | |
|
| | | | //---
|
| | | | int col, line;
|
| | | | GetLastErrorLocation(col, line);
|
| | | |
|
| | | | //---
|
| | | | string out = "";
|
| | | | PrintError(header, m_raw, m_len, col, line, m_last_err, out);
|
| | | | }
|
2026-10-08 13:39:44 -05:00 | | | |
|
| | | |
|
| | | |
|
| | | | //+------------------------------------------------------------------+
|
| | | | //| Tablas finales |
|
| | | | //+------------------------------------------------------------------+
|
| | | | string CJsonParser::s_str = ""; // streimp para las funciones internas (que requiran string)
|
| | | | const string CJsonParser::s_dtype_to_str[JSON_VTYPE_TOTAL] =
|
| | | | {
|
| | | | "",
|
| | | | "",
|
| | | | "",
|
| | | | "ulong",
|
| | | | "long",
|
| | | | "double",
|
| | | | "bool",
|
| | | | "string",
|
| | | | ""
|
| | | | };
|
| | | | const uchar CJsonParser::s_unescape_table[256] =
|
| | | | {
|
| | | | // char idx ascii
|
| | | |
|
| | | | //--- WS \ Invalid
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | |
|
2026-09-30 07:39:54 -05:00 | | | | //---
|
2026-10-08 13:39:44 -05:00 | | | | '"', // 0 0x22 \" = "
|
| | | | 0xFF, // 1 0x23 #
|
| | | | 0xFF, // 2 0x24 $
|
| | | | 0xFF, // 3 0x25 %
|
| | | | 0xFF, // 4 0x26 &
|
| | | | 0xFF, // 5 0x27 ' \' = '
|
| | | | 0xFF, // 6 0x28 (
|
| | | | 0xFF, // 7 0x29 )
|
| | | | 0xFF, // 8 0x2A *
|
| | | | 0xFF, // 9 0x2B +
|
| | | | 0xFF, // 10 0x2C ,
|
| | | | 0xFF, // 11 0x2D -
|
| | | | 0xFF, // 12 0x2E .
|
| | | | '/', // 13 0x2F / \/ = /
|
| | | | 0xFF, // 14 0x30
|
| | | | 0xFF, // 15 0x31 1
|
| | | | 0xFF, // 16 0x32 2
|
| | | | 0xFF, // 17 0x33 3
|
| | | | 0xFF, // 18 0x34 4
|
| | | | 0xFF, // 19 0x35 5
|
| | | | 0xFF, // 20 0x36 6
|
| | | | 0xFF, // 21 0x37 7
|
| | | | 0xFF, // 22 0x38 8
|
| | | | 0xFF, // 23 0x39 9
|
| | | | 0xFF, // 24 0x3A :
|
| | | | 0xFF, // 25 0x3B ;
|
| | | | 0xFF, // 26 0x3C <
|
| | | | 0xFF, // 27 0x3D =
|
| | | | 0xFF, // 28 0x3E >
|
| | | | 0xFF, // 29 0x3F ?
|
| | | | 0xFF, // 30 0x40 @
|
| | | | 0xFF, // 31 0x41 A
|
| | | | 0xFF, // 32 0x42 B
|
| | | | 0xFF, // 33 0x43 C
|
| | | | 0xFF, // 34 0x44 D
|
| | | | 0xFF, // 35 0x45 E
|
| | | | 0xFF, // 36 0x46 F
|
| | | | 0xFF, // 37 0x47 G
|
| | | | 0xFF, // 38 0x48 H
|
| | | | 0xFF, // 39 0x49 I
|
| | | | 0xFF, // 40 0x4A J
|
| | | | 0xFF, // 41 0x4B K
|
| | | | 0xFF, // 42 0x4C L
|
| | | | 0xFF, // 43 0x4D M
|
| | | | 0xFF, // 44 0x4E N
|
| | | | 0xFF, // 45 0x4F O
|
| | | | 0xFF, // 46 0x50 P
|
| | | | 0xFF, // 47 0x51 Q
|
| | | | 0xFF, // 48 0x52 R
|
| | | | 0xFF, // 49 0x53 S
|
| | | | 0xFF, // 50 0x54 T
|
| | | | 0xFF, // 51 0x55 U
|
| | | | 0xFF, // 52 0x56 V
|
| | | | 0xFF, // 53 0x57 W
|
| | | | 0xFF, // 54 0x58 X
|
| | | | 0xFF, // 55 0x59 Y
|
| | | | 0xFF, // 56 0x5A Z
|
| | | | 0xFF, // 57 0x5B [
|
| | | | '\\', // 58 0x5C \ \\ =
|
| | | | 0xFF, // 59 0x5D ]
|
| | | | 0xFF, // 60 0x5E ^
|
| | | | 0xFF, // 61 0x5F _
|
| | | | 0xFF, // 62 0x60 `
|
| | | | 0xFF, // 63 0x61 a
|
| | | | 0x08, // 64 0x62 b \b = backspace
|
| | | | 0xFF, // 65 0x63 c
|
| | | | 0xFF, // 66 0x64 d
|
| | | | 0xFF, // 67 0x65 e
|
| | | | 0x0C, // 68 0x66 f \f = form feed
|
| | | | 0xFF, // 69 0x67 g
|
| | | | 0xFF, // 70 0x68 h
|
| | | | 0xFF, // 71 0x69 i
|
| | | | 0xFF, // 72 0x6A j
|
| | | | 0xFF, // 73 0x6B k
|
| | | | 0xFF, // 74 0x6C l
|
| | | | 0xFF, // 75 0x6D m
|
| | | | 0x0A, // 76 0x6E n \n = newline
|
| | | | 0xFF, // 77 0x6F o
|
| | | | 0xFF, // 78 0x70 p
|
| | | | 0xFF, // 79 0x71 q
|
| | | | 0x0D, // 80 0x72 r \r = carriage return
|
| | | | 0xFF, // 81 0x73 s
|
| | | | 0x09, // 82 0x74 t \t = tab
|
| | | | TSN_TABLE_UNESCAPE_UNICODE, // 83 0x75 u \uXXXX unicode
|
| | | | 0xFF, // 84 0x76 v
|
| | | | 0xFF, // 85 0x77 w
|
| | | | 0xFF, // 86 0x78 x
|
| | | | 0xFF, // 87 0x79 y
|
| | | | 0xFF, // 88 0x7A z
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x7B - 0x7F
|
| | | |
|
| | | | //--- Extended / high range (0x80 - 0xFF): all invalid for JSON escape context
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
| | | | };
|
| | | | const uchar CJsonParser::s_escape_table[256] =
|
| | | | {
|
| | | | //--- 0x00–0x1F: caracteres de control
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x00 \0 null
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x01
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x02
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x03
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x04
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x05
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x06
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x07
|
| | | | 'b', // 0x08 \b backspace
|
| | | | 't', // 0x09 \t tab
|
| | | | 'n', // 0x0A \n newline
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x0B \v
|
| | | | 'f', // 0x0C \f form feed
|
| | | | 'r', // 0x0D \r carriage return
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x0E
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x0F
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x10
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x11
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x12
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x13
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x14
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x15
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x16
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x17
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x18
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x19
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x1A
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x1B
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x1C
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x1D
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x1E
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x1F
|
| | | |
|
| | | | //--- 0x20–0x21: imprimibles
|
| | | | 0xFF, // 0x20 ' ' space
|
| | | | 0xFF, // 0x21 !
|
| | | |
|
| | | | //--- 0x22: comilla doble
|
| | | | '"', // 0x22 \"
|
| | | |
|
| | | | //--- 0x23–0x26: imprimibles
|
| | | | 0xFF, // 0x23 #
|
| | | | 0xFF, // 0x24 $
|
| | | | 0xFF, // 0x25 %
|
| | | | 0xFF, // 0x26 &
|
| | | |
|
| | | | //--- 0x27: comilla simple
|
| | | | 0xFF, // 0x27 \'
|
| | | |
|
| | | | //--- 0x28–0x2E: imprimibles
|
| | | | 0xFF, // 0x28 (
|
| | | | 0xFF, // 0x29 )
|
| | | | 0xFF, // 0x2A *
|
| | | | 0xFF, // 0x2B +
|
| | | | 0xFF, // 0x2C ,
|
| | | | 0xFF, // 0x2D -
|
| | | | 0xFF, // 0x2E .
|
| | | |
|
| | | | //--- 0x2F: slash
|
| | | | '/', // 0x2F \/
|
| | | |
|
| | | | //--- 0x30–0x5B: imprimibles
|
| | | | 0xFF, // 0x30 0
|
| | | | 0xFF, // 0x31 1
|
| | | | 0xFF, // 0x32 2
|
| | | | 0xFF, // 0x33 3
|
| | | | 0xFF, // 0x34 4
|
| | | | 0xFF, // 0x35 5
|
| | | | 0xFF, // 0x36 6
|
| | | | 0xFF, // 0x37 7
|
| | | | 0xFF, // 0x38 8
|
| | | | 0xFF, // 0x39 9
|
| | | | 0xFF, // 0x3A :
|
| | | | 0xFF, // 0x3B ;
|
| | | | 0xFF, // 0x3C <
|
| | | | 0xFF, // 0x3D =
|
| | | | 0xFF, // 0x3E >
|
| | | | 0xFF, // 0x3F ?
|
| | | | 0xFF, // 0x40 @
|
| | | | 0xFF, // 0x41 A
|
| | | | 0xFF, // 0x42 B
|
| | | | 0xFF, // 0x43 C
|
| | | | 0xFF, // 0x44 D
|
| | | | 0xFF, // 0x45 E
|
| | | | 0xFF, // 0x46 F
|
| | | | 0xFF, // 0x47 G
|
| | | | 0xFF, // 0x48 H
|
| | | | 0xFF, // 0x49 I
|
| | | | 0xFF, // 0x4A J
|
| | | | 0xFF, // 0x4B K
|
| | | | 0xFF, // 0x4C L
|
| | | | 0xFF, // 0x4D M
|
| | | | 0xFF, // 0x4E N
|
| | | | 0xFF, // 0x4F O
|
| | | | 0xFF, // 0x50 P
|
| | | | 0xFF, // 0x51 Q
|
| | | | 0xFF, // 0x52 R
|
| | | | 0xFF, // 0x53 S
|
| | | | 0xFF, // 0x54 T
|
| | | | 0xFF, // 0x55 U
|
| | | | 0xFF, // 0x56 V
|
| | | | 0xFF, // 0x57 W
|
| | | | 0xFF, // 0x58 X
|
| | | | 0xFF, // 0x59 Y
|
| | | | 0xFF, // 0x5A Z
|
| | | | 0xFF, // 0x5B [
|
| | | |
|
| | | | //--- 0x5C: backslash
|
| | | | '\\', // 0x5C \\
|
| | | |
|
| | | | //--- 0x5D–0x7E: imprimibles
|
| | | | 0xFF, // 0x5D ]
|
| | | | 0xFF, // 0x5E ^
|
| | | | 0xFF, // 0x5F _
|
| | | | 0xFF, // 0x60 `
|
| | | | 0xFF, // 0x61 a
|
| | | | 0xFF, // 0x62 b
|
| | | | 0xFF, // 0x63 c
|
| | | | 0xFF, // 0x64 d
|
| | | | 0xFF, // 0x65 e
|
| | | | 0xFF, // 0x66 f
|
| | | | 0xFF, // 0x67 g
|
| | | | 0xFF, // 0x68 h
|
| | | | 0xFF, // 0x69 i
|
| | | | 0xFF, // 0x6A j
|
| | | | 0xFF, // 0x6B k
|
| | | | 0xFF, // 0x6C l
|
| | | | 0xFF, // 0x6D m
|
| | | | 0xFF, // 0x6E n
|
| | | | 0xFF, // 0x6F o
|
| | | | 0xFF, // 0x70 p
|
| | | | 0xFF, // 0x71 q
|
| | | | 0xFF, // 0x72 r
|
| | | | 0xFF, // 0x73 s
|
| | | | 0xFF, // 0x74 t
|
| | | | 0xFF, // 0x75 u
|
| | | | 0xFF, // 0x76 v
|
| | | | 0xFF, // 0x77 w
|
| | | | 0xFF, // 0x78 x
|
| | | | 0xFF, // 0x79 y
|
| | | | 0xFF, // 0x7A z
|
| | | | 0xFF, // 0x7B {
|
| | | | 0xFF, // 0x7C |
|
| | | | 0xFF, // 0x7D }
|
| | | | 0xFF, // 0x7E ~
|
| | | |
|
| | | | //--- 0x7F: DEL (control)
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x7F
|
| | | |
|
| | | | //--- 0x80–0xFF: extended ASCII → \uXXXX
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0x80–0x87
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, // 0x88–0x8F
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0x90–0x97
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0x98–0x9F
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0xA0–0xA7
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0xA8–0xAF
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0xB0–0xB7
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0xB8–0xBF
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0xC0–0xC7
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0xC8–0xCF
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0xD0–0xD7
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0xD8–0xDF
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0xE0–0xE7
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0xE8–0xEF
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0xF0–0xF7
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE,
|
| | | | TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, TSN_TABLE_ESCAPE_UNICODE, // 0xF8–0xFF
|
| | | | };
|
2026-06-02 21:23:50 -05:00 | | | | }
|
2026-10-08 13:39:44 -05:00 | | | | #endif // JSONPARSERBYLEO_SRC_JSONCORE_JSONPARSER_MQH
|
| | | | //+------------------------------------------------------------------+
|