282 lines
8 KiB
MQL5
282 lines
8 KiB
MQL5
//+------------------------------------------------------------------+
| |
//| 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
|