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
|
|
|
|
|
const uchar esc = g_tsn_table_escape_tables[c];
|
|
|
|
|
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];
|
|
|
|
|
const uchar esc = g_tsn_table_escape_tables[c];
|
|
|
|
|
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
|