From 65f9caec87f2c21021ebd45656872c15629445dc Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 28 Oct 2024 12:51:16 +0300 Subject: [PATCH] add unicode escapes support --- src/coders/commons.cpp | 7 +++++++ src/util/stringutil.cpp | 12 +++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/coders/commons.cpp b/src/coders/commons.cpp index b79dc14e..985c3440 100644 --- a/src/coders/commons.cpp +++ b/src/coders/commons.cpp @@ -360,6 +360,13 @@ std::string BasicParser::parseString(char quote, bool closeRequired) { ss << (char)parseSimpleInt(8); continue; } + if (c == 'u') { + int codepoint = parseSimpleInt(16); + ubyte bytes[4]; + int size = util::encode_utf8(codepoint, bytes); + ss.write(reinterpret_cast(bytes), size); + continue; + } switch (c) { case 'n': ss << '\n'; break; case 'r': ss << '\r'; break; diff --git a/src/util/stringutil.cpp b/src/util/stringutil.cpp index 12936343..ca7e8e46 100644 --- a/src/util/stringutil.cpp +++ b/src/util/stringutil.cpp @@ -11,7 +11,9 @@ std::string util::escape(const std::string& s) { std::stringstream ss; ss << '"'; - for (char c : s) { + size_t pos = 0; + while (pos < s.length()) { + char c = s[pos]; switch (c) { case '\n': ss << "\\n"; @@ -35,6 +37,13 @@ std::string util::escape(const std::string& s) { ss << "\\\\"; break; default: + if (c & 0x80) { + uint cpsize; + int codepoint = decode_utf8(cpsize, s.data() + pos); + pos += cpsize-1; + ss << "\\u" << std::hex << codepoint; + break; + } if (c < ' ') { ss << "\\" << std::oct << uint(ubyte(c)); break; @@ -42,6 +51,7 @@ std::string util::escape(const std::string& s) { ss << c; break; } + pos++; } ss << '"'; return ss.str();