| //+------------------------------------------------------------------+
|
| //| JsonUnescape.mqh |
|
| //| Copyright 2026, Niquel Mendoza. |
|
| //| https://www.mql5.com |
|
| //+------------------------------------------------------------------+
|
| #property copyright "Copyright 2026, Niquel Mendoza."
|
| #property link "https://www.mql5.com"
|
| #property strict
|
|
|
| #ifndef JSONPARSERBYLEO_SRC_JSONNODE_JSONNODEMETHODS_MQH
|
| #define JSONPARSERBYLEO_SRC_JSONNODE_JSONNODEMETHODS_MQH
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| //--- incluyte al parser y unescape tables
|
| #include "..\\JsonCore\\JsonParser.mqh"
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| namespace TSN
|
| {
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| //--- macro que se usa en cada iteracion de key
|
| #define JSONPARSERBYLEO_KEY_WORK(KH) \
|
| if(TSN_SBL_KEY_HAS_ISN_HASH(m_cinta[cur])) \
|
| { \
|
| int i = TSN_SBL_CLS_STR_START(cur, int); \
|
| if(!JSONPBL_MAKEHASH(m_raw, i, m_len, m_cinta[cur + 1])) \
|
| m_cinta[cur + 1] = KH + 1; \
|
| else \
|
| m_cinta[cur] |= TSN_SBL_KEY_FLAG_HASH; \
|
| } \
|
|
|
|
|
| //+------------------------------------------------------------------+
|
| //| GetStr |
|
| //+------------------------------------------------------------------+
|
| #define JPBL_STR_KEY uchar
|
| #define JPBL_STR_STR ushort
|
|
|
| //+------------------------------------------------------------------+
|
| //| Arrays helpers para evitar la resolcuino de ctx en todo mommento |
|
| //+------------------------------------------------------------------+
|
| template <typename T>
|
| void CJsonParser::ToArray(int cur, T& out_arr[], const int end) const
|
| {
|
| //---
|
| int k = 0;
|
| switch(int(m_cinta[cur] & TSN_SBL_BIT_MASK_TYPE))
|
| {
|
| case JSON_VTYPE_UINTEGER:
|
| {
|
| while(cur < end)
|
| {
|
| out_arr[k++] = T(m_cinta[cur + 1]);
|
| cur += 2;
|
| }
|
| break;
|
| }
|
| case JSON_VTYPE_INTEGER:
|
| {
|
| while(cur < end)
|
| {
|
| out_arr[k++] = T(long(m_cinta[cur + 1]));
|
| cur += 2;
|
| }
|
| break;
|
| }
|
| case JSON_VTYPE_REAL:
|
| {
|
| while(cur < end)
|
| {
|
| TsnBitInterprete bit;
|
| bit.ulong_value = m_cinta[cur + 1];
|
| out_arr[k++] = T(bit.double_value);
|
| cur += 2;
|
| }
|
| break;
|
| }
|
| case JSON_VTYPE_BOOLEAN:
|
| {
|
| while(cur < end)
|
| {
|
| out_arr[k++] = T(TSN_SBL_CLS_BOOL(cur));
|
| cur++;
|
| }
|
| break;
|
| }
|
| case JSON_VTYPE_STRING:
|
| {
|
| while(cur < end)
|
| {
|
| if(GetStrAsStr<JPBL_STR_STR>(cur, s_str))
|
| out_arr[k++] = T(s_str);
|
| //---
|
| cur++;
|
| }
|
| break;
|
| }
|
| default:
|
| break;
|
| }
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| template <typename T>
|
| bool CJsonParser::ExistInArray(int cur, const T val, const uint flags, const int end) const
|
| {
|
| while(cur < end)
|
| {
|
| //---
|
| uint ct = uint(m_cinta[cur] & TSN_SBL_BIT_MASK_TYPE);
|
| if(((1U << ct) & flags) == 0)
|
| {
|
| cur += GetStepPure(cur);
|
| continue;
|
| }
|
|
|
| //---
|
| switch(ct)
|
| {
|
| case JSON_VTYPE_UINTEGER:
|
| {
|
| if(m_cinta[cur + 1] == T(val))
|
| return true;
|
| break;
|
| }
|
| case JSON_VTYPE_INTEGER:
|
| {
|
| if((long)m_cinta[cur + 1] == T(val))
|
| return true;
|
| break;
|
| }
|
| case JSON_VTYPE_REAL:
|
| {
|
| bit.ulong_value = m_cinta[cur + 1];
|
| if(bit.double_value == T(val))
|
| return true;
|
| break;
|
| }
|
| case JSON_VTYPE_BOOLEAN:
|
| {
|
| if(val == T(TSN_SBL_CLS_BOOL(cur)))
|
| return true;
|
| break;
|
| }
|
| case JSON_VTYPE_STRING:
|
| {
|
| if(GetStrAsStr<JPBL_STR_STR>(cur, s_str) && val == T(s_str))
|
| return true;
|
| break;
|
| }
|
| case JSON_VTYPE_NULL:
|
| return true;
|
| default:
|
| return false;
|
| }
|
| //---
|
| cur += GetStepPure(cur);
|
| }
|
| return false;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| template <typename T>
|
| bool CJsonParser::ExistInArrayHomogeneo(int cur, const T val, const int end) const
|
| {
|
| switch(int(m_cinta[cur] & TSN_SBL_BIT_MASK_TYPE))
|
| {
|
| case TSN_SBL_BASE_TYPE_UINT:
|
| {
|
| while(cur < end)
|
| {
|
| if(val == T(m_cinta[cur + 1]))
|
| return true;
|
| cur += 2;
|
| }
|
| }
|
| case TSN_SBL_BASE_TYPE_INT:
|
| {
|
| while(cur < end)
|
| {
|
| if(val == T(long(m_cinta[cur + 1])))
|
| return true;
|
| cur += 2;
|
| }
|
| return false;
|
| }
|
| case TSN_SBL_BASE_TYPE_FLT:
|
| {
|
| while(cur < end)
|
| {
|
| TsnBitInterprete bit;
|
| bit.ulong_value = m_cinta[cur + 1];
|
| if(val == T(bit.double_value))
|
| return true;
|
| cur += 2;
|
| }
|
| return false;
|
| }
|
| case TSN_SBL_BASE_TYPE_BOL:
|
| {
|
| while(cur < end)
|
| {
|
| if(val == T(TSN_SBL_CLS_BOOL(cur)))
|
| return true;
|
| cur++;
|
| }
|
| return false;
|
| }
|
| case TSN_SBL_BASE_TYPE_STR:
|
| {
|
| while(cur < end)
|
| {
|
| if(GetStrAsStr<JPBL_STR_STR>(cur, s_str) && val == T(s_str))
|
| return true;
|
| cur++;
|
| }
|
| break;
|
| }
|
| default:
|
| return false;
|
| }
|
| return false;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Node at |
|
| //+------------------------------------------------------------------+
|
| __forceinline int CJsonParser::NodeAt(int cur, const int index) const
|
| {
|
| for(int k = 0; k < index; k++)
|
| cur += GetStep(cur);
|
| return cur;
|
| }
|
|
|
|
|
| //+------------------------------------------------------------------+
|
| //| Find key pos |
|
| //+------------------------------------------------------------------+
|
| // CUR = APUNTA a la primerma key
|
| int CJsonParser::NodeFindByHashFvn1A64(const ulong kh, int cur, const int end)
|
| {
|
| //---
|
| int k = 0;
|
| while(cur < end)
|
| {
|
| JSONPARSERBYLEO_KEY_WORK(kh)
|
| if(kh == m_cinta[cur + 1])
|
| return cur;
|
| cur += TSN_SBL_KEYSLOT_SIZE; // salta KEY
|
| cur += GetStep(cur);
|
| k++;
|
| }
|
| return -1;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| int CJsonParser::NodeKeyToPositionSlow(const ulong kh, int cur, const int end)
|
| {
|
| //---
|
| int k = 0;
|
| while(cur < end)
|
| {
|
| JSONPARSERBYLEO_KEY_WORK(kh)
|
| if(kh == m_cinta[cur + 1])
|
| return k;
|
| cur += TSN_SBL_KEYSLOT_SIZE; // salta KEY
|
| cur += GetStep(cur);
|
| k++;
|
| }
|
| return -1;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| __forceinline int CJsonParser::NodeObjAtSlow(int cur, const int index) const
|
| {
|
| for(int k = 0; k < index; k++)
|
| {
|
| cur += TSN_SBL_KEYSLOT_SIZE; // salta KEY
|
| cur += GetStep(cur);
|
| }
|
| return cur;
|
| }
|
|
|
|
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| int CJsonParser::NodeGetKeys(int cur, string &keys[], const int end) const
|
| {
|
| //---
|
| const int count = int((m_cinta[cur] >> TSN_SBL_BIT_START_NUM_EL) & TSN_SBL_BIT_MASK_NUM_EL);
|
| ArrayResize(keys, count);
|
|
|
| //---
|
| int i = 0;
|
| cur += TSN_SBL_SLOT_OBJ_SIZE;
|
|
|
| //---
|
| while(cur < end)
|
| {
|
| if(GetStrAsStr<JPBL_STR_KEY>(cur, s_str))
|
| keys[i++] = s_str;
|
| else
|
| keys[i++] = NULL;
|
| //---
|
| cur += TSN_SBL_KEYSLOT_SIZE; // salta KEY
|
| cur += GetStep(cur); // salta VAL
|
| }
|
|
|
| //---
|
| return count;
|
| }
|
|
|
| }
|
| #endif // JSONPARSERBYLEO_SRC_JSONNODE_JSONNODEMETHODS_MQH
|