improved performance for dump()
This commit is contained in:
parent
cb873a42ed
commit
9dbb4402fb
6 changed files with 185 additions and 156 deletions
2
Makefile
2
Makefile
|
@ -33,6 +33,6 @@ pretty:
|
|||
src/json.hpp src/json.hpp.re2c test/unit.cpp benchmarks/benchmarks.cpp
|
||||
|
||||
# benchmarks
|
||||
json_benchmarks: benchmarks/benchmarks.cpp benchmarks/benchpress.hpp benchmarks/cxxopts.hpp
|
||||
json_benchmarks: benchmarks/benchmarks.cpp benchmarks/benchpress.hpp benchmarks/cxxopts.hpp src/json.hpp
|
||||
$(CXX) -std=c++11 $(CXXFLAGS) -O3 -flto -I src -I benchmarks $< $(LDFLAGS) -o $@
|
||||
./json_benchmarks
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
version: '{build}'
|
||||
os: Visual Studio 2015 RC
|
||||
os: MinGW
|
||||
init: []
|
||||
install: []
|
||||
build_script:
|
||||
|
|
|
@ -49,12 +49,15 @@ BENCHMARK("dump jeopardy.json", [](benchpress::context* ctx)
|
|||
std::ifstream input_file("benchmarks/files/jeopardy/jeopardy.json");
|
||||
nlohmann::json j;
|
||||
j << input_file;
|
||||
std::ofstream output_file("jeopardy.dump.json");
|
||||
|
||||
ctx->reset_timer();
|
||||
for (size_t i = 0; i < ctx->num_iterations(); ++i)
|
||||
{
|
||||
j.dump();
|
||||
output_file << j;
|
||||
}
|
||||
|
||||
std::remove("jeopardy.dump.json");
|
||||
})
|
||||
|
||||
BENCHMARK("dump jeopardy.json with indent", [](benchpress::context* ctx)
|
||||
|
@ -62,10 +65,13 @@ BENCHMARK("dump jeopardy.json with indent", [](benchpress::context* ctx)
|
|||
std::ifstream input_file("benchmarks/files/jeopardy/jeopardy.json");
|
||||
nlohmann::json j;
|
||||
j << input_file;
|
||||
std::ofstream output_file("jeopardy.dump.json");
|
||||
|
||||
ctx->reset_timer();
|
||||
for (size_t i = 0; i < ctx->num_iterations(); ++i)
|
||||
{
|
||||
j.dump(4);
|
||||
output_file << std::setw(4) << j;
|
||||
}
|
||||
|
||||
std::remove("jeopardy.dump.json");
|
||||
})
|
||||
|
|
120
src/json.hpp
120
src/json.hpp
|
@ -779,14 +779,18 @@ class basic_json
|
|||
*/
|
||||
inline string_t dump(const int indent = -1) const noexcept
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
if (indent >= 0)
|
||||
{
|
||||
return dump(true, static_cast<unsigned int>(indent));
|
||||
dump(ss, true, static_cast<unsigned int>(indent));
|
||||
}
|
||||
else
|
||||
{
|
||||
return dump(false, 0);
|
||||
dump(ss, false, 0);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/// return the type of the object (explicit)
|
||||
|
@ -1964,19 +1968,21 @@ class basic_json
|
|||
friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
|
||||
{
|
||||
// read width member and use it as indentation parameter if nonzero
|
||||
const int indentation = (o.width() == 0) ? -1 : o.width();
|
||||
const bool prettyPrint = (o.width() > 0);
|
||||
const auto indentation = (prettyPrint ? o.width() : 0);
|
||||
|
||||
o << j.dump(indentation);
|
||||
// reset width to 0 for subsequent calls to this stream
|
||||
o.width(0);
|
||||
|
||||
// do the actual serialization
|
||||
j.dump(o, prettyPrint, indentation);
|
||||
return o;
|
||||
}
|
||||
|
||||
/// serialize to stream
|
||||
friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
|
||||
{
|
||||
// read width member and use it as indentation parameter if nonzero
|
||||
const int indentation = (o.width() == 0) ? -1 : o.width();
|
||||
|
||||
o << j.dump(indentation);
|
||||
o << j;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -2067,15 +2073,11 @@ class basic_json
|
|||
characters by a sequence of "\u" followed by a four-digit hex
|
||||
representation.
|
||||
|
||||
@param o the stream to write the escaped string to
|
||||
@param s the string to escape
|
||||
@return escaped string
|
||||
*/
|
||||
static string_t escape_string(const string_t& s) noexcept
|
||||
static void escape_string(std::ostream& o, const string_t& s) noexcept
|
||||
{
|
||||
// create a result string of at least the size than s
|
||||
string_t result;
|
||||
result.reserve(s.size());
|
||||
|
||||
for (const auto c : s)
|
||||
{
|
||||
switch (c)
|
||||
|
@ -2083,49 +2085,49 @@ class basic_json
|
|||
// quotation mark (0x22)
|
||||
case '"':
|
||||
{
|
||||
result += "\\\"";
|
||||
o << "\\\"";
|
||||
break;
|
||||
}
|
||||
|
||||
// reverse solidus (0x5c)
|
||||
case '\\':
|
||||
{
|
||||
result += "\\\\";
|
||||
o << "\\\\";
|
||||
break;
|
||||
}
|
||||
|
||||
// backspace (0x08)
|
||||
case '\b':
|
||||
{
|
||||
result += "\\b";
|
||||
o << "\\b";
|
||||
break;
|
||||
}
|
||||
|
||||
// formfeed (0x0c)
|
||||
case '\f':
|
||||
{
|
||||
result += "\\f";
|
||||
o << "\\f";
|
||||
break;
|
||||
}
|
||||
|
||||
// newline (0x0a)
|
||||
case '\n':
|
||||
{
|
||||
result += "\\n";
|
||||
o << "\\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// carriage return (0x0d)
|
||||
case '\r':
|
||||
{
|
||||
result += "\\r";
|
||||
o << "\\r";
|
||||
break;
|
||||
}
|
||||
|
||||
// horizontal tab (0x09)
|
||||
case '\t':
|
||||
{
|
||||
result += "\\t";
|
||||
o << "\\t";
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2135,24 +2137,19 @@ class basic_json
|
|||
{
|
||||
// control characters (everything between 0x00 and 0x1f)
|
||||
// -> create four-digit hex representation
|
||||
std::basic_stringstream<typename string_t::value_type> ss;
|
||||
ss << "\\u" << std::hex << std::setw(4) << std::setfill('0') << int(c);
|
||||
result += ss.str();
|
||||
o << "\\u" << std::hex << std::setw(4) << std::setfill('0') << int(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
// all other characters are added as-is
|
||||
result.append(1, c);
|
||||
o << c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@brief internal implementation of the serialization function
|
||||
|
||||
|
@ -2166,108 +2163,115 @@ class basic_json
|
|||
std::to_string()
|
||||
- floating-point numbers are converted to a string using "%g" format
|
||||
|
||||
@param o stream to write to
|
||||
@param prettyPrint whether the output shall be pretty-printed
|
||||
@param indentStep the indent level
|
||||
@param currentIndent the current indent level (only used internally)
|
||||
*/
|
||||
inline string_t dump(const bool prettyPrint, const unsigned int indentStep,
|
||||
inline void dump(std::ostream& o, const bool prettyPrint, const unsigned int indentStep,
|
||||
const unsigned int currentIndent = 0) const noexcept
|
||||
{
|
||||
// variable to hold indentation for recursive calls
|
||||
auto new_indent = currentIndent;
|
||||
|
||||
// helper function to return whitespace as indentation
|
||||
const auto indent = [prettyPrint, &new_indent]()
|
||||
{
|
||||
return prettyPrint ? string_t(new_indent, ' ') : string_t();
|
||||
};
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case (value_t::object):
|
||||
{
|
||||
if (m_value.object->empty())
|
||||
{
|
||||
return "{}";
|
||||
o << "{}";
|
||||
return;
|
||||
}
|
||||
|
||||
string_t result = "{";
|
||||
o << "{";
|
||||
|
||||
// increase indentation
|
||||
if (prettyPrint)
|
||||
{
|
||||
new_indent += indentStep;
|
||||
result += "\n";
|
||||
o << "\n";
|
||||
}
|
||||
|
||||
for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
|
||||
{
|
||||
if (i != m_value.object->cbegin())
|
||||
{
|
||||
result += prettyPrint ? ",\n" : ",";
|
||||
o << (prettyPrint ? ",\n" : ",");
|
||||
}
|
||||
result += indent() + "\"" + escape_string(i->first) + "\":" + (prettyPrint ? " " : "")
|
||||
+ i->second.dump(prettyPrint, indentStep, new_indent);
|
||||
o << string_t(new_indent, ' ') << "\"";
|
||||
escape_string(o, i->first);
|
||||
o << "\":" << (prettyPrint ? " " : "");
|
||||
i->second.dump(o, prettyPrint, indentStep, new_indent);
|
||||
}
|
||||
|
||||
// decrease indentation
|
||||
if (prettyPrint)
|
||||
{
|
||||
new_indent -= indentStep;
|
||||
result += "\n";
|
||||
o << "\n";
|
||||
}
|
||||
|
||||
return result + indent() + "}";
|
||||
o << string_t(new_indent, ' ') + "}";
|
||||
return;
|
||||
}
|
||||
|
||||
case (value_t::array):
|
||||
{
|
||||
if (m_value.array->empty())
|
||||
{
|
||||
return "[]";
|
||||
o << "[]";
|
||||
return;
|
||||
}
|
||||
|
||||
string_t result = "[";
|
||||
o << "[";
|
||||
|
||||
// increase indentation
|
||||
if (prettyPrint)
|
||||
{
|
||||
new_indent += indentStep;
|
||||
result += "\n";
|
||||
o << "\n";
|
||||
}
|
||||
|
||||
for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
|
||||
{
|
||||
if (i != m_value.array->cbegin())
|
||||
{
|
||||
result += prettyPrint ? ",\n" : ",";
|
||||
o << (prettyPrint ? ",\n" : ",");
|
||||
}
|
||||
result += indent() + i->dump(prettyPrint, indentStep, new_indent);
|
||||
o << string_t(new_indent, ' ');
|
||||
i->dump(o, prettyPrint, indentStep, new_indent);
|
||||
}
|
||||
|
||||
// decrease indentation
|
||||
if (prettyPrint)
|
||||
{
|
||||
new_indent -= indentStep;
|
||||
result += "\n";
|
||||
o << "\n";
|
||||
}
|
||||
|
||||
return result + indent() + "]";
|
||||
o << string_t(new_indent, ' ') << "]";
|
||||
return;
|
||||
}
|
||||
|
||||
case (value_t::string):
|
||||
{
|
||||
return string_t("\"") + escape_string(*m_value.string) + "\"";
|
||||
o << string_t("\"");
|
||||
escape_string(o, *m_value.string);
|
||||
o << "\"";
|
||||
return;
|
||||
}
|
||||
|
||||
case (value_t::boolean):
|
||||
{
|
||||
return m_value.boolean ? "true" : "false";
|
||||
o << (m_value.boolean ? "true" : "false");
|
||||
return;
|
||||
}
|
||||
|
||||
case (value_t::number_integer):
|
||||
{
|
||||
return std::to_string(m_value.number_integer);
|
||||
o << m_value.number_integer;
|
||||
return;
|
||||
}
|
||||
|
||||
case (value_t::number_float):
|
||||
|
@ -2277,16 +2281,20 @@ class basic_json
|
|||
const auto sz = static_cast<unsigned int>(std::snprintf(nullptr, 0, "%.15g", m_value.number_float));
|
||||
std::vector<typename string_t::value_type> buf(sz + 1);
|
||||
std::snprintf(&buf[0], buf.size(), "%.15g", m_value.number_float);
|
||||
return string_t(buf.data());
|
||||
o << buf.data();
|
||||
return;
|
||||
}
|
||||
|
||||
case (value_t::discarded):
|
||||
{
|
||||
return "<discarded>";
|
||||
o << "<discarded>";
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return "null";
|
||||
o << "null";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -779,14 +779,18 @@ class basic_json
|
|||
*/
|
||||
inline string_t dump(const int indent = -1) const noexcept
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
if (indent >= 0)
|
||||
{
|
||||
return dump(true, static_cast<unsigned int>(indent));
|
||||
dump(ss, true, static_cast<unsigned int>(indent));
|
||||
}
|
||||
else
|
||||
{
|
||||
return dump(false, 0);
|
||||
dump(ss, false, 0);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/// return the type of the object (explicit)
|
||||
|
@ -1964,19 +1968,21 @@ class basic_json
|
|||
friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
|
||||
{
|
||||
// read width member and use it as indentation parameter if nonzero
|
||||
const int indentation = (o.width() == 0) ? -1 : o.width();
|
||||
const bool prettyPrint = (o.width() > 0);
|
||||
const auto indentation = (prettyPrint ? o.width() : 0);
|
||||
|
||||
o << j.dump(indentation);
|
||||
// reset width to 0 for subsequent calls to this stream
|
||||
o.width(0);
|
||||
|
||||
// do the actual serialization
|
||||
j.dump(o, prettyPrint, indentation);
|
||||
return o;
|
||||
}
|
||||
|
||||
/// serialize to stream
|
||||
friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
|
||||
{
|
||||
// read width member and use it as indentation parameter if nonzero
|
||||
const int indentation = (o.width() == 0) ? -1 : o.width();
|
||||
|
||||
o << j.dump(indentation);
|
||||
o << j;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -2067,15 +2073,11 @@ class basic_json
|
|||
characters by a sequence of "\u" followed by a four-digit hex
|
||||
representation.
|
||||
|
||||
@param o the stream to write the escaped string to
|
||||
@param s the string to escape
|
||||
@return escaped string
|
||||
*/
|
||||
static string_t escape_string(const string_t& s) noexcept
|
||||
static void escape_string(std::ostream& o, const string_t& s) noexcept
|
||||
{
|
||||
// create a result string of at least the size than s
|
||||
string_t result;
|
||||
result.reserve(s.size());
|
||||
|
||||
for (const auto c : s)
|
||||
{
|
||||
switch (c)
|
||||
|
@ -2083,49 +2085,49 @@ class basic_json
|
|||
// quotation mark (0x22)
|
||||
case '"':
|
||||
{
|
||||
result += "\\\"";
|
||||
o << "\\\"";
|
||||
break;
|
||||
}
|
||||
|
||||
// reverse solidus (0x5c)
|
||||
case '\\':
|
||||
{
|
||||
result += "\\\\";
|
||||
o << "\\\\";
|
||||
break;
|
||||
}
|
||||
|
||||
// backspace (0x08)
|
||||
case '\b':
|
||||
{
|
||||
result += "\\b";
|
||||
o << "\\b";
|
||||
break;
|
||||
}
|
||||
|
||||
// formfeed (0x0c)
|
||||
case '\f':
|
||||
{
|
||||
result += "\\f";
|
||||
o << "\\f";
|
||||
break;
|
||||
}
|
||||
|
||||
// newline (0x0a)
|
||||
case '\n':
|
||||
{
|
||||
result += "\\n";
|
||||
o << "\\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// carriage return (0x0d)
|
||||
case '\r':
|
||||
{
|
||||
result += "\\r";
|
||||
o << "\\r";
|
||||
break;
|
||||
}
|
||||
|
||||
// horizontal tab (0x09)
|
||||
case '\t':
|
||||
{
|
||||
result += "\\t";
|
||||
o << "\\t";
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2135,24 +2137,19 @@ class basic_json
|
|||
{
|
||||
// control characters (everything between 0x00 and 0x1f)
|
||||
// -> create four-digit hex representation
|
||||
std::basic_stringstream<typename string_t::value_type> ss;
|
||||
ss << "\\u" << std::hex << std::setw(4) << std::setfill('0') << int(c);
|
||||
result += ss.str();
|
||||
o << "\\u" << std::hex << std::setw(4) << std::setfill('0') << int(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
// all other characters are added as-is
|
||||
result.append(1, c);
|
||||
o << c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@brief internal implementation of the serialization function
|
||||
|
||||
|
@ -2166,108 +2163,115 @@ class basic_json
|
|||
std::to_string()
|
||||
- floating-point numbers are converted to a string using "%g" format
|
||||
|
||||
@param o stream to write to
|
||||
@param prettyPrint whether the output shall be pretty-printed
|
||||
@param indentStep the indent level
|
||||
@param currentIndent the current indent level (only used internally)
|
||||
*/
|
||||
inline string_t dump(const bool prettyPrint, const unsigned int indentStep,
|
||||
inline void dump(std::ostream& o, const bool prettyPrint, const unsigned int indentStep,
|
||||
const unsigned int currentIndent = 0) const noexcept
|
||||
{
|
||||
// variable to hold indentation for recursive calls
|
||||
auto new_indent = currentIndent;
|
||||
|
||||
// helper function to return whitespace as indentation
|
||||
const auto indent = [prettyPrint, &new_indent]()
|
||||
{
|
||||
return prettyPrint ? string_t(new_indent, ' ') : string_t();
|
||||
};
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case (value_t::object):
|
||||
{
|
||||
if (m_value.object->empty())
|
||||
{
|
||||
return "{}";
|
||||
o << "{}";
|
||||
return;
|
||||
}
|
||||
|
||||
string_t result = "{";
|
||||
o << "{";
|
||||
|
||||
// increase indentation
|
||||
if (prettyPrint)
|
||||
{
|
||||
new_indent += indentStep;
|
||||
result += "\n";
|
||||
o << "\n";
|
||||
}
|
||||
|
||||
for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i)
|
||||
{
|
||||
if (i != m_value.object->cbegin())
|
||||
{
|
||||
result += prettyPrint ? ",\n" : ",";
|
||||
o << (prettyPrint ? ",\n" : ",");
|
||||
}
|
||||
result += indent() + "\"" + escape_string(i->first) + "\":" + (prettyPrint ? " " : "")
|
||||
+ i->second.dump(prettyPrint, indentStep, new_indent);
|
||||
o << string_t(new_indent, ' ') << "\"";
|
||||
escape_string(o, i->first);
|
||||
o << "\":" << (prettyPrint ? " " : "");
|
||||
i->second.dump(o, prettyPrint, indentStep, new_indent);
|
||||
}
|
||||
|
||||
// decrease indentation
|
||||
if (prettyPrint)
|
||||
{
|
||||
new_indent -= indentStep;
|
||||
result += "\n";
|
||||
o << "\n";
|
||||
}
|
||||
|
||||
return result + indent() + "}";
|
||||
o << string_t(new_indent, ' ') + "}";
|
||||
return;
|
||||
}
|
||||
|
||||
case (value_t::array):
|
||||
{
|
||||
if (m_value.array->empty())
|
||||
{
|
||||
return "[]";
|
||||
o << "[]";
|
||||
return;
|
||||
}
|
||||
|
||||
string_t result = "[";
|
||||
o << "[";
|
||||
|
||||
// increase indentation
|
||||
if (prettyPrint)
|
||||
{
|
||||
new_indent += indentStep;
|
||||
result += "\n";
|
||||
o << "\n";
|
||||
}
|
||||
|
||||
for (auto i = m_value.array->cbegin(); i != m_value.array->cend(); ++i)
|
||||
{
|
||||
if (i != m_value.array->cbegin())
|
||||
{
|
||||
result += prettyPrint ? ",\n" : ",";
|
||||
o << (prettyPrint ? ",\n" : ",");
|
||||
}
|
||||
result += indent() + i->dump(prettyPrint, indentStep, new_indent);
|
||||
o << string_t(new_indent, ' ');
|
||||
i->dump(o, prettyPrint, indentStep, new_indent);
|
||||
}
|
||||
|
||||
// decrease indentation
|
||||
if (prettyPrint)
|
||||
{
|
||||
new_indent -= indentStep;
|
||||
result += "\n";
|
||||
o << "\n";
|
||||
}
|
||||
|
||||
return result + indent() + "]";
|
||||
o << string_t(new_indent, ' ') << "]";
|
||||
return;
|
||||
}
|
||||
|
||||
case (value_t::string):
|
||||
{
|
||||
return string_t("\"") + escape_string(*m_value.string) + "\"";
|
||||
o << string_t("\"");
|
||||
escape_string(o, *m_value.string);
|
||||
o << "\"";
|
||||
return;
|
||||
}
|
||||
|
||||
case (value_t::boolean):
|
||||
{
|
||||
return m_value.boolean ? "true" : "false";
|
||||
o << (m_value.boolean ? "true" : "false");
|
||||
return;
|
||||
}
|
||||
|
||||
case (value_t::number_integer):
|
||||
{
|
||||
return std::to_string(m_value.number_integer);
|
||||
o << m_value.number_integer;
|
||||
return;
|
||||
}
|
||||
|
||||
case (value_t::number_float):
|
||||
|
@ -2277,16 +2281,20 @@ class basic_json
|
|||
const auto sz = static_cast<unsigned int>(std::snprintf(nullptr, 0, "%.15g", m_value.number_float));
|
||||
std::vector<typename string_t::value_type> buf(sz + 1);
|
||||
std::snprintf(&buf[0], buf.size(), "%.15g", m_value.number_float);
|
||||
return string_t(buf.data());
|
||||
o << buf.data();
|
||||
return;
|
||||
}
|
||||
|
||||
case (value_t::discarded):
|
||||
{
|
||||
return "<discarded>";
|
||||
o << "<discarded>";
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return "null";
|
||||
o << "null";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7162,45 +7162,52 @@ TEST_CASE("convenience functions")
|
|||
|
||||
SECTION("string escape")
|
||||
{
|
||||
CHECK(json::escape_string("\"") == "\\\"");
|
||||
CHECK(json::escape_string("\\") == "\\\\");
|
||||
CHECK(json::escape_string("\b") == "\\b");
|
||||
CHECK(json::escape_string("\f") == "\\f");
|
||||
CHECK(json::escape_string("\n") == "\\n");
|
||||
CHECK(json::escape_string("\r") == "\\r");
|
||||
CHECK(json::escape_string("\t") == "\\t");
|
||||
auto escape_string = [](const std::string & s)
|
||||
{
|
||||
std::stringstream ss;
|
||||
json::escape_string(ss, s);
|
||||
return ss.str();
|
||||
};
|
||||
|
||||
CHECK(json::escape_string("\x01") == "\\u0001");
|
||||
CHECK(json::escape_string("\x02") == "\\u0002");
|
||||
CHECK(json::escape_string("\x03") == "\\u0003");
|
||||
CHECK(json::escape_string("\x04") == "\\u0004");
|
||||
CHECK(json::escape_string("\x05") == "\\u0005");
|
||||
CHECK(json::escape_string("\x06") == "\\u0006");
|
||||
CHECK(json::escape_string("\x07") == "\\u0007");
|
||||
CHECK(json::escape_string("\x08") == "\\b");
|
||||
CHECK(json::escape_string("\x09") == "\\t");
|
||||
CHECK(json::escape_string("\x0a") == "\\n");
|
||||
CHECK(json::escape_string("\x0b") == "\\u000b");
|
||||
CHECK(json::escape_string("\x0c") == "\\f");
|
||||
CHECK(json::escape_string("\x0d") == "\\r");
|
||||
CHECK(json::escape_string("\x0e") == "\\u000e");
|
||||
CHECK(json::escape_string("\x0f") == "\\u000f");
|
||||
CHECK(json::escape_string("\x10") == "\\u0010");
|
||||
CHECK(json::escape_string("\x11") == "\\u0011");
|
||||
CHECK(json::escape_string("\x12") == "\\u0012");
|
||||
CHECK(json::escape_string("\x13") == "\\u0013");
|
||||
CHECK(json::escape_string("\x14") == "\\u0014");
|
||||
CHECK(json::escape_string("\x15") == "\\u0015");
|
||||
CHECK(json::escape_string("\x16") == "\\u0016");
|
||||
CHECK(json::escape_string("\x17") == "\\u0017");
|
||||
CHECK(json::escape_string("\x18") == "\\u0018");
|
||||
CHECK(json::escape_string("\x19") == "\\u0019");
|
||||
CHECK(json::escape_string("\x1a") == "\\u001a");
|
||||
CHECK(json::escape_string("\x1b") == "\\u001b");
|
||||
CHECK(json::escape_string("\x1c") == "\\u001c");
|
||||
CHECK(json::escape_string("\x1d") == "\\u001d");
|
||||
CHECK(json::escape_string("\x1e") == "\\u001e");
|
||||
CHECK(json::escape_string("\x1f") == "\\u001f");
|
||||
CHECK(escape_string("\"") == "\\\"");
|
||||
CHECK(escape_string("\\") == "\\\\");
|
||||
CHECK(escape_string("\b") == "\\b");
|
||||
CHECK(escape_string("\f") == "\\f");
|
||||
CHECK(escape_string("\n") == "\\n");
|
||||
CHECK(escape_string("\r") == "\\r");
|
||||
CHECK(escape_string("\t") == "\\t");
|
||||
|
||||
CHECK(escape_string("\x01") == "\\u0001");
|
||||
CHECK(escape_string("\x02") == "\\u0002");
|
||||
CHECK(escape_string("\x03") == "\\u0003");
|
||||
CHECK(escape_string("\x04") == "\\u0004");
|
||||
CHECK(escape_string("\x05") == "\\u0005");
|
||||
CHECK(escape_string("\x06") == "\\u0006");
|
||||
CHECK(escape_string("\x07") == "\\u0007");
|
||||
CHECK(escape_string("\x08") == "\\b");
|
||||
CHECK(escape_string("\x09") == "\\t");
|
||||
CHECK(escape_string("\x0a") == "\\n");
|
||||
CHECK(escape_string("\x0b") == "\\u000b");
|
||||
CHECK(escape_string("\x0c") == "\\f");
|
||||
CHECK(escape_string("\x0d") == "\\r");
|
||||
CHECK(escape_string("\x0e") == "\\u000e");
|
||||
CHECK(escape_string("\x0f") == "\\u000f");
|
||||
CHECK(escape_string("\x10") == "\\u0010");
|
||||
CHECK(escape_string("\x11") == "\\u0011");
|
||||
CHECK(escape_string("\x12") == "\\u0012");
|
||||
CHECK(escape_string("\x13") == "\\u0013");
|
||||
CHECK(escape_string("\x14") == "\\u0014");
|
||||
CHECK(escape_string("\x15") == "\\u0015");
|
||||
CHECK(escape_string("\x16") == "\\u0016");
|
||||
CHECK(escape_string("\x17") == "\\u0017");
|
||||
CHECK(escape_string("\x18") == "\\u0018");
|
||||
CHECK(escape_string("\x19") == "\\u0019");
|
||||
CHECK(escape_string("\x1a") == "\\u001a");
|
||||
CHECK(escape_string("\x1b") == "\\u001b");
|
||||
CHECK(escape_string("\x1c") == "\\u001c");
|
||||
CHECK(escape_string("\x1d") == "\\u001d");
|
||||
CHECK(escape_string("\x1e") == "\\u001e");
|
||||
CHECK(escape_string("\x1f") == "\\u001f");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue