Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
json
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
json
Commits
9dbb4402
Commit
9dbb4402
authored
Jun 03, 2015
by
Niels
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
improved performance for dump()
parent
cb873a42
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
186 additions
and
157 deletions
+186
-157
Makefile
Makefile
+1
-1
appveyor.yml
appveyor.yml
+1
-1
benchmarks/benchmarks.cpp
benchmarks/benchmarks.cpp
+8
-2
src/json.hpp
src/json.hpp
+65
-57
src/json.hpp.re2c
src/json.hpp.re2c
+65
-57
test/unit.cpp
test/unit.cpp
+46
-39
No files found.
Makefile
View file @
9dbb4402
...
...
@@ -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
appveyor.yml
View file @
9dbb4402
version
:
'
{build}'
os
:
Visual Studio 2015 RC
os
:
MinGW
init
:
[]
install
:
[]
build_script
:
...
...
benchmarks/benchmarks.cpp
View file @
9dbb4402
...
...
@@ -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"
);
})
src/json.hpp
View file @
9dbb4402
...
...
@@ -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
;
}
}
}
...
...
src/json.hpp.re2c
View file @
9dbb4402
...
...
@@ -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;
}
}
}
...
...
test/unit.cpp
View file @
9dbb4402
...
...
@@ -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"
);
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"
);
auto
escape_string
=
[](
const
std
::
string
&
s
)
{
std
::
stringstream
ss
;
json
::
escape_string
(
ss
,
s
);
return
ss
.
str
();
};
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"
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment