//+------------------------------------------------------------------+ //| 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 { //+------------------------------------------------------------------+ //| Macros | //+------------------------------------------------------------------+ #define JSONBUILDER_CHECK_PUT_ENCODE_STR(str, needed) \ const int l = StringLen(str); \ const int ex = JSONESCAPE_CR_ENCODE(l) + (needed); \ JSONBUILDER_EXPAND_E(ex) //+------------------------------------------------------------------+ #define JSONBUILDER_CHECK_PUT_ENCODE_STRU(arr, needed) \ const int l = ArraySize(arr); \ const int ex = JSONESCAPE_CR_ENCODE(l) + (needed); \ JSONBUILDER_EXPAND_E(ex) //+------------------------------------------------------------------+ #define JSONBUILDER_GENERIC_VALS \ JSON_BUILDER_COMMA_F \ m_buf[m_pos++] = '"'; \ CJsonEscape::Encode(v, l, m_buf, m_pos); \ m_buf[m_pos++] = '"'; \ //+------------------------------------------------------------------+ #define JSONBUILDER_GENERIC_VALSTR_WVER \ JSONBUILDER_EXPAND_E(2) \ JSON_BUILDER_COMMA_F \ m_buf[m_pos++] = '"'; \ PutRaw(v); \ JSONBUILDER_EXPAND_E(1) \ m_buf[m_pos++] = '"'; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ 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); // String- Con validacion CJsonBuilder* ValS(const string& v); CJsonBuilder* ValU(const uchar& v[]); CJsonBuilder* ValSNoRef(const string v); // String- Sin validacion (witohut validation WV) CJsonBuilder* ValSWV(const string& v); CJsonBuilder* ValUWV(const uchar& v[], int count = WHOLE_ARRAY); // buffer fijo sobredimensionado (ej. CStringFixed): solo copia count bytes CJsonBuilder* ValSNoRefWV(const string v); // Valid json CJsonBuilder* ValidJson(const uchar& v[], int count = WHOLE_ARRAY); CJsonBuilder* ValidJson(const string& fragment); CJsonBuilder* ValidJsonNoRef(const string fragment); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CJsonBuilder* CJsonBuilder::Key(const string& k) { //--- JSONBUILDER_CHECK_PUT_ENCODE_STR(k, 4) //--- JSON_BUILDER_COMMA_F m_buf[m_pos++] = '"'; CJsonEscape::Encode(k, l, m_buf, m_pos); m_buf[m_pos++] = '"'; m_buf[m_pos++] = ':'; //--- m_stack_first[m_sp] = true; return &this; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CJsonBuilder* CJsonBuilder::ValU(const uchar &v[]) { JSONBUILDER_CHECK_PUT_ENCODE_STRU(v, 3) JSONBUILDER_GENERIC_VALS return &this; } //+------------------------------------------------------------------+ CJsonBuilder* CJsonBuilder::ValS(const string& v) { JSONBUILDER_CHECK_PUT_ENCODE_STR(v, 3) JSONBUILDER_GENERIC_VALS return &this; } //+------------------------------------------------------------------+ CJsonBuilder* CJsonBuilder::ValSNoRef(const string v) { JSONBUILDER_CHECK_PUT_ENCODE_STR(v, 3) JSONBUILDER_GENERIC_VALS return &this; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // WV en key solo acepta ASCCI puro no caracteres de control (no espca) menos emojis (tipico en keys harcodeadas) // Si reuiqer full use la version completa CJsonBuilder* CJsonBuilder::KeyWV(const string &k) { //--- const int l = StringLen(k); const int req = l + 4; JSONBUILDER_EXPAND_E(req) //--- JSON_BUILDER_COMMA_F m_buf[m_pos++] = '"'; //--- for(int i = 0; i < l; i++) m_buf[m_pos++] = (uchar)k[i]; //-- m_buf[m_pos++] = '"'; m_buf[m_pos++] = ':'; //--- m_stack_first[m_sp] = true; return &this; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // WV aqui implcia no escape pero UTF si se soporta (en string en uchar NO) CJsonBuilder* CJsonBuilder::ValSWV(const string& v) { JSONBUILDER_GENERIC_VALSTR_WVER return &this; } //+------------------------------------------------------------------+ CJsonBuilder* CJsonBuilder::ValSNoRefWV(const string v) { JSONBUILDER_GENERIC_VALSTR_WVER return &this; } //+------------------------------------------------------------------+ CJsonBuilder* CJsonBuilder::ValUWV(const uchar &v[], int count) { //--- JSONBUILDER_EXPAND_E(2) JSON_BUILDER_COMMA_F m_buf[m_pos++] = '"'; PutRaw(v, count); JSONBUILDER_EXPAND_E(1) m_buf[m_pos++] = '"'; 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; } //--- //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // Nota deje esto pero tengan cuidado con esto... dado que no hay garantias de uso lo puse mas que todo para evitar tener que instancia un segundo builder // ahora el uso adecuado es digmoas en una funcion usarlo todo de golpe (sin llamar a funciones intermedias o aseguramente que esa funcion intermedia no lo llame) y listo // osea uso y desecho... algo asi... no tatno como "si fuera mio" si requieres cache o algo asi.. lo mejors es tener miembro CJsonBuilder... CJsonBuilder g_json_builder; } // namespace TSN //+------------------------------------------------------------------+ #endif // JSONPARSERBYLEO_SRC_JSONBUILDER_MQH