2026-04-03 22:37:29 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-04-03 22:17:13 -05:00
|
|
|
//| CYmlNode.mqh |
|
2026-04-03 21:12:36 -05:00
|
|
|
//| Copyright 2025, Niquel Mendoza. |
|
|
|
|
|
//| https://www.mql5.com/es/users/nique_372 |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#property copyright "Copyright 2025, Niquel Mendoza."
|
|
|
|
|
#property link "https://www.mql5.com/es/users/nique_372"
|
|
|
|
|
#property strict
|
|
|
|
|
|
2026-04-04 20:27:55 -05:00
|
|
|
#ifndef YMLPARSERBYLEO_SRC_YMLNODE_MQH
|
|
|
|
|
#define YMLPARSERBYLEO_SRC_YMLNODE_MQH
|
|
|
|
|
|
|
|
|
|
|
2026-04-03 21:12:36 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#include "YmlParser.mqh"
|
|
|
|
|
|
2026-04-04 08:07:02 -05:00
|
|
|
|
2026-04-03 21:12:36 -05:00
|
|
|
// KEY 2 pos [tipo|scape|hash][start<<32|end]
|
|
|
|
|
// STR 2 pos [tipo|scape][start<<32|end]
|
|
|
|
|
// STR_MULTI 2 pos [tipo|ident|saltos][start<<32|end]
|
|
|
|
|
// INTEGER 2 pos [tipo][valor_long]
|
|
|
|
|
// DBL 2 pos [tipo][valor_long (bits del double)]
|
|
|
|
|
// BOOL 1 pos [tipo|valor]
|
|
|
|
|
// NULL 1 pos [tipo]
|
|
|
|
|
// ARR 1 pos [tipo|count|closing_pos] (elementos siguen inmediatamente)
|
|
|
|
|
// OBJ 1 pos [tipo|count|closing_pos] (key+val siguen inmediatamente)
|
|
|
|
|
// ---
|
|
|
|
|
// REF_CREATE 1 pos [tipo|closing_pos] (sigue NAME 2pos + valor) (puede ser simple o compleja pero ocupa mismos dos pos)
|
|
|
|
|
// NAME 1 pos [start<<32|end] (nombre del anchor, siempre tras REF_CREATE)
|
|
|
|
|
// ---
|
|
|
|
|
// PTR 1 pos [tipo|pos_ref_create] (apunta a REF_CREATE)
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-04 16:19:18 -05:00
|
|
|
#define YML_NODE_IS_NOT_VALID (m_ctx==NULL || m_idx == -1 || m_end == -1)
|
2026-04-05 11:18:49 -05:00
|
|
|
struct CYmlIteratorArray;
|
|
|
|
|
struct CYmlIteratorObj;
|
2026-04-04 20:03:17 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
#define YML_RESOLVE_PTR(ctx, idx) ((int(ctx.m_cinta[idx] & 0xF) == YML_CLASIFIER_TOKEN_TYPE_PTR) ? (int(ctx.m_cinta[idx] >> YMLPARSER_BIT_END_TYPE) + 2) : (idx))
|
|
|
|
|
|
2026-04-03 22:17:13 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
struct CYmlNode
|
2026-04-03 21:12:36 -05:00
|
|
|
{
|
2026-04-03 22:17:13 -05:00
|
|
|
public:
|
2026-04-03 21:12:36 -05:00
|
|
|
//---
|
2026-04-04 16:19:18 -05:00
|
|
|
CYmlParser* m_ctx;
|
2026-04-05 15:04:14 -05:00
|
|
|
int m_idx;
|
|
|
|
|
int m_end;
|
2026-04-03 21:12:36 -05:00
|
|
|
|
|
|
|
|
//---
|
2026-04-03 22:17:13 -05:00
|
|
|
CYmlNode()
|
2026-04-04 16:19:18 -05:00
|
|
|
: m_ctx(NULL), m_idx(-1), m_end(-1) {}
|
2026-04-03 22:17:13 -05:00
|
|
|
//---
|
|
|
|
|
CYmlNode(CYmlParser* _ctx, int _idx, int _end)
|
2026-04-04 16:19:18 -05:00
|
|
|
: m_ctx(_ctx), m_idx(_idx), m_end(_end) {}
|
2026-04-03 21:12:36 -05:00
|
|
|
|
2026-04-03 22:37:29 -05:00
|
|
|
//--- Operators
|
2026-04-05 15:04:14 -05:00
|
|
|
CYmlNode operator[](const string& key) const;
|
|
|
|
|
CYmlNode At(const int index) const;
|
|
|
|
|
CYmlNode AtHomegeneo(const int index) const;
|
2026-04-03 22:37:29 -05:00
|
|
|
|
|
|
|
|
//--- To
|
2026-04-04 08:07:02 -05:00
|
|
|
// String
|
2026-04-05 15:04:14 -05:00
|
|
|
string ToString(string def = "") const;
|
2026-04-04 08:07:02 -05:00
|
|
|
// Int
|
2026-04-05 15:04:14 -05:00
|
|
|
long ToInt(long def) const;
|
|
|
|
|
bool ToIntSafe(long &val) const; // Version bool\true (si se pudo obtener)
|
2026-04-04 08:07:02 -05:00
|
|
|
// Dbl
|
2026-04-05 15:04:14 -05:00
|
|
|
double ToDouble(double def) const;
|
|
|
|
|
bool ToDoubleSafe(double &val) const; // Version bool\true (si se pudo obtener)
|
2026-04-04 08:07:02 -05:00
|
|
|
// Bool
|
2026-04-05 15:04:14 -05:00
|
|
|
__forceinline bool ToBool(bool def) const;
|
|
|
|
|
bool ToBoolSafe(bool& val) const; // Version bool\true (si se pudo obtener)
|
2026-04-03 22:37:29 -05:00
|
|
|
|
2026-04-06 07:49:32 -05:00
|
|
|
//--- Set
|
|
|
|
|
bool SetDbl(const double val);
|
|
|
|
|
bool SetInt(const long val);
|
|
|
|
|
bool SetBool(const bool val);
|
|
|
|
|
|
2026-04-04 20:03:17 -05:00
|
|
|
//--- Type
|
2026-04-05 15:04:14 -05:00
|
|
|
__forceinline ENUM_YML_CLASIFIER_TYPE_VAL GetType() const { return ENUM_YML_CLASIFIER_TYPE_VAL(m_ctx.m_cinta[m_idx] & 0xF); }
|
|
|
|
|
ENUM_DATATYPE GetTypeAsDataType(ENUM_DATATYPE def) const;
|
|
|
|
|
bool AssingMqlParam(MqlParam& param) const;
|
2026-04-04 20:03:17 -05:00
|
|
|
|
|
|
|
|
//--- Is
|
|
|
|
|
__forceinline bool IsValid() const;
|
|
|
|
|
__forceinline bool IsNull() const;
|
|
|
|
|
__forceinline bool IsArray() const;
|
|
|
|
|
__forceinline bool IsObject() const;
|
|
|
|
|
|
2026-04-05 11:18:49 -05:00
|
|
|
//--- Iterador
|
|
|
|
|
CYmlIteratorArray BeginArr() const;
|
|
|
|
|
CYmlIteratorObj BeginObj() const;
|
|
|
|
|
|
2026-04-04 20:03:17 -05:00
|
|
|
|
2026-04-06 07:33:39 -05:00
|
|
|
//--- Obtencion de key
|
|
|
|
|
// Esto solo aplica para los obejtos o blouqes (key:vak) donde val es homogeneo en todos (ocupa las miams posicons de cinta)
|
|
|
|
|
string AtObjKeyHomgenero(const int index) const;
|
|
|
|
|
// Obtinee key val=cualquiera
|
|
|
|
|
string AtObjKey(const int index) const;
|
|
|
|
|
|
2026-04-04 20:03:17 -05:00
|
|
|
//--- Size (arr o objeto)
|
2026-04-05 15:04:14 -05:00
|
|
|
int Size() const;
|
2026-04-05 11:18:49 -05:00
|
|
|
|
|
|
|
|
//---
|
2026-04-05 15:04:14 -05:00
|
|
|
// solo_en_el_bloque_actual= solo te permite moverte en el bloque acutal (ejemplo si estas en un objeto)
|
|
|
|
|
// Si el nueva posicion empeiza fuera de ese bloque entonces false, si quieres moveremtne libremente usa el parametro
|
|
|
|
|
// solo_en_el_bloque_actual = false
|
|
|
|
|
bool MoveToNextToken(bool solo_en_el_bloque_actual = true);
|
2026-04-06 09:56:37 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
// No safe
|
|
|
|
|
// Retorna el nodo a "posiciones" del m_idx actual
|
|
|
|
|
CYmlNode MoveNextPositions(int posiciones, bool solo_en_el_bloque_actual = true);
|
|
|
|
|
// Este muta el objeto actual no retorna
|
|
|
|
|
bool MoveNextPositionsThis(int posiciones, bool solo_en_el_bloque_actual = true);
|
2026-04-03 22:17:13 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
const CYmlNode EMPTY_YMLNODE;
|
|
|
|
|
|
2026-04-04 20:03:17 -05:00
|
|
|
|
2026-04-03 22:17:13 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
CYmlNode CYmlNode::operator[](const string& key) const
|
2026-04-03 22:17:13 -05:00
|
|
|
{
|
2026-04-04 20:03:17 -05:00
|
|
|
//---
|
2026-04-03 22:17:13 -05:00
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return EMPTY_YMLNODE;
|
|
|
|
|
|
2026-04-04 20:03:17 -05:00
|
|
|
//---
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
2026-04-03 22:17:13 -05:00
|
|
|
|
2026-04-04 20:03:17 -05:00
|
|
|
//---
|
|
|
|
|
const int tipo = int(m_ctx.m_cinta[i] & 0xF);
|
|
|
|
|
if(tipo != YML_CLASIFIER_TOKEN_TYPE_OBJ && tipo != YML_CLASIFIER_TOKEN_TYPE_REFERENCE_COMPLEX)
|
|
|
|
|
return EMPTY_YMLNODE;
|
|
|
|
|
|
|
|
|
|
//---
|
2026-04-03 22:17:13 -05:00
|
|
|
const int len = StringLen(key);
|
2026-04-04 20:03:17 -05:00
|
|
|
uint hash = 2166136261;
|
|
|
|
|
for(int k = 0; k < len; k++)
|
2026-04-03 21:12:36 -05:00
|
|
|
{
|
2026-04-04 20:03:17 -05:00
|
|
|
hash ^= (uint)key[k];
|
|
|
|
|
hash *= 16777619;
|
2026-04-03 22:17:13 -05:00
|
|
|
}
|
2026-04-03 21:12:36 -05:00
|
|
|
|
2026-04-03 22:17:13 -05:00
|
|
|
//---
|
2026-04-04 20:03:17 -05:00
|
|
|
int cur = i + 1; // salta header OBJ
|
2026-04-04 16:19:18 -05:00
|
|
|
while(cur < m_end)
|
2026-04-03 22:17:13 -05:00
|
|
|
{
|
2026-04-04 16:19:18 -05:00
|
|
|
if((m_ctx.m_cinta[cur] & 0xF) != YML_CLASIFIER_TOKEN_TYPE_KEY)
|
2026-04-03 22:17:13 -05:00
|
|
|
{
|
2026-04-04 16:19:18 -05:00
|
|
|
cur += m_ctx.GetStep(cur);
|
2026-04-03 22:17:13 -05:00
|
|
|
continue;
|
|
|
|
|
}
|
2026-04-04 16:19:18 -05:00
|
|
|
if(hash == uint(m_ctx.m_cinta[cur] >> YMLPARSER_KEY_BIT_INIT_HASH))
|
2026-04-03 22:17:13 -05:00
|
|
|
{
|
2026-04-04 20:03:17 -05:00
|
|
|
const int next_pos = cur + 2;
|
2026-04-04 16:19:18 -05:00
|
|
|
const int final_pos = next_pos + m_ctx.GetStep(next_pos);
|
2026-04-04 20:03:17 -05:00
|
|
|
return CYmlNode(m_ctx, next_pos, final_pos);
|
2026-04-03 22:17:13 -05:00
|
|
|
}
|
|
|
|
|
cur += 2;
|
2026-04-04 16:19:18 -05:00
|
|
|
cur += m_ctx.GetStep(cur);
|
2026-04-03 21:12:36 -05:00
|
|
|
}
|
2026-04-04 20:03:17 -05:00
|
|
|
return EMPTY_YMLNODE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
CYmlNode CYmlNode::At(const int index) const
|
2026-04-04 20:03:17 -05:00
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return EMPTY_YMLNODE;
|
2026-04-03 21:12:36 -05:00
|
|
|
|
2026-04-03 22:17:13 -05:00
|
|
|
//---
|
2026-04-04 20:03:17 -05:00
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
if(int(m_ctx.m_cinta[i] & 0xF) != YML_CLASIFIER_TOKEN_TYPE_ARR)
|
|
|
|
|
return EMPTY_YMLNODE;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int count = int((m_ctx.m_cinta[i] >> YMLPARSER_BIT_END_TYPE) & 0xFFFFFFF);
|
|
|
|
|
if(index < 0 || index >= count)
|
|
|
|
|
return EMPTY_YMLNODE;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
int cur = i + 1; // primer elemento
|
|
|
|
|
for(int k = 0; k < index; k++)
|
|
|
|
|
cur += m_ctx.GetStep(cur);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int final_pos = cur + m_ctx.GetStep(cur);
|
|
|
|
|
return CYmlNode(m_ctx, cur, final_pos);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-06 07:33:39 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
// At, para bloques implicitos
|
|
|
|
|
// ejemplo
|
|
|
|
|
// - valor : 10
|
|
|
|
|
// numeros: 10
|
|
|
|
|
// [obj][key][key][val][val][obj][key][key][val][val]
|
|
|
|
|
string CYmlNode::AtObjKey(const int index) const
|
|
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return "";
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
if(int(m_ctx.m_cinta[i] & 0xF) != YML_CLASIFIER_TOKEN_TYPE_OBJ)
|
|
|
|
|
return "";
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int count = int((m_ctx.m_cinta[i] >> YMLPARSER_BIT_END_TYPE) & 0xFFFFFFF);
|
|
|
|
|
if(index < 0 || index >= count)
|
|
|
|
|
return "";
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
int cur = i + 1; // primer elemento
|
|
|
|
|
for(int k = 0; k < index; k++)
|
|
|
|
|
{
|
|
|
|
|
cur += 2;
|
|
|
|
|
cur += m_ctx.GetStep(cur);
|
|
|
|
|
}
|
|
|
|
|
cur += 1; // Ahora mismo nos ubicamos en la poscion del iniico de key avanzamos a la info
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int start = int(m_ctx.m_cinta[cur] >> 32);
|
|
|
|
|
const int end = int(m_ctx.m_cinta[cur] & 0xFFFFFFFF);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return ShortArrayToString(m_ctx.m_yml, start, (end - start) + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
string CYmlNode::AtObjKeyHomgenero(const int index) const
|
|
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return "";
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
if(int(m_ctx.m_cinta[i] & 0xF) != YML_CLASIFIER_TOKEN_TYPE_OBJ)
|
|
|
|
|
return "";
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int count = int((m_ctx.m_cinta[i] >> YMLPARSER_BIT_END_TYPE) & 0xFFFFFFF);
|
|
|
|
|
if(index < 0 || index >= count)
|
|
|
|
|
return "";
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
// [obj][key][key][val][val][key][key][val][val][key][key]
|
|
|
|
|
// i = primer elemtno (en este caso key)
|
|
|
|
|
// i+3 = primer val
|
|
|
|
|
const int cur = ((i + 1) + (index * (2 + m_ctx.GetStep(i + 3)))) + 1;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int start = int(m_ctx.m_cinta[cur] >> 32);
|
|
|
|
|
const int end = int(m_ctx.m_cinta[cur] & 0xFFFFFFFF);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return ShortArrayToString(m_ctx.m_yml, start, (end - start) + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2026-04-04 20:03:17 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
CYmlNode CYmlNode::AtHomegeneo(const int index) const
|
2026-04-04 20:03:17 -05:00
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return EMPTY_YMLNODE;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
if(int(m_ctx.m_cinta[i] & 0xF) != YML_CLASIFIER_TOKEN_TYPE_ARR)
|
|
|
|
|
return EMPTY_YMLNODE;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int count = int((m_ctx.m_cinta[i] >> YMLPARSER_BIT_END_TYPE) & 0xFFFFFFF);
|
|
|
|
|
if(index < 0 || index >= count)
|
|
|
|
|
return EMPTY_YMLNODE;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
// step fijo del primer elemento
|
|
|
|
|
const int first = i + 1;
|
|
|
|
|
const int step = m_ctx.GetStep(first);
|
|
|
|
|
const int cur = first + index * step;
|
|
|
|
|
return CYmlNode(m_ctx, cur, cur + step);
|
2026-04-03 22:17:13 -05:00
|
|
|
}
|
2026-04-06 07:33:39 -05:00
|
|
|
// [obj=type arr][obj_implicito=obj][key][key][val][val][obj_implicito=obj][key][key][val][val]
|
2026-04-03 21:12:36 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-04-06 09:56:37 -05:00
|
|
|
//| Operaciones de bajo nivel mover la cinta custom |
|
2026-04-03 22:37:29 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
bool CYmlNode::MoveToNextToken(bool solo_en_el_bloque_actual = true)
|
2026-04-05 11:18:49 -05:00
|
|
|
{
|
2026-04-05 15:04:14 -05:00
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//--- Nuevas posiciones
|
|
|
|
|
const int next_pos = m_idx + m_ctx.GetStep(m_idx); // usa GetStep, no hardcodea 2
|
2026-04-05 11:18:49 -05:00
|
|
|
const int final_pos = next_pos + m_ctx.GetStep(next_pos);
|
2026-04-05 15:04:14 -05:00
|
|
|
|
|
|
|
|
//--- Check
|
|
|
|
|
if(next_pos >= (solo_en_el_bloque_actual ? m_end : m_ctx.m_cinta_pos))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
m_idx = next_pos;
|
|
|
|
|
m_end = final_pos;
|
|
|
|
|
return true;
|
2026-04-05 11:18:49 -05:00
|
|
|
}
|
|
|
|
|
|
2026-04-06 09:56:37 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CYmlNode::MoveNextPositionsThis(int posiciones, bool solo_en_el_bloque_actual = true)
|
|
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//--- Nuevas posiciones
|
|
|
|
|
const int next_pos = m_idx + posiciones; // usa GetStep, no hardcodea 2
|
|
|
|
|
// si solo nos movemos en el bloque actual el end sera el actual del bloque actual (si es que tamos)
|
|
|
|
|
// si no si es libre enotnfes al siguiente token
|
|
|
|
|
const int final_pos = solo_en_el_bloque_actual ? m_end : next_pos + m_ctx.GetStep(next_pos);
|
|
|
|
|
|
|
|
|
|
//--- Check
|
|
|
|
|
if(next_pos >= (solo_en_el_bloque_actual ? m_end : m_ctx.m_cinta_pos))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
m_idx = next_pos;
|
|
|
|
|
m_end = final_pos;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
CYmlNode CYmlNode::MoveNextPositions(int posiciones, bool solo_en_el_bloque_actual = true)
|
|
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return EMPTY_YMLNODE;
|
|
|
|
|
|
|
|
|
|
//--- Nuevas posiciones
|
|
|
|
|
const int next_pos = m_idx + posiciones; // usa GetStep, no hardcodea 2
|
|
|
|
|
const int final_pos = solo_en_el_bloque_actual ? m_end : next_pos + m_ctx.GetStep(next_pos);
|
|
|
|
|
|
|
|
|
|
//--- Check
|
|
|
|
|
if(next_pos >= (solo_en_el_bloque_actual ? m_end : m_ctx.m_cinta_pos))
|
|
|
|
|
return EMPTY_YMLNODE;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return CYmlNode(m_ctx, next_pos, final_pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2026-04-05 11:18:49 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
bool CYmlNode::AssingMqlParam(MqlParam& param) const
|
2026-04-05 11:18:49 -05:00
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int new_index = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
switch(int(m_ctx.m_cinta[new_index] & 0xF))
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_KEY:
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_STR:
|
|
|
|
|
{
|
|
|
|
|
param.type = TYPE_STRING;
|
|
|
|
|
param.string_value = ToString("");
|
2026-04-06 07:33:39 -05:00
|
|
|
return param.string_value != "";
|
2026-04-05 11:18:49 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_INTEGER:
|
|
|
|
|
{
|
|
|
|
|
param.type = TYPE_LONG;
|
2026-04-06 07:33:39 -05:00
|
|
|
return ToIntSafe(param.integer_value);
|
2026-04-05 11:18:49 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_DBL:
|
|
|
|
|
{
|
|
|
|
|
param.type = TYPE_DOUBLE;
|
2026-04-06 07:33:39 -05:00
|
|
|
return ToDoubleSafe(param.double_value);
|
2026-04-05 11:18:49 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_BOOL:
|
|
|
|
|
{
|
|
|
|
|
param.type = TYPE_BOOL;
|
|
|
|
|
bool temp;
|
2026-04-05 15:04:14 -05:00
|
|
|
if(!ToBoolSafe(temp))
|
2026-04-05 11:18:49 -05:00
|
|
|
return false;
|
|
|
|
|
param.integer_value = temp;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_NULL:
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_STR_MULTILINE:
|
|
|
|
|
{
|
|
|
|
|
param.type = TYPE_STRING;
|
|
|
|
|
param.string_value = ToString("");
|
2026-04-06 07:33:39 -05:00
|
|
|
return param.string_value != "";
|
2026-04-05 11:18:49 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_ARR:
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_OBJ:
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_REFERENCE_SIMPLE:
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_REFERENCE_COMPLEX:
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_PTR:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
ENUM_DATATYPE CYmlNode::GetTypeAsDataType(ENUM_DATATYPE def) const
|
2026-04-05 11:18:49 -05:00
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return def;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int new_index = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
switch(int(m_ctx.m_cinta[new_index] & 0xF))
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_KEY:
|
|
|
|
|
return def;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_STR:
|
|
|
|
|
return TYPE_STRING;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_INTEGER:
|
|
|
|
|
return TYPE_LONG;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_DBL:
|
|
|
|
|
return TYPE_DOUBLE;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_BOOL:
|
|
|
|
|
return TYPE_BOOL;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_NULL:
|
|
|
|
|
return def;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_STR_MULTILINE:
|
|
|
|
|
return TYPE_STRING;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_ARR:
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_OBJ:
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_REFERENCE_SIMPLE:
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_REFERENCE_COMPLEX:
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_PTR:
|
|
|
|
|
return def;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return def;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| To String |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
string CYmlNode::ToString(string def = "") const
|
2026-04-03 22:37:29 -05:00
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return def;
|
|
|
|
|
|
|
|
|
|
//---
|
2026-04-04 20:03:17 -05:00
|
|
|
const int new_index = YML_RESOLVE_PTR(m_ctx, m_idx);
|
2026-04-04 16:19:18 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
switch(int(m_ctx.m_cinta[new_index] & 0xF))
|
2026-04-03 22:37:29 -05:00
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_KEY:
|
|
|
|
|
return def;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_STR:
|
|
|
|
|
{
|
2026-04-04 16:19:18 -05:00
|
|
|
const int start = (int)(m_ctx.m_cinta[new_index + 1] >> 32);
|
|
|
|
|
const int end = (int)(m_ctx.m_cinta[new_index + 1] & 0xFFFFFFFF);
|
2026-04-06 09:56:37 -05:00
|
|
|
const bool scape = (bool)((m_ctx.m_cinta[new_index] >> YMLPARSER_BIT_END_TYPE) & 1);
|
2026-04-03 22:37:29 -05:00
|
|
|
if(scape)
|
2026-04-04 16:19:18 -05:00
|
|
|
return m_ctx.Unescape(start, end);
|
2026-04-03 22:37:29 -05:00
|
|
|
|
2026-04-04 16:19:18 -05:00
|
|
|
return ShortArrayToString(m_ctx.m_yml, start, (end - start) + 1); // raw directo
|
2026-04-03 22:37:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_INTEGER:
|
2026-04-04 16:19:18 -05:00
|
|
|
return string(m_ctx.m_cinta[new_index + 1]);
|
2026-04-03 22:37:29 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_DBL:
|
|
|
|
|
{
|
|
|
|
|
CYmlParser::LongToDbl un;
|
2026-04-04 16:19:18 -05:00
|
|
|
un.l = m_ctx.m_cinta[new_index + 1];
|
2026-04-03 22:37:29 -05:00
|
|
|
return string(un.d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_BOOL:
|
2026-04-04 16:19:18 -05:00
|
|
|
return ((m_ctx.m_cinta[new_index] >> YMLPARSER_BIT_END_TYPE) & 1) != 0 ? "true" : "false";
|
2026-04-03 22:37:29 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_NULL:
|
2026-04-04 08:07:02 -05:00
|
|
|
return def;
|
2026-04-03 22:37:29 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_STR_MULTILINE:
|
|
|
|
|
{
|
2026-04-05 22:25:16 -05:00
|
|
|
const int start = int(m_ctx.m_cinta[new_index + 1] >> 32);
|
2026-04-04 16:19:18 -05:00
|
|
|
const int end = int(m_ctx.m_cinta[new_index + 1] & 0xFFFFFFFF);
|
2026-04-05 22:25:16 -05:00
|
|
|
const int ident = int((m_ctx.m_cinta[new_index] >> YMLPARSER_BIT_END_TYPE) & 0xFFFF);
|
2026-04-04 16:19:18 -05:00
|
|
|
bool con_saltos = bool((m_ctx.m_cinta[new_index] >> 32) & 1);
|
2026-04-03 22:37:29 -05:00
|
|
|
//---
|
2026-04-04 16:19:18 -05:00
|
|
|
return m_ctx.ExtractMultiline(start, end, ident, con_saltos);
|
2026-04-03 22:37:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_ARR:
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_OBJ:
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_REFERENCE_SIMPLE:
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_REFERENCE_COMPLEX:
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_PTR:
|
|
|
|
|
return def;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return def;
|
|
|
|
|
}
|
2026-04-04 08:07:02 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 11:18:49 -05:00
|
|
|
//| To int |
|
2026-04-04 08:07:02 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
long CYmlNode::ToInt(long def) const
|
2026-04-04 08:07:02 -05:00
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return def;
|
|
|
|
|
|
2026-04-04 20:03:17 -05:00
|
|
|
//---
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
2026-04-04 16:19:18 -05:00
|
|
|
|
2026-04-04 20:03:17 -05:00
|
|
|
//---
|
2026-04-04 16:19:18 -05:00
|
|
|
switch(int(m_ctx.m_cinta[i] & 0xF))
|
2026-04-04 08:07:02 -05:00
|
|
|
{
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_INTEGER:
|
2026-04-04 16:19:18 -05:00
|
|
|
return m_ctx.m_cinta[i + 1];
|
2026-04-04 08:07:02 -05:00
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_DBL:
|
|
|
|
|
{
|
|
|
|
|
CYmlParser::LongToDbl un;
|
2026-04-04 16:19:18 -05:00
|
|
|
un.l = m_ctx.m_cinta[i + 1];
|
|
|
|
|
return long(un.d);
|
2026-04-04 08:07:02 -05:00
|
|
|
}
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_BOOL:
|
2026-04-04 16:19:18 -05:00
|
|
|
return long((m_ctx.m_cinta[i] >> YMLPARSER_BIT_END_TYPE) & 1);
|
2026-04-04 08:07:02 -05:00
|
|
|
}
|
2026-04-04 20:03:17 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return def;
|
2026-04-04 08:07:02 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
bool CYmlNode::ToIntSafe(long &val) const
|
2026-04-05 11:18:49 -05:00
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
switch(int(m_ctx.m_cinta[i] & 0xF))
|
|
|
|
|
{
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_INTEGER:
|
|
|
|
|
{
|
|
|
|
|
val = m_ctx.m_cinta[i + 1];;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_DBL:
|
|
|
|
|
{
|
|
|
|
|
CYmlParser::LongToDbl un;
|
|
|
|
|
un.l = m_ctx.m_cinta[i + 1];
|
|
|
|
|
val = long(un.d);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_BOOL:
|
|
|
|
|
val = long((m_ctx.m_cinta[i] >> YMLPARSER_BIT_END_TYPE) & 1);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| To Double |
|
2026-04-04 08:07:02 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
double CYmlNode::ToDouble(double def) const
|
2026-04-04 08:07:02 -05:00
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return def;
|
|
|
|
|
|
2026-04-04 16:19:18 -05:00
|
|
|
//---
|
2026-04-04 20:03:17 -05:00
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
2026-04-04 16:19:18 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
switch(int(m_ctx.m_cinta[i] & 0xF))
|
2026-04-04 08:07:02 -05:00
|
|
|
{
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_INTEGER:
|
2026-04-04 16:19:18 -05:00
|
|
|
return double(m_ctx.m_cinta[i + 1]);
|
2026-04-04 08:07:02 -05:00
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_DBL:
|
|
|
|
|
{
|
|
|
|
|
CYmlParser::LongToDbl un;
|
2026-04-04 16:19:18 -05:00
|
|
|
un.l = m_ctx.m_cinta[i + 1];
|
2026-04-04 08:07:02 -05:00
|
|
|
return un.d;
|
|
|
|
|
}
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_BOOL:
|
2026-04-04 16:19:18 -05:00
|
|
|
return double((m_ctx.m_cinta[i] >> YMLPARSER_BIT_END_TYPE) & 1);
|
2026-04-04 08:07:02 -05:00
|
|
|
}
|
2026-04-04 16:19:18 -05:00
|
|
|
|
|
|
|
|
//---
|
2026-04-04 08:07:02 -05:00
|
|
|
return def;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
bool CYmlNode::ToDoubleSafe(double &val) const
|
2026-04-05 11:18:49 -05:00
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
switch(int(m_ctx.m_cinta[i] & 0xF))
|
|
|
|
|
{
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_INTEGER:
|
|
|
|
|
{
|
|
|
|
|
val = double(m_ctx.m_cinta[i + 1]);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_DBL:
|
|
|
|
|
{
|
|
|
|
|
CYmlParser::LongToDbl un;
|
|
|
|
|
un.l = m_ctx.m_cinta[i + 1];
|
|
|
|
|
val = un.d;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_BOOL:
|
|
|
|
|
{
|
|
|
|
|
val = double((m_ctx.m_cinta[i] >> YMLPARSER_BIT_END_TYPE) & 1);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| To Bool |
|
2026-04-04 08:07:02 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
bool CYmlNode::ToBool(bool def) const
|
2026-04-04 08:07:02 -05:00
|
|
|
{
|
2026-04-04 16:19:18 -05:00
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return def;
|
|
|
|
|
|
|
|
|
|
//---
|
2026-04-04 20:03:17 -05:00
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
2026-04-04 16:19:18 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
switch(int(m_ctx.m_cinta[i] & 0xF))
|
|
|
|
|
{
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_INTEGER:
|
|
|
|
|
return m_ctx.m_cinta[i + 1] != 0;
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_DBL:
|
|
|
|
|
{
|
|
|
|
|
CYmlParser::LongToDbl un;
|
|
|
|
|
un.l = m_ctx.m_cinta[i + 1];
|
|
|
|
|
return un.d != 0.0;
|
|
|
|
|
}
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_BOOL:
|
|
|
|
|
return ((m_ctx.m_cinta[i] >> YMLPARSER_BIT_END_TYPE) & 1) != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return def;
|
2026-04-04 08:07:02 -05:00
|
|
|
}
|
2026-04-05 11:18:49 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
bool CYmlNode::ToBoolSafe(bool &val) const
|
2026-04-05 11:18:49 -05:00
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
switch(int(m_ctx.m_cinta[i] & 0xF))
|
|
|
|
|
{
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_INTEGER:
|
|
|
|
|
{
|
|
|
|
|
val = m_ctx.m_cinta[i + 1] != 0;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_DBL:
|
|
|
|
|
{
|
|
|
|
|
CYmlParser::LongToDbl un;
|
|
|
|
|
un.l = m_ctx.m_cinta[i + 1];
|
|
|
|
|
val = un.d != 0.0;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
case YML_CLASIFIER_TOKEN_TYPE_BOOL:
|
|
|
|
|
{
|
|
|
|
|
val = ((m_ctx.m_cinta[i] >> YMLPARSER_BIT_END_TYPE) & 1) != 0;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2026-04-04 08:07:02 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
2026-04-03 22:37:29 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 15:04:14 -05:00
|
|
|
int CYmlNode::Size() const
|
2026-04-04 16:19:18 -05:00
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
//---
|
2026-04-04 20:03:17 -05:00
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
2026-04-04 16:19:18 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int tipo = int(m_ctx.m_cinta[i] & 0xF);
|
|
|
|
|
if(tipo != YML_CLASIFIER_TOKEN_TYPE_ARR && tipo != YML_CLASIFIER_TOKEN_TYPE_OBJ)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return int((m_ctx.m_cinta[i] >> YMLPARSER_BIT_END_TYPE) & 0xFFFFFFF);
|
|
|
|
|
}
|
2026-04-04 20:03:17 -05:00
|
|
|
|
2026-04-05 11:18:49 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Is |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
__forceinline bool CYmlNode::IsValid() const { return !YML_NODE_IS_NOT_VALID; }
|
2026-04-04 20:03:17 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 11:18:49 -05:00
|
|
|
__forceinline bool CYmlNode::IsNull() const
|
|
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return true;
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
return int(m_ctx.m_cinta[i] & 0xF) == YML_CLASIFIER_TOKEN_TYPE_NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
__forceinline bool CYmlNode::IsArray() const
|
|
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return false;
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
return int(m_ctx.m_cinta[i] & 0xF) == YML_CLASIFIER_TOKEN_TYPE_ARR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
__forceinline bool CYmlNode::IsObject() const
|
|
|
|
|
{
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return false;
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
const int t = int(m_ctx.m_cinta[i] & 0xF);
|
|
|
|
|
return t == YML_CLASIFIER_TOKEN_TYPE_OBJ || t == YML_CLASIFIER_TOKEN_TYPE_REFERENCE_COMPLEX;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-06 07:49:32 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CYmlNode::SetBool(const bool val)
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
if(int(m_ctx.m_cinta[i] & 0xF) == YML_CLASIFIER_TOKEN_TYPE_BOOL)
|
|
|
|
|
{
|
|
|
|
|
m_ctx.m_cinta[i] = YML_CLASIFIER_TOKEN_TYPE_BOOL | (long(val) << YMLPARSER_BIT_END_TYPE);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CYmlNode::SetInt(const long val)
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
if(int(m_ctx.m_cinta[i] & 0xF) == YML_CLASIFIER_TOKEN_TYPE_INTEGER)
|
|
|
|
|
{
|
|
|
|
|
m_ctx.m_cinta[i + 1] = val;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
bool CYmlNode::SetDbl(const double val)
|
|
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
if(YML_NODE_IS_NOT_VALID)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
if(int(m_ctx.m_cinta[i] & 0xF) == YML_CLASIFIER_TOKEN_TYPE_DBL)
|
|
|
|
|
{
|
|
|
|
|
CYmlParser::LongToDbl un;
|
|
|
|
|
un.d = val;
|
2026-04-06 09:56:37 -05:00
|
|
|
|
2026-04-06 07:49:32 -05:00
|
|
|
m_ctx.m_cinta[i + 1] = un.l;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-05 11:18:49 -05:00
|
|
|
|
2026-04-04 20:03:17 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 11:18:49 -05:00
|
|
|
//| Iterador de arrays |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
struct CYmlIteratorObj
|
2026-04-04 20:03:17 -05:00
|
|
|
{
|
|
|
|
|
CYmlParser* m_ctx;
|
|
|
|
|
int m_cur;
|
|
|
|
|
const int m_end;
|
2026-04-05 11:18:49 -05:00
|
|
|
|
2026-04-04 20:03:17 -05:00
|
|
|
|
|
|
|
|
//---
|
2026-04-05 11:18:49 -05:00
|
|
|
CYmlIteratorObj(CYmlParser* ctx, int cur, int end)
|
|
|
|
|
: m_ctx(ctx), m_cur(cur), m_end(end)
|
2026-04-04 20:03:17 -05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
2026-04-05 11:18:49 -05:00
|
|
|
CYmlIteratorObj()
|
|
|
|
|
: m_ctx(NULL), m_cur(0), m_end(0)
|
2026-04-04 20:03:17 -05:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
__forceinline bool IsValid() { return m_cur < m_end; }
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
void Next()
|
|
|
|
|
{
|
|
|
|
|
if(m_cur >= m_end)
|
|
|
|
|
return;
|
2026-04-05 11:18:49 -05:00
|
|
|
m_cur += 2; // salta KEY
|
|
|
|
|
m_cur += m_ctx.GetStep(m_cur); // salta valor
|
2026-04-04 20:03:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
string Key()
|
|
|
|
|
{
|
2026-04-05 11:18:49 -05:00
|
|
|
if(m_cur >= m_end)
|
2026-04-04 20:03:17 -05:00
|
|
|
return "";
|
|
|
|
|
const int s = int(m_ctx.m_cinta[m_cur + 1] >> 32);
|
|
|
|
|
const int e = int(m_ctx.m_cinta[m_cur + 1] & 0xFFFFFFFF);
|
|
|
|
|
const bool scape = bool((m_ctx.m_cinta[m_cur] >> YMLPARSER_BIT_END_TYPE) & 1);
|
|
|
|
|
return scape ? m_ctx.Unescape(s, e)
|
|
|
|
|
: ShortArrayToString(m_ctx.m_yml, s, (e - s) + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
CYmlNode Val()
|
|
|
|
|
{
|
|
|
|
|
if(m_cur >= m_end)
|
|
|
|
|
return EMPTY_YMLNODE;
|
2026-04-05 11:18:49 -05:00
|
|
|
const int pos = m_cur + 2;
|
2026-04-04 20:03:17 -05:00
|
|
|
const int fin = pos + m_ctx.GetStep(pos);
|
|
|
|
|
return CYmlNode(m_ctx, pos, fin);
|
|
|
|
|
}
|
|
|
|
|
};
|
2026-04-05 11:18:49 -05:00
|
|
|
const CYmlIteratorObj EMPTY_YMLITERATOR_OBJ;
|
2026-04-04 20:03:17 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 11:18:49 -05:00
|
|
|
//| Iterador de arrays |
|
2026-04-04 20:03:17 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 11:18:49 -05:00
|
|
|
struct CYmlIteratorArray
|
2026-04-04 20:03:17 -05:00
|
|
|
{
|
2026-04-05 11:18:49 -05:00
|
|
|
CYmlParser* m_ctx;
|
|
|
|
|
int m_cur;
|
|
|
|
|
const int m_end;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
CYmlIteratorArray(CYmlParser* ctx, int cur, int end)
|
|
|
|
|
: m_ctx(ctx), m_cur(cur), m_end(end)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
CYmlIteratorArray()
|
|
|
|
|
: m_ctx(NULL), m_cur(0), m_end(0)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
__forceinline bool IsValid() { return m_cur < m_end; }
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
void Next()
|
|
|
|
|
{
|
|
|
|
|
if(m_cur >= m_end)
|
|
|
|
|
return;
|
|
|
|
|
m_cur += m_ctx.GetStep(m_cur);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
CYmlNode Val()
|
|
|
|
|
{
|
|
|
|
|
if(m_cur >= m_end)
|
|
|
|
|
return EMPTY_YMLNODE;
|
|
|
|
|
const int pos = m_cur;
|
|
|
|
|
const int fin = pos + m_ctx.GetStep(pos);
|
|
|
|
|
return CYmlNode(m_ctx, pos, fin);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const CYmlIteratorArray EMPTY_YMLITERATOR_ARR;
|
|
|
|
|
|
2026-04-04 20:03:17 -05:00
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 11:18:49 -05:00
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
CYmlIteratorArray CYmlNode::BeginArr() const
|
2026-04-04 20:03:17 -05:00
|
|
|
{
|
2026-04-05 11:18:49 -05:00
|
|
|
//---
|
2026-04-04 20:03:17 -05:00
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
2026-04-05 11:18:49 -05:00
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int tipo = int(m_ctx.m_cinta[i] & 0xF);
|
|
|
|
|
if(tipo != YML_CLASIFIER_TOKEN_TYPE_ARR)
|
|
|
|
|
return EMPTY_YMLITERATOR_ARR;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return CYmlIteratorArray(m_ctx, i + 1, m_end);
|
2026-04-04 20:03:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 11:18:49 -05:00
|
|
|
CYmlIteratorObj CYmlNode::BeginObj() const
|
2026-04-04 20:03:17 -05:00
|
|
|
{
|
|
|
|
|
//---
|
|
|
|
|
const int i = YML_RESOLVE_PTR(m_ctx, m_idx);
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
const int tipo = int(m_ctx.m_cinta[i] & 0xF);
|
2026-04-05 11:18:49 -05:00
|
|
|
if(tipo != YML_CLASIFIER_TOKEN_TYPE_OBJ)
|
|
|
|
|
return EMPTY_YMLITERATOR_OBJ;
|
|
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
return CYmlIteratorObj(m_ctx, i + 1, m_end);
|
2026-04-04 20:03:17 -05:00
|
|
|
}
|
2026-04-05 11:18:49 -05:00
|
|
|
|
2026-04-06 07:49:32 -05:00
|
|
|
|
2026-04-04 16:19:18 -05:00
|
|
|
//+------------------------------------------------------------------+
|
2026-04-05 11:18:49 -05:00
|
|
|
#endif // YMLPARSERBYLEO_SRC_YMLNODE_MQH
|