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
e7a60d89
Commit
e7a60d89
authored
Oct 12, 2016
by
Niels
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feature/issue323' into develop
parents
a0ef5a19
470197bd
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
95 additions
and
9 deletions
+95
-9
README.md
README.md
+6
-6
operatorjson_pointer.cpp
doc/examples/operatorjson_pointer.cpp
+1
-1
json.hpp
src/json.hpp
+31
-0
json.hpp.re2c
src/json.hpp.re2c
+31
-0
unit-deserialization.cpp
test/src/unit-deserialization.cpp
+12
-0
unit-json_pointer.cpp
test/src/unit-json_pointer.cpp
+7
-2
unit-regression.cpp
test/src/unit-regression.cpp
+7
-0
No files found.
README.md
View file @
e7a60d89
...
@@ -515,17 +515,17 @@ To compile and run the tests, you need to execute
...
@@ -515,17 +515,17 @@ To compile and run the tests, you need to execute
$ make check
$ make check
===============================================================================
===============================================================================
All tests passed (890516
1
assertions in 35 test cases)
All tests passed (890516
6
assertions in 35 test cases)
```
```
Alternatively, you can use [https://cmake.org](CMake) and run
Alternatively, you can use [https://cmake.org](CMake) and run
```
sh
```
sh
mkdir build
$
mkdir build
cd build
$
cd build
cmake ..
$
cmake ..
make
$
make
ctest
$
ctest
```
```
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/operatorjson_pointer.cpp
View file @
e7a60d89
...
@@ -40,7 +40,7 @@ int main()
...
@@ -40,7 +40,7 @@ int main()
// output the changed array
// output the changed array
std
::
cout
<<
j
[
"array"
]
<<
'\n'
;
std
::
cout
<<
j
[
"array"
]
<<
'\n'
;
// "change" the arry element past the end
// "change" the arr
a
y element past the end
j
[
"/array/-"
_json_pointer
]
=
55
;
j
[
"/array/-"
_json_pointer
]
=
55
;
// output the changed array
// output the changed array
std
::
cout
<<
j
[
"array"
]
<<
'\n'
;
std
::
cout
<<
j
[
"array"
]
<<
'\n'
;
...
...
src/json.hpp
View file @
e7a60d89
...
@@ -32,6 +32,7 @@ SOFTWARE.
...
@@ -32,6 +32,7 @@ SOFTWARE.
#include <algorithm>
#include <algorithm>
#include <array>
#include <array>
#include <cassert>
#include <cassert>
#include <cctype>
#include <ciso646>
#include <ciso646>
#include <cmath>
#include <cmath>
#include <cstddef>
#include <cstddef>
...
@@ -9436,6 +9437,12 @@ basic_json_parser_63:
...
@@ -9436,6 +9437,12 @@ basic_json_parser_63:
/*!
/*!
@brief return a reference to the pointed to value
@brief return a reference to the pointed to value
@note This version does not throw if a value is not present, but tries
to create nested values instead. For instance, calling this function
with pointer `"/this/that"` on a null value is equivalent to calling
`operator[]("this").operator[]("that")` on that value, effectively
changing the null value to an object.
@param[in] ptr a JSON value
@param[in] ptr a JSON value
@return reference to the JSON value pointed to by the JSON pointer
@return reference to the JSON value pointed to by the JSON pointer
...
@@ -9450,6 +9457,29 @@ basic_json_parser_63:
...
@@ -9450,6 +9457,29 @@ basic_json_parser_63:
{
{
for
(
const
auto
&
reference_token
:
reference_tokens
)
for
(
const
auto
&
reference_token
:
reference_tokens
)
{
{
// convert null values to arrays or objects before continuing
if
(
ptr
->
m_type
==
value_t
::
null
)
{
// check if reference token is a number
const
bool
nums
=
std
::
all_of
(
reference_token
.
begin
(),
reference_token
.
end
(),
[](
const
char
x
)
{
return
std
::
isdigit
(
x
);
});
// change value to array for numbers or "-" or to object
// otherwise
if
(
nums
or
reference_token
==
"-"
)
{
*
ptr
=
value_t
::
array
;
}
else
{
*
ptr
=
value_t
::
object
;
}
}
switch
(
ptr
->
m_type
)
switch
(
ptr
->
m_type
)
{
{
case
value_t
:
:
object
:
case
value_t
:
:
object
:
...
@@ -9461,6 +9491,7 @@ basic_json_parser_63:
...
@@ -9461,6 +9491,7 @@ basic_json_parser_63:
case
value_t
:
:
array
:
case
value_t
:
:
array
:
{
{
// error condition (cf. RFC 6901, Sect. 4)
// error condition (cf. RFC 6901, Sect. 4)
if
(
reference_token
.
size
()
>
1
and
reference_token
[
0
]
==
'0'
)
if
(
reference_token
.
size
()
>
1
and
reference_token
[
0
]
==
'0'
)
{
{
...
...
src/json.hpp.re2c
View file @
e7a60d89
...
@@ -32,6 +32,7 @@ SOFTWARE.
...
@@ -32,6 +32,7 @@ SOFTWARE.
#include <algorithm>
#include <algorithm>
#include <array>
#include <array>
#include <cassert>
#include <cassert>
#include <cctype>
#include <ciso646>
#include <ciso646>
#include <cmath>
#include <cmath>
#include <cstddef>
#include <cstddef>
...
@@ -8733,6 +8734,12 @@ class basic_json
...
@@ -8733,6 +8734,12 @@ class basic_json
/*!
/*!
@brief return a reference to the pointed to value
@brief return a reference to the pointed to value
@note This version does not throw if a value is not present, but tries
to create nested values instead. For instance, calling this function
with pointer `"/this/that"` on a null value is equivalent to calling
`operator[]("this").operator[]("that")` on that value, effectively
changing the null value to an object.
@param[in] ptr a JSON value
@param[in] ptr a JSON value
@return reference to the JSON value pointed to by the JSON pointer
@return reference to the JSON value pointed to by the JSON pointer
...
@@ -8747,6 +8754,29 @@ class basic_json
...
@@ -8747,6 +8754,29 @@ class basic_json
{
{
for (const auto& reference_token : reference_tokens)
for (const auto& reference_token : reference_tokens)
{
{
// convert null values to arrays or objects before continuing
if (ptr->m_type == value_t::null)
{
// check if reference token is a number
const bool nums = std::all_of(reference_token.begin(),
reference_token.end(),
[](const char x)
{
return std::isdigit(x);
});
// change value to array for numbers or "-" or to object
// otherwise
if (nums or reference_token == "-")
{
*ptr = value_t::array;
}
else
{
*ptr = value_t::object;
}
}
switch (ptr->m_type)
switch (ptr->m_type)
{
{
case value_t::object:
case value_t::object:
...
@@ -8758,6 +8788,7 @@ class basic_json
...
@@ -8758,6 +8788,7 @@ class basic_json
case value_t::array:
case value_t::array:
{
{
// error condition (cf. RFC 6901, Sect. 4)
// error condition (cf. RFC 6901, Sect. 4)
if (reference_token.size() > 1 and reference_token[0] == '0')
if (reference_token.size() > 1 and reference_token[0] == '0')
{
{
...
...
test/src/unit-deserialization.cpp
View file @
e7a60d89
...
@@ -238,6 +238,18 @@ TEST_CASE("deserialization")
...
@@ -238,6 +238,18 @@ TEST_CASE("deserialization")
uint8_t
v
[]
=
{
'\"'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'\\'
,
'u'
,
'1'
};
uint8_t
v
[]
=
{
'\"'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'\\'
,
'u'
,
'1'
};
CHECK_THROWS_AS
(
json
::
parse
(
std
::
begin
(
v
),
std
::
end
(
v
)),
std
::
invalid_argument
);
CHECK_THROWS_AS
(
json
::
parse
(
std
::
begin
(
v
),
std
::
end
(
v
)),
std
::
invalid_argument
);
}
}
SECTION
(
"case 3"
)
{
uint8_t
v
[]
=
{
'\"'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'\\'
,
'u'
,
'1'
,
'1'
,
'1'
,
'1'
,
'1'
,
'1'
,
'1'
,
'1'
};
CHECK_THROWS_AS
(
json
::
parse
(
std
::
begin
(
v
),
std
::
end
(
v
)),
std
::
invalid_argument
);
}
SECTION
(
"case 4"
)
{
uint8_t
v
[]
=
{
'\"'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'a'
,
'u'
,
'1'
,
'1'
,
'1'
,
'1'
,
'1'
,
'1'
,
'1'
,
'1'
,
'\\'
};
CHECK_THROWS_AS
(
json
::
parse
(
std
::
begin
(
v
),
std
::
end
(
v
)),
std
::
invalid_argument
);
}
}
}
}
}
}
}
test/src/unit-json_pointer.cpp
View file @
e7a60d89
...
@@ -109,8 +109,13 @@ TEST_CASE("JSON pointers")
...
@@ -109,8 +109,13 @@ TEST_CASE("JSON pointers")
CHECK
(
j
[
json
::
json_pointer
(
"/m~0n"
)]
==
j
[
"m~n"
]);
CHECK
(
j
[
json
::
json_pointer
(
"/m~0n"
)]
==
j
[
"m~n"
]);
// unescaped access
// unescaped access
CHECK_THROWS_AS
(
j
[
json
::
json_pointer
(
"/a/b"
)],
std
::
out_of_range
);
// access to nonexisting values yield object creation
CHECK_THROWS_WITH
(
j
[
json
::
json_pointer
(
"/a/b"
)],
"unresolved reference token 'b'"
);
CHECK_NOTHROW
(
j
[
json
::
json_pointer
(
"/a/b"
)]
=
42
);
CHECK
(
j
[
"a"
][
"b"
]
==
json
(
42
));
CHECK_NOTHROW
(
j
[
json
::
json_pointer
(
"/a/c/1"
)]
=
42
);
CHECK
(
j
[
"a"
][
"c"
]
==
json
({
nullptr
,
42
}));
CHECK_NOTHROW
(
j
[
json
::
json_pointer
(
"/a/d/-"
)]
=
42
);
CHECK
(
j
[
"a"
][
"d"
]
==
json
::
array
({
42
}));
// "/a/b" works for JSON {"a": {"b": 42}}
// "/a/b" works for JSON {"a": {"b": 42}}
CHECK
(
json
({{
"a"
,
{{
"b"
,
42
}}}})[
json
::
json_pointer
(
"/a/b"
)]
==
json
(
42
));
CHECK
(
json
({{
"a"
,
{{
"b"
,
42
}}}})[
json
::
json_pointer
(
"/a/b"
)]
==
json
(
42
));
...
...
test/src/unit-regression.cpp
View file @
e7a60d89
...
@@ -482,4 +482,11 @@ TEST_CASE("regression tests")
...
@@ -482,4 +482,11 @@ TEST_CASE("regression tests")
CHECK_NOTHROW
(
j
<<
f
);
CHECK_NOTHROW
(
j
<<
f
);
}
}
}
}
SECTION
(
"issue #323 - add nested object capabilities to pointers"
)
{
json
j
;
j
[
"/this/that"
_json_pointer
]
=
27
;
CHECK
(
j
==
json
({{
"this"
,
{{
"that"
,
27
}}}}));
}
}
}
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