895 lines
23 KiB
MQL5
895 lines
23 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_DOM_IMP_MQH
| |
#define BASESPARSERSLAN_SRC_DOM_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].ContainsKey(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];
| |
| |
//---
| |
if(!ptr.ContainsKey(key))
| |
return false;
| |
| |
//---
| |
// #1: truco de bajo nivel hashmap guarda la ultima posicion ahi..
| |
CDomNodeBase* f = ptr.m_table[ptr.m_last_pos_tbl].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.RemoveLastFindCall(); // eliminamos el ultimo caller
| |
return true;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
void CDomNodeBase::NewObj(int inital_hash_map_size)
| |
{
| |
//--- Revisamos previa.. (en caso de ser compejo liberamos)
| |
BASESPARSERSLAN_DOMNODE_FREE
| |
| |
//---
| |
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_ARR:
| |
return m_ctx.m_node[m_v.ix].values_size;
| |
case TSN_SBL_BASE_TYPE_OBJ:
| |
return m_ctx.m_objs[m_v.ix].Count();
| |
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)
| |
BASESPARSERSLAN_DOMNODE_FREE
| |
| |
//---
| |
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
| |
{
| |
if(m_type != TSN_SBL_BASE_TYPE_ARR)
| |
return -1; // Error
| |
return m_ctx.ToArray(m_v.ix, array);
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
__forceinline int CDomNodeBase::CopyTo(CDomNodeBase *&out[], int dst_start) const
| |
{
| |
switch(m_type)
| |
{
| |
case TSN_SBL_BASE_TYPE_ARR:
| |
return m_ctx.ArrCopyTo(m_v.ix, out, dst_start);
| |
case TSN_SBL_BASE_TYPE_OBJ:
| |
return m_ctx.m_objs[m_v.ix].GetValues(out, dst_start);
| |
default:
| |
return -1;
| |
}
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
__forceinline int CDomNodeBase::PySlicing(CDomNodeBase *&out[], int dst_start = 0,
| |
int start = -1, int end = -1, int step = 1) const
| |
{
| |
if(m_type != TSN_SBL_BASE_TYPE_ARR)
| |
return -1; // Error
| |
return m_ctx.SlicingArr(m_v.ix, out, dst_start, start, end, step);
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void CDomNodeBase::Clear()
| |
{
| |
switch(m_type)
| |
{
| |
case TSN_SBL_BASE_TYPE_ARR:
| |
{
| |
m_ctx.ClearArray(m_v.ix);
| |
break;
| |
}
| |
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(CheckPointer(f) == POINTER_DYNAMIC && f.m_ctx == m_ctx)
| |
delete f;
| |
| |
//---
| |
it.Next();
| |
}
| |
| |
//---
| |
ptr.Clear();
| |
break;
| |
}
| |
default:
| |
break;
| |
}
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
void CDomNodeBase::Type(const uchar tt, int default_els_in_arrojb)
| |
{
| |
//---
| |
BASESPARSERSLAN_DOMNODE_FREE
| |
| |
//---
| |
m_type = tt; // reasignamos el nuevo tipo
| |
switch(tt)
| |
{
| |
case TSN_SBL_BASE_TYPE_ARR:
| |
{
| |
NewArr(default_els_in_arrojb);
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_OBJ:
| |
{
| |
NewObj(default_els_in_arrojb);
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_UINT:
| |
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_v.ix = m_ctx.ReserveString();
| |
break;
| |
}
| |
case TSN_SBL_BASE_DOM_NULL:
| |
break;
| |
default:
| |
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;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| String |
| |
//+------------------------------------------------------------------+
| |
bool CDomNodeBase::As(const string v)
| |
{
| |
switch(m_type)
| |
{
| |
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_OBJ:
| |
{
| |
m_ctx.FreeObj(m_v.ix);
| |
m_type = TSN_SBL_BASE_TYPE_STR;
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_UINT:
| |
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_ARR:
| |
{
| |
m_ctx.FreeArr(m_v.ix);
| |
m_type = TSN_SBL_BASE_TYPE_STR;
| |
break;
| |
}
| |
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_UINT:
| |
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 |
| |
//+------------------------------------------------------------------+
| |
bool CDomNodeBase::operator=(const bool v)
| |
{
| |
switch(m_type)
| |
{
| |
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_OBJ:
| |
{
| |
m_ctx.FreeObj(m_v.ix);
| |
m_type = TSN_SBL_BASE_TYPE_BOL;
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_UINT:
| |
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;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Reales |
| |
//+------------------------------------------------------------------+
| |
bool CDomNodeBase::operator=(const double v)
| |
{
| |
switch(m_type)
| |
{
| |
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_OBJ:
| |
{
| |
m_ctx.FreeObj(m_v.ix);
| |
m_type = TSN_SBL_BASE_TYPE_FLT;
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_UINT:
| |
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;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Enteros |
| |
//+------------------------------------------------------------------+
| |
bool CDomNodeBase::operator=(const ulong v)
| |
{
| |
switch(m_type)
| |
{
| |
case TSN_SBL_BASE_TYPE_ARR:
| |
{
| |
m_ctx.FreeArr(m_v.ix);
| |
m_type = TSN_SBL_BASE_TYPE_UINT;
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_OBJ:
| |
{
| |
m_ctx.FreeObj(m_v.ix);
| |
m_type = TSN_SBL_BASE_TYPE_UINT;
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_UINT:
| |
break; // NADA sale
| |
case TSN_SBL_BASE_TYPE_INT:
| |
case TSN_SBL_BASE_TYPE_FLT:
| |
case TSN_SBL_BASE_TYPE_BOL:
| |
{
| |
m_type = TSN_SBL_BASE_TYPE_UINT;
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_STR:
| |
{
| |
m_ctx.FreeString(m_v.ix);
| |
m_type = TSN_SBL_BASE_TYPE_UINT;
| |
break;
| |
}
| |
case TSN_SBL_BASE_DOM_NULL:
| |
{
| |
m_type = TSN_SBL_BASE_TYPE_UINT;
| |
break;
| |
}
| |
default:
| |
return false;
| |
}
| |
| |
//---
| |
m_v.uv = v;
| |
return true;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
bool CDomNodeBase::operator=(const long v)
| |
{
| |
switch(m_type)
| |
{
| |
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_OBJ:
| |
{
| |
m_ctx.FreeObj(m_v.ix);
| |
m_type = TSN_SBL_BASE_TYPE_INT;
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_UINT:
| |
{
| |
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;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
bool CDomNodeBase::operator=(const int v)
| |
{
| |
switch(m_type)
| |
{
| |
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_OBJ:
| |
{
| |
m_ctx.FreeObj(m_v.ix);
| |
m_type = TSN_SBL_BASE_TYPE_INT;
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_UINT:
| |
{
| |
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;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| At |
| |
//+------------------------------------------------------------------+
| |
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(CheckPointer(old) == POINTER_DYNAMIC && old.m_ctx == m_ctx)
| |
delete old;
| |
m_ctx.m_node[m_v.ix].values[idx] = val;
| |
return true;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Key-Resolved |
| |
//+------------------------------------------------------------------+
| |
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];
| |
return ptr.ContainsKey(key) ? ptr.m_table[ptr.m_last_pos_tbl].value : NULL;
| |
} // En caso no existe da error
| |
| |
//+------------------------------------------------------------------+
| |
CDomNodeBase* const CDomNodeBase::Get(const ulong fnv164_hash) const
| |
{
| |
if(m_type != TSN_SBL_BASE_TYPE_OBJ)
| |
return NULL;
| |
| |
//----
| |
CHashMapFast(string, CDomNodeBase*)* ptr = m_ctx.m_objs[m_v.ix];
| |
return ptr.ContainsKeyByHash(fnv164_hash) ? ptr.m_table[ptr.m_last_pos_tbl].value : NULL;
| |
} // En caso no existe da error
| |
| |
| |
//+------------------------------------------------------------------+
| |
bool CDomNodeBase::Set(const string &key, CDomNodeBase *val)
| |
{
| |
if(m_type != TSN_SBL_BASE_TYPE_OBJ)
| |
return false;
| |
| |
//---
| |
// JUSTO el caso de uso de bajo nivel que requerismo para evitar dos finds..
| |
CHashMapFast(string, CDomNodeBase*)* ptr = m_ctx.m_objs[m_v.ix];
| |
| |
//--- Esta funcion se comporta como un find, si retonra false es que ya exciste
| |
if(!ptr.ReserveSlot(key))
| |
{
| |
// existe
| |
const uint p = ptr.m_last_pos_tbl;
| |
CDomNodeBase* old = ptr.m_table[p].value;
| |
if(CheckPointer(old) == POINTER_DYNAMIC && old.m_ctx == m_ctx)
| |
delete old;
| |
ptr.m_table[p].value = val; // replace
| |
return true;
| |
}
| |
| |
//--- no existe, entonces ya no reservaron un slot
| |
// Solo hay que llenarlo (key, value, hash ya lo hace la lib en si)
| |
const uint p = ptr.m_last_pos_tbl;
| |
ptr.m_table[p].key = key;
| |
ptr.m_table[p].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];
| |
if(!ptr.ReserveSlot(key)) // existe
| |
return ptr.m_table[ptr.m_last_pos_tbl].value;
| |
| |
//--- No existe entonces ya nos reservaron un slot lo podemos poner ahi
| |
const uint p = ptr.m_last_pos_tbl;
| |
ptr.m_table[p].key = key; // llenamos key
| |
| |
//--- ahora retornamos una vez que llenamos value
| |
return (ptr.m_table[p].value = new CDomNodeBase(m_ctx));
| |
} // En caso no existe lo crea.
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
ulong CDomNodeBase::ToUint(const ulong def) const
| |
{
| |
switch(m_type)
| |
{
| |
case TSN_SBL_BASE_TYPE_UINT:
| |
return m_v.uv;
| |
case TSN_SBL_BASE_TYPE_INT:
| |
return (ulong)m_v.iv;
| |
case TSN_SBL_BASE_TYPE_FLT:
| |
return (ulong)m_v.dv;
| |
case TSN_SBL_BASE_TYPE_BOL:
| |
return m_v.bv;
| |
case TSN_SBL_BASE_TYPE_STR:
| |
return (ulong)m_ctx.m_string_stack[m_v.ix];
| |
default:
| |
return def;
| |
}
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
bool CDomNodeBase::ToUintSafe(ulong &val) const
| |
{
| |
switch(m_type)
| |
{
| |
case TSN_SBL_BASE_TYPE_UINT:
| |
val = m_v.uv;
| |
return true;
| |
case TSN_SBL_BASE_TYPE_INT:
| |
val = (ulong)m_v.iv;
| |
return true;
| |
case TSN_SBL_BASE_TYPE_FLT:
| |
val = (ulong)m_v.dv;
| |
return true;
| |
case TSN_SBL_BASE_TYPE_BOL:
| |
val = m_v.bv;
| |
return true;
| |
case TSN_SBL_BASE_TYPE_STR:
| |
val = (ulong)m_ctx.m_string_stack[m_v.ix];
| |
return true;
| |
default:
| |
return false;
| |
}
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
long CDomNodeBase::ToInt(const long def) const
| |
{
| |
switch(m_type)
| |
{
| |
case TSN_SBL_BASE_TYPE_UINT:
| |
return (long)m_v.uv;
| |
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_UINT:
| |
val = (long)m_v.uv;
| |
return true;
| |
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_UINT:
| |
return (double)m_v.uv;
| |
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::ToBool(const bool def) const
| |
{
| |
switch(m_type)
| |
{
| |
case TSN_SBL_BASE_TYPE_UINT:
| |
return m_v.uv != 0;
| |
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_UINT:
| |
val = m_v.uv != 0;
| |
return true;
| |
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_UINT:
| |
return (string)m_v.uv;
| |
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_DOM_IMP_MQH
|