|
JSON Voorhees
Killer JSON for C++
|
The JSON documents in one input, read one after another, each through a reader of its own.
More...
#include <jsonv/reader.hpp>
Inheritance diagram for jsonv::documents:
Collaboration diagram for jsonv::documents:Public Types | |
| using | iterator_concept = std::input_iterator_tag |
| What this models in C++20 terms: an input iterator, since each document is parsed onto the tape of the last. | |
| using | value_type = reader |
| What dereferencing gives a reference to. | |
| using | difference_type = std::ptrdiff_t |
| What every iterator has to name, although stepping through documents never measures a distance. | |
Public Member Functions | |
| documents (const documents &)=delete | |
| documents & | operator= (const documents &)=delete |
| iterator | begin () |
| Get an iterator on the first document which has not been passed yet. | |
| std::default_sentinel_t | end () const noexcept |
The end of the documents, which an iterator compares equal to once it has passed the last one. | |
| iterator () noexcept=default | |
| Create an iterator which is already at the end. | |
| reader & | operator* () const |
| Get the reader for the document this is on. | |
| documents (std::string_view source) | |
| Read the documents in JSON source. | |
| documents (std::string_view source, const parse_options &parse_options) | |
| Read the documents in JSON source. | |
| documents (const char *source) | |
| Read the documents in JSON source. | |
| documents (const char *source, const parse_options &parse_options) | |
| Read the documents in JSON source. | |
| documents (std::string &&source) | |
| Read the documents in JSON source. | |
| documents (std::string &&source, const parse_options &parse_options) | |
| Read the documents in JSON source. | |
| documents (std::istream &source) | |
Read the documents in what is left of the source stream, as reader(std::istream&) reads one. | |
| documents (std::istream &source, const parse_options &parse_options) | |
Read the documents in what is left of the source stream, as reader(std::istream&) reads one. | |
| documents (documents &&) noexcept | |
| Moving transfers the source and the position in it. | |
| documents & | operator= (documents &&) noexcept |
| Moving transfers the source and the position in it. | |
| iterator & | operator++ () |
| Parse the next document and move onto it, or onto the end if there is no other. | |
| void | operator++ (int) |
| Parse the next document and move onto it, or onto the end if there is no other. | |
Friends | |
| bool | operator== (const iterator &self, std::default_sentinel_t) noexcept |
Is self at the end of its documents? | |
The JSON documents in one input, read one after another, each through a reader of its own.
An input iterator over documents.
Every other way of reading JSON text takes all of it as one document, and refuses anything after its value. This takes it as a sequence of documents instead: JSON Lines, with one to a line; concatenated JSON as jq reads and writes it, as in {"a":1}{"a":2}; or a run of pretty-printed documents. Any whitespace may separate two documents, as may comments where parse_options::comments allows them, or nothing at all where the first ends with a character the second could not have continued: [1][2] and "a""b" are two documents each, while 12 is one.
Each document is handed out as a reader on its ast_node_type::document_start, as a freshly-created one is, so jsonv::deserialize reads it as a whole document and anything else which takes a reader takes it. It is parsed with the parse_options this was created with as though it were the only document: parse_options::require_document and parse_options::max_structure_depth apply to each one. Nothing is parsed until the iterator reaches it, and then onto the tape the document before it was read from, so many small documents cost one tape the size of the largest rather than one each. That is also why the reader for a document is valid only until the iterator moves on, wherever it has been moved to: by then its tape holds the next document.
Whitespace and comments after the last document end the sequence, so input with no value in it holds no documents.
Parsing text never throws, here as elsewhere. A document which is not valid JSON is still handed out, as a reader whose reader::validate throws parse_error and from which jsonv::deserialize throws a deserialization_error saying so, and the sequence ends with it: the parse stopped at the error, and nothing says where that document would have ended and the next begun. The position in a parse_error counts from the start of the whole input, not of the document it is in.
A std::string_view deserialized from a document views the source. A source given as a std::string rvalue or a std::istream is kept by this instance, so such a view is valid for as long as it is; any other is the caller's, and valid for as long as the caller keeps it.
Dereferencing it gives the reader for the document it is on, and incrementing it parses the next one. Once it has passed the last, it compares equal to std::default_sentinel.
Definition at line 508 of file reader.hpp.
| using jsonv::documents::difference_type = std::ptrdiff_t |
What every iterator has to name, although stepping through documents never measures a distance.
Definition at line 590 of file reader.hpp.
| using jsonv::documents::iterator_concept = std::input_iterator_tag |
What this models in C++20 terms: an input iterator, since each document is parsed onto the tape of the last.
Definition at line 584 of file reader.hpp.
| using jsonv::documents::value_type = reader |
What dereferencing gives a reference to.
Definition at line 587 of file reader.hpp.
|
explicit |
Read the documents in JSON source.
The source must stay in memory for as long as this instance and the readers it hands out are used, unless it is an rvalue reference to a std::string, which is moved into this instance to keep it alive. It is parsed with parse_options where they are given, and with the defaults parse_index::parse uses where they are not.
|
explicit |
Read the documents in JSON source.
The source must stay in memory for as long as this instance and the readers it hands out are used, unless it is an rvalue reference to a std::string, which is moved into this instance to keep it alive. It is parsed with parse_options where they are given, and with the defaults parse_index::parse uses where they are not.
|
explicit |
Read the documents in JSON source.
The source must stay in memory for as long as this instance and the readers it hands out are used, unless it is an rvalue reference to a std::string, which is moved into this instance to keep it alive. It is parsed with parse_options where they are given, and with the defaults parse_index::parse uses where they are not.
|
explicit |
Read the documents in JSON source.
The source must stay in memory for as long as this instance and the readers it hands out are used, unless it is an rvalue reference to a std::string, which is moved into this instance to keep it alive. It is parsed with parse_options where they are given, and with the defaults parse_index::parse uses where they are not.
|
explicit |
Read the documents in JSON source.
The source must stay in memory for as long as this instance and the readers it hands out are used, unless it is an rvalue reference to a std::string, which is moved into this instance to keep it alive. It is parsed with parse_options where they are given, and with the defaults parse_index::parse uses where they are not.
|
explicit |
Read the documents in JSON source.
The source must stay in memory for as long as this instance and the readers it hands out are used, unless it is an rvalue reference to a std::string, which is moved into this instance to keep it alive. It is parsed with parse_options where they are given, and with the defaults parse_index::parse uses where they are not.
|
explicit |
Read the documents in what is left of the source stream, as reader(std::istream&) reads one.
The stream is read to its end here, and this instance keeps the text, so nothing reads source again once this returns. A parse_error position counts from where source was when this was called.
|
explicit |
Read the documents in what is left of the source stream, as reader(std::istream&) reads one.
The stream is read to its end here, and this instance keeps the text, so nothing reads source again once this returns. A parse_error position counts from where source was when this was called.
|
noexcept |
Moving transfers the source and the position in it.
Iterators and readers already handed out are unaffected, and go on belonging to the instance moved to. The moved-from instance has no documents to give: begin throws std::invalid_argument, as using a moved-from reader does.
| iterator jsonv::documents::begin | ( | ) |
Get an iterator on the first document which has not been passed yet.
The first call parses the first document; any later call returns an iterator wherever the earlier ones have got to, since this is an input range and can only be walked once.
| std::invalid_argument | if this instance has been moved-from, or if the parse_options ask for a parse_options::max_structure_depth beyond the limit, as parse_index::parse does. |
|
inlinenoexcept |
The end of the documents, which an iterator compares equal to once it has passed the last one.
Definition at line 566 of file reader.hpp.
| reader & jsonv::documents::operator* | ( | ) | const |
Get the reader for the document this is on.
It reads the tape every document of the documents is parsed onto, so it is valid until this iterator, or any other from the same documents, is incremented.
| std::logic_error | if this iterator is at the end. |
| iterator & jsonv::documents::operator++ | ( | ) |
Parse the next document and move onto it, or onto the end if there is no other.
| std::bad_alloc | if the tape cannot grow to hold the next document, which ends the sequence there. |
|
inline |
Parse the next document and move onto it, or onto the end if there is no other.
| std::bad_alloc | if the tape cannot grow to hold the next document, which ends the sequence there. |
Definition at line 609 of file reader.hpp.
Moving transfers the source and the position in it.
Iterators and readers already handed out are unaffected, and go on belonging to the instance moved to. The moved-from instance has no documents to give: begin throws std::invalid_argument, as using a moved-from reader does.
|
friend |
Definition at line 620 of file reader.hpp.
|
friend |
Is self at the end of its documents?
Definition at line 614 of file reader.hpp.