more on #290
This commit is contained in:
parent
eef8059003
commit
b4571360df
16 changed files with 298 additions and 101 deletions
|
@ -511,7 +511,7 @@ To compile and run the tests, you need to execute
|
||||||
$ make check
|
$ make check
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
All tests passed (8905099 assertions in 32 test cases)
|
All tests passed (8905119 assertions in 32 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).
|
||||||
|
|
28
doc/examples/parse__array__parser_callback_t.cpp
Normal file
28
doc/examples/parse__array__parser_callback_t.cpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a JSON text
|
||||||
|
char text[] = R"(
|
||||||
|
{
|
||||||
|
"Image": {
|
||||||
|
"Width": 800,
|
||||||
|
"Height": 600,
|
||||||
|
"Title": "View from 15th Floor",
|
||||||
|
"Thumbnail": {
|
||||||
|
"Url": "http://www.example.com/image/481989943",
|
||||||
|
"Height": 125,
|
||||||
|
"Width": 100
|
||||||
|
},
|
||||||
|
"Animated" : false,
|
||||||
|
"IDs": [116, 943, 234, 38793]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
// parse and serialize JSON
|
||||||
|
json j_complete = json::parse(text);
|
||||||
|
std::cout << std::setw(4) << j_complete << "\n\n";
|
||||||
|
}
|
1
doc/examples/parse__array__parser_callback_t.link
Normal file
1
doc/examples/parse__array__parser_callback_t.link
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<a target="_blank" href="http://melpon.org/wandbox/permlink/LvZQq5fybVH1nh9L"><b>online</b></a>
|
20
doc/examples/parse__array__parser_callback_t.output
Normal file
20
doc/examples/parse__array__parser_callback_t.output
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"Image": {
|
||||||
|
"Animated": false,
|
||||||
|
"Height": 600,
|
||||||
|
"IDs": [
|
||||||
|
116,
|
||||||
|
943,
|
||||||
|
234,
|
||||||
|
38793
|
||||||
|
],
|
||||||
|
"Thumbnail": {
|
||||||
|
"Height": 125,
|
||||||
|
"Url": "http://www.example.com/image/481989943",
|
||||||
|
"Width": 100
|
||||||
|
},
|
||||||
|
"Title": "View from 15th Floor",
|
||||||
|
"Width": 800
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a JSON text given as std::vector
|
||||||
|
std::vector<uint8_t> text = {'[', '1', ',', '2', ',', '3', ']', '\0'};
|
||||||
|
|
||||||
|
// parse and serialize JSON
|
||||||
|
json j_complete = json::parse(text);
|
||||||
|
std::cout << std::setw(4) << j_complete << "\n\n";
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
<a target="_blank" href="http://melpon.org/wandbox/permlink/F8VaVFyys87qQRt5"><b>online</b></a>
|
|
@ -0,0 +1,6 @@
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
|
13
doc/examples/parse__iteratortype__parser_callback_t.cpp
Normal file
13
doc/examples/parse__iteratortype__parser_callback_t.cpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// a JSON text given as std::vector
|
||||||
|
std::vector<uint8_t> text = {'[', '1', ',', '2', ',', '3', ']', '\0'};
|
||||||
|
|
||||||
|
// parse and serialize JSON
|
||||||
|
json j_complete = json::parse(text.begin(), text.end());
|
||||||
|
std::cout << std::setw(4) << j_complete << "\n\n";
|
||||||
|
}
|
1
doc/examples/parse__iteratortype__parser_callback_t.link
Normal file
1
doc/examples/parse__iteratortype__parser_callback_t.link
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<a target="_blank" href="http://melpon.org/wandbox/permlink/ojh4Eeol4G9RgeRV"><b>online</b></a>
|
|
@ -0,0 +1,6 @@
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
|
|
@ -5,7 +5,7 @@ using json = nlohmann::json;
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// a JSON text
|
// a JSON text
|
||||||
std::string text = R"(
|
auto text = R"(
|
||||||
{
|
{
|
||||||
"Image": {
|
"Image": {
|
||||||
"Width": 800,
|
"Width": 800,
|
||||||
|
@ -44,4 +44,4 @@ int main()
|
||||||
// parse (with callback) and serialize JSON
|
// parse (with callback) and serialize JSON
|
||||||
json j_filtered = json::parse(text, cb);
|
json j_filtered = json::parse(text, cb);
|
||||||
std::cout << std::setw(4) << j_filtered << '\n';
|
std::cout << std::setw(4) << j_filtered << '\n';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<a target="_blank" href="http://melpon.org/wandbox/permlink/SrKpkE9ivmvd2OUy"><b>online</b></a>
|
<a target="_blank" href="http://melpon.org/wandbox/permlink/n888UNQlMFduURhE"><b>online</b></a>
|
133
src/json.hpp
133
src/json.hpp
|
@ -951,7 +951,7 @@ class basic_json
|
||||||
|
|
||||||
With a parser callback function, the result of parsing a JSON text can be
|
With a parser callback function, the result of parsing a JSON text can be
|
||||||
influenced. When passed to @ref parse(std::istream&, const
|
influenced. When passed to @ref parse(std::istream&, const
|
||||||
parser_callback_t) or @ref parse(const string_t&, const parser_callback_t),
|
parser_callback_t) or @ref parse(const char*, const parser_callback_t),
|
||||||
it is called on certain events (passed as @ref parse_event_t via parameter
|
it is called on certain events (passed as @ref parse_event_t via parameter
|
||||||
@a event) with a set recursion depth @a depth and context JSON value
|
@a event) with a set recursion depth @a depth and context JSON value
|
||||||
@a parsed. The return value of the callback function is a boolean
|
@a parsed. The return value of the callback function is a boolean
|
||||||
|
@ -994,7 +994,7 @@ class basic_json
|
||||||
skipped completely or replaced by an empty discarded object.
|
skipped completely or replaced by an empty discarded object.
|
||||||
|
|
||||||
@sa @ref parse(std::istream&, parser_callback_t) or
|
@sa @ref parse(std::istream&, parser_callback_t) or
|
||||||
@ref parse(const string_t&, parser_callback_t) for examples
|
@ref parse(const char*, parser_callback_t) for examples
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
*/
|
*/
|
||||||
|
@ -5933,9 +5933,9 @@ class basic_json
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief deserialize from string
|
@brief deserialize from string literal
|
||||||
|
|
||||||
@param[in] s string to read a serialized JSON value from
|
@param[in] s string literal to read a serialized JSON value from
|
||||||
@param[in] cb a parser callback function of type @ref parser_callback_t
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
which is used to control the deserialization by filtering unwanted values
|
which is used to control the deserialization by filtering unwanted values
|
||||||
(optional)
|
(optional)
|
||||||
|
@ -5947,6 +5947,8 @@ class basic_json
|
||||||
@a cb has a super-linear complexity.
|
@a cb has a super-linear complexity.
|
||||||
|
|
||||||
@note A UTF-8 byte order mark is silently ignored.
|
@note A UTF-8 byte order mark is silently ignored.
|
||||||
|
@note String containers like `std::string` or @ref string_t can be parsed
|
||||||
|
with @ref parse(const ContiguousContainer&, const parser_callback_t)
|
||||||
|
|
||||||
@liveexample{The example below demonstrates the `parse()` function with
|
@liveexample{The example below demonstrates the `parse()` function with
|
||||||
and without callback function.,parse__string__parser_callback_t}
|
and without callback function.,parse__string__parser_callback_t}
|
||||||
|
@ -5954,24 +5956,47 @@ class basic_json
|
||||||
@sa @ref parse(std::istream&, const parser_callback_t) for a version that
|
@sa @ref parse(std::istream&, const parser_callback_t) for a version that
|
||||||
reads from an input stream
|
reads from an input stream
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0 (originally for @ref string_t)
|
||||||
*/
|
*/
|
||||||
/*
|
static basic_json parse(const char* s,
|
||||||
static basic_json parse(const string_t& s,
|
|
||||||
const parser_callback_t cb = nullptr)
|
const parser_callback_t cb = nullptr)
|
||||||
{
|
{
|
||||||
return parser(s, cb).parse();
|
return parser(s, cb).parse();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief deserialize from string literal
|
@brief deserialize from an array
|
||||||
@copydoc parse(const string_t&, const parser_callback_t)
|
|
||||||
|
This function reads from an array of 1-byte values.
|
||||||
|
|
||||||
|
@pre Each element of the container has a size of 1 byte. Violating this
|
||||||
|
precondition yields undefined behavior. **This precondition is enforced
|
||||||
|
with a static assertion.**
|
||||||
|
|
||||||
|
@param[in] array array to read from
|
||||||
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
|
which is used to control the deserialization by filtering unwanted values
|
||||||
|
(optional)
|
||||||
|
|
||||||
|
@return result of the deserialization
|
||||||
|
|
||||||
|
@complexity Linear in the length of the input. The parser is a predictive
|
||||||
|
LL(1) parser. The complexity can be higher if the parser callback function
|
||||||
|
@a cb has a super-linear complexity.
|
||||||
|
|
||||||
|
@note A UTF-8 byte order mark is silently ignored.
|
||||||
|
|
||||||
|
@liveexample{The example below demonstrates the `parse()` function reading
|
||||||
|
from an array.,parse__array__parser_callback_t}
|
||||||
|
|
||||||
|
@since version 2.0.3
|
||||||
*/
|
*/
|
||||||
static basic_json parse(const typename string_t::value_type* s,
|
template<class T, std::size_t N>
|
||||||
|
static basic_json parse(T (&array)[N],
|
||||||
const parser_callback_t cb = nullptr)
|
const parser_callback_t cb = nullptr)
|
||||||
{
|
{
|
||||||
return parser(s, cb).parse();
|
// delegate the call to the iterator-range parse overload
|
||||||
|
return parse(std::begin(array), std::end(array), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -5993,7 +6018,7 @@ class basic_json
|
||||||
@liveexample{The example below demonstrates the `parse()` function with
|
@liveexample{The example below demonstrates the `parse()` function with
|
||||||
and without callback function.,parse__istream__parser_callback_t}
|
and without callback function.,parse__istream__parser_callback_t}
|
||||||
|
|
||||||
@sa @ref parse(const string_t&, const parser_callback_t) for a version
|
@sa @ref parse(const char*, const parser_callback_t) for a version
|
||||||
that reads from a string
|
that reads from a string
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
|
@ -6014,7 +6039,7 @@ class basic_json
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief deserialize from a iterator range with contiguous storage
|
@brief deserialize from an iterator range with contiguous storage
|
||||||
|
|
||||||
This function reads from an iterator range of a container with contiguous
|
This function reads from an iterator range of a container with contiguous
|
||||||
storage of 1-byte values. Compatible container types include
|
storage of 1-byte values. Compatible container types include
|
||||||
|
@ -6029,13 +6054,14 @@ class basic_json
|
||||||
precondition yields undefined behavior. **This precondition is enforced
|
precondition yields undefined behavior. **This precondition is enforced
|
||||||
with a static assertion.**
|
with a static assertion.**
|
||||||
|
|
||||||
@warning There is no way to enforce the preconditions at compile-time. If
|
@warning There is no way to enforce all preconditions at compile-time. If
|
||||||
the function is called with noncompliant iterators, the behavior
|
the function is called with noncompliant iterators and with
|
||||||
is undefined and will most liekely yield segmentation violation.
|
assertions switched off, the behavior is undefined and will most
|
||||||
|
likely yield segmentation violation.
|
||||||
|
|
||||||
@param[in] first begin of the range to parse (included)
|
@param[in] first begin of the range to parse (included)
|
||||||
@param[in] last end of the range to parse (excluded)
|
@param[in] last end of the range to parse (excluded)
|
||||||
@param[in] cb a parser callback function of type @ref parser_callback_t
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
which is used to control the deserialization by filtering unwanted values
|
which is used to control the deserialization by filtering unwanted values
|
||||||
(optional)
|
(optional)
|
||||||
|
|
||||||
|
@ -6047,7 +6073,8 @@ class basic_json
|
||||||
|
|
||||||
@note A UTF-8 byte order mark is silently ignored.
|
@note A UTF-8 byte order mark is silently ignored.
|
||||||
|
|
||||||
@todo Example and references.
|
@liveexample{The example below demonstrates the `parse()` function reading
|
||||||
|
from an iterator range.,parse__iteratortype__parser_callback_t}
|
||||||
|
|
||||||
@since version 2.0.3
|
@since version 2.0.3
|
||||||
*/
|
*/
|
||||||
|
@ -6084,6 +6111,45 @@ class basic_json
|
||||||
return parser(first, last, cb).parse();
|
return parser(first, last, cb).parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief deserialize from a container with contiguous storage
|
||||||
|
|
||||||
|
This function reads from a container with contiguous storage of 1-byte
|
||||||
|
values. Compatible container types include `std::vector`, `std::string`,
|
||||||
|
`std::array`, and `std::initializer_list`. User-defined containers can be
|
||||||
|
used as long as they implement random-access iterators and a contiguous
|
||||||
|
storage.
|
||||||
|
|
||||||
|
@pre The container storage is contiguous. Violating this precondition
|
||||||
|
yields undefined behavior. **This precondition is enforced with an
|
||||||
|
assertion.**
|
||||||
|
@pre Each element of the container has a size of 1 byte. Violating this
|
||||||
|
precondition yields undefined behavior. **This precondition is enforced
|
||||||
|
with a static assertion.**
|
||||||
|
|
||||||
|
@warning There is no way to enforce all preconditions at compile-time. If
|
||||||
|
the function is called with a noncompliant container and with
|
||||||
|
assertions switched off, the behavior is undefined and will most
|
||||||
|
likely yield segmentation violation.
|
||||||
|
|
||||||
|
@param[in] c container to read from
|
||||||
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
|
which is used to control the deserialization by filtering unwanted values
|
||||||
|
(optional)
|
||||||
|
|
||||||
|
@return result of the deserialization
|
||||||
|
|
||||||
|
@complexity Linear in the length of the input. The parser is a predictive
|
||||||
|
LL(1) parser. The complexity can be higher if the parser callback function
|
||||||
|
@a cb has a super-linear complexity.
|
||||||
|
|
||||||
|
@note A UTF-8 byte order mark is silently ignored.
|
||||||
|
|
||||||
|
@liveexample{The example below demonstrates the `parse()` function reading
|
||||||
|
from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
|
||||||
|
|
||||||
|
@since version 2.0.3
|
||||||
|
*/
|
||||||
template<class ContiguousContainer, typename
|
template<class ContiguousContainer, typename
|
||||||
std::enable_if<
|
std::enable_if<
|
||||||
std::is_base_of<
|
std::is_base_of<
|
||||||
|
@ -6097,14 +6163,6 @@ class basic_json
|
||||||
return parse(std::begin(c), std::end(c), cb);
|
return parse(std::begin(c), std::end(c), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
static basic_json parse(T (&array)[N],
|
|
||||||
const parser_callback_t cb = nullptr)
|
|
||||||
{
|
|
||||||
// delegate the call to the iterator-range parse overload
|
|
||||||
return parse(std::begin(array), std::end(array), cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief deserialize from stream
|
@brief deserialize from stream
|
||||||
|
|
||||||
|
@ -6158,7 +6216,7 @@ class basic_json
|
||||||
Returns the type name as string to be used in error messages - usually to
|
Returns the type name as string to be used in error messages - usually to
|
||||||
indicate that a function was called on a wrong JSON type.
|
indicate that a function was called on a wrong JSON type.
|
||||||
|
|
||||||
@return basically a string representation of a the @ref m_type member
|
@return basically a string representation of a the @a m_type member
|
||||||
|
|
||||||
@complexity Constant.
|
@complexity Constant.
|
||||||
|
|
||||||
|
@ -7626,7 +7684,7 @@ class basic_json
|
||||||
fill_line_buffer();
|
fill_line_buffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// switch off unwanted functions
|
// switch off unwanted functions (due to pointer members)
|
||||||
lexer() = delete;
|
lexer() = delete;
|
||||||
lexer(const lexer&) = delete;
|
lexer(const lexer&) = delete;
|
||||||
lexer operator=(const lexer&) = delete;
|
lexer operator=(const lexer&) = delete;
|
||||||
|
@ -8979,24 +9037,17 @@ basic_json_parser_63:
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// a parser reading from a string literal
|
/// a parser reading from a string literal
|
||||||
parser(const typename string_t::value_type* buff,
|
parser(const char* buff, const parser_callback_t cb = nullptr)
|
||||||
const parser_callback_t cb = nullptr)
|
|
||||||
: callback(cb),
|
: callback(cb),
|
||||||
m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), strlen(buff))
|
m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), strlen(buff))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// a parser reading from a string container
|
|
||||||
parser(const string_t& s, const parser_callback_t cb = nullptr)
|
|
||||||
: callback(cb),
|
|
||||||
m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(s.c_str()), s.size())
|
|
||||||
{}
|
|
||||||
|
|
||||||
/// a parser reading from an input stream
|
/// a parser reading from an input stream
|
||||||
parser(std::istream& is, const parser_callback_t cb = nullptr)
|
parser(std::istream& is, const parser_callback_t cb = nullptr)
|
||||||
: callback(cb), m_lexer(is)
|
: callback(cb), m_lexer(is)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// a parser reading from a container with contiguous storage
|
/// a parser reading from an iterator range with contiguous storage
|
||||||
template <class IteratorType, typename
|
template <class IteratorType, typename
|
||||||
std::enable_if<
|
std::enable_if<
|
||||||
std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
|
std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
|
||||||
|
@ -10560,7 +10611,7 @@ if no parse error occurred.
|
||||||
*/
|
*/
|
||||||
inline nlohmann::json operator "" _json(const char* s, std::size_t)
|
inline nlohmann::json operator "" _json(const char* s, std::size_t)
|
||||||
{
|
{
|
||||||
return nlohmann::json::parse(reinterpret_cast<const nlohmann::json::string_t::value_type*>(s));
|
return nlohmann::json::parse(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -951,7 +951,7 @@ class basic_json
|
||||||
|
|
||||||
With a parser callback function, the result of parsing a JSON text can be
|
With a parser callback function, the result of parsing a JSON text can be
|
||||||
influenced. When passed to @ref parse(std::istream&, const
|
influenced. When passed to @ref parse(std::istream&, const
|
||||||
parser_callback_t) or @ref parse(const string_t&, const parser_callback_t),
|
parser_callback_t) or @ref parse(const char*, const parser_callback_t),
|
||||||
it is called on certain events (passed as @ref parse_event_t via parameter
|
it is called on certain events (passed as @ref parse_event_t via parameter
|
||||||
@a event) with a set recursion depth @a depth and context JSON value
|
@a event) with a set recursion depth @a depth and context JSON value
|
||||||
@a parsed. The return value of the callback function is a boolean
|
@a parsed. The return value of the callback function is a boolean
|
||||||
|
@ -994,7 +994,7 @@ class basic_json
|
||||||
skipped completely or replaced by an empty discarded object.
|
skipped completely or replaced by an empty discarded object.
|
||||||
|
|
||||||
@sa @ref parse(std::istream&, parser_callback_t) or
|
@sa @ref parse(std::istream&, parser_callback_t) or
|
||||||
@ref parse(const string_t&, parser_callback_t) for examples
|
@ref parse(const char*, parser_callback_t) for examples
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
*/
|
*/
|
||||||
|
@ -5933,9 +5933,9 @@ class basic_json
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief deserialize from string
|
@brief deserialize from string literal
|
||||||
|
|
||||||
@param[in] s string to read a serialized JSON value from
|
@param[in] s string literal to read a serialized JSON value from
|
||||||
@param[in] cb a parser callback function of type @ref parser_callback_t
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
which is used to control the deserialization by filtering unwanted values
|
which is used to control the deserialization by filtering unwanted values
|
||||||
(optional)
|
(optional)
|
||||||
|
@ -5947,6 +5947,8 @@ class basic_json
|
||||||
@a cb has a super-linear complexity.
|
@a cb has a super-linear complexity.
|
||||||
|
|
||||||
@note A UTF-8 byte order mark is silently ignored.
|
@note A UTF-8 byte order mark is silently ignored.
|
||||||
|
@note String containers like `std::string` or @ref string_t can be parsed
|
||||||
|
with @ref parse(const ContiguousContainer&, const parser_callback_t)
|
||||||
|
|
||||||
@liveexample{The example below demonstrates the `parse()` function with
|
@liveexample{The example below demonstrates the `parse()` function with
|
||||||
and without callback function.,parse__string__parser_callback_t}
|
and without callback function.,parse__string__parser_callback_t}
|
||||||
|
@ -5954,24 +5956,47 @@ class basic_json
|
||||||
@sa @ref parse(std::istream&, const parser_callback_t) for a version that
|
@sa @ref parse(std::istream&, const parser_callback_t) for a version that
|
||||||
reads from an input stream
|
reads from an input stream
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0 (originally for @ref string_t)
|
||||||
*/
|
*/
|
||||||
/*
|
static basic_json parse(const char* s,
|
||||||
static basic_json parse(const string_t& s,
|
|
||||||
const parser_callback_t cb = nullptr)
|
const parser_callback_t cb = nullptr)
|
||||||
{
|
{
|
||||||
return parser(s, cb).parse();
|
return parser(s, cb).parse();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief deserialize from string literal
|
@brief deserialize from an array
|
||||||
@copydoc parse(const string_t&, const parser_callback_t)
|
|
||||||
|
This function reads from an array of 1-byte values.
|
||||||
|
|
||||||
|
@pre Each element of the container has a size of 1 byte. Violating this
|
||||||
|
precondition yields undefined behavior. **This precondition is enforced
|
||||||
|
with a static assertion.**
|
||||||
|
|
||||||
|
@param[in] array array to read from
|
||||||
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
|
which is used to control the deserialization by filtering unwanted values
|
||||||
|
(optional)
|
||||||
|
|
||||||
|
@return result of the deserialization
|
||||||
|
|
||||||
|
@complexity Linear in the length of the input. The parser is a predictive
|
||||||
|
LL(1) parser. The complexity can be higher if the parser callback function
|
||||||
|
@a cb has a super-linear complexity.
|
||||||
|
|
||||||
|
@note A UTF-8 byte order mark is silently ignored.
|
||||||
|
|
||||||
|
@liveexample{The example below demonstrates the `parse()` function reading
|
||||||
|
from an array.,parse__array__parser_callback_t}
|
||||||
|
|
||||||
|
@since version 2.0.3
|
||||||
*/
|
*/
|
||||||
static basic_json parse(const typename string_t::value_type* s,
|
template<class T, std::size_t N>
|
||||||
|
static basic_json parse(T (&array)[N],
|
||||||
const parser_callback_t cb = nullptr)
|
const parser_callback_t cb = nullptr)
|
||||||
{
|
{
|
||||||
return parser(s, cb).parse();
|
// delegate the call to the iterator-range parse overload
|
||||||
|
return parse(std::begin(array), std::end(array), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -5993,7 +6018,7 @@ class basic_json
|
||||||
@liveexample{The example below demonstrates the `parse()` function with
|
@liveexample{The example below demonstrates the `parse()` function with
|
||||||
and without callback function.,parse__istream__parser_callback_t}
|
and without callback function.,parse__istream__parser_callback_t}
|
||||||
|
|
||||||
@sa @ref parse(const string_t&, const parser_callback_t) for a version
|
@sa @ref parse(const char*, const parser_callback_t) for a version
|
||||||
that reads from a string
|
that reads from a string
|
||||||
|
|
||||||
@since version 1.0.0
|
@since version 1.0.0
|
||||||
|
@ -6014,7 +6039,7 @@ class basic_json
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief deserialize from a iterator range with contiguous storage
|
@brief deserialize from an iterator range with contiguous storage
|
||||||
|
|
||||||
This function reads from an iterator range of a container with contiguous
|
This function reads from an iterator range of a container with contiguous
|
||||||
storage of 1-byte values. Compatible container types include
|
storage of 1-byte values. Compatible container types include
|
||||||
|
@ -6029,13 +6054,14 @@ class basic_json
|
||||||
precondition yields undefined behavior. **This precondition is enforced
|
precondition yields undefined behavior. **This precondition is enforced
|
||||||
with a static assertion.**
|
with a static assertion.**
|
||||||
|
|
||||||
@warning There is no way to enforce the preconditions at compile-time. If
|
@warning There is no way to enforce all preconditions at compile-time. If
|
||||||
the function is called with noncompliant iterators, the behavior
|
the function is called with noncompliant iterators and with
|
||||||
is undefined and will most liekely yield segmentation violation.
|
assertions switched off, the behavior is undefined and will most
|
||||||
|
likely yield segmentation violation.
|
||||||
|
|
||||||
@param[in] first begin of the range to parse (included)
|
@param[in] first begin of the range to parse (included)
|
||||||
@param[in] last end of the range to parse (excluded)
|
@param[in] last end of the range to parse (excluded)
|
||||||
@param[in] cb a parser callback function of type @ref parser_callback_t
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
which is used to control the deserialization by filtering unwanted values
|
which is used to control the deserialization by filtering unwanted values
|
||||||
(optional)
|
(optional)
|
||||||
|
|
||||||
|
@ -6047,7 +6073,8 @@ class basic_json
|
||||||
|
|
||||||
@note A UTF-8 byte order mark is silently ignored.
|
@note A UTF-8 byte order mark is silently ignored.
|
||||||
|
|
||||||
@todo Example and references.
|
@liveexample{The example below demonstrates the `parse()` function reading
|
||||||
|
from an iterator range.,parse__iteratortype__parser_callback_t}
|
||||||
|
|
||||||
@since version 2.0.3
|
@since version 2.0.3
|
||||||
*/
|
*/
|
||||||
|
@ -6084,6 +6111,45 @@ class basic_json
|
||||||
return parser(first, last, cb).parse();
|
return parser(first, last, cb).parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
@brief deserialize from a container with contiguous storage
|
||||||
|
|
||||||
|
This function reads from a container with contiguous storage of 1-byte
|
||||||
|
values. Compatible container types include `std::vector`, `std::string`,
|
||||||
|
`std::array`, and `std::initializer_list`. User-defined containers can be
|
||||||
|
used as long as they implement random-access iterators and a contiguous
|
||||||
|
storage.
|
||||||
|
|
||||||
|
@pre The container storage is contiguous. Violating this precondition
|
||||||
|
yields undefined behavior. **This precondition is enforced with an
|
||||||
|
assertion.**
|
||||||
|
@pre Each element of the container has a size of 1 byte. Violating this
|
||||||
|
precondition yields undefined behavior. **This precondition is enforced
|
||||||
|
with a static assertion.**
|
||||||
|
|
||||||
|
@warning There is no way to enforce all preconditions at compile-time. If
|
||||||
|
the function is called with a noncompliant container and with
|
||||||
|
assertions switched off, the behavior is undefined and will most
|
||||||
|
likely yield segmentation violation.
|
||||||
|
|
||||||
|
@param[in] c container to read from
|
||||||
|
@param[in] cb a parser callback function of type @ref parser_callback_t
|
||||||
|
which is used to control the deserialization by filtering unwanted values
|
||||||
|
(optional)
|
||||||
|
|
||||||
|
@return result of the deserialization
|
||||||
|
|
||||||
|
@complexity Linear in the length of the input. The parser is a predictive
|
||||||
|
LL(1) parser. The complexity can be higher if the parser callback function
|
||||||
|
@a cb has a super-linear complexity.
|
||||||
|
|
||||||
|
@note A UTF-8 byte order mark is silently ignored.
|
||||||
|
|
||||||
|
@liveexample{The example below demonstrates the `parse()` function reading
|
||||||
|
from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
|
||||||
|
|
||||||
|
@since version 2.0.3
|
||||||
|
*/
|
||||||
template<class ContiguousContainer, typename
|
template<class ContiguousContainer, typename
|
||||||
std::enable_if<
|
std::enable_if<
|
||||||
std::is_base_of<
|
std::is_base_of<
|
||||||
|
@ -6097,14 +6163,6 @@ class basic_json
|
||||||
return parse(std::begin(c), std::end(c), cb);
|
return parse(std::begin(c), std::end(c), cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, std::size_t N>
|
|
||||||
static basic_json parse(T (&array)[N],
|
|
||||||
const parser_callback_t cb = nullptr)
|
|
||||||
{
|
|
||||||
// delegate the call to the iterator-range parse overload
|
|
||||||
return parse(std::begin(array), std::end(array), cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief deserialize from stream
|
@brief deserialize from stream
|
||||||
|
|
||||||
|
@ -6158,7 +6216,7 @@ class basic_json
|
||||||
Returns the type name as string to be used in error messages - usually to
|
Returns the type name as string to be used in error messages - usually to
|
||||||
indicate that a function was called on a wrong JSON type.
|
indicate that a function was called on a wrong JSON type.
|
||||||
|
|
||||||
@return basically a string representation of a the @ref m_type member
|
@return basically a string representation of a the @a m_type member
|
||||||
|
|
||||||
@complexity Constant.
|
@complexity Constant.
|
||||||
|
|
||||||
|
@ -7626,7 +7684,7 @@ class basic_json
|
||||||
fill_line_buffer();
|
fill_line_buffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// switch off unwanted functions
|
// switch off unwanted functions (due to pointer members)
|
||||||
lexer() = delete;
|
lexer() = delete;
|
||||||
lexer(const lexer&) = delete;
|
lexer(const lexer&) = delete;
|
||||||
lexer operator=(const lexer&) = delete;
|
lexer operator=(const lexer&) = delete;
|
||||||
|
@ -8276,24 +8334,17 @@ class basic_json
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// a parser reading from a string literal
|
/// a parser reading from a string literal
|
||||||
parser(const typename string_t::value_type* buff,
|
parser(const char* buff, const parser_callback_t cb = nullptr)
|
||||||
const parser_callback_t cb = nullptr)
|
|
||||||
: callback(cb),
|
: callback(cb),
|
||||||
m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), strlen(buff))
|
m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(buff), strlen(buff))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// a parser reading from a string container
|
|
||||||
parser(const string_t& s, const parser_callback_t cb = nullptr)
|
|
||||||
: callback(cb),
|
|
||||||
m_lexer(reinterpret_cast<const typename lexer::lexer_char_t*>(s.c_str()), s.size())
|
|
||||||
{}
|
|
||||||
|
|
||||||
/// a parser reading from an input stream
|
/// a parser reading from an input stream
|
||||||
parser(std::istream& is, const parser_callback_t cb = nullptr)
|
parser(std::istream& is, const parser_callback_t cb = nullptr)
|
||||||
: callback(cb), m_lexer(is)
|
: callback(cb), m_lexer(is)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// a parser reading from a container with contiguous storage
|
/// a parser reading from an iterator range with contiguous storage
|
||||||
template <class IteratorType, typename
|
template <class IteratorType, typename
|
||||||
std::enable_if<
|
std::enable_if<
|
||||||
std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
|
std::is_same<typename std::iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value
|
||||||
|
@ -9857,7 +9908,7 @@ if no parse error occurred.
|
||||||
*/
|
*/
|
||||||
inline nlohmann::json operator "" _json(const char* s, std::size_t)
|
inline nlohmann::json operator "" _json(const char* s, std::size_t)
|
||||||
{
|
{
|
||||||
return nlohmann::json::parse(reinterpret_cast<const nlohmann::json::string_t::value_type*>(s));
|
return nlohmann::json::parse(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -477,7 +477,7 @@ TEST_CASE("parser class")
|
||||||
case ('r'):
|
case ('r'):
|
||||||
case ('t'):
|
case ('t'):
|
||||||
{
|
{
|
||||||
CHECK_NOTHROW(json::parser(s).parse());
|
CHECK_NOTHROW(json::parser(s.c_str()).parse());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,8 +490,8 @@ TEST_CASE("parser class")
|
||||||
// any other combination of backslash and character is invalid
|
// any other combination of backslash and character is invalid
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
CHECK_THROWS_AS(json::parser(s).parse(), std::invalid_argument);
|
CHECK_THROWS_AS(json::parser(s.c_str()).parse(), std::invalid_argument);
|
||||||
CHECK_THROWS_WITH(json::parser(s).parse(), "parse error - unexpected '\"'");
|
CHECK_THROWS_WITH(json::parser(s.c_str()).parse(), "parse error - unexpected '\"'");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -549,22 +549,22 @@ TEST_CASE("parser class")
|
||||||
|
|
||||||
if (valid(c))
|
if (valid(c))
|
||||||
{
|
{
|
||||||
CHECK_NOTHROW(json::parser(s1).parse());
|
CHECK_NOTHROW(json::parser(s1.c_str()).parse());
|
||||||
CHECK_NOTHROW(json::parser(s2).parse());
|
CHECK_NOTHROW(json::parser(s2.c_str()).parse());
|
||||||
CHECK_NOTHROW(json::parser(s3).parse());
|
CHECK_NOTHROW(json::parser(s3.c_str()).parse());
|
||||||
CHECK_NOTHROW(json::parser(s4).parse());
|
CHECK_NOTHROW(json::parser(s4.c_str()).parse());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CHECK_THROWS_AS(json::parser(s1).parse(), std::invalid_argument);
|
CHECK_THROWS_AS(json::parser(s1.c_str()).parse(), std::invalid_argument);
|
||||||
CHECK_THROWS_AS(json::parser(s2).parse(), std::invalid_argument);
|
CHECK_THROWS_AS(json::parser(s2.c_str()).parse(), std::invalid_argument);
|
||||||
CHECK_THROWS_AS(json::parser(s3).parse(), std::invalid_argument);
|
CHECK_THROWS_AS(json::parser(s3.c_str()).parse(), std::invalid_argument);
|
||||||
CHECK_THROWS_AS(json::parser(s4).parse(), std::invalid_argument);
|
CHECK_THROWS_AS(json::parser(s4.c_str()).parse(), std::invalid_argument);
|
||||||
|
|
||||||
CHECK_THROWS_WITH(json::parser(s1).parse(), "parse error - unexpected '\"'");
|
CHECK_THROWS_WITH(json::parser(s1.c_str()).parse(), "parse error - unexpected '\"'");
|
||||||
CHECK_THROWS_WITH(json::parser(s2).parse(), "parse error - unexpected '\"'");
|
CHECK_THROWS_WITH(json::parser(s2.c_str()).parse(), "parse error - unexpected '\"'");
|
||||||
CHECK_THROWS_WITH(json::parser(s3).parse(), "parse error - unexpected '\"'");
|
CHECK_THROWS_WITH(json::parser(s3.c_str()).parse(), "parse error - unexpected '\"'");
|
||||||
CHECK_THROWS_WITH(json::parser(s4).parse(), "parse error - unexpected '\"'");
|
CHECK_THROWS_WITH(json::parser(s4.c_str()).parse(), "parse error - unexpected '\"'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,12 @@ TEST_CASE("deserialization")
|
||||||
std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e', '\0'};
|
std::initializer_list<uint8_t> v = {'t', 'r', 'u', 'e', '\0'};
|
||||||
CHECK(json::parse(v) == json(true));
|
CHECK(json::parse(v) == json(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("empty container")
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> v;
|
||||||
|
CHECK_THROWS_AS(json::parse(v), std::invalid_argument);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("via iterator range")
|
SECTION("via iterator range")
|
||||||
|
|
Loading…
Reference in a new issue