//+------------------------------------------------------------------+ //| 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 //+------------------------------------------------------------------+