Merge branch 'feature/issue323' into develop
This commit is contained in:
		
						commit
						e7a60d8961
					
				
					 7 changed files with 95 additions and 9 deletions
				
			
		
							
								
								
									
										12
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								README.md
									
										
									
									
									
								
							|  | @ -515,17 +515,17 @@ To compile and run the tests, you need to execute | |||
| $ make check | ||||
| 
 | ||||
| =============================================================================== | ||||
| All tests passed (8905161 assertions in 35 test cases) | ||||
| All tests passed (8905166 assertions in 35 test cases) | ||||
| ``` | ||||
| 
 | ||||
| Alternatively, you can use [https://cmake.org](CMake) and run | ||||
| 
 | ||||
| ```sh | ||||
| mkdir build | ||||
| cd build | ||||
| cmake .. | ||||
| make | ||||
| ctest | ||||
| $ mkdir build | ||||
| $ cd build | ||||
| $ cmake .. | ||||
| $ make | ||||
| $ ctest | ||||
| ``` | ||||
| 
 | ||||
| For more information, have a look at the file [.travis.yml](https://github.com/nlohmann/json/blob/master/.travis.yml). | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ int main() | |||
|     // output the changed array
 | ||||
|     std::cout << j["array"] << '\n'; | ||||
| 
 | ||||
|     // "change" the arry element past the end
 | ||||
|     // "change" the array element past the end
 | ||||
|     j["/array/-"_json_pointer] = 55; | ||||
|     // output the changed array
 | ||||
|     std::cout << j["array"] << '\n'; | ||||
|  |  | |||
							
								
								
									
										31
									
								
								src/json.hpp
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								src/json.hpp
									
										
									
									
									
								
							|  | @ -32,6 +32,7 @@ SOFTWARE. | |||
| #include <algorithm> | ||||
| #include <array> | ||||
| #include <cassert> | ||||
| #include <cctype> | ||||
| #include <ciso646> | ||||
| #include <cmath> | ||||
| #include <cstddef> | ||||
|  | @ -9436,6 +9437,12 @@ basic_json_parser_63: | |||
|         /*!
 | ||||
|         @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 | ||||
| 
 | ||||
|         @return reference to the JSON value pointed to by the JSON pointer | ||||
|  | @ -9450,6 +9457,29 @@ basic_json_parser_63: | |||
|         { | ||||
|             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) | ||||
|                 { | ||||
|                     case value_t::object: | ||||
|  | @ -9461,6 +9491,7 @@ basic_json_parser_63: | |||
| 
 | ||||
|                     case value_t::array: | ||||
|                     { | ||||
| 
 | ||||
|                         // error condition (cf. RFC 6901, Sect. 4)
 | ||||
|                         if (reference_token.size() > 1 and reference_token[0] == '0') | ||||
|                         { | ||||
|  |  | |||
|  | @ -32,6 +32,7 @@ SOFTWARE. | |||
| #include <algorithm> | ||||
| #include <array> | ||||
| #include <cassert> | ||||
| #include <cctype> | ||||
| #include <ciso646> | ||||
| #include <cmath> | ||||
| #include <cstddef> | ||||
|  | @ -8733,6 +8734,12 @@ class basic_json | |||
|         /*! | ||||
|         @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 | ||||
| 
 | ||||
|         @return reference to the JSON value pointed to by the JSON pointer | ||||
|  | @ -8747,6 +8754,29 @@ class basic_json | |||
|         { | ||||
|             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) | ||||
|                 { | ||||
|                     case value_t::object: | ||||
|  | @ -8758,6 +8788,7 @@ class basic_json | |||
| 
 | ||||
|                     case value_t::array: | ||||
|                     { | ||||
| 
 | ||||
|                         // error condition (cf. RFC 6901, Sect. 4) | ||||
|                         if (reference_token.size() > 1 and reference_token[0] == '0') | ||||
|                         { | ||||
|  |  | |||
|  | @ -238,6 +238,18 @@ TEST_CASE("deserialization") | |||
|                 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); | ||||
|             } | ||||
| 
 | ||||
|             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); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -109,8 +109,13 @@ TEST_CASE("JSON pointers") | |||
|             CHECK(j[json::json_pointer("/m~0n")] == j["m~n"]); | ||||
| 
 | ||||
|             // unescaped access
 | ||||
|             CHECK_THROWS_AS(j[json::json_pointer("/a/b")], std::out_of_range); | ||||
|             CHECK_THROWS_WITH(j[json::json_pointer("/a/b")], "unresolved reference token 'b'"); | ||||
|             // access to nonexisting values yield object creation
 | ||||
|             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}}
 | ||||
|             CHECK(json({{"a", {{"b", 42}}}})[json::json_pointer("/a/b")] == json(42)); | ||||
| 
 | ||||
|  |  | |||
|  | @ -482,4 +482,11 @@ TEST_CASE("regression tests") | |||
|             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}}}})); | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue