std::string valueToQuotedString( const char *value ) { // Not sure how to handle unicode... if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && !containsControlCharacter( value )) return std::string("\"") + value + "\""; // We have to walk value and escape any special characters. // Appending to std::string is not efficient, but this should be rare. // (Note: forward slashes are *not* rare, but I am not escaping them.) unsigned maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL std::string result; result.reserve(maxsize); // to avoid lots of mallocs result += "\""; for (const char* c=value; *c != 0; ++c) { switch(*c) { case '\"': result += "\\\""; break; case '\\': result += "\\\\"; break; case '\b': result += "\\b"; break; case '\f': result += "\\f"; break; case '\n': result += "\\n"; break; case '\r': result += "\\r"; break; case '\t': result += "\\t"; break; //case '/': // Even though \/ is considered a legal escape in JSON, a bare // slash is also legal, so I see no reason to escape it. // (I hope I am not misunderstanding something. // blep notes: actually escaping \/ may be useful in javascript to avoid </ // sequence. // Should add a flag to allow this compatibility mode and prevent this // sequence from occurring. default: if ( isControlCharacter( *c ) ) { std::ostringstream oss; oss << "\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << static_cast<int>(*c); result += oss.str(); } else { result += *c; } break; } } result += "\""; return result; }
std::string valueToQuotedString( const char *value ) { // Not sure how to handle unicode... //if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && !containsControlCharacter( value )) // return std::string("\"") + value + "\""; // We have to walk value and escape any special characters. // Appending to std::string is not efficient, but this should be rare. // (Note: forward slashes are *not* rare, but I am not escaping them.) std::string::size_type maxsize = strlen(value) * 2 + 3; // allescaped+quotes+NULL std::string result; result.reserve(maxsize); // to avoid lots of mallocs result += "\""; // ΪÁËÕýÈ·¼ì²éUnicode×Ö·û£¬¿½±´Ò»·Ý¿í×Ö·û°æ±¾À´±éÀú int newLen = MultiByteToWideChar(CP_ACP, 0, value, -1, nullptr, 0); LPWSTR wValue = (LPWSTR)calloc(newLen + 1, sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, value, -1, wValue, newLen); const char* c = value; for (const WCHAR* wc = wValue; *wc != 0; ++wc) { switch(*c) { case '\"': result += "\\\""; break; case '\\': result += "\\\\"; break; case '\b': result += "\\b"; break; case '\f': result += "\\f"; break; case '\n': result += "\\n"; break; case '\r': result += "\\r"; break; case '\t': result += "\\t"; break; //case '/': // Even though \/ is considered a legal escape in JSON, a bare // slash is also legal, so I see no reason to escape it. // (I hope I am not misunderstanding something. // blep notes: actually escaping \/ may be useful in javascript to avoid </ // sequence. // Should add a flag to allow this compatibility mode and prevent this // sequence from occurring. default: if ( isControlCharacter( *c ) ) { std::ostringstream oss; oss << "\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << static_cast<int>(*c); result += oss.str(); } else { // ÊÇ·ñΪUnicode×Ö·û if (*wc > 127) { char chr[7] = ""; sprintf(chr, "\\u%4X", *wc); result += chr; ++c; } else result += *c; } break; } ++c; } result += "\""; free(wValue); return result; }