forked from nique_372/BasesParserSLan
475 lines
12 KiB
MQL5
475 lines
12 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| DomDef.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_DEF_MQH
| |
#define BASESPARSERSLAN_SRC_DOM_DOM_DEF_MQH
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
#include "DomBaseHeader.mqh"
| |
| |
//+------------------------------------------------------------------+
| |
//| Code |
| |
//+------------------------------------------------------------------+
| |
namespace TSN
| |
{
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
class CDomNodeManager
| |
{
| |
public:
| |
CDomNodeManager();
| |
~CDomNodeManager() {}
| |
| |
//--- String
| |
//- Stack
| |
int m_string_stack_size;
| |
int m_string_stack_r;
| |
string m_string_stack[];
| |
//- Free
| |
int m_string_free[];
| |
int m_string_free_r;
| |
int m_string_free_s;
| |
//- Methods
| |
void FreeString(const int ix);
| |
int ReserveString();
| |
| |
//--- Array
| |
struct NodeValues
| |
{
| |
CDomNodeBase* values[];
| |
int values_size;
| |
int values_r;
| |
};
| |
//- node
| |
NodeValues m_node[];
| |
int m_node_size;
| |
int m_node_r;
| |
//- free
| |
int m_node_free[];
| |
int m_node_free_r;
| |
int m_node_free_s;
| |
| |
//- Methods
| |
template <typename T>
| |
int ToArray(const int ix, T& array[]) const;
| |
void ClearArray(const int ix);
| |
bool DeleteElementArr(const int ix, const int el);
| |
bool AddElementArr(const int ix, CDomNodeBase* ptr);
| |
void FreeArr(const int ix);
| |
int ReserveArr(const int initial_reserve);
| |
int SlicingArr(const int ix, CDomNodeBase* &out[], int dst_start = 0
| |
, int cur = -1, int end = -1, int step = 1) const;
| |
int ArrCopyTo(const int ix, CDomNodeBase *&out[], int dst_start) const;
| |
| |
//--- Obj
| |
CHashMapFast(string, CDomNodeBase*)* m_objs[];
| |
int m_objs_size;
| |
int m_objs_r;
| |
//- free
| |
int m_objs_free[];
| |
int m_objs_free_r;
| |
int m_objs_free_s;
| |
| |
//- Methods
| |
void FreeObj(const int ix);
| |
int ReserveObj(const int initial_reserve);
| |
};
| |
| |
//+------------------------------------------------------------------+
| |
//| |
| |
//+------------------------------------------------------------------+
| |
CDomNodeManager::CDomNodeManager()
| |
: m_string_free_s(0), m_string_stack_size(0), m_node_free_s(0), m_node_size(0), m_objs_size(0), m_objs_free_s(0),
| |
m_string_free_r(8), m_string_stack_r(8), m_node_free_r(8), m_node_r(8), m_objs_free_r(8), m_objs_r(8)
| |
{
| |
ArrayResize(m_string_free, m_string_free_r, m_string_free_r);
| |
ArrayResize(m_string_stack, m_string_stack_r, m_string_stack_r);
| |
| |
ArrayResize(m_node_free, m_node_free_r, m_node_free_r);
| |
ArrayResize(m_node, m_node_r, m_node_r);
| |
| |
ArrayResize(m_objs_free, m_objs_free_r, m_objs_free_r);
| |
ArrayResize(m_objs, m_objs_r, m_objs_r);
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Obj |
| |
//+------------------------------------------------------------------+
| |
int CDomNodeManager::ReserveObj(const int initial_reserve)
| |
{
| |
//---
| |
if(m_objs_free_s > 0)
| |
{
| |
const int idx = m_objs_free[--m_objs_free_s];
| |
return idx;
| |
}
| |
| |
//---
| |
if(m_objs_size + 1 >= m_objs_r)
| |
{
| |
m_objs_r <<= 1;
| |
ArrayResize(m_objs, m_objs_r, m_objs_r);
| |
}
| |
| |
//---
| |
m_objs[m_objs_size++] = new CHashMapFast(string, CDomNodeBase*)(initial_reserve);
| |
return m_objs_size - 1;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
void CDomNodeManager::FreeObj(const int ix)
| |
{
| |
//---
| |
//Print("INicio elimiacion: " , ix);
| |
CHashMapFast(string, CDomNodeBase*)* ptr = m_objs[ix];
| |
CHashMapFastIterator(string, CDomNodeBase*) it = ptr.BeginIteration();
| |
| |
//--- Iteramos por todas los value y eliminamos todos los valores
| |
while(it.IsValid())
| |
{
| |
CDomNodeBase* f = it.Val();
| |
// Print(it.Key());
| |
// En caso el contexto del objeto... a eliminar es el mismo (proviene de la misma pila)
| |
// ENtonces eliminamos..
| |
| |
//---
| |
// puntero colgado
| |
// hacemos esto dado qeu si se elimina un ref antes del "base"
| |
// se qeuda colgado por lo que ya su valor es invaido y no podemos tocar dicho objeto
| |
if(CheckPointer(f) == POINTER_DYNAMIC && f.m_ctx == &this)
| |
{
| |
//Print("Eliminado: " , it.Key(), " Es nuestro");
| |
| |
delete f;
| |
}
| |
// else
| |
// Print("No eliminado: " , it.Key(), " No es nuestro");
| |
| |
//---
| |
it.Next();
| |
}
| |
| |
//--- Eliminamos el hashmap
| |
if(CheckPointer(ptr) == POINTER_DYNAMIC)
| |
delete ptr;
| |
| |
//--- Delete
| |
if(m_objs_free_s + 1 >= m_objs_free_r)
| |
{
| |
m_objs_free_r <<= 1;
| |
ArrayResize(m_objs_free, m_objs_free_r, m_objs_free_r);
| |
}
| |
m_objs_free[m_objs_free_s++] = ix;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Stirng |
| |
//+------------------------------------------------------------------+
| |
int CDomNodeManager::ReserveString(void)
| |
{
| |
//---
| |
if(m_string_free_s > 0)
| |
{
| |
const int idx = m_string_free[--m_string_free_s];
| |
return idx;
| |
}
| |
| |
//---
| |
if(m_string_stack_size + 1 >= m_string_stack_r)
| |
{
| |
m_string_stack_r <<= 1;
| |
ArrayResize(m_string_stack, m_string_stack_r, m_string_stack_r);
| |
}
| |
m_string_stack_size++;
| |
return m_string_stack_size - 1;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
void CDomNodeManager::FreeString(const int ix)
| |
{
| |
if(m_string_free_s + 1 >= m_string_free_r)
| |
{
| |
m_string_free_r <<= 1;
| |
ArrayResize(m_string_free, m_string_free_r, m_string_free_r);
| |
}
| |
m_string_free[m_string_free_s++] = ix;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
//| Array |
| |
//+------------------------------------------------------------------+
| |
bool CDomNodeManager::AddElementArr(const int ix, CDomNodeBase *ptr)
| |
{
| |
//---
| |
if(m_node[ix].values_size + 1 >= m_node[ix].values_r)
| |
{
| |
m_node[ix].values_r <<= 1;
| |
ArrayResize(m_node[ix].values, m_node[ix].values_r, m_node[ix].values_r);
| |
}
| |
| |
//---
| |
m_node[ix].values[m_node[ix].values_size++] = ptr;
| |
return true;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
bool CDomNodeManager::DeleteElementArr(const int ix, const int el)
| |
{
| |
//---
| |
if(el < 0 || el >= m_node[ix].values_size)
| |
return false;
| |
| |
//---
| |
const int t = --m_node[ix].values_size;
| |
| |
//---
| |
CDomNodeBase* ptr = m_node[ix].values[el];
| |
if(CheckPointer(ptr) == POINTER_DYNAMIC && ptr.m_ctx == &this)
| |
delete ptr;
| |
| |
//---
| |
for(int i = el; i < t; i++)
| |
m_node[ix].values[i] = m_node[ix].values[i + 1];
| |
| |
//---
| |
return true;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
int CDomNodeManager::ReserveArr(const int initial_reserve)
| |
{
| |
//---
| |
if(m_node_free_s > 0)
| |
{
| |
const int idx = m_node_free[--m_node_free_s];
| |
return idx;
| |
}
| |
| |
//---
| |
if(m_node_size + 1 >= m_node_r)
| |
{
| |
m_node_r <<= 1;
| |
ArrayResize(m_node, m_node_r, m_node_r);
| |
}
| |
| |
//---
| |
m_node[m_node_size].values_r = ArrayResize(m_node[m_node_size].values, initial_reserve, initial_reserve);
| |
m_node[m_node_size++].values_size = 0; // 0 elementos
| |
return m_node_size - 1;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
void CDomNodeManager::FreeArr(const int ix)
| |
{
| |
//---
| |
//Print("--------------------");
| |
ClearArray(ix);
| |
| |
//---
| |
if(m_node_free_s + 1 >= m_node_free_r)
| |
{
| |
m_node_free_r <<= 1;
| |
ArrayResize(m_node_free, m_node_free_r, m_node_free_r);
| |
}
| |
m_node_free[m_node_free_s++] = ix;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
void CDomNodeManager::ClearArray(const int ix)
| |
{
| |
//--- iteramos por todos los elementos y vamos eliminando los que son del own
| |
//Print("DEL START: ", m_node[ix].values_size);
| |
for(int i = 0; i < m_node[ix].values_size; i++)
| |
{
| |
//Print("Iteration: ", i);
| |
CDomNodeBase* ptr = m_node[ix].values[i];
| |
if(CheckPointer(ptr) == POINTER_DYNAMIC && ptr.m_ctx == &this)
| |
{
| |
// Print("Del: ", i);
| |
delete ptr;
| |
}
| |
}
| |
//Print("DEL END");
| |
| |
//--- resize
| |
m_node[ix].values_size = 0; // 0 elementos
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
int CDomNodeManager::ArrCopyTo(const int ix, CDomNodeBase *&out[], int dst_start) const
| |
{
| |
//---
| |
const int t = m_node[ix].values_size;
| |
if(t < 1)
| |
return 0;
| |
| |
//---
| |
const int n = dst_start + t;
| |
if(n > ArraySize(out)) // es mayor..
| |
{
| |
ArrayResize(out, n);
| |
}
| |
| |
//---
| |
for(int i = 0; i < t; i++)
| |
{
| |
out[dst_start++] = m_node[ix].values[i];
| |
}
| |
return t;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
int CDomNodeManager::SlicingArr(const int ix, CDomNodeBase* &out[], int dst_start = 0
| |
, int cur = -1, int end = -1, int step = 1) const
| |
{
| |
//---
| |
int l = m_node[ix].values_size;
| |
if(l < 1)
| |
return 0;
| |
| |
//---
| |
const int lock = dst_start;
| |
| |
//---
| |
if(step > 0)
| |
{
| |
//---
| |
if(cur == -1)
| |
cur = 0;
| |
else
| |
if(cur < 0)
| |
{
| |
cur = l + cur;
| |
if(cur < 0)
| |
cur = 0;
| |
}
| |
| |
//---
| |
if(end == -1)
| |
end = l;
| |
else
| |
if(end < 0)
| |
{
| |
end = l + end;
| |
if(end < 0)
| |
end = 0;
| |
}
| |
| |
//---
| |
cur = cur < l ? cur : l;
| |
end = end < l ? end : l;
| |
| |
//---
| |
const int n = dst_start + (end - cur);
| |
if(n > ArraySize(out))
| |
ArrayResize(out, n);
| |
| |
//---
| |
while(cur < end)
| |
{
| |
out[dst_start++] = m_node[ix].values[cur];
| |
cur += step;
| |
}
| |
}
| |
else
| |
{
| |
//---
| |
// 2 + -3
| |
if(cur == -1)
| |
cur = l - 1;
| |
else
| |
if(cur < 0)
| |
{
| |
cur = l + cur;
| |
if(cur < 0)
| |
cur = -1;
| |
}
| |
| |
//---
| |
if(end == -1)
| |
end = -1;
| |
else
| |
if(end < 0)
| |
{
| |
end = l + end;
| |
if(end < 0)
| |
end = -1;
| |
}
| |
| |
//---
| |
l--;
| |
cur = cur < l ? cur : l;
| |
end = end < l ? end : l;
| |
| |
| |
//---
| |
const int n = dst_start + (cur - end);
| |
| |
if(n > ArraySize(out))
| |
ArrayResize(out, n);
| |
| |
//---
| |
while(cur > end)
| |
{
| |
out[dst_start++] = m_node[ix].values[cur];
| |
cur += step;
| |
}
| |
}
| |
return dst_start - lock;
| |
}
| |
| |
//+------------------------------------------------------------------+
| |
template <typename T>
| |
int CDomNodeManager::ToArray(const int ix, T &array[]) const
| |
{
| |
const int t = m_node[ix].values_size;
| |
ArrayResize(array, t);
| |
for(int i = 0; i < t; i++)
| |
{
| |
switch(m_node[ix].values[i].m_type)
| |
{
| |
case TSN_SBL_BASE_TYPE_UINT:
| |
{
| |
array[i] = (T)m_node[ix].values[i].m_v.uv;
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_INT:
| |
{
| |
array[i] = (T)m_node[ix].values[i].m_v.iv;
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_FLT:
| |
{
| |
array[i] = (T)m_node[ix].values[i].m_v.dv;
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_BOL:
| |
{
| |
array[i] = (T)m_node[ix].values[i].m_v.bv;
| |
break;
| |
}
| |
case TSN_SBL_BASE_TYPE_STR:
| |
{
| |
const int ri = m_node[ix].values[i].m_v.ix;
| |
array[i] = (T)m_string_stack[ri];
| |
break;
| |
}
| |
default:
| |
array[i] = (T)NULL;
| |
break;
| |
}
| |
}
| |
return t;
| |
}
| |
}
| |
//+------------------------------------------------------------------+
| |
#endif // BASESPARSERSLAN_SRC_DOM_DOM_DEF_MQH
|