forked from nique_372/BasesParserSLan
149 lines
3.8 KiB
MQL5
149 lines
3.8 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Pointer.mqh |
|
|
//| Copyright 2026, Niquel Mendoza |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2026, Niquel Mendoza"
|
|
#property link "https://www.mql5.com"
|
|
#property strict
|
|
|
|
#ifndef BASESPARSERSLAN_SRC_POINTER_MQH
|
|
#define BASESPARSERSLAN_SRC_POINTER_MQH
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
#include "DomBaseHeader.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
namespace TSN
|
|
{
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename TCtx>
|
|
class CDomNodePointer
|
|
{
|
|
protected:
|
|
int m_p;
|
|
int m_len;
|
|
CDomNodeBase* m_base;
|
|
|
|
public:
|
|
CDomNodePointer() : m_base(NULL) {}
|
|
~CDomNodePointer() {}
|
|
|
|
//---
|
|
void Base(CDomNodeBase* ptr) { m_base = ptr;}
|
|
CDomNodeBase* Base() { return m_base; }
|
|
|
|
//--- last
|
|
__forceinline int LastQueryLen() const { return m_len; }
|
|
|
|
//---
|
|
CDomNodeBase* Query(const string &json_pointer);
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename TCtx>
|
|
CDomNodeBase* CDomNodePointer::Query(const string &json_pointer)
|
|
{
|
|
//---
|
|
if(((1 << m_base.m_type) & (TSN_SBL_BASE_F_ARR | TSN_SBL_BASE_F_OBJ)) == 0)
|
|
return NULL;
|
|
|
|
//---
|
|
if(json_pointer == "")
|
|
return m_base;
|
|
|
|
//---
|
|
if(json_pointer[0] != '/')
|
|
return NULL;
|
|
|
|
|
|
//---
|
|
CDomNodeBase* curr = m_base;
|
|
m_len = StringLen(json_pointer);
|
|
m_p = 1;
|
|
|
|
//---
|
|
while(true)
|
|
{
|
|
const uchar t = curr.m_type;
|
|
if(t == TSN_SBL_BASE_TYPE_OBJ)
|
|
{
|
|
//--- Calcula y va escapando el key hash...y avanza m_p
|
|
const ulong khash = TCtx::EscapePointer(json_pointer, m_p, m_len);
|
|
// Ahora mismo en final o /
|
|
|
|
//---
|
|
CHashMapFast(string, CDomNodeBase*)* hs = curr.HashMap();
|
|
const int idx = hs.FindByHash(khash);
|
|
if(idx == -1)
|
|
return NULL;
|
|
|
|
//---
|
|
curr = hs.m_table[idx].value;
|
|
}
|
|
else
|
|
if(t == TSN_SBL_BASE_TYPE_ARR)
|
|
{
|
|
//---
|
|
uchar ch = (uchar)json_pointer[m_p] ^ '0';
|
|
int last_index = -1;
|
|
|
|
//---
|
|
if(ch < 10)
|
|
{
|
|
last_index = 0;
|
|
while(true)
|
|
{
|
|
//---
|
|
last_index = (last_index << 3) + (last_index << 1) + ch;
|
|
m_p++;
|
|
if(m_p >= m_len)
|
|
break;
|
|
|
|
//---
|
|
ch = (uchar)json_pointer[m_p];
|
|
// m_p luego del /
|
|
if(ch == '/')
|
|
{
|
|
m_p++;
|
|
break;
|
|
}
|
|
|
|
//--
|
|
ch ^= '0';
|
|
}
|
|
}
|
|
|
|
//---
|
|
if(!curr.InRange(last_index))
|
|
return NULL;
|
|
|
|
//-- Accedemos
|
|
curr = curr.At(last_index);
|
|
}
|
|
else
|
|
{
|
|
// No se puede
|
|
return NULL;
|
|
}
|
|
|
|
//---
|
|
if(m_p >= m_len)
|
|
return curr;
|
|
}
|
|
|
|
//---
|
|
return NULL;
|
|
}
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
#endif // BASESPARSERSLAN_SRC_POINTER_MQH
|