result_t XmlParser::parse(XmlDocument* doc, exlib::string source) { XmlParser parser(doc, true); parser.m_now = doc; parser.m_list.push_back(doc); XML_Parser xml_parser = XML_ParserCreate(NULL); XML_SetParamEntityParsing(xml_parser, XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE); XML_SetUserData(xml_parser, &parser); XML_SetXmlDeclHandler(xml_parser, XmlDeclHandler); XML_SetElementHandler(xml_parser, StartElementHandler, EndElementHandler); XML_SetCharacterDataHandler(xml_parser, CharacterDataHandler); XML_SetProcessingInstructionHandler(xml_parser, ProcessingInstructionHandler); XML_SetCommentHandler(xml_parser, CommentHandler); XML_SetCdataSectionHandler(xml_parser, StartCdataSectionHandler, EndCdataSectionHandler); XML_SetStartDoctypeDeclHandler(xml_parser, StartDoctypeDeclHandler); if (XML_Parse(xml_parser, source.c_str(), (int32_t)source.length(), true) != XML_STATUS_OK) { char msg[128]; sprintf(msg, "XmlParser: error on line %lu at column %lu: %s", XML_GetCurrentLineNumber(xml_parser), XML_GetCurrentColumnNumber(xml_parser) + 1, XML_ErrorString(XML_GetErrorCode(xml_parser))); XML_ParserFree(xml_parser); return CHECK_ERROR(Runtime::setError(msg)); } XML_ParserFree(xml_parser); return 0; }
result_t HttpCollection::parseCookie(exlib::string &str) { const char *pstr = str.c_str(); int32_t nSize = (int32_t) str.length(); const char *pstrTemp; exlib::string strKey, strValue; while (nSize) { while (nSize && *pstr == ' ') { pstr++; nSize--; } pstrTemp = pstr; while (nSize && *pstr != '=' && *pstr != ';') { pstr++; nSize--; } if (pstr > pstrTemp) Url::decodeURI(pstrTemp, (int32_t) (pstr - pstrTemp), strKey, true); else strKey.clear(); if (nSize && *pstr == '=') { nSize--; pstr++; } pstrTemp = pstr; while (nSize && *pstr != ';') { pstr++; nSize--; } if (!strKey.empty()) { if (pstr > pstrTemp) Url::decodeURI(pstrTemp, (int32_t) (pstr - pstrTemp), strValue, true); else strValue.clear(); } if (nSize) { nSize--; pstr++; } if (!strKey.empty()) add(strKey, strValue); } return 0; }
result_t X509Cert::get_serial(exlib::string &retVal) { mbedtls_x509_crt *crt = get_crt(); if (!crt) return CHECK_ERROR(CALL_E_INVALID_CALL); int32_t ret; mbedtls_mpi serial; mbedtls_mpi_init(&serial); ret = mbedtls_mpi_read_binary(&serial, crt->serial.p, crt->serial.len); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); retVal.resize(8192); size_t sz = retVal.length(); ret = mbedtls_mpi_write_string(&serial, 10, &retVal[0], sz, &sz); mbedtls_mpi_free(&serial); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); retVal.resize(sz - 1); return 0; }
result_t SQLite::execute(exlib::string sql, obj_ptr<DBResult_base> &retVal, AsyncEvent *ac) { if (!m_db) return CHECK_ERROR(CALL_E_INVALID_CALL); if (!ac) return CHECK_ERROR(CALL_E_NOSYNC); return execute(sql.c_str(), (int32_t) sql.length(), retVal); }
result_t X509Crl::load(exlib::string pemCrl) { int32_t ret; ret = mbedtls_x509_crl_parse(&m_crl, (const unsigned char *)pemCrl.c_str(), pemCrl.length() + 1); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); return 0; }
result_t base64vlq_base::decode(exlib::string data, v8::Local<v8::Array>& retVal) { static const char decodeTable[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, /* 2x !"#$%&'()*+,-./ */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 3x 0123456789:;<=>? */ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 4x @ABCDEFGHIJKLMNO */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, /* 5X PQRSTUVWXYZ[\]^_ */ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 6x `abcdefghijklmno */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 7X pqrstuvwxyz{\}~DEL */ }; const char* _data = data.c_str(); const char* end = _data + data.length(); int32_t cnt = 0; Isolate* isolate = Isolate::current(); retVal = v8::Array::New(isolate->m_isolate); while (_data < end) { uint32_t ch; int32_t bits = 0; int32_t num = 0; while ((ch = utf_getchar(_data, end)) != 0) { int32_t byte = (ch > 0x20 && ch < 0x80) ? decodeTable[ch - 0x20] : -1; if (byte != -1) { num += (byte & 0x1f) << (bits * 5); bits++; if (!(byte & 0x20)) break; } else break; } if (num & 1) num = -(num >> 1); else num = num >> 1; retVal->Set(cnt++, v8::Number::New(isolate->m_isolate, num)); }
void Url::parseHost(const char*& url, exlib::string& hostname, exlib::string& port) { const char* p1 = url; const char* p2 = NULL; char ch; if (*p1 == '[') { p1++; while ((ch = *p1) && (qisxdigit(ch) || ch == ':' || ch == '.')) p1++; if (ch == ']') ch = *++p1; else url++; } else { while ((ch = *p1) && (qisascii(ch) || qisdigit(ch) || ch == '.' || ch == '_' || ch == '-' || ch < 0)) p1++; } if (ch == ':') { p2 = p1 + 1; while ((ch = *p2) && qisdigit(ch)) p2++; } if (*url == '[') hostname.assign(url + 1, p1 - url - 2); else hostname.assign(url, p1 - url); if (hostname.length() > 0) { qstrlwr(&hostname[0]); punycode_base::toASCII(hostname, hostname); } if (p2) port.assign(p1 + 1, p2 - p1 - 1); else port.clear(); url = p2 ? p2 : p1; }
result_t path_base::basename(exlib::string path, exlib::string ext, exlib::string &retVal) { char ch; const char* c_str = path.c_str(); const char *p1 = c_str; int32_t extlen = (int32_t)ext.length(); while (*c_str) { ch = *c_str++; if (isPathSlash(ch)) p1 = c_str; } if (extlen && ((int32_t) (c_str - p1) >= extlen) && !pathcmp(ext.c_str(), c_str - extlen, extlen)) c_str -= extlen; retVal.assign(p1, (int32_t) (c_str - p1)); return 0; }
result_t X509Cert::load(exlib::string txtCert) { if (m_root) return CHECK_ERROR(CALL_E_INVALID_CALL); int32_t ret; if (qstrstr(txtCert.c_str(), "BEGIN CERTIFICATE")) { ret = mbedtls_x509_crt_parse(&m_crt, (const unsigned char *)txtCert.c_str(), txtCert.length() + 1); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); return 0; } _parser p(txtCert); QuickArray<std::pair<exlib::string, exlib::string> > values; std::map<exlib::string, bool> verifies; std::map<exlib::string, bool> certs; while (!p.end()) { exlib::string cka_label; exlib::string cka_value; exlib::string cka_serial; exlib::string _value; bool in_multiline = false, in_obj = false; bool is_cert = false; bool is_trust = false; bool is_value = false; bool is_serial = false; bool is_ca = false; bool is_verify = false; while (!p.end()) { exlib::string line; exlib::string cmd, type, value; p.getLine(line); _parser p1(line); p1.skipSpace(); if (p1.get() == '#') continue; if (in_multiline) { if (p1.get() == '\\') { while (p1.get() == '\\') { char ch1, ch2, ch3; p1.skip(); ch1 = p1.getChar(); if (ch1 < '0' || ch1 > '7') break; ch2 = p1.getChar(); if (ch2 < '0' || ch2 > '7') break; ch3 = p1.getChar(); if (ch3 < '0' || ch3 > '7') break; ch1 = (ch1 - '0') * 64 + (ch2 - '0') * 8 + (ch3 - '0'); _value.append(&ch1, 1); } continue; } p1.getWord(cmd); if ((cmd == "END")) { if (is_value) cka_value = _value; else if (is_serial) cka_serial = _value; in_multiline = false; } continue; } p1.getWord(cmd); p1.skipSpace(); p1.getWord(type); if ((type == "MULTILINE_OCTAL")) { in_multiline = true; _value.resize(0); is_value = is_cert && (cmd == "CKA_VALUE"); is_serial = (cmd == "CKA_SERIAL_NUMBER"); continue; } p1.skipSpace(); p1.getLeft(value); if (!in_obj) { if ((cmd == "CKA_CLASS")) { in_obj = true; is_cert = (value == "CKO_CERTIFICATE"); is_trust = (value == "CKO_NSS_TRUST"); } continue; } if ((cmd == "CKA_LABEL")) cka_label = value; else if (is_trust && (cmd == "CKA_TRUST_SERVER_AUTH")) { is_ca = (value == "CKT_NSS_TRUSTED_DELEGATOR"); is_verify = (value == "CKT_NSS_MUST_VERIFY_TRUST"); } if (cmd.empty()) break; } if (!cka_label.empty()) { if (is_trust) { if (is_ca) certs.insert(std::pair<exlib::string, bool>(cka_label + cka_serial, true)); if (is_verify) verifies.insert(std::pair<exlib::string, bool>(cka_label + cka_serial, true)); } else if (is_cert && !cka_value.empty()) values.append(std::pair<exlib::string, exlib::string>(cka_label + cka_serial, cka_value)); } } bool is_loaded = false; int32_t i; for (i = 0; i < (int32_t)values.size(); i++) { std::pair<exlib::string, exlib::string> &c = values[i]; std::map<exlib::string, bool>::iterator it_trust; it_trust = verifies.find(c.first); if (it_trust != verifies.end()) { ret = mbedtls_x509_crt_parse_der(&m_crt, (const unsigned char *)c.second.c_str(), c.second.length()); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); is_loaded = true; } } for (i = 0; i < (int32_t)values.size(); i++) { std::pair<exlib::string, exlib::string> &c = values[i]; std::map<exlib::string, bool>::iterator it_trust; it_trust = certs.find(c.first); if (it_trust != certs.end()) { ret = mbedtls_x509_crt_parse_der(&m_crt, (const unsigned char *)c.second.c_str(), c.second.length() ); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); is_loaded = true; } } if (!is_loaded) return CHECK_ERROR(_ssl::setError(MBEDTLS_ERR_X509_INVALID_FORMAT)); return 0; }
void std_logger::out(exlib::string& txt) { #ifdef _WIN32 class color_out { public: color_out() { m_handle = GetStdHandle(STD_OUTPUT_HANDLE); m_Now = m_wAttr = 0x7; m_wLight = m_wAttr & FOREGROUND_INTENSITY; } void out(exlib::string& s) { exlib::wstring ws = utf8to16String(s); exlib::wchar *ptr = &ws[0]; exlib::wchar *pend = ptr + ws.length(); exlib::wchar *ptr2; DWORD dwWrite; while (ptr2 = (exlib::wchar *) qstrchr(ptr, L'\x1b')) { if (ptr2[1] == '[') { WriteConsoleW(m_handle, ptr, (DWORD)(ptr2 - ptr), &dwWrite, NULL); ptr2 += 2; while (true) { if (ptr2[0] == 'm') { m_Now = m_wAttr; m_wLight = m_wAttr & FOREGROUND_INTENSITY; SetConsoleTextAttribute(m_handle, m_Now); ptr2 ++; break; } if (qisdigit(ptr2[0])) { if (ptr2[1] == 'm') { if (ptr2[0] == '0') { m_Now = m_wAttr; m_wLight = m_wAttr & FOREGROUND_INTENSITY; SetConsoleTextAttribute(m_handle, m_Now); } ptr2 += 2; break; } WORD mask, val; WORD light = m_wLight; if (ptr2[1] == ';') { if (ptr2[0] == '0') m_wLight = light = 0; else if (ptr2[0] == '1') m_wLight = light = FOREGROUND_INTENSITY; ptr2 += 2; } if (ptr2[0] == '3') { mask = 0xf0; ptr2 ++; } else if (ptr2[0] == '4') { mask = 0x0f; ptr2 ++; } else if (ptr2[0] == '9') { mask = 0xf0; light |= FOREGROUND_INTENSITY; ptr2 ++; } else if (ptr2[0] == '1' && ptr2[1] == '0') { mask = 0x0f; light |= FOREGROUND_INTENSITY << 4; ptr2 += 2; } else break; if (!qisdigit(ptr2[0])) break; val = ptr2[0] - '0'; if (val != 8) { if (val == 9) { val = (m_wAttr & 0x0f) | (m_Now & 0xf0); m_Now = val | light; SetConsoleTextAttribute(m_handle, m_Now); } else { val = (val & 2) | ((val & 1) ? 4 : 0) | ((val & 4) ? 1 : 0); if (mask == 0x0f) val <<= 4; m_Now = (m_Now & mask) | val | light; SetConsoleTextAttribute(m_handle, m_Now); } } ptr2 ++; if (ptr2[0] == 'm') { ptr2 ++; break; } } } } ptr = ptr2; } WriteConsoleW(m_handle, ptr, (DWORD)(pend - ptr), &dwWrite, NULL); } private: HANDLE m_handle; WORD m_wAttr, m_Now; WORD m_wLight; }; static color_out s_out; if (_isatty(_fileno(stdout))) s_out.out(txt); else #endif { fwrite(txt.c_str(), 1, txt.length(), stdout); fflush(stdout); } }
void std_logger::out(exlib::string& txt) { fwrite(txt.c_str(), 1, txt.length(), stdout); }
void out(exlib::string& s) { static HANDLE s_console; if (!m_tty) { fwrite(s.c_str(), 1, s.length(), stdout); return; } if (!m_handle) { if (!s_console) { AllocConsole(); freopen("CONIN$", "r", stdin); freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); s_console = GetStdHandle(STD_OUTPUT_HANDLE); } m_handle = s_console; m_Now = m_wAttr = 0x7; m_wLight = m_wAttr & FOREGROUND_INTENSITY; } exlib::wstring ws = utf8to16String(s); exlib::wchar* ptr = &ws[0]; exlib::wchar* pend = ptr + ws.length(); exlib::wchar* ptr2; while (ptr2 = (exlib::wchar*)qstrchr(ptr, L'\x1b')) { if (ptr2[1] == '[') { WriteConsole(ptr, ptr2 - ptr); ptr2 += 2; while (true) { if (ptr2[0] == 'm') { m_Now = m_wAttr; m_wLight = m_wAttr & FOREGROUND_INTENSITY; SetConsoleTextAttribute(m_handle, m_Now); ptr2++; break; } if (qisdigit(ptr2[0])) { if (ptr2[1] == 'm') { if (ptr2[0] == '0') { m_Now = m_wAttr; m_wLight = m_wAttr & FOREGROUND_INTENSITY; SetConsoleTextAttribute(m_handle, m_Now); } ptr2 += 2; break; } WORD mask, val; WORD light = m_wLight; if (ptr2[1] == ';') { if (ptr2[0] == '0') m_wLight = light = 0; else if (ptr2[0] == '1') m_wLight = light = FOREGROUND_INTENSITY; ptr2 += 2; } if (ptr2[0] == '3') { mask = 0xf0; ptr2++; } else if (ptr2[0] == '4') { mask = 0x0f; ptr2++; } else if (ptr2[0] == '9') { mask = 0xf0; light |= FOREGROUND_INTENSITY; ptr2++; } else if (ptr2[0] == '1' && ptr2[1] == '0') { mask = 0x0f; light |= FOREGROUND_INTENSITY << 4; ptr2 += 2; } else break; if (!qisdigit(ptr2[0])) break; val = ptr2[0] - '0'; if (val != 8) { if (val == 9) { val = (m_wAttr & 0x0f) | (m_Now & 0xf0); m_Now = val | light; SetConsoleTextAttribute(m_handle, m_Now); } else { val = (val & 2) | ((val & 1) ? 4 : 0) | ((val & 4) ? 1 : 0); if (mask == 0x0f) val <<= 4; m_Now = (m_Now & mask) | val | light; SetConsoleTextAttribute(m_handle, m_Now); } } ptr2++; if (ptr2[0] == 'm') { ptr2++; break; } } } } ptr = ptr2; } WriteConsole(ptr, pend - ptr); }
result_t db_base::escape(exlib::string str, bool mysql, exlib::string& retVal) { _escape(str.c_str(), (int32_t)str.length(), mysql, retVal); return 0; }
result_t HttpCollection::parse(exlib::string& str, const char* sep, const char* eq) { const char* pstr = str.c_str(); int32_t nSize = (int32_t)str.length(); const char* pstrTemp; exlib::string strKey, strValue; int32_t sep_len = (int32_t)qstrlen(sep); int32_t eq_len = (int32_t)qstrlen(eq); bool found_eq; while (nSize) { pstrTemp = pstr; found_eq = false; while (nSize) { if (!qstrcmp(pstr, sep, sep_len)) break; if (!qstrcmp(pstr, eq, eq_len)) { found_eq = true; break; } pstr++; nSize--; } if (pstr > pstrTemp) Url::decodeURI(pstrTemp, (int32_t)(pstr - pstrTemp), strKey, true); else strKey.clear(); if (nSize && found_eq) { nSize -= eq_len; pstr += eq_len; } pstrTemp = pstr; while (nSize && qstrcmp(pstr, sep, sep_len)) { pstr++; nSize--; } if (!strKey.empty()) { if (pstr > pstrTemp) Url::decodeURI(pstrTemp, (int32_t)(pstr - pstrTemp), strValue, true); else strValue.clear(); } if (nSize) { nSize -= sep_len; pstr += sep_len; } if (!strKey.empty()) add(strKey, strValue); } return 0; }
void HttpUploadCollection::parse(exlib::string& str, const char* boundary) { const char* pstr = str.c_str(); int32_t nSize = (int32_t)str.length(); exlib::string strName; exlib::string strFileName; exlib::string strContentType; exlib::string strContentTransferEncoding; const char *p, *p1, *p2, *szQueryString; const char* pstrSplit; int32_t uiSplitSize; char ch; boundary += 20; while (*boundary && *boundary == ' ') boundary++; if (qstricmp(boundary, "boundary=", 9)) return; boundary += 9; uiSplitSize = (int32_t)qstrlen(boundary); pstrSplit = szQueryString = pstr; if (nSize < uiSplitSize + 2 || szQueryString[0] != '-' || szQueryString[1] != '-' || qstrcmp(szQueryString + 2, boundary, uiSplitSize)) return; uiSplitSize += 2; szQueryString += uiSplitSize; nSize -= uiSplitSize; while (nSize) { strFileName.clear(); strContentType.clear(); strContentTransferEncoding.clear(); while (nSize > 0) { ch = *szQueryString++; nSize--; if (ch != '\r') return; if (nSize > 0 && *szQueryString == '\n') { nSize--; szQueryString++; } p = szQueryString; while (nSize > 0 && *p != '\r') { nSize--; p++; } if (nSize == 0) break; p1 = szQueryString; szQueryString = p; if (p != p1) { if (p1 + 20 < p && !qstricmp(p1, "Content-Disposition:", 20)) { p1 += 20; while (p1 < p && *p1 == ' ') p1++; if (p1 + 10 >= p || qstricmp(p1, "form-data;", 10)) return; p1 += 10; while (p1 < p && *p1 == ' ') p1++; if (p1 + 5 >= p || qstricmp(p1, "name=", 5)) return; p1 += 5; while (p1 < p && *p1 == ' ') p1++; ch = ';'; if (*p1 == '\"') { p1++; ch = '\"'; } p2 = p1; while (p1 < p && *p1 != ch) p1++; strName.assign(p2, (int32_t)(p1 - p2)); if (p1 < p && *p1 == '\"') p1++; if (p1 < p && *p1 == ';') p1++; while (p1 < p && *p1 == ' ') p1++; if (p1 + 9 < p && !qstricmp(p1, "filename=", 9)) { p1 += 9; while (p1 < p && *p1 == ' ') p1++; ch = ';'; if (*p1 == '\"') { p1++; ch = '\"'; } p2 = p1; while (p1 < p && *p1 != ch) { if (*p1 == '/' || *p1 == '\\') p2 = p1 + 1; p1++; } strFileName.assign(p2, (int32_t)(p1 - p2)); } } else if (p1 + 13 < p && !qstricmp(p1, "Content-Type:", 13)) { p1 += 13; while (p1 < p && *p1 == ' ') p1++; strContentType.assign(p1, (int32_t)(p - p1)); } else if (p1 + 26 < p && !qstricmp(p1, "Content-Transfer-Encoding:", 26)) { p1 += 26; while (p1 < p && *p1 == ' ') p1++; strContentTransferEncoding.assign(p1, (int32_t)(p - p1)); } } else { ch = *szQueryString++; nSize--; if (ch != '\r') return; if (nSize > 0 && *szQueryString == '\n') { nSize--; szQueryString++; } break; } } p = szQueryString; p1 = p + nSize; while (p1 > p && (p = (char*)memchr(p, '-', p1 - p)) && p1 > p + uiSplitSize && memcmp(p, pstrSplit, uiSplitSize)) p++; if (!p || p1 <= p + uiSplitSize) break; nSize = (int32_t)(p1 - p - uiSplitSize); p1 = szQueryString; szQueryString = p + uiSplitSize; if (p > p1) { p--; ch = *p; if (ch != '\n') return; if (p > p1 && *(p - 1) == '\r') p--; } if (!strName.empty()) { int32_t uiSize = (int32_t)(p - p1); exlib::string strTemp; Variant varTemp; strTemp.assign(p1, uiSize); if (strFileName.empty()) varTemp = strTemp; else { obj_ptr<HttpUploadData> objTemp = new HttpUploadData(); date_t tm; objTemp->m_name = strFileName; objTemp->m_type = strContentType; objTemp->m_encoding = strContentTransferEncoding; objTemp->m_body = new MemoryStream::CloneStream(strTemp, tm); varTemp = objTemp; } add(strName, varTemp); } } }
result_t util_base::compile(exlib::string srcname, exlib::string script, int32_t mode, obj_ptr<Buffer_base>& retVal) { Isolate* isolate = Isolate::current(); exlib::string oname = srcname; v8::Local<v8::String> soname = isolate->NewFromUtf8(oname); v8::Local<v8::Script> code; { TryCatch try_catch; { v8::ScriptCompiler::Source script_source( isolate->NewFromUtf8(script)); if (v8::ScriptCompiler::CompileUnbound( isolate->m_isolate, &script_source) .IsEmpty()) return throwSyntaxError(try_catch); } const char* args; switch (mode) { case 1: args = main_args; break; case 2: args = script_args; break; case 3: args = worker_args; break; default: args = module_args; break; } script = args + script + "\n});"; v8::ScriptCompiler::Source script_source( isolate->NewFromUtf8(script), v8::ScriptOrigin(soname)); if (v8::ScriptCompiler::CompileUnbound( isolate->m_isolate, &script_source, v8::ScriptCompiler::kProduceCodeCache) .IsEmpty()) return throwSyntaxError(try_catch); const v8::ScriptCompiler::CachedData* cache = script_source.GetCachedData(); exlib::string buf((const char*)cache->data, cache->length); int32_t len = (int32_t)script.length(); buf.append((const char*)&len, sizeof(len)); obj_ptr<Buffer_base> unz = new Buffer(buf); return zlib_base::cc_gzip(unz, retVal); } return 0; }
void Url::trimUrl(exlib::string url, exlib::string& retVal) { exlib::string rest; int32_t start = -1; int32_t end = -1; int32_t lastPos = 0; int32_t i; bool isWs; bool inWs = false; for (i = 0; i < (int32_t)url.length(); i++) { isWs = url[i] == 32 || url[i] == 9 || url[i] == 13 || url[i] == 10 || url[i] == 12; if (*(unsigned char*)&url[i] == 0xc2 && *(unsigned char*)&url[i + 1] == 0xa0) { isWs = true; i++; } if (*(unsigned char*)&url[i] == 239 && *(unsigned char*)&url[i + 1] == 187 && *(unsigned char*)&url[i + 2] == 191) { isWs = true; i += 2; } if (start == -1) { if (isWs) continue; lastPos = start = i; } else { if (inWs) { if (!isWs) { end = -1; inWs = false; } } else if (isWs) { end = i; inWs = true; } } if (url[i] == 92 && i - lastPos > 0) url[i] = '/'; } if (start != -1) { if (lastPos == start) { if (end == -1) { if (start == 0) rest = url; else rest = url.substr(start); } else { rest = url.substr(start, end - start); } } else if (end == -1 && lastPos < (int32_t)url.length()) { // We converted some backslashes and have only part of the entire string rest = url.substr(lastPos); } else if (end != -1 && lastPos < end) { // We converted some backslashes and have only part of the entire string rest = url.substr(lastPos, end); } } retVal = rest; }