2026-08-27 13:56:43 -05:00 | | | //+------------------------------------------------------------------+
|
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
|
2026-08-27 13:56:43 -05:00 | | | 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
|