2026-06-03 14:16:03 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| JsonBuilder.mqh |
|
| | | //| Copyright 2026, Niquel Mendoza. |
|
| | | //| https://www.mql5.com/ |
|
| | | //+------------------------------------------------------------------+
|
| | | #property copyright "Copyright 2026, Niquel Mendoza."
|
| | | #property link "https://www.mql5.com/"
|
| | | #property strict
|
| | |
|
| | | #ifndef JSONPARSERBYLEO_SRC_JSONBUILDER_MQH
|
| | | #define JSONPARSERBYLEO_SRC_JSONBUILDER_MQH
|
| | |
|
2026-06-30 08:24:44 -05:00 | | |
|
2026-06-03 14:16:03 -05:00 | | | //+------------------------------------------------------------------+
|
2026-06-30 08:24:44 -05:00 | | | //| |
|
2026-06-03 14:16:03 -05:00 | | | //+------------------------------------------------------------------+
|
2026-07-13 18:47:16 -05:00 | | | #include "BuilderDefs.mqh"
|
2026-06-03 14:16:03 -05:00 | | |
|
2026-06-30 08:24:44 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | namespace TSN
|
| | | {
|
2026-06-03 14:16:03 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
2026-07-13 18:47:16 -05:00 | | | class CJsonBuilder : public CJsonBuilderBase
|
2026-06-03 14:16:03 -05:00 | | | {
|
| | | public:
|
2026-07-13 18:47:16 -05:00 | | | CJsonBuilder(int initial_cap = 1024) : CJsonBuilderBase(initial_cap) {}
|
2026-06-03 14:16:03 -05:00 | | | ~CJsonBuilder() {}
|
| | |
|
| | | //--- Key / Values
|
| | | CJsonBuilder* Key(const string& k);
|
2026-07-10 07:17:28 -05:00 | | | CJsonBuilder* KeyWV(const string& k);
|
| | |
|
| | | // Valid json
|
2026-07-11 16:31:27 -05:00 | | | CJsonBuilder* ValidJson(const uchar& v[], int count = WHOLE_ARRAY);
|
2026-06-03 14:16:03 -05:00 | | | CJsonBuilder* ValidJson(const string& fragment);
|
2026-06-03 16:57:42 -05:00 | | | CJsonBuilder* ValidJsonNoRef(const string fragment);
|
2026-07-10 07:17:28 -05:00 | | |
|
| | | // String- Con validacion
|
| | | CJsonBuilder* ValS(const string& v);
|
| | | CJsonBuilder* ValU(const uchar& data[]);
|
| | | CJsonBuilder* ValSNoRef(const string v);
|
| | |
|
| | | // String- Sin validacion (witohut validation WV)
|
| | | CJsonBuilder* ValSWV(const string& v);
|
| | | CJsonBuilder* ValUWV(const uchar& data[]);
|
| | | CJsonBuilder* ValSNoRefWV(const string v);
|
| | |
|
2026-07-13 18:47:16 -05:00 | | | //--- Put encode
|
2026-07-11 16:31:27 -05:00 | | | void PutEncodedStr(const string& s);
|
| | | void PutEncodedStrU(const uchar& s[]);
|
2026-06-03 14:16:03 -05:00 | | | };
|
| | |
|
2026-07-11 16:31:27 -05:00 | | |
|
2026-06-03 14:16:03 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
2026-07-13 18:47:16 -05:00 | | | void CJsonBuilder::PutEncodedStr(const string& s)
|
2026-06-03 14:16:03 -05:00 | | | {
|
| | | const int l = StringLen(s);
|
2026-07-13 18:47:16 -05:00 | | | const int ex = 3 + (l * 6);
|
| | | JSONBUILDER_EXPAND_E(ex)
|
2026-06-03 14:16:03 -05:00 | | |
|
| | | //---
|
2026-07-13 18:47:16 -05:00 | | | m_buf[m_pos++] = '"';
|
2026-06-03 14:16:03 -05:00 | | |
|
| | | //---
|
| | | for(int i = 0; i < l; i++)
|
| | | {
|
| | | const ushort c = s[i];
|
| | |
|
2026-06-30 08:24:44 -05:00 | | | //--- Unicode > 0xFF: \uXXXX con los 4 nibbles completos
|
| | | if(c > 0xFF)
|
2026-06-03 14:16:03 -05:00 | | | {
|
2026-06-30 08:24:44 -05:00 | | | m_buf[m_pos++] = '\\';
|
| | | m_buf[m_pos++] = 'u';
|
| | | uchar t;
|
| | | t = uchar((c >> 12) & 0xF);
|
| | | m_buf[m_pos++] = (uchar)(t < 10 ? '0' + t : 'a' + t - 10);
|
| | | t = uchar((c >> 8) & 0xF);
|
| | | m_buf[m_pos++] = (uchar)(t < 10 ? '0' + t : 'a' + t - 10);
|
| | | t = uchar((c >> 4) & 0xF);
|
| | | m_buf[m_pos++] = (uchar)(t < 10 ? '0' + t : 'a' + t - 10);
|
| | | t = uchar(c & 0xF);
|
| | | m_buf[m_pos++] = (uchar)(t < 10 ? '0' + t : 'a' + t - 10);
|
2026-06-03 14:16:03 -05:00 | | | continue;
|
| | | }
|
| | |
|
2026-06-30 08:24:44 -05:00 | | | //--- 0x00–0xFF: lookup en tabla
|
2026-07-19 18:50:54 -05:00 | | | const uchar esc = g_tsn_table_json_escape_tables[c];
|
2026-06-30 08:24:44 -05:00 | | | if(esc == TSN_TABLE_ESCAPE_PASSTHROUGH)
|
2026-06-03 14:16:03 -05:00 | | | {
|
| | | m_buf[m_pos++] = (uchar)c;
|
| | | }
|
| | | else
|
2026-06-30 08:24:44 -05:00 | | | if(esc == TSN_TABLE_ESCAPE_UNICODE)
|
2026-06-03 14:16:03 -05:00 | | | {
|
2026-06-30 08:24:44 -05:00 | | | m_buf[m_pos++] = '\\';
|
| | | m_buf[m_pos++] = 'u';
|
| | | m_buf[m_pos++] = '0';
|
| | | m_buf[m_pos++] = '0';
|
| | | uchar t;
|
| | | t = uchar((c >> 4) & 0xF);
|
| | | m_buf[m_pos++] = (uchar)(t < 10 ? '0' + t : 'a' + t - 10);
|
| | | t = uchar(c & 0xF);
|
| | | m_buf[m_pos++] = (uchar)(t < 10 ? '0' + t : 'a' + t - 10);
|
| | | }
|
| | | else
|
| | | {
|
| | | //--- letra dedicada: \n \t \\ \" etc.
|
2026-06-03 14:16:03 -05:00 | | | m_buf[m_pos++] = '\\';
|
2026-06-30 08:24:44 -05:00 | | | m_buf[m_pos++] = esc;
|
2026-06-03 14:16:03 -05:00 | | | }
|
2026-06-30 08:24:44 -05:00 | | | }
|
2026-07-13 18:47:16 -05:00 | | | m_buf[m_pos++] = '"';
|
2026-06-30 08:24:44 -05:00 | | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | void CJsonBuilder::PutEncodedStrU(const uchar& s[])
|
| | | {
|
2026-07-11 16:31:27 -05:00 | | | //---
|
2026-07-13 18:47:16 -05:00 | | | const int l = ArraySize(s);
|
| | | const int ex = 3 + (l * 6);
|
| | | JSONBUILDER_EXPAND_E(ex)
|
| | |
|
| | | //---
|
| | | m_buf[m_pos++] = '"';
|
2026-06-30 08:24:44 -05:00 | | |
|
2026-07-11 16:31:27 -05:00 | | | //---
|
2026-06-30 08:24:44 -05:00 | | | for(int i = 0; i < l; i++)
|
| | | {
|
| | | const uchar c = s[i];
|
2026-07-19 18:50:54 -05:00 | | | const uchar esc = g_tsn_table_json_escape_tables[c];
|
2026-06-30 08:24:44 -05:00 | | | if(esc == TSN_TABLE_ESCAPE_PASSTHROUGH)
|
| | | {
|
| | | m_buf[m_pos++] = c;
|
| | | }
|
| | | else
|
| | | if(esc == TSN_TABLE_ESCAPE_UNICODE)
|
2026-06-03 14:16:03 -05:00 | | | {
|
| | | m_buf[m_pos++] = '\\';
|
| | | m_buf[m_pos++] = 'u';
|
| | | m_buf[m_pos++] = '0';
|
| | | m_buf[m_pos++] = '0';
|
2026-06-30 08:24:44 -05:00 | | | uchar t;
|
| | | t = uchar((c >> 4) & 0xF);
|
2026-06-03 14:16:03 -05:00 | | | m_buf[m_pos++] = (uchar)(t < 10 ? '0' + t : 'a' + t - 10);
|
| | | t = uchar(c & 0xF);
|
| | | m_buf[m_pos++] = (uchar)(t < 10 ? '0' + t : 'a' + t - 10);
|
| | | }
|
2026-06-30 08:24:44 -05:00 | | | else
|
| | | {
|
| | | m_buf[m_pos++] = '\\';
|
| | | m_buf[m_pos++] = esc;
|
| | | }
|
2026-06-03 14:16:03 -05:00 | | | }
|
| | |
|
2026-07-13 18:47:16 -05:00 | | | //---
|
| | | m_buf[m_pos++] = '"';
|
2026-06-03 14:16:03 -05:00 | | | }
|
| | |
|
2026-07-11 16:31:27 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
2026-06-03 14:16:03 -05:00 | | | //+------------------------------------------------------------------+
|
| | | CJsonBuilder* CJsonBuilder::Key(const string& k)
|
| | | {
|
| | | JSON_BUILDER_COMMA
|
| | | PutEncodedStr(k);
|
| | | JSON_BUILDER_PUT(':')
|
| | | m_stack_first[m_sp] = true;
|
| | | return &this;
|
2026-06-30 08:24:44 -05:00 | | | }
|
| | |
|
2026-07-11 16:31:27 -05:00 | | | //+------------------------------------------------------------------+
|
| | | CJsonBuilder* CJsonBuilder::KeyWV(const string &k)
|
| | | {
|
| | | //---
|
| | | JSON_BUILDER_COMMA
|
| | | JSON_BUILDER_PUT('"')
|
| | | PutRaw(k);
|
| | | JSON_BUILDER_PUT('"')
|
| | | JSON_BUILDER_PUT(':')
|
| | |
|
| | | //---
|
| | | m_stack_first[m_sp] = true;
|
| | | return &this;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
2026-06-30 08:24:44 -05:00 | | | //+------------------------------------------------------------------+
|
| | | CJsonBuilder* CJsonBuilder::ValU(const uchar &data[])
|
| | | {
|
| | | JSON_BUILDER_COMMA
|
| | | PutEncodedStrU(data);
|
| | | return &this;
|
2026-06-03 14:16:03 -05:00 | | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | CJsonBuilder* CJsonBuilder::ValS(const string& v)
|
| | | {
|
| | | JSON_BUILDER_COMMA
|
| | | PutEncodedStr(v);
|
| | | return &this;
|
| | | }
|
| | |
|
2026-06-03 22:08:03 -05:00 | | | //+------------------------------------------------------------------+
|
| | | CJsonBuilder* CJsonBuilder::ValSNoRef(const string v)
|
| | | {
|
| | | JSON_BUILDER_COMMA
|
| | | PutEncodedStr(v);
|
| | | return &this;
|
| | | }
|
| | |
|
2026-07-11 16:31:27 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | CJsonBuilder* CJsonBuilder::ValSWV(const string& v)
|
| | | {
|
| | | JSON_BUILDER_COMMA
|
| | | JSON_BUILDER_PUT('"')
|
| | | PutRaw(v);
|
| | | JSON_BUILDER_PUT('"')
|
| | | return &this;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | CJsonBuilder* CJsonBuilder::ValSNoRefWV(const string v)
|
| | | {
|
| | | JSON_BUILDER_COMMA
|
| | | JSON_BUILDER_PUT('"')
|
| | | PutRawNoRef(v);
|
| | | JSON_BUILDER_PUT('"')
|
| | | return &this;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | CJsonBuilder* CJsonBuilder::ValUWV(const uchar &data[])
|
| | | {
|
| | | JSON_BUILDER_COMMA
|
| | | JSON_BUILDER_PUT('"')
|
| | | PutRaw(data);
|
| | | JSON_BUILDER_PUT('"')
|
| | | return &this;
|
| | | }
|
| | |
|
2026-06-03 14:16:03 -05:00 | | |
|
2026-06-03 18:53:05 -05:00 | | |
|
| | | //+------------------------------------------------------------------+
|
2026-07-11 16:31:27 -05:00 | | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | CJsonBuilder* CJsonBuilder::ValidJson(const uchar& v[], int count = WHOLE_ARRAY)
|
2026-06-03 18:53:05 -05:00 | | | {
|
| | | JSON_BUILDER_COMMA
|
2026-07-11 16:31:27 -05:00 | | | PutRaw(v, count);
|
2026-06-03 18:53:05 -05:00 | | | return &this;
|
| | | }
|
| | |
|
2026-06-03 14:16:03 -05:00 | | | //+------------------------------------------------------------------+
|
| | | CJsonBuilder* CJsonBuilder::ValidJson(const string& fragment)
|
| | | {
|
| | | JSON_BUILDER_COMMA
|
| | | PutRaw(fragment);
|
| | | return &this;
|
| | | }
|
| | |
|
2026-06-03 16:57:42 -05:00 | | | //+------------------------------------------------------------------+
|
| | | CJsonBuilder* CJsonBuilder::ValidJsonNoRef(const string fragment)
|
| | | {
|
| | | JSON_BUILDER_COMMA
|
| | | PutRaw(fragment);
|
| | | return &this;
|
| | | }
|
| | |
|
| | | //---
|
| | | CJsonBuilder g_json_builder;
|
2026-06-03 14:16:03 -05:00 | | | } // namespace TSN
|
| | | //+------------------------------------------------------------------+
|
| | | #endif // JSONPARSERBYLEO_SRC_JSONBUILDER_MQH
|