BasesParserSLan/Src/DomImp.mqh
Nique_372 e17fae1c7d
2026-07-21 10:57:52 -05:00

724 lines
18 KiB
MQL5

//+------------------------------------------------------------------+
//| DomImp.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_DOM_IMP_MQH
#define BASESPARSERSLAN_SRC_DOM_IMP_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "DomDef.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| Keys |
//+------------------------------------------------------------------+
__forceinline int CDomNodeBase::GetKeys(string &out[]) const
{
return m_type == TSN_SBL_BASE_TYPE_OBJ ? m_ctx.m_objs[m_v.ix].GetKeys(out) : 0;
}
//+------------------------------------------------------------------+
__forceinline bool CDomNodeBase::HasKey(const string &key) const
{
return m_type == TSN_SBL_BASE_TYPE_OBJ ? m_ctx.m_objs[m_v.ix].Contains(key) : false;
}
//+------------------------------------------------------------------+
bool CDomNodeBase::Remove(const string &key)
{
if(m_type != TSN_SBL_BASE_TYPE_OBJ)
return false;
//---
CHashMapFast(string, CDomNodeBase*)* ptr = m_ctx.m_objs[m_v.ix];
//---
uint i;
int bit_pos;
if(!ptr.Find(key, i, bit_pos))
return false;
//---
CDomNodeBase* f = ptr.m_table[TSN_FASTHASHMAP_INDEX(i, bit_pos)].value;
// En caso el contexto del objeto... a eliminar es el mismo (proviene de la misma pila)
// ENtonces eliminamos..
if(f.m_ctx == m_ctx && CheckPointer(f) == POINTER_DYNAMIC)
delete f;
ptr.Remove(i, bit_pos);
return true;
}
//+------------------------------------------------------------------+
void CDomNodeBase::NewObj(int inital_hash_map_size)
{
//--- Revisamos previa.. (en caso de ser compejo liberamos)
switch(m_type)
{
case TSN_SBL_BASE_TYPE_OBJ:
m_ctx.FreeObj(m_v.ix);
break;
case TSN_SBL_BASE_TYPE_ARR:
m_ctx.FreeArr(m_v.ix);
break;
case TSN_SBL_BASE_TYPE_INT:
case TSN_SBL_BASE_TYPE_FLT:
case TSN_SBL_BASE_TYPE_BOL:
break;
case TSN_SBL_BASE_TYPE_STR:
m_ctx.FreeString(m_v.ix);
break;
default:
break;
}
//---
m_type = TSN_SBL_BASE_TYPE_OBJ;
m_v.ix = m_ctx.ReserveObj(inital_hash_map_size);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
__forceinline int CDomNodeBase::Size(void) const
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_OBJ:
return m_ctx.m_objs[m_v.ix].Count();
case TSN_SBL_BASE_TYPE_ARR:
return m_ctx.m_node[m_v.ix].values_size;
default:
return 0;
}
}
//+------------------------------------------------------------------+
__forceinline bool CDomNodeBase::InRange(const int index) const
{
const int t = Size();
return index >= 0 && index < t;
}
//+------------------------------------------------------------------+
__forceinline bool CDomNodeBase::RemoveItem(const int index)
{
return m_type == TSN_SBL_BASE_TYPE_ARR ? m_ctx.DeleteElementArr(m_v.ix, index) : false;
}
//+------------------------------------------------------------------+
__forceinline bool CDomNodeBase::AddItem(CDomNodeBase* node)
{
return m_type == TSN_SBL_BASE_TYPE_ARR ? m_ctx.AddElementArr(m_v.ix, node) : false;
}
//+------------------------------------------------------------------+
void CDomNodeBase::NewArr(int inital_reserve)
{
//--- Revisamos previa.. (en caso de ser compejo liberamos)
switch(m_type)
{
case TSN_SBL_BASE_TYPE_OBJ:
m_ctx.FreeObj(m_v.ix);
break;
case TSN_SBL_BASE_TYPE_ARR:
m_ctx.FreeArr(m_v.ix);
break;
case TSN_SBL_BASE_TYPE_INT:
case TSN_SBL_BASE_TYPE_FLT:
case TSN_SBL_BASE_TYPE_BOL:
break;
case TSN_SBL_BASE_TYPE_STR:
m_ctx.FreeString(m_v.ix);
break;
default:
break;
}
//---
m_type = TSN_SBL_BASE_TYPE_ARR;
m_v.ix = m_ctx.ReserveArr(inital_reserve);
}
//+------------------------------------------------------------------+
template <typename T>
__forceinline int CDomNodeBase::ToArray(T &array[]) const
{
return m_ctx.ToArray(m_v.ix, array);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CDomNodeBase::Clear()
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_OBJ:
{
//---
CHashMapFast(string, CDomNodeBase*)* ptr = m_ctx.m_objs[m_v.ix];
CHashMapFastIterator(string, CDomNodeBase*) it = ptr.BeginIteration();
//---
while(it.IsValid())
{
CDomNodeBase* f = it.Val();
// En caso el contexto del objeto... a eliminar es el mismo (proviene de la misma pila)
// ENtonces eliminamos..
if(f.m_ctx == m_ctx && CheckPointer(f) == POINTER_DYNAMIC)
delete f;
//---
it.Next();
}
//---
ptr.Clear();
break;
}
case TSN_SBL_BASE_TYPE_ARR:
{
m_ctx.ClearArray(m_v.ix);
break;
}
}
}
//+------------------------------------------------------------------+
//| Asignaciones |
//+------------------------------------------------------------------+
bool CDomNodeBase::operator=(CDomNodeBase* ptr)
{
if(ptr.m_ctx != m_ctx)
return false;
//---
m_ctx = ptr.m_ctx;
m_v = ptr.m_v;
m_type = ptr.m_type;
return true;
}
//+------------------------------------------------------------------+
bool CDomNodeBase::operator=(CDomNodeBase& ref)
{
if(ref.m_ctx != m_ctx)
return false;
//---
m_ctx = ref.m_ctx;
m_v = ref.m_v;
m_type = ref.m_type;
return true;
}
//+------------------------------------------------------------------+
bool CDomNodeBase::As(const string v)
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_OBJ:
{
m_ctx.FreeObj(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_STR;
break;
}
case TSN_SBL_BASE_TYPE_ARR:
{
m_ctx.FreeArr(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_STR;
break;
}
case TSN_SBL_BASE_TYPE_INT:
case TSN_SBL_BASE_TYPE_FLT:
case TSN_SBL_BASE_TYPE_BOL:
m_type = TSN_SBL_BASE_TYPE_STR;
break;
case TSN_SBL_BASE_TYPE_STR:
{
m_ctx.m_string_stack[m_v.ix] = v;
return true;
}
case TSN_SBL_BASE_DOM_NULL:
{
m_type = TSN_SBL_BASE_TYPE_STR;
break;
}
default:
{
return false;
}
}
//---
m_v.ix = m_ctx.ReserveString();
m_ctx.m_string_stack[m_v.ix] = v;
return true;
}
//+------------------------------------------------------------------+
bool CDomNodeBase::operator=(const string& v)
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_OBJ:
{
m_ctx.FreeObj(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_STR;
break;
}
case TSN_SBL_BASE_TYPE_ARR:
{
m_ctx.FreeArr(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_STR;
break;
}
case TSN_SBL_BASE_TYPE_INT:
case TSN_SBL_BASE_TYPE_FLT:
case TSN_SBL_BASE_TYPE_BOL:
m_type = TSN_SBL_BASE_TYPE_STR;
break;
case TSN_SBL_BASE_TYPE_STR:
{
m_ctx.m_string_stack[m_v.ix] = v;
return true;
}
case TSN_SBL_BASE_DOM_NULL:
{
m_type = TSN_SBL_BASE_TYPE_STR;
break;
}
default:
{
return false;
}
}
//---
m_v.ix = m_ctx.ReserveString();
m_ctx.m_string_stack[m_v.ix] = v;
return true;
}
//+------------------------------------------------------------------+
bool CDomNodeBase::operator=(const bool v)
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_OBJ:
{
m_ctx.FreeObj(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_BOL;
break;
}
case TSN_SBL_BASE_TYPE_ARR:
{
m_ctx.FreeArr(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_BOL;
break;
}
case TSN_SBL_BASE_TYPE_INT:
case TSN_SBL_BASE_TYPE_FLT:
{
m_type = TSN_SBL_BASE_TYPE_BOL;
break;
}
case TSN_SBL_BASE_TYPE_BOL:
break;
case TSN_SBL_BASE_TYPE_STR:
{
m_ctx.FreeString(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_BOL;
break;
}
case TSN_SBL_BASE_DOM_NULL:
{
m_type = TSN_SBL_BASE_TYPE_BOL;
break;
}
default:
{
return false;
}
}
//---
m_v.bv = v;
return true;
}
//+------------------------------------------------------------------+
bool CDomNodeBase::operator=(const double v)
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_OBJ:
{
m_ctx.FreeObj(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_FLT;
break;
}
case TSN_SBL_BASE_TYPE_ARR:
{
m_ctx.FreeArr(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_FLT;
break;
}
case TSN_SBL_BASE_TYPE_INT:
{
m_type = TSN_SBL_BASE_TYPE_FLT;
break;
}
case TSN_SBL_BASE_TYPE_FLT:
break;
case TSN_SBL_BASE_TYPE_BOL:
{
m_type = TSN_SBL_BASE_TYPE_FLT;
break;
}
case TSN_SBL_BASE_TYPE_STR:
{
m_ctx.FreeString(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_FLT;
break;
}
case TSN_SBL_BASE_DOM_NULL:
{
m_type = TSN_SBL_BASE_TYPE_FLT;
break;
}
default:
{
return false;
}
}
//---
m_v.dv = v;
return true;
}
//+------------------------------------------------------------------+
bool CDomNodeBase::operator=(const long v)
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_OBJ:
{
m_ctx.FreeObj(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_INT;
break;
}
case TSN_SBL_BASE_TYPE_ARR:
{
m_ctx.FreeArr(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_INT;
break;
}
case TSN_SBL_BASE_TYPE_INT:
break; // Nada sale
case TSN_SBL_BASE_TYPE_FLT:
case TSN_SBL_BASE_TYPE_BOL:
{
m_type = TSN_SBL_BASE_TYPE_INT;
break;
}
case TSN_SBL_BASE_TYPE_STR:
{
m_ctx.FreeString(m_v.ix);
m_type = TSN_SBL_BASE_TYPE_INT;
break;
}
case TSN_SBL_BASE_DOM_NULL:
{
m_type = TSN_SBL_BASE_TYPE_INT;
break;
}
default:
{
return false;
}
}
//---
m_v.iv = v;
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CDomNodeBase* const CDomNodeBase::At(const int idx) const
{
if(m_type != TSN_SBL_BASE_TYPE_ARR)
return NULL;
return m_ctx.m_node[m_v.ix].values[idx];
}
//+------------------------------------------------------------------+
CDomNodeBase* const CDomNodeBase::AtSafe(const int idx) const
{
if(m_type != TSN_SBL_BASE_TYPE_ARR)
return NULL;
const int t = m_ctx.m_node[m_v.ix].values_size;
if(idx < 0 || idx >= t)
return NULL;
return m_ctx.m_node[m_v.ix].values[idx];
}
//+------------------------------------------------------------------+
bool CDomNodeBase::Ats(const int idx, CDomNodeBase *val)
{
if(m_type != TSN_SBL_BASE_TYPE_ARR)
return false;
const int t = m_ctx.m_node[m_v.ix].values_size;
if(idx < 0 || idx >= t)
return false;
// Ya existe... siempre..
CDomNodeBase* old = m_ctx.m_node[m_v.ix].values[idx];
if(old.m_ctx == m_ctx && CheckPointer(old) == POINTER_DYNAMIC)
delete old;
m_ctx.m_node[m_v.ix].values[idx] = val;
return true;
}
//+------------------------------------------------------------------+
CDomNodeBase* const CDomNodeBase::Get(const string &key) const
{
if(m_type != TSN_SBL_BASE_TYPE_OBJ)
return NULL;
//----
CHashMapFast(string, CDomNodeBase*)* ptr = m_ctx.m_objs[m_v.ix];
const int idx = ptr.Find(key);
return idx == -1 ? NULL : ptr.m_table[idx].value;
} // En caso no existe da error
//+------------------------------------------------------------------+
CDomNodeBase* const CDomNodeBase::Get(const ulong hash) const
{
if(m_type != TSN_SBL_BASE_TYPE_OBJ)
return NULL;
//----
CHashMapFast(string, CDomNodeBase*)* ptr = m_ctx.m_objs[m_v.ix];
const int idx = ptr.Find(hash);
return idx == -1 ? NULL : ptr.m_table[idx].value;
} // En caso no existe da error
//+------------------------------------------------------------------+
bool CDomNodeBase::Set(const string &key, CDomNodeBase *val)
{
if(m_type != TSN_SBL_BASE_TYPE_OBJ)
return false;
//---
CHashMapFast(string, CDomNodeBase*)* ptr = m_ctx.m_objs[m_v.ix];
//--- si ya existe la key, hay que liberar lo viejo (si es nuestro) antes de pisar
const int idx = ptr.Find(key);
if(idx != -1)
{
CDomNodeBase* old = ptr.m_table[idx].value;
if(old.m_ctx == m_ctx && CheckPointer(old) == POINTER_DYNAMIC)
delete old;
ptr.m_table[idx].value = val;
return true;
}
//--- no existe, reservamos slot y lo plantamos
if(!ptr.Add(key))
return false;
//---
ptr.m_table[ptr.m_last_created_pos].value = val;
return true;
}
//+------------------------------------------------------------------+
CDomNodeBase* const CDomNodeBase::operator[](const string& key)
{
if(m_type != TSN_SBL_BASE_TYPE_OBJ)
return NULL;
//---
CHashMapFast(string, CDomNodeBase*)* ptr = m_ctx.m_objs[m_v.ix];
const int idx = ptr.Find(key);
if(idx != -1)
{
return ptr.m_table[idx].value; // puntero
}
//--- No existe creamos entonces...
if(!ptr.Add(key))
return NULL;
//---
return (ptr.m_table[ptr.m_last_created_pos].value = new CDomNodeBase(m_ctx));
} // En caso no existe lo crea.
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
long CDomNodeBase::ToInt(const long def) const
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_INT:
return m_v.iv;
case TSN_SBL_BASE_TYPE_FLT:
return (long)m_v.dv;
case TSN_SBL_BASE_TYPE_BOL:
return m_v.bv;
case TSN_SBL_BASE_TYPE_STR:
return (long)m_ctx.m_string_stack[m_v.ix];
default:
return def;
}
}
//+------------------------------------------------------------------+
bool CDomNodeBase::ToIntSafe(long &val) const
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_INT:
val = m_v.iv;
return true;
case TSN_SBL_BASE_TYPE_FLT:
val = (long)m_v.dv;
return true;
case TSN_SBL_BASE_TYPE_BOL:
val = m_v.bv;
return true;
case TSN_SBL_BASE_TYPE_STR:
val = (long)m_ctx.m_string_stack[m_v.ix];
return true;
default:
return false;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CDomNodeBase::ToDouble(const double def) const
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_INT:
return (double)m_v.iv;
case TSN_SBL_BASE_TYPE_FLT:
return m_v.dv;
case TSN_SBL_BASE_TYPE_BOL:
return m_v.bv;
case TSN_SBL_BASE_TYPE_STR:
return (double)m_ctx.m_string_stack[m_v.ix];
default:
return def;
}
}
//+------------------------------------------------------------------+
bool CDomNodeBase::ToDoubleSafe(double &val) const
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_INT:
val = (double)m_v.iv;
return true;
case TSN_SBL_BASE_TYPE_FLT:
val = m_v.dv;
return true;
case TSN_SBL_BASE_TYPE_BOL:
val = m_v.bv;
return true;
case TSN_SBL_BASE_TYPE_STR:
val = (double)m_ctx.m_string_stack[m_v.ix];
return true;
default:
return false;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CDomNodeBase::ToBool(const bool def) const
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_INT:
return m_v.iv != 0;
case TSN_SBL_BASE_TYPE_FLT:
return m_v.dv != 0.0;
case TSN_SBL_BASE_TYPE_BOL:
return m_v.bv;
default:
return def;
}
}
//+------------------------------------------------------------------+
bool CDomNodeBase::ToBoolSafe(bool &val) const
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_INT:
val = m_v.iv != 0;
return true;
case TSN_SBL_BASE_TYPE_FLT:
val = m_v.dv != 0.0;
return true;
case TSN_SBL_BASE_TYPE_BOL:
val = m_v.bv;
return true;
default:
return false;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string CDomNodeBase::ToString(const string def = "") const
{
switch(m_type)
{
case TSN_SBL_BASE_TYPE_INT:
return (string)m_v.iv;
case TSN_SBL_BASE_TYPE_FLT:
return (string)m_v.dv;
case TSN_SBL_BASE_TYPE_BOL:
return (string)m_v.bv;
case TSN_SBL_BASE_TYPE_STR:
return m_ctx.m_string_stack[m_v.ix];
default:
return def;
}
}
//+------------------------------------------------------------------+
int CDomNodeBase::StrLenRaw(void) const
{
return m_type == TSN_SBL_BASE_TYPE_STR ? StringLen(m_ctx.m_string_stack[m_v.ix]) : 0;
}
}
//+------------------------------------------------------------------+
#endif // BASESPARSERSLAN_SRC_DOM_IMP_MQH