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.
48 const std::optional<std::size_t>& character() const { return _character; }
49
50private:
51 std::optional<std::size_t> _character;
52};
53
54/// Get a string representation of a \c parse_error.
55JSONV_PUBLIC std::ostream& operator<<(std::ostream& os, const parse_error& p);
56
57/// Get a string representation of a \c parse_error.
58JSONV_PUBLIC std::string to_string(const parse_error& p);
59
60/// Configuration for various parsing options. All parse functions should take in a \c parse_options as a paramter and
61/// should respect your settings.
63{
64public:
65 using size_type = value::size_type;
66
67 /** The encoding format for strings. **/
68 enum class encoding
69 {
70 /// Default UTF-8 encoding scheme.
71 ///
72 /// \see http://www.unicode.org/versions/Unicode6.2.0/ch03.pdf#G7404
73 utf8,
74 /// Like \c utf8, but check that there are no unprintable characters in the input stream (see \c std::isprint).
75 /// To contrast this with \c utf8, this mode will reject things such as the \c tab and \c newline characters,
76 /// while this will reject them.
77 utf8_strict,
78 };
79
80 struct k final
81 {
82 /// The absolute maximum structure depth to parse. This sets the upper allowable limit
83 static constexpr size_type max_structure_depth = size_type(JSONV_PARSE_MAX_STRUCTURE_DEPTH);
84 };
85
86public:
87 /// Create an instance with the default options.
89
91
92 /// Create a parser with the default options -- this is the same result as the default constructor, but might be
93 /// helpful if you like to be more explicit.
94 static parse_options create_default();
95
96 /// Create a strict parser. In general, these options are meant to fail on anything that is not a 100% valid JSON
97 /// document. More specifically:
98 ///
99 /// \code
100 /// string_encoding() == encoding::utf8_strict
101 /// max_structure_depth() == 20
102 /// require_document() == true
103 /// complete_parse() == true
104 /// comments() == false
105 /// \endcode
106 static parse_options create_strict();
107
108 /// \{
109 /// The output encoding for multi-byte characters in strings. The default value is \c encoding::utf8.
110 encoding string_encoding() const { return _string_encoding; }
111 parse_options& string_encoding(encoding);
112 /// \}
113
114 /// \{
115 /// The maximum allowed nesting depth of any structure in the JSON document. The JSON specification technically
116 /// limits the depth to 20, but very few implementations actually conform to this, so it is fairly dangerous to set
117 /// this value. By default, the value is \c nullopt, which means implementations should limit structure depth to
118 /// \c k::max_structure_depth. Setting \a depth to a value above \c k::max_structure_depth is will cause
119 /// \c std::invalid_argument to be thrown from \c parse functions.
120 std::optional<size_type> max_structure_depth() const { return _max_struct_depth; }
121 parse_options& max_structure_depth(std::optional<size_type> depth);
122 /// \}
123
124 /// \{
125 /// If set to true, the result of a parse is required to have \c kind of \c kind::object or \c kind::array. By
126 /// default, this is turned off, which will allow \c parse to return values with \c kind::string or
127 /// \c kind::integer.
128 bool require_document() const { return _require_document; }
129 parse_options& require_document(bool);
130 /// \}
131
132 /// \{
133 /// Should the input be completely parsed to consider the parsing a success? This is on by default. Disabling this
134 /// option can be useful for situations where JSON input is coming from some stream and you wish to process distinct
135 /// objects separately.
136 bool complete_parse() const { return _complete_parse; }
137 parse_options& complete_parse(bool);
138 /// \}
139
140 /// \{
141 /// Are JSON comments allowed? While there is no official syntax for JSON comments, this uses the de-facto standard
142 /// of ECMAScript-style block comments: `/* comment */`. If this is enabled, comments are treated exactly like
143 /// whitespace.
144 bool comments() const { return _comments; }
145 parse_options& comments(bool);
146 /// \}
147
148private:
149 // For the purposes of ABI compliance, most modifications to the variables in this class should bump the minor
150 // version number.
151 encoding _string_encoding = encoding::utf8;
152 std::optional<size_type> _max_struct_depth = std::nullopt;
153 bool _require_document = false;
154 bool _complete_parse = true;
155 bool _comments = true;
156};
157
158/// \{
159/// Construct a JSON value from the given \a input.
160///
161/// \example "parse(std::string_view)"
162/// \code
163/// jsonv::value out = jsonv::parse(R"( { "a": 1, "b": [ 2, 3, 4 ] } )");
164/// \endcode
165///
166/// \param parse_options Options specific to parsing the \a input -- the indexing of source text into an AST. If
167/// unspecified, this is \c parse_options::create_default().
168/// \param extract_options Options specific to extraction -- transforming the AST into a \c jsonv::value. If
169/// unspecified, this is \c extract_options::create_default().
170///
171/// \throws parse_error if the source text is invalid JSON. This is thrown for errors like unterminated strings, arrays,
172/// or stray literals. Errors of this category are described as an offset into \a input.
173/// \throws extract_error if the AST can not be transformed into a \c jsonv::value. This is thrown for errors like an
174/// object with duplicate keys (note that the default \c jsonv::formats does not throw for this case).
176value parse(std::string_view input,
177 const parse_options& parse_options,
178 const extract_options& extract_options
179 );
180
181JSONV_PUBLIC value parse(std::string_view input);
182JSONV_PUBLIC value parse(std::string_view input, const parse_options& parse_options);
183JSONV_PUBLIC value parse(std::string_view input, const extract_options& extract_options);
184/// \}
185
186/// \{
187/// Reads a JSON value from the \a input stream.
188///
189/// \example "parse(std::istream&)"
190/// Parse JSON from some file.
191/// \code
192/// std::ifstream file("file.json");
193/// jsonv::value out = parse(file);
194/// \endcode
195///
196/// \param parse_options Options specific to parsing the \a input -- the indexing of source text into an AST. If
197/// unspecified, this is \c parse_options::create_default().
198/// \param extract_options Options specific to extraction -- transforming the AST into a \c jsonv::value. If
199/// unspecified, this is \c extract_options::create_default().
200///
201/// \throws parse_error if the source text is invalid JSON. This is thrown for errors like unterminated strings, arrays,
202/// or stray literals. Errors of this category are described as an offset into \a input.
203/// \throws extract_error if the AST can not be transformed into a \c jsonv::value. This is thrown for errors like an
204/// object with duplicate keys (note that the default \c jsonv::formats does not throw for this case).
206value parse(std::istream& input,
207 const parse_options& parse_options,
208 const extract_options& extract_options
209 );
210
211JSONV_PUBLIC value parse(std::istream& input);
212JSONV_PUBLIC value parse(std::istream& input, const parse_options& parse_options);
213JSONV_PUBLIC value parse(std::istream& input, const extract_options& extract_options);
214/// \}
215
216/// \{
217/// Read a JSON value from the string bound by `[begin, end)`.
219value parse(const char* begin,
220 const char* end,
223 );
224JSONV_PUBLIC value parse(const char* begin, const char* end, const parse_options& parse_options);
225JSONV_PUBLIC value parse(const char* begin, const char* end, const extract_options& extract_options);
226JSONV_PUBLIC value parse(const char* begin, const char* end);
227/// \}
228
229}
An adapter for enumeration types.
Configuration for various extraction options. This becomes part of the extraction_context.
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:63
bool require_document() const
Definition parse.hpp:128
bool comments() const
Definition parse.hpp:144
std::optional< size_type > max_structure_depth() const
Definition parse.hpp:120
parse_options()
Create an instance with the default options.
encoding
The encoding format for strings.
Definition parse.hpp:69
bool complete_parse() const
Definition parse.hpp:136
Represents a single JSON value, which can be any one of a potential kind, each behaving slightly diff...
Definition value.hpp:107
Copyright (c) 2014-2020 by Travis Gockel.
#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.