724 lines
18 KiB
MQL5
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
|