100.00% Lines (29/29)
100.00% Functions (10/10)
| TLA | Baseline | Branch | ||||||
|---|---|---|---|---|---|---|---|---|
| Line | Hits | Code | Line | Hits | Code | |||
| 1 | // | 1 | // | |||||
| 2 | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) | 2 | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) | |||||
| 3 | // | 3 | // | |||||
| 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |||||
| 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |||||
| 6 | // | 6 | // | |||||
| 7 | // Official repository: https://github.com/boostorg/json | 7 | // Official repository: https://github.com/boostorg/json | |||||
| 8 | // | 8 | // | |||||
| 9 | 9 | |||||||
| 10 | #ifndef BOOST_JSON_PARSER_HPP | 10 | #ifndef BOOST_JSON_PARSER_HPP | |||||
| 11 | #define BOOST_JSON_PARSER_HPP | 11 | #define BOOST_JSON_PARSER_HPP | |||||
| 12 | 12 | |||||||
| 13 | #include <boost/json/detail/config.hpp> | 13 | #include <boost/json/detail/config.hpp> | |||||
| 14 | #include <boost/json/basic_parser.hpp> | 14 | #include <boost/json/basic_parser.hpp> | |||||
| 15 | #include <boost/json/storage_ptr.hpp> | 15 | #include <boost/json/storage_ptr.hpp> | |||||
| 16 | #include <boost/json/value.hpp> | 16 | #include <boost/json/value.hpp> | |||||
| 17 | #include <boost/json/detail/handler.hpp> | 17 | #include <boost/json/detail/handler.hpp> | |||||
| 18 | #include <type_traits> | 18 | #include <type_traits> | |||||
| 19 | #include <cstddef> | 19 | #include <cstddef> | |||||
| 20 | 20 | |||||||
| 21 | namespace boost { | 21 | namespace boost { | |||||
| 22 | namespace json { | 22 | namespace json { | |||||
| 23 | 23 | |||||||
| 24 | //---------------------------------------------------------- | 24 | //---------------------------------------------------------- | |||||
| 25 | 25 | |||||||
| 26 | /** A DOM parser for JSON contained in a single buffer. | 26 | /** A DOM parser for JSON contained in a single buffer. | |||||
| 27 | 27 | |||||||
| 28 | This class is used to parse a JSON text contained in a single character | 28 | This class is used to parse a JSON text contained in a single character | |||||
| 29 | buffer, into a @ref value container. | 29 | buffer, into a @ref value container. | |||||
| 30 | 30 | |||||||
| 31 | @par Usage | 31 | @par Usage | |||||
| 32 | To use the parser first construct it, then optionally call @ref reset to | 32 | To use the parser first construct it, then optionally call @ref reset to | |||||
| 33 | specify a @ref storage_ptr to use for the resulting @ref value. Then call | 33 | specify a @ref storage_ptr to use for the resulting @ref value. Then call | |||||
| 34 | @ref write to parse a character buffer containing a complete JSON text. If | 34 | @ref write to parse a character buffer containing a complete JSON text. If | |||||
| 35 | the parse is successful, call @ref release to take ownership of the value: | 35 | the parse is successful, call @ref release to take ownership of the value: | |||||
| 36 | @code | 36 | @code | |||||
| 37 | parser p; // construct a parser | 37 | parser p; // construct a parser | |||||
| 38 | size_t n = p.write( "[1,2,3]" ); // parse a complete JSON text | 38 | size_t n = p.write( "[1,2,3]" ); // parse a complete JSON text | |||||
| 39 | assert( n == 7 ); // all characters consumed | 39 | assert( n == 7 ); // all characters consumed | |||||
| 40 | value jv = p.release(); // take ownership of the value | 40 | value jv = p.release(); // take ownership of the value | |||||
| 41 | @endcode | 41 | @endcode | |||||
| 42 | 42 | |||||||
| 43 | @par Extra Data | 43 | @par Extra Data | |||||
| 44 | When the character buffer provided as input contains additional data that | 44 | When the character buffer provided as input contains additional data that | |||||
| 45 | is not part of the complete JSON text, an error is returned. The @ref | 45 | is not part of the complete JSON text, an error is returned. The @ref | |||||
| 46 | write_some function is an alternative which allows the parse to finish | 46 | write_some function is an alternative which allows the parse to finish | |||||
| 47 | early, without consuming all the characters in the buffer. This allows | 47 | early, without consuming all the characters in the buffer. This allows | |||||
| 48 | parsing of a buffer containing multiple individual JSON texts or containing | 48 | parsing of a buffer containing multiple individual JSON texts or containing | |||||
| 49 | different protocol data: | 49 | different protocol data: | |||||
| 50 | @code | 50 | @code | |||||
| 51 | parser p; // construct a parser | 51 | parser p; // construct a parser | |||||
| 52 | size_t n = p.write_some( "[1,2,3] null" ); // parse a complete JSON text | 52 | size_t n = p.write_some( "[1,2,3] null" ); // parse a complete JSON text | |||||
| 53 | assert( n == 8 ); // only some characters consumed | 53 | assert( n == 8 ); // only some characters consumed | |||||
| 54 | value jv = p.release(); // take ownership of the value | 54 | value jv = p.release(); // take ownership of the value | |||||
| 55 | @endcode | 55 | @endcode | |||||
| 56 | 56 | |||||||
| 57 | @par Temporary Storage | 57 | @par Temporary Storage | |||||
| 58 | The parser may dynamically allocate temporary storage as needed to | 58 | The parser may dynamically allocate temporary storage as needed to | |||||
| 59 | accommodate the nesting level of the JSON text being parsed. Temporary | 59 | accommodate the nesting level of the JSON text being parsed. Temporary | |||||
| 60 | storage is first obtained from an optional, caller-owned buffer specified | 60 | storage is first obtained from an optional, caller-owned buffer specified | |||||
| 61 | upon construction. When that is exhausted, the next allocation uses the | 61 | upon construction. When that is exhausted, the next allocation uses the | |||||
| 62 | @ref boost::container::pmr::memory_resource passed to the constructor; if | 62 | @ref boost::container::pmr::memory_resource passed to the constructor; if | |||||
| 63 | no such argument is specified, the default memory resource is used. | 63 | no such argument is specified, the default memory resource is used. | |||||
| 64 | Temporary storage is freed only when the parser is destroyed; The | 64 | Temporary storage is freed only when the parser is destroyed; The | |||||
| 65 | performance of parsing multiple JSON texts may be improved by reusing the | 65 | performance of parsing multiple JSON texts may be improved by reusing the | |||||
| 66 | same parser instance. | 66 | same parser instance. | |||||
| 67 | 67 | |||||||
| 68 | It is important to note that the `boost::container::pmr::memory_resource` | 68 | It is important to note that the `boost::container::pmr::memory_resource` | |||||
| 69 | supplied upon construction is used for temporary storage only, and not for | 69 | supplied upon construction is used for temporary storage only, and not for | |||||
| 70 | allocating the elements which make up the parsed value. That other memory | 70 | allocating the elements which make up the parsed value. That other memory | |||||
| 71 | resource is optionally supplied in each call to @ref reset. | 71 | resource is optionally supplied in each call to @ref reset. | |||||
| 72 | 72 | |||||||
| 73 | @par Duplicate Keys | 73 | @par Duplicate Keys | |||||
| 74 | If there are object elements with duplicate keys; that is, if multiple | 74 | If there are object elements with duplicate keys; that is, if multiple | |||||
| 75 | elements in an object have keys that compare equal, only the last | 75 | elements in an object have keys that compare equal, only the last | |||||
| 76 | equivalent element will be inserted. | 76 | equivalent element will be inserted. | |||||
| 77 | 77 | |||||||
| 78 | @par Non-Standard JSON | 78 | @par Non-Standard JSON | |||||
| 79 | The @ref parse_options structure optionally provided upon construction is | 79 | The @ref parse_options structure optionally provided upon construction is | |||||
| 80 | used to customize some parameters of the parser, including which | 80 | used to customize some parameters of the parser, including which | |||||
| 81 | non-standard JSON extensions should be allowed. A default-constructed parse | 81 | non-standard JSON extensions should be allowed. A default-constructed parse | |||||
| 82 | options allows only standard JSON. | 82 | options allows only standard JSON. | |||||
| 83 | 83 | |||||||
| 84 | @par Thread Safety | 84 | @par Thread Safety | |||||
| 85 | Distinct instances may be accessed concurrently. Non-const member functions | 85 | Distinct instances may be accessed concurrently. Non-const member functions | |||||
| 86 | of a shared instance may not be called concurrently with any other member | 86 | of a shared instance may not be called concurrently with any other member | |||||
| 87 | functions of that instance. | 87 | functions of that instance. | |||||
| 88 | 88 | |||||||
| 89 | @see @ref parse, @ref stream_parser. | 89 | @see @ref parse, @ref stream_parser. | |||||
| 90 | */ | 90 | */ | |||||
| 91 | class parser | 91 | class parser | |||||
| 92 | { | 92 | { | |||||
| 93 | basic_parser<detail::handler> p_; | 93 | basic_parser<detail::handler> p_; | |||||
| 94 | 94 | |||||||
| 95 | public: | 95 | public: | |||||
| 96 | /** Assignment operator. | 96 | /** Assignment operator. | |||||
| 97 | 97 | |||||||
| 98 | This type is neither copyable nor movable. The operator is deleted. | 98 | This type is neither copyable nor movable. The operator is deleted. | |||||
| 99 | */ | 99 | */ | |||||
| 100 | parser& operator=( | 100 | parser& operator=( | |||||
| 101 | parser const&) = delete; | 101 | parser const&) = delete; | |||||
| 102 | 102 | |||||||
| 103 | /** Destructor. | 103 | /** Destructor. | |||||
| 104 | 104 | |||||||
| 105 | All dynamically allocated memory, including | 105 | All dynamically allocated memory, including | |||||
| 106 | any incomplete parsing results, is freed. | 106 | any incomplete parsing results, is freed. | |||||
| 107 | 107 | |||||||
| 108 | @par Complexity | 108 | @par Complexity | |||||
| 109 | Linear in the size of partial results. | 109 | Linear in the size of partial results. | |||||
| 110 | 110 | |||||||
| 111 | @par Exception Safety | 111 | @par Exception Safety | |||||
| 112 | No-throw guarantee. | 112 | No-throw guarantee. | |||||
| 113 | */ | 113 | */ | |||||
| HITCBC | 114 | 2001563 | ~parser() = default; | 114 | 2001563 | ~parser() = default; | ||
| 115 | 115 | |||||||
| 116 | /** Constructors. | 116 | /** Constructors. | |||||
| 117 | 117 | |||||||
| 118 | Construct a new parser. | 118 | Construct a new parser. | |||||
| 119 | 119 | |||||||
| 120 | The parser will only support standard JSON if overloads **(1)** | 120 | The parser will only support standard JSON if overloads **(1)** | |||||
| 121 | or **(2)** are used. Otherwise the parser will support extensions | 121 | or **(2)** are used. Otherwise the parser will support extensions | |||||
| 122 | specified by the parameter `opt`. | 122 | specified by the parameter `opt`. | |||||
| 123 | 123 | |||||||
| 124 | The parsed value will use the \<\<default_memory_resource,default | 124 | The parsed value will use the \<\<default_memory_resource,default | |||||
| 125 | memory resource\>\> for storage. To use a different resource, call @ref | 125 | memory resource\>\> for storage. To use a different resource, call @ref | |||||
| 126 | reset after construction. | 126 | reset after construction. | |||||
| 127 | 127 | |||||||
| 128 | The main difference between the overloads is in what the constructed | 128 | The main difference between the overloads is in what the constructed | |||||
| 129 | parser will use for temporary storage: | 129 | parser will use for temporary storage: | |||||
| 130 | 130 | |||||||
| 131 | @li **(1)** the constructed parser uses the default memory resource for | 131 | @li **(1)** the constructed parser uses the default memory resource for | |||||
| 132 | temporary storage. | 132 | temporary storage. | |||||
| 133 | 133 | |||||||
| 134 | @li **(2)**, **(3)** the constructed parser uses the memory resource of | 134 | @li **(2)**, **(3)** the constructed parser uses the memory resource of | |||||
| 135 | `sp` for temporary storage. | 135 | `sp` for temporary storage. | |||||
| 136 | 136 | |||||||
| 137 | @li **(4)**, **(6)** the constructed parser first uses the caller-owned | 137 | @li **(4)**, **(6)** the constructed parser first uses the caller-owned | |||||
| 138 | storage `[buffer, buffer + size)` for temporary storage, falling back | 138 | storage `[buffer, buffer + size)` for temporary storage, falling back | |||||
| 139 | to the memory resource of `sp` if needed. | 139 | to the memory resource of `sp` if needed. | |||||
| 140 | 140 | |||||||
| 141 | @li **(5)**, **(7)** the constructed parser first uses the caller-owned | 141 | @li **(5)**, **(7)** the constructed parser first uses the caller-owned | |||||
| 142 | storage `[buffer, buffer + N)` for temporary storage, falling back to | 142 | storage `[buffer, buffer + N)` for temporary storage, falling back to | |||||
| 143 | the memory resource of `sp` if needed. | 143 | the memory resource of `sp` if needed. | |||||
| 144 | 144 | |||||||
| 145 | @note Ownership of `buffer` is not transferred. The caller is | 145 | @note Ownership of `buffer` is not transferred. The caller is | |||||
| 146 | responsible for ensuring the lifetime of the storage pointed to by | 146 | responsible for ensuring the lifetime of the storage pointed to by | |||||
| 147 | `buffer` extends until the parser is destroyed. | 147 | `buffer` extends until the parser is destroyed. | |||||
| 148 | 148 | |||||||
| 149 | Overload **(8)** is the copy constructor. The type is neither copyable | 149 | Overload **(8)** is the copy constructor. The type is neither copyable | |||||
| 150 | nor movable, so the overload is deleted. | 150 | nor movable, so the overload is deleted. | |||||
| 151 | 151 | |||||||
| 152 | @par Complexity | 152 | @par Complexity | |||||
| 153 | Constant. | 153 | Constant. | |||||
| 154 | 154 | |||||||
| 155 | @par Exception Safety | 155 | @par Exception Safety | |||||
| 156 | No-throw guarantee. | 156 | No-throw guarantee. | |||||
| 157 | 157 | |||||||
| 158 | @{ | 158 | @{ | |||||
| 159 | */ | 159 | */ | |||||
| HITCBC | 160 | 53 | parser() noexcept | 160 | 53 | parser() noexcept | ||
| HITCBC | 161 | 53 | : parser({}, {}) | 161 | 53 | : parser({}, {}) | ||
| 162 | { | 162 | { | |||||
| HITCBC | 163 | 53 | } | 163 | 53 | } | ||
| 164 | 164 | |||||||
| 165 | /** Overload | 165 | /** Overload | |||||
| 166 | 166 | |||||||
| 167 | @param sp The memory resource to use for temporary storage. | 167 | @param sp The memory resource to use for temporary storage. | |||||
| 168 | */ | 168 | */ | |||||
| 169 | explicit | 169 | explicit | |||||
| HITCBC | 170 | 1 | parser(storage_ptr sp) noexcept | 170 | 1 | parser(storage_ptr sp) noexcept | ||
| HITCBC | 171 | 1 | : parser(std::move(sp), {}) | 171 | 1 | : parser(std::move(sp), {}) | ||
| 172 | { | 172 | { | |||||
| HITCBC | 173 | 1 | } | 173 | 1 | } | ||
| 174 | 174 | |||||||
| 175 | /** Overload | 175 | /** Overload | |||||
| 176 | 176 | |||||||
| 177 | @param opt The parsing options to use. | 177 | @param opt The parsing options to use. | |||||
| 178 | @param sp | 178 | @param sp | |||||
| 179 | */ | 179 | */ | |||||
| 180 | BOOST_JSON_DECL | 180 | BOOST_JSON_DECL | |||||
| 181 | parser( | 181 | parser( | |||||
| 182 | storage_ptr sp, | 182 | storage_ptr sp, | |||||
| 183 | parse_options const& opt) noexcept; | 183 | parse_options const& opt) noexcept; | |||||
| 184 | 184 | |||||||
| 185 | /** Overload | 185 | /** Overload | |||||
| 186 | 186 | |||||||
| 187 | @param buffer A pointer to valid storage. | 187 | @param buffer A pointer to valid storage. | |||||
| 188 | @param size The number of valid bytes in `buffer`. | 188 | @param size The number of valid bytes in `buffer`. | |||||
| 189 | @param sp | 189 | @param sp | |||||
| 190 | @param opt | 190 | @param opt | |||||
| 191 | */ | 191 | */ | |||||
| 192 | BOOST_JSON_DECL | 192 | BOOST_JSON_DECL | |||||
| 193 | parser( | 193 | parser( | |||||
| 194 | storage_ptr sp, | 194 | storage_ptr sp, | |||||
| 195 | parse_options const& opt, | 195 | parse_options const& opt, | |||||
| 196 | unsigned char* buffer, | 196 | unsigned char* buffer, | |||||
| 197 | std::size_t size) noexcept; | 197 | std::size_t size) noexcept; | |||||
| 198 | 198 | |||||||
| 199 | /** Overload | 199 | /** Overload | |||||
| 200 | 200 | |||||||
| 201 | @tparam N The number of valid bytes in `buffer`. | 201 | @tparam N The number of valid bytes in `buffer`. | |||||
| 202 | @param sp | 202 | @param sp | |||||
| 203 | @param opt | 203 | @param opt | |||||
| 204 | @param buffer | 204 | @param buffer | |||||
| 205 | */ | 205 | */ | |||||
| 206 | template<std::size_t N> | 206 | template<std::size_t N> | |||||
| HITCBC | 207 | 2001506 | parser( | 207 | 2001506 | parser( | ||
| 208 | storage_ptr sp, | 208 | storage_ptr sp, | |||||
| 209 | parse_options const& opt, | 209 | parse_options const& opt, | |||||
| 210 | unsigned char(&buffer)[N]) noexcept | 210 | unsigned char(&buffer)[N]) noexcept | |||||
| HITCBC | 211 | 2001506 | : parser(std::move(sp), | 211 | 2001506 | : parser(std::move(sp), | ||
| HITCBC | 212 | 2001506 | opt, &buffer[0], N) | 212 | 2001506 | opt, &buffer[0], N) | ||
| 213 | { | 213 | { | |||||
| HITCBC | 214 | 2001506 | } | 214 | 2001506 | } | ||
| 215 | 215 | |||||||
| 216 | #if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS) | 216 | #if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS) | |||||
| 217 | /** Overload | 217 | /** Overload | |||||
| 218 | 218 | |||||||
| 219 | @param buffer | 219 | @param buffer | |||||
| 220 | @param size | 220 | @param size | |||||
| 221 | @param sp | 221 | @param sp | |||||
| 222 | @param opt | 222 | @param opt | |||||
| 223 | */ | 223 | */ | |||||
| 224 | parser( | 224 | parser( | |||||
| 225 | storage_ptr sp, | 225 | storage_ptr sp, | |||||
| 226 | parse_options const& opt, | 226 | parse_options const& opt, | |||||
| 227 | std::byte* buffer, | 227 | std::byte* buffer, | |||||
| 228 | std::size_t size) noexcept | 228 | std::size_t size) noexcept | |||||
| 229 | : parser(sp, opt, reinterpret_cast< | 229 | : parser(sp, opt, reinterpret_cast< | |||||
| 230 | unsigned char*>(buffer), size) | 230 | unsigned char*>(buffer), size) | |||||
| 231 | { | 231 | { | |||||
| 232 | } | 232 | } | |||||
| 233 | 233 | |||||||
| 234 | /** Overload | 234 | /** Overload | |||||
| 235 | 235 | |||||||
| 236 | @tparam N | 236 | @tparam N | |||||
| 237 | @param sp | 237 | @param sp | |||||
| 238 | @param opt | 238 | @param opt | |||||
| 239 | @param buffer | 239 | @param buffer | |||||
| 240 | */ | 240 | */ | |||||
| 241 | template<std::size_t N> | 241 | template<std::size_t N> | |||||
| 242 | parser( | 242 | parser( | |||||
| 243 | storage_ptr sp, | 243 | storage_ptr sp, | |||||
| 244 | parse_options const& opt, | 244 | parse_options const& opt, | |||||
| 245 | std::byte(&buffer)[N]) noexcept | 245 | std::byte(&buffer)[N]) noexcept | |||||
| 246 | : parser(std::move(sp), | 246 | : parser(std::move(sp), | |||||
| 247 | opt, &buffer[0], N) | 247 | opt, &buffer[0], N) | |||||
| 248 | { | 248 | { | |||||
| 249 | } | 249 | } | |||||
| 250 | #endif | 250 | #endif | |||||
| 251 | 251 | |||||||
| 252 | #ifndef BOOST_JSON_DOCS | 252 | #ifndef BOOST_JSON_DOCS | |||||
| 253 | // Safety net for accidental buffer overflows | 253 | // Safety net for accidental buffer overflows | |||||
| 254 | template<std::size_t N> | 254 | template<std::size_t N> | |||||
| 255 | parser( | 255 | parser( | |||||
| 256 | storage_ptr sp, | 256 | storage_ptr sp, | |||||
| 257 | parse_options const& opt, | 257 | parse_options const& opt, | |||||
| 258 | unsigned char(&buffer)[N], | 258 | unsigned char(&buffer)[N], | |||||
| 259 | std::size_t n) noexcept | 259 | std::size_t n) noexcept | |||||
| 260 | : parser(std::move(sp), | 260 | : parser(std::move(sp), | |||||
| 261 | opt, &buffer[0], n) | 261 | opt, &buffer[0], n) | |||||
| 262 | { | 262 | { | |||||
| 263 | // If this goes off, check your parameters | 263 | // If this goes off, check your parameters | |||||
| 264 | // closely, chances are you passed an array | 264 | // closely, chances are you passed an array | |||||
| 265 | // thinking it was a pointer. | 265 | // thinking it was a pointer. | |||||
| 266 | BOOST_ASSERT(n <= N); | 266 | BOOST_ASSERT(n <= N); | |||||
| 267 | } | 267 | } | |||||
| 268 | 268 | |||||||
| 269 | #ifdef __cpp_lib_byte | 269 | #ifdef __cpp_lib_byte | |||||
| 270 | // Safety net for accidental buffer overflows | 270 | // Safety net for accidental buffer overflows | |||||
| 271 | template<std::size_t N> | 271 | template<std::size_t N> | |||||
| 272 | parser( | 272 | parser( | |||||
| 273 | storage_ptr sp, | 273 | storage_ptr sp, | |||||
| 274 | parse_options const& opt, | 274 | parse_options const& opt, | |||||
| 275 | std::byte(&buffer)[N], std::size_t n) noexcept | 275 | std::byte(&buffer)[N], std::size_t n) noexcept | |||||
| 276 | : parser(std::move(sp), | 276 | : parser(std::move(sp), | |||||
| 277 | opt, &buffer[0], n) | 277 | opt, &buffer[0], n) | |||||
| 278 | { | 278 | { | |||||
| 279 | // If this goes off, check your parameters | 279 | // If this goes off, check your parameters | |||||
| 280 | // closely, chances are you passed an array | 280 | // closely, chances are you passed an array | |||||
| 281 | // thinking it was a pointer. | 281 | // thinking it was a pointer. | |||||
| 282 | BOOST_ASSERT(n <= N); | 282 | BOOST_ASSERT(n <= N); | |||||
| 283 | } | 283 | } | |||||
| 284 | #endif | 284 | #endif | |||||
| 285 | #endif | 285 | #endif | |||||
| 286 | 286 | |||||||
| 287 | /// Overload | 287 | /// Overload | |||||
| 288 | parser( | 288 | parser( | |||||
| 289 | parser const&) = delete; | 289 | parser const&) = delete; | |||||
| 290 | /// @} | 290 | /// @} | |||||
| 291 | 291 | |||||||
| 292 | 292 | |||||||
| 293 | /** Reset the parser for a new JSON text. | 293 | /** Reset the parser for a new JSON text. | |||||
| 294 | 294 | |||||||
| 295 | This function is used to reset the parser to | 295 | This function is used to reset the parser to | |||||
| 296 | prepare it for parsing a new complete JSON text. | 296 | prepare it for parsing a new complete JSON text. | |||||
| 297 | Any previous partial results are destroyed. | 297 | Any previous partial results are destroyed. | |||||
| 298 | 298 | |||||||
| 299 | @par Complexity | 299 | @par Complexity | |||||
| 300 | Constant or linear in the size of any previous | 300 | Constant or linear in the size of any previous | |||||
| 301 | partial parsing results. | 301 | partial parsing results. | |||||
| 302 | 302 | |||||||
| 303 | @par Exception Safety | 303 | @par Exception Safety | |||||
| 304 | No-throw guarantee. | 304 | No-throw guarantee. | |||||
| 305 | 305 | |||||||
| 306 | @param sp A pointer to the @ref boost::container::pmr::memory_resource | 306 | @param sp A pointer to the @ref boost::container::pmr::memory_resource | |||||
| 307 | to use for the resulting @ref value. The parser will acquire shared | 307 | to use for the resulting @ref value. The parser will acquire shared | |||||
| 308 | ownership. | 308 | ownership. | |||||
| 309 | */ | 309 | */ | |||||
| 310 | BOOST_JSON_DECL | 310 | BOOST_JSON_DECL | |||||
| 311 | void | 311 | void | |||||
| 312 | reset(storage_ptr sp = {}) noexcept; | 312 | reset(storage_ptr sp = {}) noexcept; | |||||
| 313 | 313 | |||||||
| 314 | /** Parse a buffer containing a complete JSON text. | 314 | /** Parse a buffer containing a complete JSON text. | |||||
| 315 | 315 | |||||||
| 316 | This function parses a complete JSON text contained in the specified | 316 | This function parses a complete JSON text contained in the specified | |||||
| 317 | character buffer. Additional characters past the end of the complete | 317 | character buffer. Additional characters past the end of the complete | |||||
| 318 | JSON text are ignored. The function returns the actual number of | 318 | JSON text are ignored. The function returns the actual number of | |||||
| 319 | characters parsed, which may be less than the size of the input. This | 319 | characters parsed, which may be less than the size of the input. This | |||||
| 320 | allows parsing of a buffer containing multiple individual JSON texts or | 320 | allows parsing of a buffer containing multiple individual JSON texts or | |||||
| 321 | containing different protocol data: | 321 | containing different protocol data: | |||||
| 322 | 322 | |||||||
| 323 | @par Example | 323 | @par Example | |||||
| 324 | @code | 324 | @code | |||||
| 325 | parser p; // construct a parser | 325 | parser p; // construct a parser | |||||
| 326 | size_t n = p.write_some( "[1,2,3] null" ); // parse a complete JSON text | 326 | size_t n = p.write_some( "[1,2,3] null" ); // parse a complete JSON text | |||||
| 327 | assert( n == 8 ); // only some characters consumed | 327 | assert( n == 8 ); // only some characters consumed | |||||
| 328 | value jv = p.release(); // take ownership of the value | 328 | value jv = p.release(); // take ownership of the value | |||||
| 329 | @endcode | 329 | @endcode | |||||
| 330 | 330 | |||||||
| 331 | Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by | 331 | Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by | |||||
| 332 | setting `ec`. Overloads **(3)** and **(6)** report errors by throwing | 332 | setting `ec`. Overloads **(3)** and **(6)** report errors by throwing | |||||
| 333 | exceptions. | 333 | exceptions. | |||||
| 334 | 334 | |||||||
| 335 | @par Complexity | 335 | @par Complexity | |||||
| 336 | @li **(1)**--**(3)** linear in `size`. | 336 | @li **(1)**--**(3)** linear in `size`. | |||||
| 337 | @li **(4)**--**(6)** linear in `s.size()`. | 337 | @li **(4)**--**(6)** linear in `s.size()`. | |||||
| 338 | 338 | |||||||
| 339 | @par Exception Safety | 339 | @par Exception Safety | |||||
| 340 | Basic guarantee. Calls to `memory_resource::allocate` may throw. Upon | 340 | Basic guarantee. Calls to `memory_resource::allocate` may throw. Upon | |||||
| 341 | error or exception, subsequent calls will fail until @ref reset is | 341 | error or exception, subsequent calls will fail until @ref reset is | |||||
| 342 | called to parse a new JSON text. | 342 | called to parse a new JSON text. | |||||
| 343 | 343 | |||||||
| 344 | @return The number of characters consumed from the buffer. | 344 | @return The number of characters consumed from the buffer. | |||||
| 345 | 345 | |||||||
| 346 | @param data A pointer to a buffer of `size` characters to parse. | 346 | @param data A pointer to a buffer of `size` characters to parse. | |||||
| 347 | @param size The number of characters pointed to by `data`. | 347 | @param size The number of characters pointed to by `data`. | |||||
| 348 | @param ec Set to the error, if any occurred. | 348 | @param ec Set to the error, if any occurred. | |||||
| 349 | 349 | |||||||
| 350 | @{ | 350 | @{ | |||||
| 351 | */ | 351 | */ | |||||
| 352 | BOOST_JSON_DECL | 352 | BOOST_JSON_DECL | |||||
| 353 | std::size_t | 353 | std::size_t | |||||
| 354 | write_some( | 354 | write_some( | |||||
| 355 | char const* data, | 355 | char const* data, | |||||
| 356 | std::size_t size, | 356 | std::size_t size, | |||||
| 357 | system::error_code& ec); | 357 | system::error_code& ec); | |||||
| 358 | 358 | |||||||
| 359 | BOOST_JSON_DECL | 359 | BOOST_JSON_DECL | |||||
| 360 | std::size_t | 360 | std::size_t | |||||
| 361 | write_some( | 361 | write_some( | |||||
| 362 | char const* data, | 362 | char const* data, | |||||
| 363 | std::size_t size, | 363 | std::size_t size, | |||||
| 364 | std::error_code& ec); | 364 | std::error_code& ec); | |||||
| 365 | 365 | |||||||
| 366 | /** Overload | 366 | /** Overload | |||||
| 367 | 367 | |||||||
| 368 | @param data | 368 | @param data | |||||
| 369 | @param size | 369 | @param size | |||||
| 370 | */ | 370 | */ | |||||
| 371 | BOOST_JSON_DECL | 371 | BOOST_JSON_DECL | |||||
| 372 | std::size_t | 372 | std::size_t | |||||
| 373 | write_some( | 373 | write_some( | |||||
| 374 | char const* data, | 374 | char const* data, | |||||
| 375 | std::size_t size); | 375 | std::size_t size); | |||||
| 376 | 376 | |||||||
| 377 | /** Overload | 377 | /** Overload | |||||
| 378 | 378 | |||||||
| 379 | @param s The character string to parse. | 379 | @param s The character string to parse. | |||||
| 380 | @param ec | 380 | @param ec | |||||
| 381 | */ | 381 | */ | |||||
| 382 | std::size_t | 382 | std::size_t | |||||
| HITCBC | 383 | 2 | write_some( | 383 | 2 | write_some( | ||
| 384 | string_view s, | 384 | string_view s, | |||||
| 385 | system::error_code& ec) | 385 | system::error_code& ec) | |||||
| 386 | { | 386 | { | |||||
| HITCBC | 387 | 2 | return write_some( | 387 | 2 | return write_some( | ||
| HITCBC | 388 | 2 | s.data(), s.size(), ec); | 388 | 2 | s.data(), s.size(), ec); | ||
| 389 | } | 389 | } | |||||
| 390 | 390 | |||||||
| 391 | /** Overload | 391 | /** Overload | |||||
| 392 | 392 | |||||||
| 393 | @param s | 393 | @param s | |||||
| 394 | @param ec | 394 | @param ec | |||||
| 395 | */ | 395 | */ | |||||
| 396 | std::size_t | 396 | std::size_t | |||||
| HITCBC | 397 | 2 | write_some( | 397 | 2 | write_some( | ||
| 398 | string_view s, | 398 | string_view s, | |||||
| 399 | std::error_code& ec) | 399 | std::error_code& ec) | |||||
| 400 | { | 400 | { | |||||
| HITCBC | 401 | 2 | return write_some( | 401 | 2 | return write_some( | ||
| HITCBC | 402 | 2 | s.data(), s.size(), ec); | 402 | 2 | s.data(), s.size(), ec); | ||
| 403 | } | 403 | } | |||||
| 404 | 404 | |||||||
| 405 | /** Overload | 405 | /** Overload | |||||
| 406 | 406 | |||||||
| 407 | @param s | 407 | @param s | |||||
| 408 | */ | 408 | */ | |||||
| 409 | std::size_t | 409 | std::size_t | |||||
| HITCBC | 410 | 4 | write_some( | 410 | 4 | write_some( | ||
| 411 | string_view s) | 411 | string_view s) | |||||
| 412 | { | 412 | { | |||||
| HITCBC | 413 | 4 | return write_some( | 413 | 4 | return write_some( | ||
| HITCBC | 414 | 2 | s.data(), s.size()); | 414 | 2 | s.data(), s.size()); | ||
| 415 | } | 415 | } | |||||
| 416 | /// @} | 416 | /// @} | |||||
| 417 | 417 | |||||||
| 418 | /** Parse a buffer containing a complete JSON text. | 418 | /** Parse a buffer containing a complete JSON text. | |||||
| 419 | 419 | |||||||
| 420 | This function parses a complete JSON text contained in the specified | 420 | This function parses a complete JSON text contained in the specified | |||||
| 421 | character buffer. The entire buffer must be consumed; if there are | 421 | character buffer. The entire buffer must be consumed; if there are | |||||
| 422 | additional characters past the end of the complete JSON text, the parse | 422 | additional characters past the end of the complete JSON text, the parse | |||||
| 423 | fails and an error is returned. | 423 | fails and an error is returned. | |||||
| 424 | 424 | |||||||
| 425 | @par Example | 425 | @par Example | |||||
| 426 | @code | 426 | @code | |||||
| 427 | parser p; // construct a parser | 427 | parser p; // construct a parser | |||||
| 428 | size_t n = p.write( "[1,2,3]" ); // parse a complete JSON text | 428 | size_t n = p.write( "[1,2,3]" ); // parse a complete JSON text | |||||
| 429 | assert( n == 7 ); // all characters consumed | 429 | assert( n == 7 ); // all characters consumed | |||||
| 430 | value jv = p.release(); // take ownership of the value | 430 | value jv = p.release(); // take ownership of the value | |||||
| 431 | @endcode | 431 | @endcode | |||||
| 432 | 432 | |||||||
| 433 | Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by | 433 | Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by | |||||
| 434 | setting `ec`. Overloads **(3)** and **(6)** report errors by throwing | 434 | setting `ec`. Overloads **(3)** and **(6)** report errors by throwing | |||||
| 435 | exceptions. | 435 | exceptions. | |||||
| 436 | 436 | |||||||
| 437 | @par Complexity | 437 | @par Complexity | |||||
| 438 | @li **(1)**--**(3)** linear in `size`. | 438 | @li **(1)**--**(3)** linear in `size`. | |||||
| 439 | @li **(4)**--**(6)** linear in `s.size()`. | 439 | @li **(4)**--**(6)** linear in `s.size()`. | |||||
| 440 | 440 | |||||||
| 441 | @par Exception Safety | 441 | @par Exception Safety | |||||
| 442 | Basic guarantee. Calls to `memory_resource::allocate` may throw. Upon | 442 | Basic guarantee. Calls to `memory_resource::allocate` may throw. Upon | |||||
| 443 | error or exception, subsequent calls will fail until @ref reset is | 443 | error or exception, subsequent calls will fail until @ref reset is | |||||
| 444 | called to parse a new JSON text. | 444 | called to parse a new JSON text. | |||||
| 445 | 445 | |||||||
| 446 | @return The number of characters consumed from the buffer. | 446 | @return The number of characters consumed from the buffer. | |||||
| 447 | 447 | |||||||
| 448 | @param data A pointer to a buffer of `size` characters to parse. | 448 | @param data A pointer to a buffer of `size` characters to parse. | |||||
| 449 | @param size The number of characters pointed to by `data`. | 449 | @param size The number of characters pointed to by `data`. | |||||
| 450 | @param ec Set to the error, if any occurred. | 450 | @param ec Set to the error, if any occurred. | |||||
| 451 | 451 | |||||||
| 452 | @{ | 452 | @{ | |||||
| 453 | */ | 453 | */ | |||||
| 454 | BOOST_JSON_DECL | 454 | BOOST_JSON_DECL | |||||
| 455 | std::size_t | 455 | std::size_t | |||||
| 456 | write( | 456 | write( | |||||
| 457 | char const* data, | 457 | char const* data, | |||||
| 458 | std::size_t size, | 458 | std::size_t size, | |||||
| 459 | system::error_code& ec); | 459 | system::error_code& ec); | |||||
| 460 | 460 | |||||||
| 461 | BOOST_JSON_DECL | 461 | BOOST_JSON_DECL | |||||
| 462 | std::size_t | 462 | std::size_t | |||||
| 463 | write( | 463 | write( | |||||
| 464 | char const* data, | 464 | char const* data, | |||||
| 465 | std::size_t size, | 465 | std::size_t size, | |||||
| 466 | std::error_code& ec); | 466 | std::error_code& ec); | |||||
| 467 | 467 | |||||||
| 468 | /** Overload | 468 | /** Overload | |||||
| 469 | 469 | |||||||
| 470 | @throw `boost::system::system_error` Thrown on error. | 470 | @throw `boost::system::system_error` Thrown on error. | |||||
| 471 | */ | 471 | */ | |||||
| 472 | BOOST_JSON_DECL | 472 | BOOST_JSON_DECL | |||||
| 473 | std::size_t | 473 | std::size_t | |||||
| 474 | write( | 474 | write( | |||||
| 475 | char const* data, | 475 | char const* data, | |||||
| 476 | std::size_t size); | 476 | std::size_t size); | |||||
| 477 | 477 | |||||||
| 478 | /** Overload | 478 | /** Overload | |||||
| 479 | 479 | |||||||
| 480 | @param s The character string to parse. | 480 | @param s The character string to parse. | |||||
| 481 | @param ec | 481 | @param ec | |||||
| 482 | */ | 482 | */ | |||||
| 483 | std::size_t | 483 | std::size_t | |||||
| HITCBC | 484 | 2001508 | write( | 484 | 2001508 | write( | ||
| 485 | string_view s, | 485 | string_view s, | |||||
| 486 | system::error_code& ec) | 486 | system::error_code& ec) | |||||
| 487 | { | 487 | { | |||||
| HITCBC | 488 | 2001508 | return write( | 488 | 2001508 | return write( | ||
| HITCBC | 489 | 2001507 | s.data(), s.size(), ec); | 489 | 2001507 | s.data(), s.size(), ec); | ||
| 490 | } | 490 | } | |||||
| 491 | 491 | |||||||
| 492 | /** Overload | 492 | /** Overload | |||||
| 493 | 493 | |||||||
| 494 | @param s | 494 | @param s | |||||
| 495 | @param ec | 495 | @param ec | |||||
| 496 | */ | 496 | */ | |||||
| 497 | std::size_t | 497 | std::size_t | |||||
| HITCBC | 498 | 3 | write( | 498 | 3 | write( | ||
| 499 | string_view s, | 499 | string_view s, | |||||
| 500 | std::error_code& ec) | 500 | std::error_code& ec) | |||||
| 501 | { | 501 | { | |||||
| HITCBC | 502 | 3 | return write( | 502 | 3 | return write( | ||
| HITCBC | 503 | 3 | s.data(), s.size(), ec); | 503 | 3 | s.data(), s.size(), ec); | ||
| 504 | } | 504 | } | |||||
| 505 | 505 | |||||||
| 506 | /** Overload | 506 | /** Overload | |||||
| 507 | 507 | |||||||
| 508 | @param s | 508 | @param s | |||||
| 509 | */ | 509 | */ | |||||
| 510 | std::size_t | 510 | std::size_t | |||||
| HITCBC | 511 | 8 | write( | 511 | 8 | write( | ||
| 512 | string_view s) | 512 | string_view s) | |||||
| 513 | { | 513 | { | |||||
| HITCBC | 514 | 8 | return write( | 514 | 8 | return write( | ||
| HITCBC | 515 | 4 | s.data(), s.size()); | 515 | 4 | s.data(), s.size()); | ||
| 516 | } | 516 | } | |||||
| 517 | /// @} | 517 | /// @} | |||||
| 518 | 518 | |||||||
| 519 | /** Return the parsed JSON text as a @ref value. | 519 | /** Return the parsed JSON text as a @ref value. | |||||
| 520 | 520 | |||||||
| 521 | This returns the parsed value, or throws an exception if the parsing is | 521 | This returns the parsed value, or throws an exception if the parsing is | |||||
| 522 | incomplete or failed. It is necessary to call @ref reset after calling | 522 | incomplete or failed. It is necessary to call @ref reset after calling | |||||
| 523 | this function in order to parse another JSON text. | 523 | this function in order to parse another JSON text. | |||||
| 524 | 524 | |||||||
| 525 | @par Complexity | 525 | @par Complexity | |||||
| 526 | Constant. | 526 | Constant. | |||||
| 527 | 527 | |||||||
| 528 | @return The parsed value. Ownership of this value is transferred to the | 528 | @return The parsed value. Ownership of this value is transferred to the | |||||
| 529 | caller. | 529 | caller. | |||||
| 530 | 530 | |||||||
| 531 | @throw boost::system::system_error A complete JSON text hasn't been | 531 | @throw boost::system::system_error A complete JSON text hasn't been | |||||
| 532 | parsed, or parsing failed. | 532 | parsed, or parsing failed. | |||||
| 533 | */ | 533 | */ | |||||
| 534 | BOOST_JSON_DECL | 534 | BOOST_JSON_DECL | |||||
| 535 | value | 535 | value | |||||
| 536 | release(); | 536 | release(); | |||||
| 537 | }; | 537 | }; | |||||
| 538 | 538 | |||||||
| 539 | } // namespace json | 539 | } // namespace json | |||||
| 540 | } // namespace boost | 540 | } // namespace boost | |||||
| 541 | 541 | |||||||
| 542 | #endif | 542 | #endif | |||||