📄 stringencode.cc
字号:
if (bufpos + esclen >= buflen) { break; } memcpy(buffer + bufpos, escseq, esclen); bufpos += esclen; } else { buffer[bufpos++] = ch; } } else { // Largest value is 0x1FFFFF => � (10 characters) char escseq[11]; unsigned long val; if (size_t vallen = utf8_decode(&source[srcpos], srclen - srcpos, &val)) { srcpos += vallen; } else { // Not a valid utf8 sequence, just use the raw character. val = static_cast<unsigned char>(source[srcpos++]); } size_t esclen = sprintfn(escseq, ARRAY_SIZE(escseq), "&#%lu;", val); if (bufpos + esclen >= buflen) { break; } memcpy(buffer + bufpos, escseq, esclen); bufpos += esclen; } } buffer[bufpos] = '\0'; return bufpos;}size_t html_decode(char * buffer, size_t buflen, const char * source, size_t srclen) { ASSERT(NULL != buffer); // TODO: estimate output size return xml_decode(buffer, buflen, source, srclen);}size_t xml_encode(char * buffer, size_t buflen, const char * source, size_t srclen) { ASSERT(NULL != buffer); // TODO: estimate output size if (buflen <= 0) return 0; size_t srcpos = 0, bufpos = 0; while ((srcpos < srclen) && (bufpos + 1 < buflen)) { unsigned char ch = source[srcpos++]; if ((ch < 128) && (ASCII_CLASS[ch] & XML_UNSAFE)) { const char * escseq = 0; size_t esclen = 0; switch (ch) { case '<': escseq = "<"; esclen = 4; break; case '>': escseq = ">"; esclen = 4; break; case '\'': escseq = "'"; esclen = 6; break; case '\"': escseq = """; esclen = 6; break; case '&': escseq = "&"; esclen = 5; break; default: ASSERT(false); } if (bufpos + esclen >= buflen) { break; } memcpy(buffer + bufpos, escseq, esclen); bufpos += esclen; } else { buffer[bufpos++] = ch; } } buffer[bufpos] = '\0'; return bufpos;}size_t xml_decode(char * buffer, size_t buflen, const char * source, size_t srclen) { ASSERT(NULL != buffer); // TODO: estimate output size if (buflen <= 0) return 0; size_t srcpos = 0, bufpos = 0; while ((srcpos < srclen) && (bufpos + 1 < buflen)) { unsigned char ch = source[srcpos++]; if (ch != '&') { buffer[bufpos++] = ch; } else if ((srcpos + 2 < srclen) && (memcmp(source + srcpos, "lt;", 3) == 0)) { buffer[bufpos++] = '<'; srcpos += 3; } else if ((srcpos + 2 < srclen) && (memcmp(source + srcpos, "gt;", 3) == 0)) { buffer[bufpos++] = '>'; srcpos += 3; } else if ((srcpos + 4 < srclen) && (memcmp(source + srcpos, "apos;", 5) == 0)) { buffer[bufpos++] = '\''; srcpos += 5; } else if ((srcpos + 4 < srclen) && (memcmp(source + srcpos, "quot;", 5) == 0)) { buffer[bufpos++] = '\"'; srcpos += 5; } else if ((srcpos + 3 < srclen) && (memcmp(source + srcpos, "amp;", 4) == 0)) { buffer[bufpos++] = '&'; srcpos += 4; } else if ((srcpos < srclen) && (source[srcpos] == '#')) { int int_base = 10; if ((srcpos + 1 < srclen) && (source[srcpos+1] == 'x')) { int_base = 16; srcpos += 1; } char * ptr; // TODO: Fix hack (ptr may go past end of data) unsigned long val = strtoul(source + srcpos + 1, &ptr, int_base); if ((static_cast<size_t>(ptr - source) < srclen) && (*ptr == ';')) { srcpos = ptr - source + 1; } else { // Not a valid escape sequence. break; } if (size_t esclen = utf8_encode(buffer + bufpos, buflen - bufpos, val)) { bufpos += esclen; } else { // Not enough room to encode the character, or illegal character break; } } else { // Unrecognized escape sequence. break; } } buffer[bufpos] = '\0'; return bufpos;}size_t hex_encode(char * buffer, size_t buflen, const char * csource, size_t srclen) { ASSERT(NULL != buffer); // TODO: estimate output size if (buflen <= 0) return 0; const unsigned char * bsource = reinterpret_cast<const unsigned char *>(csource); size_t srcpos = 0, bufpos = 0; srclen = _min(srclen, (buflen - 1) / 2); while (srcpos < srclen) { unsigned char ch = bsource[srcpos++]; buffer[bufpos ] = hex_encode((ch >> 4) & 0xF); buffer[bufpos+1] = hex_encode((ch ) & 0xF); bufpos += 2; } buffer[bufpos] = '\0'; return bufpos;}size_t hex_decode(char * cbuffer, size_t buflen, const char * source, size_t srclen) { ASSERT(NULL != cbuffer); // TODO: estimate output size if (buflen <= 0) return 0; unsigned char * bbuffer = reinterpret_cast<unsigned char *>(cbuffer); size_t srcpos = 0, bufpos = 0; while ((srcpos + 1 < srclen) && (bufpos + 1 < buflen)) { unsigned char v1 = (hex_decode(source[srcpos]) << 4); unsigned char v2 = hex_decode(source[srcpos+1]); bbuffer[bufpos++] = v1 | v2; srcpos += 2; } bbuffer[bufpos] = '\0'; return bufpos;}void transform(std::string& value, size_t maxlen, const std::string& source, Transform t) { char * buffer = static_cast<char *>(_alloca(maxlen + 1)); value.assign(buffer, t(buffer, maxlen + 1, source.data(), source.length()));}std::string s_transform(const std::string& source, Transform t) { // Ask transformation function to approximate the destination size (returns upper bound) size_t maxlen = t(NULL, 0, source.data(), source.length()); char * buffer = static_cast<char *>(_alloca(maxlen)); size_t len = t(buffer, maxlen, source.data(), source.length()); std::string result(buffer, len); return result;}char make_char_safe_for_filename(char c) { if (c < 32) return '_'; switch (c) { case '<': case '>': case ':': case '"': case '/': case '\\': case '|': case '*': case '?': return '_'; default: return c; }}/*void sprintf(std::string& value, size_t maxlen, const char * format, ...) { char * buffer = static_cast<char *>(alloca(maxlen + 1)); va_list args; va_start(args, format); value.assign(buffer, vsprintfn(buffer, maxlen + 1, format, args)); va_end(args);}*//////////////////////////////////////////////////////////////////////////////// Unit Tests/////////////////////////////////////////////////////////////////////////////#ifdef _DEBUGstatic int utf8_unittest() { const struct Utf8Test { const char* encoded; size_t encsize, enclen; unsigned long decoded; } kTests[] = { { "a ", 5, 1, 'a' }, { "\x7F ", 5, 1, 0x7F }, { "\xC2\x80 ", 5, 2, 0x80 }, { "\xDF\xBF ", 5, 2, 0x7FF }, { "\xE0\xA0\x80 ", 5, 3, 0x800 }, { "\xEF\xBF\xBF ", 5, 3, 0xFFFF }, { "\xF0\x90\x80\x80 ", 5, 4, 0x10000 }, { "\xF0\x90\x80\x80 ", 3, 0, 0x10000 }, { "\xF0\xF0\x80\x80 ", 5, 0, 0 }, { "\xF0\x90\x80 ", 5, 0, 0 }, { "\x90\x80\x80 ", 5, 0, 0 }, { NULL, 0, 0 }, }; for (size_t i=0; kTests[i].encoded; ++i) { unsigned long val = 0; ASSERT(kTests[i].enclen == utf8_decode(kTests[i].encoded, kTests[i].encsize, &val)); unsigned long result = (kTests[i].enclen == 0) ? 0 : kTests[i].decoded; ASSERT(val == result); if (kTests[i].decoded == 0) { // Not an interesting encoding test case continue; } char buffer[5]; memset(buffer, 0x01, ARRAY_SIZE(buffer)); ASSERT(kTests[i].enclen == utf8_encode(buffer, kTests[i].encsize, kTests[i].decoded)); ASSERT(memcmp(buffer, kTests[i].encoded, kTests[i].enclen) == 0); // Make sure remainder of buffer is unchanged ASSERT(memory_check(buffer + kTests[i].enclen, 0x1, ARRAY_SIZE(buffer) - kTests[i].enclen)); } return 1;}int test = utf8_unittest();#endif // _DEBUG/////////////////////////////////////////////////////////////////////////////} // namespace utils_base
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -