//+------------------------------------------------------------------+ //| JsonEscape.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_JSONESCAPE_MQH #define JSONPARSERBYLEO_SRC_JSONESCAPE_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include "Tables\\UnescapeEscape.mqh" #include //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ namespace TSN { //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // CR = CALC RESERVE // aqui el maximo valor es \uXXXX (6 chars) #define JSONESCAPE_CR_ENCODE(len) ((len*6)) // aqui el maximo valor es \\uXXXX (7 chars) #define JSONESCAPE_CR_ENCODESTR(len) ((len*7)) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CJsonEscape { public: CJsonEscape(void) {} ~CJsonEscape(void) {} //--- static void Encode(const string& s, const int l, uchar& buf[], int& pos); static void Encode(const uchar& s[], const int l, uchar& buf[], int& pos); //--- static void EncodeStr(const string& s, const int l, uchar& buf[], int& pos); static void EncodeStr(const uchar& s[], const int l, uchar& buf[], int& pos); }; //+------------------------------------------------------------------+ //| Trabajo con string | //+------------------------------------------------------------------+ static void CJsonEscape::EncodeStr(const string &s, const int l, uchar &buf[], int &pos) { for(int i = 0; i < l; i++) { const ushort c = s[i]; //--- Unicode > 0xFF: \uXXXX con los 4 nibbles completos if(c > 0xFF) { buf[pos++] = '\\'; buf[pos++] = '\\'; buf[pos++] = 'u'; uchar t; t = uchar((c >> 12) & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; t = uchar((c >> 8) & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; t = uchar((c >> 4) & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; t = uchar(c & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; continue; } //--- 0x00–0xFF: lookup en tabla const uchar esc = g_tsn_table_json_escape_tables[c]; if(esc == TSN_TABLE_ESCAPE_PASSTHROUGH) { buf[pos++] = (uchar)c; } else if(esc == TSN_TABLE_ESCAPE_UNICODE) { buf[pos++] = '\\'; buf[pos++] = '\\'; buf[pos++] = 'u'; buf[pos++] = '0'; buf[pos++] = '0'; uchar t; t = uchar((c >> 4) & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; t = uchar(c & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; } else { //--- letra dedicada: \n \t \\ \" etc. buf[pos++] = '\\'; buf[pos++] = '\\'; if(esc == '\\' || esc == '"') buf[pos++] = '\\'; buf[pos++] = esc; } } } //+------------------------------------------------------------------+ static void CJsonEscape::Encode(const string& s, const int l, uchar& buf[], int& pos) { for(int i = 0; i < l; i++) { const ushort c = s[i]; //--- Unicode > 0xFF: \uXXXX con los 4 nibbles completos if(c > 0xFF) { buf[pos++] = '\\'; buf[pos++] = 'u'; uchar t; t = uchar((c >> 12) & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; t = uchar((c >> 8) & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; t = uchar((c >> 4) & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; t = uchar(c & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; continue; } //--- 0x00–0xFF: lookup en tabla const uchar esc = g_tsn_table_json_escape_tables[c]; if(esc == TSN_TABLE_ESCAPE_PASSTHROUGH) { buf[pos++] = (uchar)c; } else if(esc == TSN_TABLE_ESCAPE_UNICODE) { buf[pos++] = '\\'; buf[pos++] = 'u'; buf[pos++] = '0'; buf[pos++] = '0'; uchar t; t = uchar((c >> 4) & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; t = uchar(c & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; } else { //--- letra dedicada: \n \t \\ \" etc. buf[pos++] = '\\'; buf[pos++] = esc; } } } //+------------------------------------------------------------------+ //| Trabajo con uchar array | //+------------------------------------------------------------------+ static void CJsonEscape::Encode(const uchar &s[], const int l, uchar &buf[], int &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) { buf[pos++] = c; } else if(esc == TSN_TABLE_ESCAPE_UNICODE) { buf[pos++] = '\\'; buf[pos++] = 'u'; buf[pos++] = '0'; buf[pos++] = '0'; uchar t; t = ((c >> 4) & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; t = (c & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; } else { buf[pos++] = '\\'; buf[pos++] = esc; } } } //+------------------------------------------------------------------+ void CJsonEscape::EncodeStr(const uchar &s[], const int l, uchar &buf[], int &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) { buf[pos++] = c; } else if(esc == TSN_TABLE_ESCAPE_UNICODE) { buf[pos++] = '\\'; buf[pos++] = '\\'; buf[pos++] = 'u'; buf[pos++] = '0'; buf[pos++] = '0'; uchar t; t = ((c >> 4) & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; t = (c & 0xF); buf[pos++] = g_tsntables_hex_digits[t]; } else { buf[pos++] = '\\'; buf[pos++] = '\\'; if(esc == '\\' || esc == '"') buf[pos++] = '\\'; buf[pos++] = esc; } } } //--- } #endif // JSONPARSERBYLEO_SRC_JSONESCAPE_MQH