Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
json
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
json
Commits
62682879
Commit
62682879
authored
Apr 17, 2016
by
Niels
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
improved documentation and test coverage
parent
7034ae24
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
106 additions
and
25 deletions
+106
-25
README.md
README.md
+1
-1
flatten.cpp
doc/examples/flatten.cpp
+3
-0
flatten.link
doc/examples/flatten.link
+2
-2
flatten.output
doc/examples/flatten.output
+1
-0
json.hpp
src/json.hpp
+47
-11
json.hpp.re2c
src/json.hpp.re2c
+47
-11
unit.cpp
test/unit.cpp
+5
-0
No files found.
README.md
View file @
62682879
...
@@ -428,7 +428,7 @@ $ make
...
@@ -428,7 +428,7 @@ $ make
$ ./json_unit "
*
"
$ ./json_unit "
*
"
===============================================================================
===============================================================================
All tests passed (3344
299 assertions in 29
test cases)
All tests passed (3344
416 assertions in 30
test cases)
```
```
For more information, have a look at the file
[
.travis.yml
](
https://github.com/nlohmann/json/blob/master/.travis.yml
)
.
For more information, have a look at the file
[
.travis.yml
](
https://github.com/nlohmann/json/blob/master/.travis.yml
)
.
doc/examples/flatten.cpp
View file @
62682879
...
@@ -31,4 +31,7 @@ int main()
...
@@ -31,4 +31,7 @@ int main()
// call flatten()
// call flatten()
std
::
cout
<<
std
::
setw
(
4
)
<<
j
.
flatten
()
<<
'\n'
;
std
::
cout
<<
std
::
setw
(
4
)
<<
j
.
flatten
()
<<
'\n'
;
// flatten for a primitive value
std
::
cout
<<
j
[
"pi"
].
flatten
()
<<
'\n'
;
}
}
doc/examples/flatten.link
View file @
62682879
<a target="_blank" href="http://melpon.org/wandbox/permlink/kODXfzcksgstdBRD"><b>online</b></a>
<a target="_blank" href="http://melpon.org/wandbox/permlink/skGi8b32VhI8HOgV"><b>online</b></a>
\ No newline at end of file
\ No newline at end of file
doc/examples/flatten.output
View file @
62682879
...
@@ -14,3 +14,4 @@
...
@@ -14,3 +14,4 @@
"/object/~1": "slash",
"/object/~1": "slash",
"/pi": 3.141
"/pi": 3.141
}
}
{"":3.141}
src/json.hpp
View file @
62682879
...
@@ -3273,8 +3273,8 @@ class basic_json
...
@@ -3273,8 +3273,8 @@ class basic_json
@return reference to the element at index @a idx
@return reference to the element at index @a idx
@throw std::domain_error if JSON is not an array or null; example:
`"cannot
@throw std::domain_error if JSON is not an array or null; example:
use operator[] with string"`
`"cannot
use operator[] with string"`
@complexity Constant if @a idx is in the range of the array. Otherwise
@complexity Constant if @a idx is in the range of the array. Otherwise
linear in `idx - size()`.
linear in `idx - size()`.
...
@@ -3620,7 +3620,9 @@ class basic_json
...
@@ -3620,7 +3620,9 @@ class basic_json
@complexity Linear in the length of the JSON pointer.
@complexity Linear in the length of the JSON pointer.
@throw std::out_of_range if the JSON pointer can not be resolved
@throw std::out_of_range if the JSON pointer can not be resolved
@throw std::domain_error if an array index begins with '0'
@throw std::invalid_argument if an array index was not a number
@liveexample{The behavior is shown in the example.,operatorjson_pointer}
@liveexample{The behavior is shown in the example.,operatorjson_pointer}
...
@@ -3645,8 +3647,9 @@ class basic_json
...
@@ -3645,8 +3647,9 @@ class basic_json
@complexity Linear in the length of the JSON pointer.
@complexity Linear in the length of the JSON pointer.
@throw std::out_of_range if the JSON pointer can not be resolved
@throw std::out_of_range if the JSON pointer can not be resolved
@throw std::out_of_range if the special value `-` is used for an array
@throw std::domain_error if an array index begins with '0'
@throw std::invalid_argument if an array index was not a number
@liveexample{The behavior is shown in the example.,
@liveexample{The behavior is shown in the example.,
operatorjson_pointer_const}
operatorjson_pointer_const}
...
@@ -8923,9 +8926,12 @@ basic_json_parser_63:
...
@@ -8923,9 +8926,12 @@ basic_json_parser_63:
empty string is assumed which references the whole JSON
empty string is assumed which references the whole JSON
value
value
@throw std::domain_error if reference token is nonempty and does not
@throw std::domain_error if reference token is nonempty and does not
begin with a slash (`/`), or if a tilde (`~`) is not followed
begin with a slash (`/`); example: `"JSON pointer must be empty or
by `0` (representing `~`) or `1` (representing `/`).
begin with /"`
@throw std::domain_error if a tilde (`~`) is not followed by `0`
(representing `~`) or `1` (representing `/`); example: `"escape error:
~ must be followed with 0 or 1"`
@liveexample{The example shows the construction several valid JSON
@liveexample{The example shows the construction several valid JSON
pointers as well as the exceptional behavior.,json_pointer}
pointers as well as the exceptional behavior.,json_pointer}
...
@@ -8944,6 +8950,8 @@ basic_json_parser_63:
...
@@ -8944,6 +8950,8 @@ basic_json_parser_63:
{
{
pointer
result
=
&
j
;
pointer
result
=
&
j
;
// in case no reference tokens exist, return a reference to the
// JSON value j which will be overwritten by a primitive value
for
(
const
auto
&
reference_token
:
reference_tokens
)
for
(
const
auto
&
reference_token
:
reference_tokens
)
{
{
switch
(
result
->
m_type
)
switch
(
result
->
m_type
)
...
@@ -8952,10 +8960,12 @@ basic_json_parser_63:
...
@@ -8952,10 +8960,12 @@ basic_json_parser_63:
{
{
if
(
reference_token
==
"0"
)
if
(
reference_token
==
"0"
)
{
{
// start a new array if reference token is 0
result
=
&
result
->
operator
[](
0
);
result
=
&
result
->
operator
[](
0
);
}
}
else
else
{
{
// start a new object otherwise
result
=
&
result
->
operator
[](
reference_token
);
result
=
&
result
->
operator
[](
reference_token
);
}
}
break
;
break
;
...
@@ -8963,19 +8973,38 @@ basic_json_parser_63:
...
@@ -8963,19 +8973,38 @@ basic_json_parser_63:
case
value_t
:
:
object
:
case
value_t
:
:
object
:
{
{
// create an entry in the object
result
=
&
result
->
operator
[](
reference_token
);
result
=
&
result
->
operator
[](
reference_token
);
break
;
break
;
}
}
case
value_t
:
:
array
:
case
value_t
:
:
array
:
{
{
// create an entry in the array
result
=
&
result
->
operator
[](
static_cast
<
size_t
>
(
std
::
stoi
(
reference_token
)));
result
=
&
result
->
operator
[](
static_cast
<
size_t
>
(
std
::
stoi
(
reference_token
)));
break
;
break
;
}
}
/*
This function is only to be called from the unflatten()
function. There, j is initially of type null.
- In case the reference tokens are empty, a reference to
j is returned and overwritten by the desired value by
the unflatten() function.
- If there are reference tokens, the null value of j will
be changed to an object or array after reading the first
reference token.
- All subsequent tokens work on arrays or objects and will
not change the type of j.
Consequently, the type of @a j will always be null,
object, or array. Hence, the following line is
unreachable.
*/
default
:
default
:
{
{
throw
std
::
domain_error
(
"unresolved reference token '"
+
reference_token
+
"'"
);
break
;
// LCOV_EXCL_LINE
}
}
}
}
}
}
...
@@ -9361,7 +9390,11 @@ basic_json_parser_63:
...
@@ -9361,7 +9390,11 @@ basic_json_parser_63:
throw
std
::
domain_error
(
"values in object must be primitive"
);
throw
std
::
domain_error
(
"values in object must be primitive"
);
}
}
// assign value to reference pointed to by JSON pointer
// assign value to reference pointed to by JSON pointer;
// Note that if the JSON pointer is "" (i.e., points to the
// whole value), function get_and_create returns a reference
// to result itself. An assignment will then create a
// primitive value.
json_pointer
(
element
.
first
).
get_and_create
(
result
)
=
element
.
second
;
json_pointer
(
element
.
first
).
get_and_create
(
result
)
=
element
.
second
;
}
}
...
@@ -9390,7 +9423,8 @@ basic_json_parser_63:
...
@@ -9390,7 +9423,8 @@ basic_json_parser_63:
@return an object that maps JSON pointers to primitve values
@return an object that maps JSON pointers to primitve values
@note Empty objects and arrays are flattened to `null`.
@note Empty objects and arrays are flattened to `null` and will not be
reconstructed correctly by the @ref unflatten() function.
@complexity Linear in the size the JSON value.
@complexity Linear in the size the JSON value.
...
@@ -9428,6 +9462,8 @@ basic_json_parser_63:
...
@@ -9428,6 +9462,8 @@ basic_json_parser_63:
@complexity Linear in the size the JSON value.
@complexity Linear in the size the JSON value.
@throws std::domain_error
@liveexample{The following code shows how a flattened JSON object is
@liveexample{The following code shows how a flattened JSON object is
unflattened into the original nested JSON object.,unflatten}
unflattened into the original nested JSON object.,unflatten}
...
...
src/json.hpp.re2c
View file @
62682879
...
@@ -3273,8 +3273,8 @@ class basic_json
...
@@ -3273,8 +3273,8 @@ class basic_json
@return reference to the element at index @a idx
@return reference to the element at index @a idx
@throw std::domain_error if JSON is not an array or null; example:
`"cannot
@throw std::domain_error if JSON is not an array or null; example:
use operator[] with string"`
`"cannot
use operator[] with string"`
@complexity Constant if @a idx is in the range of the array. Otherwise
@complexity Constant if @a idx is in the range of the array. Otherwise
linear in `idx - size()`.
linear in `idx - size()`.
...
@@ -3620,7 +3620,9 @@ class basic_json
...
@@ -3620,7 +3620,9 @@ class basic_json
@complexity Linear in the length of the JSON pointer.
@complexity Linear in the length of the JSON pointer.
@throw std::out_of_range if the JSON pointer can not be resolved
@throw std::out_of_range if the JSON pointer can not be resolved
@throw std::domain_error if an array index begins with '0'
@throw std::invalid_argument if an array index was not a number
@liveexample{The behavior is shown in the example.,operatorjson_pointer}
@liveexample{The behavior is shown in the example.,operatorjson_pointer}
...
@@ -3645,8 +3647,9 @@ class basic_json
...
@@ -3645,8 +3647,9 @@ class basic_json
@complexity Linear in the length of the JSON pointer.
@complexity Linear in the length of the JSON pointer.
@throw std::out_of_range if the JSON pointer can not be resolved
@throw std::out_of_range if the JSON pointer can not be resolved
@throw std::out_of_range if the special value `-` is used for an array
@throw std::domain_error if an array index begins with '0'
@throw std::invalid_argument if an array index was not a number
@liveexample{The behavior is shown in the example.,
@liveexample{The behavior is shown in the example.,
operatorjson_pointer_const}
operatorjson_pointer_const}
...
@@ -8233,9 +8236,12 @@ class basic_json
...
@@ -8233,9 +8236,12 @@ class basic_json
empty string is assumed which references the whole JSON
empty string is assumed which references the whole JSON
value
value
@throw std::domain_error if reference token is nonempty and does not
@throw std::domain_error if reference token is nonempty and does not
begin with a slash (`/`), or if a tilde (`~`) is not followed
begin with a slash (`/`); example: `"JSON pointer must be empty or
by `0` (representing `~`) or `1` (representing `/`).
begin with /"`
@throw std::domain_error if a tilde (`~`) is not followed by `0`
(representing `~`) or `1` (representing `/`); example: `"escape error:
~ must be followed with 0 or 1"`
@liveexample{The example shows the construction several valid JSON
@liveexample{The example shows the construction several valid JSON
pointers as well as the exceptional behavior.,json_pointer}
pointers as well as the exceptional behavior.,json_pointer}
...
@@ -8254,6 +8260,8 @@ class basic_json
...
@@ -8254,6 +8260,8 @@ class basic_json
{
{
pointer result = &j;
pointer result = &j;
// in case no reference tokens exist, return a reference to the
// JSON value j which will be overwritten by a primitive value
for (const auto& reference_token : reference_tokens)
for (const auto& reference_token : reference_tokens)
{
{
switch (result->m_type)
switch (result->m_type)
...
@@ -8262,10 +8270,12 @@ class basic_json
...
@@ -8262,10 +8270,12 @@ class basic_json
{
{
if (reference_token == "0")
if (reference_token == "0")
{
{
// start a new array if reference token is 0
result = &result->operator[](0);
result = &result->operator[](0);
}
}
else
else
{
{
// start a new object otherwise
result = &result->operator[](reference_token);
result = &result->operator[](reference_token);
}
}
break;
break;
...
@@ -8273,19 +8283,38 @@ class basic_json
...
@@ -8273,19 +8283,38 @@ class basic_json
case value_t::object:
case value_t::object:
{
{
// create an entry in the object
result = &result->operator[](reference_token);
result = &result->operator[](reference_token);
break;
break;
}
}
case value_t::array:
case value_t::array:
{
{
// create an entry in the array
result = &result->operator[](static_cast<size_t>(std::stoi(reference_token)));
result = &result->operator[](static_cast<size_t>(std::stoi(reference_token)));
break;
break;
}
}
/*
This function is only to be called from the unflatten()
function. There, j is initially of type null.
- In case the reference tokens are empty, a reference to
j is returned and overwritten by the desired value by
the unflatten() function.
- If there are reference tokens, the null value of j will
be changed to an object or array after reading the first
reference token.
- All subsequent tokens work on arrays or objects and will
not change the type of j.
Consequently, the type of @a j will always be null,
object, or array. Hence, the following line is
unreachable.
*/
default:
default:
{
{
throw std::domain_error("unresolved reference token '" + reference_token + "'");
break; // LCOV_EXCL_LINE
}
}
}
}
}
}
...
@@ -8671,7 +8700,11 @@ class basic_json
...
@@ -8671,7 +8700,11 @@ class basic_json
throw std::domain_error("values in object must be primitive");
throw std::domain_error("values in object must be primitive");
}
}
// assign value to reference pointed to by JSON pointer
// assign value to reference pointed to by JSON pointer;
// Note that if the JSON pointer is "" (i.e., points to the
// whole value), function get_and_create returns a reference
// to result itself. An assignment will then create a
// primitive value.
json_pointer(element.first).get_and_create(result) = element.second;
json_pointer(element.first).get_and_create(result) = element.second;
}
}
...
@@ -8700,7 +8733,8 @@ class basic_json
...
@@ -8700,7 +8733,8 @@ class basic_json
@return an object that maps JSON pointers to primitve values
@return an object that maps JSON pointers to primitve values
@note Empty objects and arrays are flattened to `null`.
@note Empty objects and arrays are flattened to `null` and will not be
reconstructed correctly by the @ref unflatten() function.
@complexity Linear in the size the JSON value.
@complexity Linear in the size the JSON value.
...
@@ -8738,6 +8772,8 @@ class basic_json
...
@@ -8738,6 +8772,8 @@ class basic_json
@complexity Linear in the size the JSON value.
@complexity Linear in the size the JSON value.
@throws std::domain_error
@liveexample{The following code shows how a flattened JSON object is
@liveexample{The following code shows how a flattened JSON object is
unflattened into the original nested JSON object.,unflatten}
unflattened into the original nested JSON object.,unflatten}
...
...
test/unit.cpp
View file @
62682879
...
@@ -12365,6 +12365,11 @@ TEST_CASE("JSON pointers")
...
@@ -12365,6 +12365,11 @@ TEST_CASE("JSON pointers")
CHECK_THROWS_AS
(
json
({{
"/1"
,
{
1
,
2
,
3
}}}).
unflatten
(),
std
::
domain_error
);
CHECK_THROWS_AS
(
json
({{
"/1"
,
{
1
,
2
,
3
}}}).
unflatten
(),
std
::
domain_error
);
CHECK_THROWS_WITH
(
json
({{
"/1"
,
{
1
,
2
,
3
}}}).
unflatten
(),
"values in object must be primitive"
);
CHECK_THROWS_WITH
(
json
({{
"/1"
,
{
1
,
2
,
3
}}}).
unflatten
(),
"values in object must be primitive"
);
// error for conflicting values
json
j_error
=
{{
""
,
42
},
{
"/foo"
,
17
}};
CHECK_THROWS_AS
(
j_error
.
unflatten
(),
std
::
domain_error
);
CHECK_THROWS_WITH
(
j_error
.
unflatten
(),
"unresolved reference token 'foo'"
);
// explicit roundtrip check
// explicit roundtrip check
CHECK
(
j
.
flatten
().
unflatten
()
==
j
);
CHECK
(
j
.
flatten
().
unflatten
()
==
j
);
...
...
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