//+------------------------------------------------------------------+ //| JsonUnescape.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_JSONUNESCAPE_MQH #define JSONPARSERBYLEO_SRC_JSONUNESCAPE_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //--- incluyte al parser y defines.mqh #include "JsonParser.mqh" #include //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ namespace TSN { //+------------------------------------------------------------------+ //| Version que retorna string | //+------------------------------------------------------------------+ static bool CJsonParser::MakeString(const uchar &in[], int i, int len, string& res) { //--- StringInit(res, len, ' '); int pos = 0; //--- len += i; for(; i < len; i++) { //--- const uchar ch = in[i]; if(ch == '\\') { const uchar next = g_tsn_table_json_unescape_table[in[++i]]; switch(next) { case TSN_TABLE_UNESCAPE_UNICODE: { if(i + 4 >= len) return false; //--- DOMBASEULTIS_MAKESTRING_CODE(code, i) //--- Vefificamos low\high surrogate if(code >= 0xD800 && code <= 0xDBFF) { if(i + 6 < len && in[i + 1] == '\\' && in[i + 2] == 'u') { int j = i + 2; DOMBASEULTIS_MAKESTRING_CODE(low, j) //--- if(low >= 0xDC00 && low <= 0xDFFF) { res.SetChar(pos++, code); res.SetChar(pos++, low); i = j; break; } } //--- // if(sizeof(TStrict) == JSONUNESCAPE_STRICT) // return def; res.SetChar(pos++, 0xFFFD); } else if(code >= 0xDC00 && code <= 0xDFFF) { //if(sizeof(TStrict) == JSONUNESCAPE_STRICT) //return def; res.SetChar(pos++, 0xFFFD); } else res.SetChar(pos++, code); break; } case TSN_TABLE_UNESCAPE_INVALID: return false; default: res.SetChar(pos++, next); break; } continue; } //--- res.SetChar(pos++, ch); } //--- res.Truncate(pos); return true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static int CJsonParser::MakeUArray(const uchar &in[], int i, int len, uchar &res[], int pos = 0) { //--- ArrayResize(res, len); //--- len += i; for(; i < len; i++) { //--- const uchar ch = in[i]; if(ch == '\\') { const uchar next = g_tsn_table_json_unescape_table[in[++i]]; switch(next) { case TSN_TABLE_UNESCAPE_UNICODE: { if(i + 4 >= len) return -1; // error //--- DOMBASEULTIS_MAKESTRING_CODE(code, i) //--- if(code < 0x80) { res[pos++] = uchar(code); continue; } else if(code < 0x800) { res[pos++] = uchar(0xC0 | (code >> 6)); res[pos++] = uchar(0x80 | (code & 0x3F)); continue; } //--- uint cp = code; if(code >= 0xD800 && code <= 0xDBFF) // Esta en rango buscamos otro mas. { if(i + 6 < len && in[i + 1] == '\\' && in[i + 2] == 'u') { int j = i + 2; DOMBASEULTIS_MAKESTRING_CODE(low, j) if(low >= 0xDC00 && low <= 0xDFFF) { cp = 0x10000 + ((code - 0xD800) << 10) + (low - 0xDC00); i = j; //--- emoji res[pos++] = uchar(0xF0 | (cp >> 18)); res[pos++] = uchar(0x80 | ((cp >> 12) & 0x3F)); res[pos++] = uchar(0x80 | ((cp >> 6) & 0x3F)); res[pos++] = uchar(0x80 | (cp & 0x3F)); continue; } } //--- // if(sizeof(TStrict) == JSONUNESCAPE_STRICT) // return -1; code = 0xFFFD; // huerfano, no hay low surrogate despues } else if(code >= 0xDC00 && code <= 0xDFFF) { // if(sizeof(TStrict) == JSONUNESCAPE_STRICT) // return -1; code = 0xFFFD; } //--- res[pos++] = uchar(0xE0 | (code >> 12)); res[pos++] = uchar(0x80 | ((code >> 6) & 0x3F)); res[pos++] = uchar(0x80 | (code & 0x3F)); continue; } case TSN_TABLE_UNESCAPE_INVALID: return -1; // error default: res[pos++] = next; continue; } } //--- res[pos++] = ch; } //--- return ArrayResize(res, pos); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool CJsonParser::EscapePointer(const string &in, int &i, int len, ulong &hash) { //--- hash = 14695981039346656037ULL; for(; i < len; i++) // nota aqui el " se nos garantiza pero igual en uncidoe hay que vertiicar el len { //--- const ushort ch = in[i]; if(ch == '\\') { const uchar next = g_tsn_table_json_unescape_table[in[++i]]; switch(next) { case TSN_TABLE_UNESCAPE_UNICODE: { if(i + 4 >= len) return false; //--- DOMBASEULTIS_MAKESTRING_CODE(code, i) //--- Vefificamos low\high surrogate if(code >= 0xD800 && code <= 0xDBFF) { if(i + 6 < len && in[i + 1] == '\\' && in[i + 2] == 'u') { int j = i + 2; DOMBASEULTIS_MAKESTRING_CODE(low, j) //--- if(low >= 0xDC00 && low <= 0xDFFF) { DOMBASEULTIS_MKH_ITER(code) DOMBASEULTIS_MKH_ITER(low) i = j; break; } } //--- // if(sizeof(TStrict) == JSONUNESCAPE_STRICT) // return def; DOMBASEULTIS_MKH_ITER(0xFFFD) } else if(code >= 0xDC00 && code <= 0xDFFF) { //if(sizeof(TStrict) == JSONUNESCAPE_STRICT) //return def; DOMBASEULTIS_MKH_ITER(0xFFFD) } else { DOMBASEULTIS_MKH_ITER(code) } break; } case TSN_TABLE_UNESCAPE_INVALID: return false; default: DOMBASEULTIS_MKH_ITER(next) break; } continue; } if(ch == '/') return true; if(ch == '~') { const ushort n = in[++i]; if(n == '1') { DOMBASEULTIS_MKH_ITER('/') continue; } else if(n == '0') { DOMBASEULTIS_MKH_ITER('~') continue; } return false; // escape invalido } //--- DOMBASEULTIS_MKH_ITER(ch) } return true; } //--- end namespace } #endif // JSONPARSERBYLEO_SRC_JSONUNESCAPE_MQH