Use Lemire's fast check whether to escape a JSON string (#6923)

This commit is contained in:
Dennis Luxen 2024-05-31 19:58:57 +02:00 committed by GitHub
parent 42fafdcdfe
commit 2725202771
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,8 +1,9 @@
#ifndef STRING_UTIL_HPP #ifndef STRING_UTIL_HPP
#define STRING_UTIL_HPP #define STRING_UTIL_HPP
#include <array>
#include <cctype> #include <cctype>
#include <cstddef>
#include <random> #include <random>
#include <string> #include <string>
#include <vector> #include <vector>
@ -10,26 +11,30 @@
namespace osrm::util namespace osrm::util
{ {
// implements Lemire's table-based escape needs check
// cf. https://lemire.me/blog/2024/05/31/quickly-checking-whether-a-string-needs-escaping/
inline static constexpr std::array<uint8_t, 256> json_quotable_character = []() constexpr
{
std::array<uint8_t, 256> result{};
for (auto i = 0; i < 32; i++)
{
result[i] = 1;
}
for (auto i : {'"', '\\'})
{
result[i] = 1;
}
return result;
}();
inline bool RequiresJSONStringEscaping(const std::string &string) inline bool RequiresJSONStringEscaping(const std::string &string)
{ {
for (const char letter : string) uint8_t needs = 0;
for (uint8_t c : string)
{ {
switch (letter) needs |= json_quotable_character[c];
{
case '\\':
case '"':
case '/':
case '\b':
case '\f':
case '\n':
case '\r':
case '\t':
return true;
default:
continue;
} }
} return needs;
return false;
} }
inline void EscapeJSONString(const std::string &input, std::string &output) inline void EscapeJSONString(const std::string &input, std::string &output)