Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
畅游知识海洋
json
提交
9dbb4402
J
json
项目概览
畅游知识海洋
/
json
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
json
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
9dbb4402
编写于
6月 03, 2015
作者:
N
Niels
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
improved performance for dump()
上级
cb873a42
变更
6
显示空白变更内容
内联
并排
Showing
6 changed file
with
186 addition
and
157 deletion
+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
未找到文件。
Makefile
浏览文件 @
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
浏览文件 @
9dbb4402
version
:
'
{build}'
os
:
Visual Studio 2015 RC
os
:
MinGW
init
:
[]
install
:
[]
build_script
:
...
...
benchmarks/benchmarks.cpp
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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"
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录