JsonParserByLeo/Src/DOM/JsonDomSerializer.mqh

297 lines
8.6 KiB
MQL5

//+------------------------------------------------------------------+
2026-07-19 15:56:41 -05:00
//| JsonDomSerializer.mqh |
//| Copyright 2026, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
2026-10-08 13:39:44 -05:00
#property copyright "Copyright 2026, Niquel Mendoza."
2026-07-19 15:56:41 -05:00
#property link "https://www.mql5.com"
#property strict
2026-10-08 13:39:44 -05:00
#ifndef JSONPARSERBYLEO_SRC_DOM_JSONDOMSERIALIZER_MQH
#define JSONPARSERBYLEO_SRC_DOM_JSONDOMSERIALIZER_MQH
2026-07-19 18:32:50 -05:00
2026-07-19 15:56:41 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-10-08 13:39:44 -05:00
#include "..\\Ser\\JsonEscape.mqh"
2026-07-19 15:56:41 -05:00
2026-07-19 18:32:50 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-19 15:56:41 -05:00
namespace TSN
{
2026-10-08 21:07:14 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#define JSDOMBASE_DOMSER_EMPTY (TSN_SBL_BASE_DOM_NULL+1)
2026-07-19 15:56:41 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-20 09:30:41 -05:00
class CJsonDomSerializer
2026-07-19 15:56:41 -05:00
{
2026-07-19 18:32:50 -05:00
public:
//---
uchar m_buf[];
int m_buf_s;
int m_buf_r;
2026-07-19 15:56:41 -05:00
private:
2026-09-19 22:46:26 -05:00
//---
uchar m_dbl_reserve;
uchar m_digits;
2026-07-19 18:32:50 -05:00
//-- stacks
CHashMapFastIterator(string, CDomNodeBase*) m_stack_it_obj[JSONPARSERBYLEO_MAX_STACK];
int m_stack_count[JSONPARSERBYLEO_MAX_STACK];
int m_stack_ix[JSONPARSERBYLEO_MAX_STACK];
int m_stack_k[JSONPARSERBYLEO_MAX_STACK];
2026-07-19 18:32:50 -05:00
int m_stack_it_obj_curr;
2026-07-19 15:56:41 -05:00
public:
2026-07-20 09:30:41 -05:00
CJsonDomSerializer(void);
~CJsonDomSerializer(void) {}
2026-07-19 15:56:41 -05:00
2026-09-19 22:46:26 -05:00
//---
void Digitos(uchar v);
__forceinline uchar Digitos() const { return m_digits; }
2026-07-19 15:56:41 -05:00
//---
bool Serialize(CDomNodeBase* v);
};
2026-07-19 18:32:50 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-20 09:30:41 -05:00
CJsonDomSerializer::CJsonDomSerializer()
2026-09-19 22:46:26 -05:00
: m_buf_s(0), m_buf_r(4096), m_dbl_reserve(MQLARTICLES_CONV_MAXDIG_DBL(8)), m_digits(8), m_stack_it_obj_curr(0)
2026-07-19 15:56:41 -05:00
{
2026-07-19 18:32:50 -05:00
ArrayResize(m_buf, m_buf_r, m_buf_r);
}
2026-09-19 22:46:26 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#define DOMMANAGERCHEKCAP_JSON(N) \
if(m_buf_s + (N) >= m_buf_r) \
{ \
2026-10-03 17:00:34 -05:00
m_buf_r = (m_buf_s + (N)) << 1; \
2026-09-19 22:46:26 -05:00
ArrayResize(m_buf, m_buf_r, m_buf_r); \
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CJsonDomSerializer::Digitos(uchar v)
{
m_digits = v;
m_dbl_reserve = MQLARTICLES_CONV_MAXDIG_DBL(v);
}
2026-07-19 18:32:50 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-07-20 09:30:41 -05:00
bool CJsonDomSerializer::Serialize(CDomNodeBase* v)
2026-07-19 18:32:50 -05:00
{
//---
2026-09-19 22:46:26 -05:00
uchar next = v.m_type;
2026-07-20 09:30:41 -05:00
m_stack_it_obj_curr = -1;
2026-07-19 19:15:32 -05:00
m_buf_s = 0;
2026-07-19 18:32:50 -05:00
//---
while(true)
{
switch(next)
2026-07-19 15:56:41 -05:00
{
2026-10-08 13:39:44 -05:00
// case 0: nuevas updates esto ya no existe no hay el tipo key este diremctne vive en el hashmap
// break; // Sale noma..
case TSN_SBL_BASE_TYPE_ARR:
2026-07-19 18:32:50 -05:00
{
//---
2026-07-20 09:30:41 -05:00
m_stack_it_obj_curr++;
2026-10-08 13:39:44 -05:00
m_stack_ix[m_stack_it_obj_curr] = v.m_v.ix;
m_stack_count[m_stack_it_obj_curr] = v.Size();
2026-07-19 18:32:50 -05:00
m_stack_k[m_stack_it_obj_curr] = 0;
//---
DOMMANAGERCHEKCAP_JSON(1)
2026-10-08 13:39:44 -05:00
m_buf[m_buf_s++] = '[';
2026-07-19 18:32:50 -05:00
break;
}
2026-10-08 13:39:44 -05:00
case TSN_SBL_BASE_TYPE_OBJ:
2026-07-19 18:32:50 -05:00
{
//---
2026-07-20 09:30:41 -05:00
m_stack_it_obj_curr++;
2026-10-08 13:39:44 -05:00
m_stack_it_obj[m_stack_it_obj_curr] = v.HashMap().BeginIteration();
m_stack_ix[m_stack_it_obj_curr] = -1; // no usar
2026-07-19 18:32:50 -05:00
m_stack_k[m_stack_it_obj_curr] = 0;
//---
DOMMANAGERCHEKCAP_JSON(1)
2026-10-08 13:39:44 -05:00
m_buf[m_buf_s++] = '{';
2026-07-19 18:32:50 -05:00
break;
}
2026-09-30 07:39:54 -05:00
case TSN_SBL_BASE_TYPE_UINT:
{
//---
DOMMANAGERCHEKCAP_JSON(MQLARTICLES_CONV_MAXDIG_UL)
STRCONV_VALTOBUFFER_USIGNED(v.m_v.uv, m_buf, m_buf_s)
//---
break;
}
2026-07-19 18:32:50 -05:00
case TSN_SBL_BASE_TYPE_INT:
{
//---
2026-09-19 22:46:26 -05:00
DOMMANAGERCHEKCAP_JSON(MQLARTICLES_CONV_MAXDIG_L)
2026-09-21 12:52:37 -05:00
STRCONV_VALTOBUFFER_SIGNED(v.m_v.iv, m_buf, m_buf_s, ulong, uvalue)
2026-09-30 07:39:54 -05:00
2026-07-19 18:32:50 -05:00
//---
break;
}
case TSN_SBL_BASE_TYPE_FLT:
{
//---
2026-09-19 22:46:26 -05:00
DOMMANAGERCHEKCAP_JSON(m_dbl_reserve)
//---
if(!MathIsValidNumber(v.m_v.dv))
2026-07-19 18:32:50 -05:00
{
m_buf[m_buf_s++] = 'n';
m_buf[m_buf_s++] = 'u';
m_buf[m_buf_s++] = 'l';
m_buf[m_buf_s++] = 'l';
break; // Salimos..
}
//---
2026-09-19 22:46:26 -05:00
CValueToBuffer::ToValue(v.m_v.dv, m_buf, m_buf_s, m_digits);
2026-07-19 18:32:50 -05:00
//---
break;
}
case TSN_SBL_BASE_TYPE_BOL:
{
DOMMANAGERCHEKCAP_JSON(7)
if(v.m_v.bv)
{
m_buf[m_buf_s++] = 't';
m_buf[m_buf_s++] = 'r';
m_buf[m_buf_s++] = 'u';
m_buf[m_buf_s++] = 'e';
}
else
{
m_buf[m_buf_s++] = 'f';
m_buf[m_buf_s++] = 'a';
m_buf[m_buf_s++] = 'l';
m_buf[m_buf_s++] = 's';
m_buf[m_buf_s++] = 'e';
}
break;
}
case TSN_SBL_BASE_TYPE_STR:
{
//---
const int i = v.m_v.ix;
2026-07-20 09:30:41 -05:00
const int l = StringLen(v.m_ctx.m_string_stack[i]);
2026-09-20 11:21:36 -05:00
const int r = JSONESCAPE_CR_ENCODE(l) + 2;
2026-07-19 18:32:50 -05:00
DOMMANAGERCHEKCAP_JSON(r)
//---
m_buf[m_buf_s++] = '"';
2026-10-13 21:28:39 -05:00
CJsonEscape::Encode(v.m_ctx.m_string_stack[i], 0, l, m_buf, m_buf_s);
2026-07-19 18:32:50 -05:00
m_buf[m_buf_s++] = '"';
//---
break;
}
case TSN_SBL_BASE_DOM_NULL:
{
DOMMANAGERCHEKCAP_JSON(6)
m_buf[m_buf_s++] = 'n';
m_buf[m_buf_s++] = 'u';
m_buf[m_buf_s++] = 'l';
m_buf[m_buf_s++] = 'l';
break;
}
2026-10-08 21:07:14 -05:00
case JSDOMBASE_DOMSER_EMPTY:
break;
2026-07-19 18:32:50 -05:00
default:
return false;
2026-07-19 15:56:41 -05:00
}
2026-07-19 18:32:50 -05:00
//----
2026-07-20 09:30:41 -05:00
if(m_stack_ix[m_stack_it_obj_curr] == -1)
2026-07-19 15:56:41 -05:00
{
2026-07-19 18:32:50 -05:00
if(m_stack_it_obj[m_stack_it_obj_curr].IsValid())
{
if(m_stack_k[m_stack_it_obj_curr] > 0)
m_buf[m_buf_s++] = ',';
//--- Key
2026-07-23 16:13:49 -05:00
static string out;
m_stack_it_obj[m_stack_it_obj_curr].Key(out);
//---
const int l = StringLen(out);
2026-09-20 11:21:36 -05:00
const int r = JSONESCAPE_CR_ENCODE(l) + 3;
2026-07-19 18:32:50 -05:00
DOMMANAGERCHEKCAP_JSON(r)
//--- Escape
m_buf[m_buf_s++] = '"';
2026-10-13 21:28:39 -05:00
CJsonEscape::Encode(out, 0, l, m_buf, m_buf_s);
2026-07-19 18:32:50 -05:00
m_buf[m_buf_s++] = '"';
m_buf[m_buf_s++] = ':';
//--- Value
v = m_stack_it_obj[m_stack_it_obj_curr].Val(); // assing..
m_stack_it_obj[m_stack_it_obj_curr].Next();
next = v.m_type;
2026-07-19 15:56:41 -05:00
2026-07-19 18:32:50 -05:00
//---
m_stack_k[m_stack_it_obj_curr]++;
continue;
}
2026-09-20 11:21:36 -05:00
//---
2026-07-19 18:32:50 -05:00
// Ya no..
DOMMANAGERCHEKCAP_JSON(2)
m_buf[m_buf_s++] = '}';
2026-07-19 15:56:41 -05:00
}
2026-07-19 18:32:50 -05:00
else
2026-07-19 15:56:41 -05:00
{
2026-07-19 18:32:50 -05:00
if(m_stack_k[m_stack_it_obj_curr] < m_stack_count[m_stack_it_obj_curr])
{
//---
if(m_stack_k[m_stack_it_obj_curr] > 0)
m_buf[m_buf_s++] = ',';
2026-07-19 15:56:41 -05:00
2026-07-19 18:32:50 -05:00
//--- Avanzamos..
2026-07-20 09:30:41 -05:00
v = v.m_ctx.m_node[m_stack_ix[m_stack_it_obj_curr]].values[m_stack_k[m_stack_it_obj_curr]++]; // assing..
2026-07-19 18:32:50 -05:00
next = v.m_type;
continue;
}
2026-09-20 11:21:36 -05:00
//---
2026-07-19 18:32:50 -05:00
// Ya no ...
DOMMANAGERCHEKCAP_JSON(2)
m_buf[m_buf_s++] = ']';
2026-07-19 15:56:41 -05:00
}
2026-07-19 18:32:50 -05:00
//---
2026-07-20 09:30:41 -05:00
m_stack_it_obj_curr--; // Baja
if(m_stack_it_obj_curr < 0)
2026-07-19 18:32:50 -05:00
return true;
//---
2026-10-08 21:07:14 -05:00
next = JSDOMBASE_DOMSER_EMPTY; // break y vuleve a evaluar denbuvo...
2026-07-19 15:56:41 -05:00
}
2026-07-19 18:32:50 -05:00
//---
return false;
2026-07-19 15:56:41 -05:00
}
}
//+------------------------------------------------------------------+
2026-10-08 13:39:44 -05:00
#endif // JSONPARSERBYLEO_SRC_DOM_JSONDOMSERIALIZER_MQH