summaryrefslogtreecommitdiff
path: root/src/text/json_formatter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/text/json_formatter.cpp')
-rw-r--r--src/text/json_formatter.cpp29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/text/json_formatter.cpp b/src/text/json_formatter.cpp
index efa807f58c..bd882c15d2 100644
--- a/src/text/json_formatter.cpp
+++ b/src/text/json_formatter.cpp
@@ -71,7 +71,11 @@ namespace //anonymous
{ os << "[" << ba.size() << " bytes]"; }
void visit(const tag_string& s) override
- { os << '"' << s.get() << '"'; } //TODO: escape special characters
+ {
+ os << '"';
+ write_escaped_string(s.get());
+ os << '"';
+ }
void visit(const tag_list& l) override
{
@@ -198,6 +202,29 @@ namespace //anonymous
{
os << "null";
}
+
+ void write_escaped_string(const std::string& str)
+ {
+ for (char c : str) {
+ switch (c) {
+ case '"': os << "\\\""; break;
+ case '\\': os << "\\\\"; break;
+ case '\b': os << "\\b"; break;
+ case '\f': os << "\\f"; break;
+ case '\n': os << "\\n"; break;
+ case '\r': os << "\\r"; break;
+ case '\t': os << "\\t"; break;
+ default:
+ if (static_cast<unsigned char>(c) < 32 || c == 127) {
+ // Control characters, escape as \u00XX
+ os << "\\u00" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(static_cast<unsigned char>(c));
+ } else {
+ os << c;
+ }
+ break;
+ }
+ }
+ }
};
}