JSON Voorhees
Killer JSON for C++
Loading...
Searching...
No Matches
parse.hpp
Go to the documentation of this file.
1/// \file jsonv/parse.hpp
2///
3/// Copyright (c) 2012-2020 by Travis Gockel. All rights reserved.
4///
5/// This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
6/// as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
7/// version.
8///
9/// \author Travis Gockel (travis@gockelhut.com)
10#pragma once
11
12#include <jsonv/config.hpp>
13#include <optional>
14#include <string_view>
15#include <jsonv/value.hpp>
16
17#include <cstddef>
18#include <stdexcept>
19
20/// \def JSONV_PARSE_MAX_STRUCTURE_DEPTH
21/// See \c jsonv::parse_options::k::max_structure_depth.
22#ifndef JSONV_PARSE_MAX_STRUCTURE_DEPTH
23# define JSONV_PARSE_MAX_STRUCTURE_DEPTH 128
24#endif
25
26namespace jsonv
27{
28
29class extract_options;
30class tokenizer;
31
32/// An error encountered when parsing.
33///
34/// \see parse
36 public std::runtime_error
37{
38public:
39 /// \{
40 /// Create an error with the given \a message and optional \a character location.
41 explicit parse_error(const char* message, std::optional<std::size_t> character) noexcept;
42 explicit parse_error(const char* message) noexcept;
43 /// \}
44
45 virtual ~parse_error() noexcept;
46
47 /// Get the character location of the encountered error.
49 const std::optional<std::size_t>& character() const { return _character; }
50
51private:
52 std::optional<std::size_t> _character;
53};
54
55/// Get a string representation of a \c parse_error.
56JSONV_PUBLIC std::ostream& operator<<(std::ostream& os, const parse_error& p);
57
58/// Get a string representation of a \c parse_error.
59JSONV_NODISCARD JSONV_PUBLIC std::string to_string(const parse_error& p);
60
61/// Configuration for various parsing options. All parse functions should take in a \c parse_options as a paramter and
62/// should respect your settings.
64{
65public:
66 using size_type = value::size_type;
67
68 /** The encoding format for strings. **/
69 enum class encoding
70 {
71 /// Default UTF-8 encoding scheme.
72 ///
73 /// \see http://www.unicode.org/versions/Unicode6.2.0/ch03.pdf#G7404
74 utf8,
75 /// Like \c utf8, but check that there are no unprintable characters in the input stream (see \c std::isprint).
76 /// To contrast this with \c utf8, this mode will reject things such as the \c tab and \c newline characters,
77 /// while this will reject them.
78 utf8_strict,
79 };
80
81 struct k final
82 {
83 /// The absolute maximum structure depth to parse. This sets the upper allowable limit
84 static constexpr size_type max_structure_depth = size_type(JSONV_PARSE_MAX_STRUCTURE_DEPTH);
85 };
86
87public:
88 /// Create an instance with the default options.
90
92
93 /// Create a parser with the default options -- this is the same result as the default constructor, but might be
94 /// helpful if you like to be more explicit.
96 static parse_options create_default();
97
98 /// Create a strict parser. In general, these options are meant to fail on anything that is not a 100% valid JSON
99 /// document. More specifically:
100 ///
101 /// \code
102 /// string_encoding() == encoding::utf8_strict
103 /// max_structure_depth() == 20
104 /// require_document() == true
105 /// complete_parse() == true
106 /// comments() == false
107 /// \endcode
109 static parse_options create_strict();
110
111 /// \{
112 /// The output encoding for multi-byte characters in strings. The default value is \c encoding::utf8.
114 encoding string_encoding() const { return _string_encoding; }
115 parse_options& string_encoding(encoding);
116 /// \}
117
118 /// \{
119 /// The maximum allowed nesting depth of any structure in the JSON document. The JSON specification technically
120 /// limits the depth to 20, but very few implementations actually conform to this, so it is fairly dangerous to set
121 /// this value. By default, the value is \c nullopt, which means implementations should limit structure depth to
122 /// \c k::max_structure_depth. Setting \a depth to a value above \c k::max_structure_depth is will cause
123 /// \c std::invalid_argument to be thrown from \c parse functions.
125 std::optional<size_type> max_structure_depth() const { return _max_struct_depth; }
126 parse_options& max_structure_depth(std::optional<size_type> depth);
127 /// \}
128
129 /// \{
130 /// If set to true, the result of a parse is required to have \c kind of \c kind::object or \c kind::array. By
131 /// default, this is turned off, which will allow \c parse to return values with \c kind::string or
132 /// \c kind::integer.
134 bool require_document() const { return _require_document; }
135 parse_options& require_document(bool);
136 /// \}
137
138 /// \{
139 /// Should the input be completely parsed to consider the parsing a success? This is on by default. Disabling this
140 /// option can be useful for situations where JSON input is coming from some stream and you wish to process distinct
141 /// objects separately.
143 bool complete_parse() const { return _complete_parse; }
144 parse_options& complete_parse(bool);
145 /// \}
146
147 /// \{
148 /// Are JSON comments allowed? While there is no official syntax for JSON comments, this uses the de-facto standard
149 /// of ECMAScript-style block comments: `/* comment */`. If this is enabled, comments are treated exactly like
150 /// whitespace.
152 bool comments() const { return _comments; }
153 parse_options& comments(bool);
154 /// \}
155
156private:
157 // For the purposes of ABI compliance, most modifications to the variables in this class should bump the minor
158 // version number.
159 encoding _string_encoding = encoding::utf8;
160 std::optional<size_type> _max_struct_depth = std::nullopt;
161 bool _require_document = false;
162 bool _complete_parse = true;
163 bool _comments = true;
164};
165
166/// \{
167/// Construct a JSON value from the given \a input.
168///
169/// \example "parse(std::string_view)"
170/// \code
171/// jsonv::value out = jsonv::parse(R"( { "a": 1, "b": [ 2, 3, 4 ] } )");
172/// \endcode
173///
174/// \param parse_options Options specific to parsing the \a input -- the indexing of source text into an AST. If
175/// unspecified, this is \c parse_options::create_default().
176/// \param extract_options Options specific to extraction -- transforming the AST into a \c jsonv::value. If
177/// unspecified, this is \c extract_options::create_default().
178///
179/// \throws parse_error if the source text is invalid JSON. This is thrown for errors like unterminated strings, arrays,
180/// or stray literals. Errors of this category are described as an offset into \a input.
181/// \throws extract_error if the AST can not be transformed into a \c jsonv::value. This is thrown for errors like an
182/// object with duplicate keys (note that the default \c jsonv::formats does not throw for this case).
184value parse(std::string_view input,
185 const parse_options& parse_options,
186 const extract_options& extract_options
187 );
188
189JSONV_NODISCARD JSONV_PUBLIC value parse(std::string_view input);
190JSONV_NODISCARD JSONV_PUBLIC value parse(std::string_view input, const parse_options& parse_options);
191JSONV_NODISCARD JSONV_PUBLIC value parse(std::string_view input, const extract_options& extract_options);
192/// \}
193
194/// \{
195/// Reads a JSON value from the \a input stream.
196///
197/// \example "parse(std::istream&)"
198/// Parse JSON from some file.
199/// \code
200/// std::ifstream file("file.json");
201/// jsonv::value out = parse(file);
202/// \endcode
203///
204/// \param parse_options Options specific to parsing the \a input -- the indexing of source text into an AST. If
205/// unspecified, this is \c parse_options::create_default().
206/// \param extract_options Options specific to extraction -- transforming the AST into a \c jsonv::value. If
207/// unspecified, this is \c extract_options::create_default().
208///
209/// \throws parse_error if the source text is invalid JSON. This is thrown for errors like unterminated strings, arrays,
210/// or stray literals. Errors of this category are described as an offset into \a input.
211/// \throws extract_error if the AST can not be transformed into a \c jsonv::value. This is thrown for errors like an
212/// object with duplicate keys (note that the default \c jsonv::formats does not throw for this case).
214value parse(std::istream& input,
215 const parse_options& parse_options,
216 const extract_options& extract_options
217 );
218
219JSONV_NODISCARD JSONV_PUBLIC value parse(std::istream& input);
220JSONV_NODISCARD JSONV_PUBLIC value parse(std::istream& input, const parse_options& parse_options);
221JSONV_NODISCARD JSONV_PUBLIC value parse(std::istream& input, const extract_options& extract_options);
222/// \}
223
224/// \{
225/// Read a JSON value from the string bound by `[begin, end)`.
227value parse(const char* begin,
228 const char* end,
231 );
232JSONV_NODISCARD JSONV_PUBLIC value parse(const char* begin, const char* end, const parse_options& parse_options);
233JSONV_NODISCARD JSONV_PUBLIC value parse(const char* begin, const char* end, const extract_options& extract_options);
234JSONV_NODISCARD JSONV_PUBLIC value parse(const char* begin, const char* end);
235/// \}
236
237}
An adapter for enumeration types.
Configuration for various extraction options. This becomes part of the extraction_context.
Definition extract.hpp:213
An error encountered when parsing.
Definition parse.hpp:37
parse_error(const char *message, std::optional< std::size_t > character) noexcept
Configuration for various parsing options.
Definition parse.hpp:64
bool require_document() const
Definition parse.hpp:134
bool comments() const
Definition parse.hpp:152
std::optional< size_type > max_structure_depth() const
Definition parse.hpp:125
parse_options()
Create an instance with the default options.
encoding
The encoding format for strings.
Definition parse.hpp:70
bool complete_parse() const
Definition parse.hpp:143
Represents a single JSON value, which can be any one of a potential kind, each behaving slightly diff...
Definition value.hpp:113
Copyright (c) 2014-2020 by Travis Gockel.
#define JSONV_NODISCARD
Warn if the caller discards the result of this function.
Definition config.hpp:121
#define JSONV_PUBLIC
This function or class is part of the public API for JSON Voorhees.
Definition config.hpp:102
STL namespace.
#define JSONV_PARSE_MAX_STRUCTURE_DEPTH
See jsonv::parse_options::k::max_structure_depth.
Definition parse.hpp:23
Copyright (c) 2012-2020 by Travis Gockel.