Refactor JSON::encode_string

This commit is contained in:
m-holger 2023-02-03 14:28:45 +00:00 committed by Jay Berkenbilt
parent 1787d85096
commit 415e67951b
1 changed files with 52 additions and 32 deletions

View File

@ -220,41 +220,61 @@ JSON::unparse() const
std::string std::string
JSON::encode_string(std::string const& str) JSON::encode_string(std::string const& str)
{ {
std::string result; static auto constexpr hexchars = "0123456789abcdef";
size_t len = str.length();
for (size_t i = 0; i < len; ++i) { auto begin = str.cbegin();
unsigned char ch = static_cast<unsigned char>(str.at(i)); auto end = str.cend();
switch (ch) { auto iter = begin;
case '\\': while (iter != end) {
result += "\\\\"; auto c = static_cast<unsigned char>(*iter);
break; if ((c > 34 && c != '\\') || c == ' ' || c == 33) {
case '\"': // Optimistically check that no char in str requires escaping.
result += "\\\""; // Hopefully we can just return the input str.
break; ++iter;
case '\b': } else {
result += "\\b"; // We found a char that requires escaping. Initialize result to the
break; // chars scanned so far, append/replace the rest of str one char at
case '\f': // a time, and return the result.
result += "\\f"; std::string result{begin, iter};
break;
case '\n': for (; iter != end; ++iter) {
result += "\\n"; auto ch = static_cast<unsigned char>(*iter);
break; if ((ch > 34 && ch != '\\') || ch == ' ' || ch == 33) {
case '\r': // Check for most common case first.
result += "\\r"; result += *iter;
break; } else {
case '\t': switch (ch) {
result += "\\t"; case '\\':
break; result += "\\\\";
default: break;
if (ch < 32) { case '\"':
result += "\\u" + QUtil::int_to_string_base(ch, 16, 4); result += "\\\"";
} else { break;
result.append(1, static_cast<char>(ch)); 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;
default:
result += ch < 16 ? "\\u000" : "\\u001";
result += hexchars[ch % 16];
}
}
} }
return result;
} }
} }
return result; return str;
} }
JSON JSON