JsonParserByLeo/Src/JsonStrBuilder.mqh
2026-07-19 18:50:54 -05:00

316 行
8.9 KiB
MQL5

//+------------------------------------------------------------------+
//| JsonStrBuilder.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_JSONSTRBUILDER_MQH
#define JSONPARSERBYLEO_SRC_JSONSTRBUILDER_MQH
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
#include "BuilderDefs.mqh"
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
namespace TSN
{
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CJsonBuilderStr : public CJsonBuilderBase
{
private:
void PutEncodedStr(const string& s);
void PutEncodedStrU(const uchar& s[]);
public:
CJsonBuilderStr(int initial_cap = 1024): CJsonBuilderBase(initial_cap) {}
~CJsonBuilderStr() {}
//--- Key / Values
CJsonBuilderStr* Key(const string& k);
CJsonBuilderStr* KeyWV(const string& k);
// Valid json
// CJsonBuilderStr* ValidJson(const uchar& v[], int count = WHOLE_ARRAY);
// CJsonBuilderStr* ValidJson(const string& fragment);
// CJsonBuilderStr* ValidJsonNoRef(const string fragment);
// String- Con validacion
CJsonBuilderStr* ValS(const string& v);
CJsonBuilderStr* ValU(const uchar& data[]);
CJsonBuilderStr* ValSNoRef(const string v);
// String- Sin validacion (witohut validation WV)
CJsonBuilderStr* ValSWV(const string& v);
CJsonBuilderStr* ValUWV(const uchar& data[]);
CJsonBuilderStr* ValSNoRefWV(const string v);
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CJsonBuilderStr::PutEncodedStr(const string& s)
{
//---
const int l = StringLen(s);
const int ex = 5 + (l << 3); // peor caso todos unicode \uXXXX
// 2 + 2 + len * 7
JSONBUILDER_EXPAND_E(ex)
m_buf[m_pos++] = '\\';
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++] = '\\';
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++] = '\\';
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++] = '\\';
if(esc == '\\' || esc == '"')
m_buf[m_pos++] = '\\';
m_buf[m_pos++] = esc;
}
}
m_buf[m_pos++] = '\\';
m_buf[m_pos++] = '"';
}
// \\n
//
//
//+------------------------------------------------------------------+
void CJsonBuilderStr::PutEncodedStrU(const uchar& s[])
{
//---
const int l = ArraySize(s);
const int ex = 5 + (l << 3);
JSONBUILDER_EXPAND_E(ex)
//---
m_buf[m_pos++] = '\\';
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++] = '\\';
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++] = '\\';
if(esc == '\\' || esc == '"')
m_buf[m_pos++] = '\\';
m_buf[m_pos++] = esc;
}
}
//---
m_buf[m_pos++] = '\\';
m_buf[m_pos++] = '"';
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CJsonBuilderStr* CJsonBuilderStr::Key(const string& k)
{
JSON_BUILDER_COMMA
PutEncodedStr(k);
JSON_BUILDER_PUT(':')
m_stack_first[m_sp] = true;
return &this;
}
//+------------------------------------------------------------------+
CJsonBuilderStr* CJsonBuilderStr::KeyWV(const string &k)
{
//---
JSON_BUILDER_COMMA
JSONBUILDER_EXPAND(2)
m_buf[m_pos++] = '\\';
m_buf[m_pos++] = '"';
PutRaw(k);
JSONBUILDER_EXPAND(2)
m_buf[m_pos++] = '\\';
m_buf[m_pos++] = '"';
JSON_BUILDER_PUT(':')
//---
m_stack_first[m_sp] = true;
return &this;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CJsonBuilderStr* CJsonBuilderStr::ValU(const uchar &data[])
{
JSON_BUILDER_COMMA
PutEncodedStrU(data);
return &this;
}
//+------------------------------------------------------------------+
CJsonBuilderStr* CJsonBuilderStr::ValS(const string& v)
{
JSON_BUILDER_COMMA
PutEncodedStr(v);
return &this;
}
//+------------------------------------------------------------------+
CJsonBuilderStr* CJsonBuilderStr::ValSNoRef(const string v)
{
JSON_BUILDER_COMMA
PutEncodedStr(v);
return &this;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CJsonBuilderStr* CJsonBuilderStr::ValSWV(const string& v)
{
JSON_BUILDER_COMMA
JSONBUILDER_EXPAND(2)
m_buf[m_pos++] = '\\';
m_buf[m_pos++] = '"';
PutRaw(v);
JSONBUILDER_EXPAND(2)
m_buf[m_pos++] = '\\';
m_buf[m_pos++] = '"';
return &this;
}
//+------------------------------------------------------------------+
CJsonBuilderStr* CJsonBuilderStr::ValSNoRefWV(const string v)
{
JSON_BUILDER_COMMA
JSONBUILDER_EXPAND(2)
m_buf[m_pos++] = '\\';
m_buf[m_pos++] = '"';
PutRawNoRef(v);
JSONBUILDER_EXPAND(2)
m_buf[m_pos++] = '\\';
m_buf[m_pos++] = '"';
return &this;
}
//+------------------------------------------------------------------+
CJsonBuilderStr* CJsonBuilderStr::ValUWV(const uchar &data[])
{
JSON_BUILDER_COMMA
JSONBUILDER_EXPAND(2)
m_buf[m_pos++] = '\\';
m_buf[m_pos++] = '"';
PutRaw(data);
JSONBUILDER_EXPAND(2)
m_buf[m_pos++] = '\\';
m_buf[m_pos++] = '"';
return &this;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
/*CJsonBuilderStr* CJsonBuilderStr::ValidJson(const uchar& v[], int count = WHOLE_ARRAY)
{
JSON_BUILDER_COMMA
PutRaw(v, count);
return &this;
}
//+------------------------------------------------------------------+
CJsonBuilderStr* CJsonBuilderStr::ValidJson(const string& fragment)
{
JSON_BUILDER_COMMA
PutRaw(fragment);
return &this;
}
//+------------------------------------------------------------------+
CJsonBuilderStr* CJsonBuilderStr::ValidJsonNoRef(const string fragment)
{
JSON_BUILDER_COMMA
PutRaw(fragment);
return &this;
}
*/
//--- end namespace
}
#endif // JSONPARSERBYLEO_SRC_JSONSTRBUILDER_MQH
//+------------------------------------------------------------------+