2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-06-16 00:42:21 +00:00

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

View File

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