| //+------------------------------------------------------------------+
|
| //| 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
|
|
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| #include "BuilderDefs.mqh"
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| namespace TSN
|
| {
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| class CJsonBuilder : public CJsonBuilderBase
|
| {
|
| public:
|
| CJsonBuilder(int initial_cap = 1024) : CJsonBuilderBase(initial_cap) {}
|
| ~CJsonBuilder() {}
|
|
|
| //--- Key / Values
|
| CJsonBuilder* Key(const string& k);
|
| CJsonBuilder* KeyWV(const string& k);
|
|
|
| // Valid json
|
| CJsonBuilder* ValidJson(const uchar& v[], int count = WHOLE_ARRAY);
|
| CJsonBuilder* ValidJson(const string& fragment);
|
| CJsonBuilder* ValidJsonNoRef(const string fragment);
|
|
|
| // 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);
|
|
|
| //--- Put encode
|
| void PutEncodedStr(const string& s);
|
| void PutEncodedStrU(const uchar& s[]);
|
| };
|
|
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| void CJsonBuilder::PutEncodedStr(const string& s)
|
| {
|
| const int l = StringLen(s);
|
| const int ex = 3 + (l * 6);
|
| JSONBUILDER_EXPAND_E(ex)
|
|
|
| //---
|
| m_buf[m_pos++] = '"';
|
|
|
| //---
|
| for(int i = 0; i < l; i++)
|
| {
|
| const ushort c = s[i];
|
|
|
| //--- Unicode > 0xFF: \uXXXX con los 4 nibbles completos
|
| if(c > 0xFF)
|
| {
|
| 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);
|
| continue;
|
| }
|
|
|
| //--- 0x00–0xFF: lookup en tabla
|
| const uchar esc = g_tsn_table_json_escape_tables[c];
|
| if(esc == TSN_TABLE_ESCAPE_PASSTHROUGH)
|
| {
|
| m_buf[m_pos++] = (uchar)c;
|
| }
|
| else
|
| if(esc == TSN_TABLE_ESCAPE_UNICODE)
|
| {
|
| 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.
|
| m_buf[m_pos++] = '\\';
|
| m_buf[m_pos++] = esc;
|
| }
|
| }
|
| m_buf[m_pos++] = '"';
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| void CJsonBuilder::PutEncodedStrU(const uchar& s[])
|
| {
|
| //---
|
| const int l = ArraySize(s);
|
| const int ex = 3 + (l * 6);
|
| JSONBUILDER_EXPAND_E(ex)
|
|
|
| //---
|
| m_buf[m_pos++] = '"';
|
|
|
| //---
|
| for(int i = 0; i < l; i++)
|
| {
|
| const uchar c = s[i];
|
| const uchar esc = g_tsn_table_json_escape_tables[c];
|
| if(esc == TSN_TABLE_ESCAPE_PASSTHROUGH)
|
| {
|
| m_buf[m_pos++] = c;
|
| }
|
| else
|
| if(esc == TSN_TABLE_ESCAPE_UNICODE)
|
| {
|
| 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
|
| {
|
| m_buf[m_pos++] = '\\';
|
| m_buf[m_pos++] = esc;
|
| }
|
| }
|
|
|
| //---
|
| m_buf[m_pos++] = '"';
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| CJsonBuilder* CJsonBuilder::Key(const string& k)
|
| {
|
| JSON_BUILDER_COMMA
|
| PutEncodedStr(k);
|
| JSON_BUILDER_PUT(':')
|
| m_stack_first[m_sp] = true;
|
| return &this;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| 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;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| CJsonBuilder* CJsonBuilder::ValU(const uchar &data[])
|
| {
|
| JSON_BUILDER_COMMA
|
| PutEncodedStrU(data);
|
| return &this;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| CJsonBuilder* CJsonBuilder::ValS(const string& v)
|
| {
|
| JSON_BUILDER_COMMA
|
| PutEncodedStr(v);
|
| return &this;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| CJsonBuilder* CJsonBuilder::ValSNoRef(const string v)
|
| {
|
| JSON_BUILDER_COMMA
|
| PutEncodedStr(v);
|
| return &this;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| 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;
|
| }
|
|
|
|
|
|
|
| //+------------------------------------------------------------------+
|
| //| |
|
| //+------------------------------------------------------------------+
|
| CJsonBuilder* CJsonBuilder::ValidJson(const uchar& v[], int count = WHOLE_ARRAY)
|
| {
|
| JSON_BUILDER_COMMA
|
| PutRaw(v, count);
|
| return &this;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| CJsonBuilder* CJsonBuilder::ValidJson(const string& fragment)
|
| {
|
| JSON_BUILDER_COMMA
|
| PutRaw(fragment);
|
| return &this;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| CJsonBuilder* CJsonBuilder::ValidJsonNoRef(const string fragment)
|
| {
|
| JSON_BUILDER_COMMA
|
| PutRaw(fragment);
|
| return &this;
|
| }
|
|
|
| //---
|
| CJsonBuilder g_json_builder;
|
| } // namespace TSN
|
| //+------------------------------------------------------------------+
|
| #endif // JSONPARSERBYLEO_SRC_JSONBUILDER_MQH
|