BasesParserSLan/Src/Pointer.mqh
2026-07-26 17:15:14 -05:00

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