1
0
mirror of https://github.com/nlohmann/json.git synced 2025-07-15 07:41:50 +03:00

more documentation

In this commit, also the semantics for values skipped via the parser
callback has changed. Now, the top-level value is returned as “null”
instead of “discarded”.
This commit is contained in:
Niels
2015-06-24 12:15:51 +02:00
parent 48545f5b18
commit 457572184c
25 changed files with 856 additions and 60 deletions

View File

@ -336,20 +336,77 @@ class basic_json
// JSON parser callback //
//////////////////////////
/// JSON callback event enumeration
/*!
@brief JSON callback events
This enumeration lists the parser events that can trigger calling a
callback function of type @ref parser_callback_t during parsing.
*/
enum class parse_event_t : uint8_t
{
object_start, ///< start an object scope (found a '{' token)
object_end, ///< end of an object scope (found '}' token)
array_start, ///< start of an array scope (found '[' token)
array_end, ///< end of an array scope (found ']' token)
key, ///< found an object key within an object scope
value ///< a value in an appropriate context (i.e., following a tag in an object scope)
/// the parser read `{` and started to process a JSON object
object_start,
/// the parser read `}` and finished processing a JSON object
object_end,
/// the parser read `[` and started to process a JSON array
array_start,
/// the parser read `]` and finished processing a JSON array
array_end,
/// the parser read a key of a value in an object
key,
/// the parser finished reading a JSON value
value
};
/// per-element parser callback type
using parser_callback_t = std::function<bool(int depth, parse_event_t event,
const basic_json& parsed)>;
/*!
@brief per-element parser callback type
With a parser callback function, the result of parsing a JSON text can be
influenced. When passed to @ref parse(std::istream&, parser_callback_t) or
@ref parse(const string_t&, parser_callback_t), 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 parsed. The return value
of the callback function is a boolean indicating whether the element that
emitted the callback shall be kept or not.
We distinguish six scenarios (determined by the event type) in which the
callback function can be called. The following table describes the values
of the parameters @a depth, @a event, and @a parsed.
parameter @a event | description | parameter @a depth | parameter @a parsed
------------------ | ----------- | ------------------ | -------------------
parse_event_t::object_start | the parser read `{` and started to process a JSON object | depth of the parent of the JSON object | a JSON value with type discarded
parse_event_t::key | the parser read a key of a value in an object | depth of the currently parsed JSON object | a JSON string containing the key
parse_event_t::object_end | the parser read `}` and finished processing a JSON object | depth of the parent of the JSON object | the parsed JSON object
parse_event_t::array_start | the parser read `[` and started to process a JSON array | depth of the parent of the JSON array | a JSON value with type discarded
parse_event_t::array_end | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array
parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
Discarding a value (i.e., returning `false`) has different effects depending on the
context in which function was called:
- Discarded values in structured types are skipped. That is, the parser
will behave as if the discarded value was never read.
- In case a value outside a structured type is skipped, it is replaced with
`null`. This case happens if the top-level element is skipped.
@param[in] depth the depth of the recursion during parsing
@param[in] event an event of type parse_event_t indicating the context in
the callback function has been called
@param[in,out] parsed the current intermediate parse result; note that
writing to this value has no effect for parse_event_t::key events
@return Whether the JSON value which called the function during parsing
should be kept (`true`) or not (`false`). In the latter case, it is either
skipped completely or replaced by an empty discarded object.
@sa @ref parse(std::istream&, parser_callback_t) or
@ref parse(const string_t&, parser_callback_t) for examples
*/
using parser_callback_t = std::function<bool(
int depth, parse_event_t event, basic_json& parsed)>;
/*!
@brief comparison operator for JSON value types
@ -1760,7 +1817,25 @@ class basic_json
/// @name element access
/// @{
/// access specified element with bounds checking
/*!
@brief access specified array element with bounds checking
Returns a reference to the element at specified location @a idx, with
bounds checking.
@param[in] idx index of the element to access
@return reference to the element at index @a idx
@throw std::domain_error if JSON is not an array
@throw std::out_of_range if the index @a idx is out of range of the array;
that is, `idx >= size()`
@complexity Constant.
@liveexample{The example below shows how array elements can be read and
written using at.,at__size_type}
*/
reference at(size_type idx)
{
// at only works for arrays
@ -1772,7 +1847,25 @@ class basic_json
return m_value.array->at(idx);
}
/// access specified element with bounds checking
/*!
@brief access specified array element with bounds checking
Returns a const reference to the element at specified location @a idx, with
bounds checking.
@param[in] idx index of the element to access
@return const reference to the element at index @a idx
@throw std::domain_error if JSON is not an array
@throw std::out_of_range if the index @a idx is out of range of the array;
that is, `idx >= size()`
@complexity Constant.
@liveexample{The example below shows how array elements can be read using
at.,at__size_type_const}
*/
const_reference at(size_type idx) const
{
// at only works for arrays
@ -1784,7 +1877,25 @@ class basic_json
return m_value.array->at(idx);
}
/// access specified element with bounds checking
/*!
@brief access specified object element with bounds checking
Returns a reference to the element at with specified key @a key, with
bounds checking.
@param[in] key key of the element to access
@return reference to the element at key @a key
@throw std::domain_error if JSON is not an object
@throw std::out_of_range if the key @a key is is not stored in the object;
that is, `find(key) == end()`
@complexity Logarithmic in the size of the container.
@liveexample{The example below shows how object elements can be read and
written using at.,at__object_t_key_type}
*/
reference at(const typename object_t::key_type& key)
{
// at only works for objects
@ -1796,7 +1907,25 @@ class basic_json
return m_value.object->at(key);
}
/// access specified element with bounds checking
/*!
@brief access specified object element with bounds checking
Returns a const reference to the element at with specified key @a key, with
bounds checking.
@param[in] key key of the element to access
@return const reference to the element at key @a key
@throw std::domain_error if JSON is not an object
@throw std::out_of_range if the key @a key is is not stored in the object;
that is, `find(key) == end()`
@complexity Logarithmic in the size of the container.
@liveexample{The example below shows how object elements can be read using
at.,at__object_t_key_type_const}
*/
const_reference at(const typename object_t::key_type& key) const
{
// at only works for objects
@ -1808,7 +1937,28 @@ class basic_json
return m_value.object->at(key);
}
/// access specified element
/*!
@brief access specified array element
Returns a reference to the element at specified location @a idx.
@note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
then the array is silently filled up with `null` values to make `idx` a
valid reference to the last stored element.
@param[in] idx index of the element to access
@return reference to the element at index @a idx
@throw std::domain_error if JSON is not an array or null
@complexity Constant if @a idx is in the range of the array. Otherwise
linear in `idx - size()`.
@liveexample{The example below shows how array elements can be read and
written using [] operator. Note the addition of `null`
values.,operatorarray__size_type}
*/
reference operator[](size_type idx)
{
// implicitly convert null to object
@ -1834,7 +1984,22 @@ class basic_json
return m_value.array->operator[](idx);
}
/// access specified element
/*!
@brief access specified array element
Returns a const reference to the element at specified location @a idx.
@param[in] idx index of the element to access
@return const reference to the element at index @a idx
@throw std::domain_error if JSON is not an array
@complexity Constant.
@liveexample{The example below shows how array elements can be read using
the [] operator.,operatorarray__size_type_const}
*/
const_reference operator[](size_type idx) const
{
// at only works for arrays
@ -2750,6 +2915,19 @@ class basic_json
/*!
@brief exchanges the values
Exchanges the contents of the JSON value with those of @a other. Does not
invoke any move, copy, or swap operations on individual elements. All
iterators and references remain valid. The past-the-end iterator is
invalidated.
@param[in,out] other JSON value to exchange the contents with
@complexity Constant.
@liveexample{The example below shows how JSON arrays can be
swapped.,swap__reference}
@ingroup container
*/
void swap(reference other) noexcept (
@ -2763,7 +2941,25 @@ class basic_json
std::swap(m_value, other.m_value);
}
/// swaps the contents
/*!
@brief exchanges the values
Exchanges the contents of a JSON array with those of @a other. Does not
invoke any move, copy, or swap operations on individual elements. All
iterators and references remain valid. The past-the-end iterator is
invalidated.
@param[in,out] other array to exchange the contents with
@throw std::domain_error when JSON value is not an array
@complexity Constant.
@liveexample{The example below shows how JSON values can be
swapped.,swap__array_t}
@ingroup container
*/
void swap(array_t& other)
{
// swap only works for arrays
@ -3082,8 +3278,9 @@ class basic_json
@brief deserialize from string
@param[in] s string to read a serialized JSON value from
@param[in] cb a parser callback function of type parser_callback_t which is
used to control the deserialization by filtering unwanted values (optional)
@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
@ -3091,7 +3288,8 @@ class basic_json
LL(1) parser. The complexity can be higher if the parser callback function
@a cb has a super-linear complexity.
@todo Add example.
@liveexample{The example below demonstrates the parse function with and
without callback function.,parse__string__parser_callback_t}
@sa parse(std::istream&, parser_callback_t) for a version that reads from
an input stream
@ -3105,8 +3303,9 @@ class basic_json
@brief deserialize from stream
@param[in,out] i stream to read a serialized JSON value from
@param[in] cb a parser callback function of type parser_callback_t which is
used to control the deserialization by filtering unwanted values (optional)
@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
@ -3114,7 +3313,8 @@ class basic_json
LL(1) parser. The complexity can be higher if the parser callback function
@a cb has a super-linear complexity.
@todo Add example.
@liveexample{The example below demonstrates the parse function with and
without callback function.,parse__istream__parser_callback_t}
@sa parse(const string_t&, parser_callback_t) for a version that reads
from a string
@ -5016,7 +5216,9 @@ class basic_json
expect(lexer::token_type::end_of_input);
return result;
// return parser result and replace it with null in case the
// top-level value was discarded by the callback function
return result.is_discarded() ? basic_json() : result;
}
private:
@ -5069,7 +5271,15 @@ class basic_json
bool keep_tag = false;
if (keep)
{
keep_tag = callback ? callback(depth, parse_event_t::key, basic_json(key)) : true;
if (callback)
{
basic_json k(key);
keep_tag = callback(depth, parse_event_t::key, k);
}
else
{
keep_tag = true;
}
}
// parse separator (:)