Path: blob/master/thirdparty/openxr/src/external/jsoncpp/include/json/reader.h
9913 views
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors1// Distributed under MIT license, or public domain if desired and2// recognized in your jurisdiction.3// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE45#ifndef JSON_READER_H_INCLUDED6#define JSON_READER_H_INCLUDED78#if !defined(JSON_IS_AMALGAMATION)9#include "json_features.h"10#include "value.h"11#endif // if !defined(JSON_IS_AMALGAMATION)12#include <deque>13#include <iosfwd>14#include <istream>15#include <stack>16#include <string>1718// Disable warning C4251: <data member>: <type> needs to have dll-interface to19// be used by...20#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)21#pragma warning(push)22#pragma warning(disable : 4251)23#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)2425#pragma pack(push)26#pragma pack()2728namespace Json {2930/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a31* Value.32*33* \deprecated Use CharReader and CharReaderBuilder.34*/3536class JSON_API Reader {37public:38using Char = char;39using Location = const Char*;4041/** \brief An error tagged with where in the JSON text it was encountered.42*43* The offsets give the [start, limit) range of bytes within the text. Note44* that this is bytes, not codepoints.45*/46struct StructuredError {47ptrdiff_t offset_start;48ptrdiff_t offset_limit;49String message;50};5152/** \brief Constructs a Reader allowing all features for parsing.53* \deprecated Use CharReader and CharReaderBuilder.54*/55Reader();5657/** \brief Constructs a Reader allowing the specified feature set for parsing.58* \deprecated Use CharReader and CharReaderBuilder.59*/60Reader(const Features& features);6162/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>63* document.64*65* \param document UTF-8 encoded string containing the document66* to read.67* \param[out] root Contains the root value of the document if it68* was successfully parsed.69* \param collectComments \c true to collect comment and allow writing70* them back during serialization, \c false to71* discard comments. This parameter is ignored72* if Features::allowComments_ is \c false.73* \return \c true if the document was successfully parsed, \c false if an74* error occurred.75*/76bool parse(const std::string& document, Value& root,77bool collectComments = true);7879/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>80* document.81*82* \param beginDoc Pointer on the beginning of the UTF-8 encoded83* string of the document to read.84* \param endDoc Pointer on the end of the UTF-8 encoded string85* of the document to read. Must be >= beginDoc.86* \param[out] root Contains the root value of the document if it87* was successfully parsed.88* \param collectComments \c true to collect comment and allow writing89* them back during serialization, \c false to90* discard comments. This parameter is ignored91* if Features::allowComments_ is \c false.92* \return \c true if the document was successfully parsed, \c false if an93* error occurred.94*/95bool parse(const char* beginDoc, const char* endDoc, Value& root,96bool collectComments = true);9798/// \brief Parse from input stream.99/// \see Json::operator>>(std::istream&, Json::Value&).100bool parse(IStream& is, Value& root, bool collectComments = true);101102/** \brief Returns a user friendly string that list errors in the parsed103* document.104*105* \return Formatted error message with the list of errors with their106* location in the parsed document. An empty string is returned if no error107* occurred during parsing.108* \deprecated Use getFormattedErrorMessages() instead (typo fix).109*/110JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")111String getFormatedErrorMessages() const;112113/** \brief Returns a user friendly string that list errors in the parsed114* document.115*116* \return Formatted error message with the list of errors with their117* location in the parsed document. An empty string is returned if no error118* occurred during parsing.119*/120String getFormattedErrorMessages() const;121122/** \brief Returns a vector of structured errors encountered while parsing.123*124* \return A (possibly empty) vector of StructuredError objects. Currently125* only one error can be returned, but the caller should tolerate multiple126* errors. This can occur if the parser recovers from a non-fatal parse127* error and then encounters additional errors.128*/129std::vector<StructuredError> getStructuredErrors() const;130131/** \brief Add a semantic error message.132*133* \param value JSON Value location associated with the error134* \param message The error message.135* \return \c true if the error was successfully added, \c false if the Value136* offset exceeds the document size.137*/138bool pushError(const Value& value, const String& message);139140/** \brief Add a semantic error message with extra context.141*142* \param value JSON Value location associated with the error143* \param message The error message.144* \param extra Additional JSON Value location to contextualize the error145* \return \c true if the error was successfully added, \c false if either146* Value offset exceeds the document size.147*/148bool pushError(const Value& value, const String& message, const Value& extra);149150/** \brief Return whether there are any errors.151*152* \return \c true if there are no errors to report \c false if errors have153* occurred.154*/155bool good() const;156157private:158enum TokenType {159tokenEndOfStream = 0,160tokenObjectBegin,161tokenObjectEnd,162tokenArrayBegin,163tokenArrayEnd,164tokenString,165tokenNumber,166tokenTrue,167tokenFalse,168tokenNull,169tokenArraySeparator,170tokenMemberSeparator,171tokenComment,172tokenError173};174175class Token {176public:177TokenType type_;178Location start_;179Location end_;180};181182class ErrorInfo {183public:184Token token_;185String message_;186Location extra_;187};188189using Errors = std::deque<ErrorInfo>;190191bool readToken(Token& token);192bool readTokenSkippingComments(Token& token);193void skipSpaces();194bool match(const Char* pattern, int patternLength);195bool readComment();196bool readCStyleComment();197bool readCppStyleComment();198bool readString();199void readNumber();200bool readValue();201bool readObject(Token& token);202bool readArray(Token& token);203bool decodeNumber(Token& token);204bool decodeNumber(Token& token, Value& decoded);205bool decodeString(Token& token);206bool decodeString(Token& token, String& decoded);207bool decodeDouble(Token& token);208bool decodeDouble(Token& token, Value& decoded);209bool decodeUnicodeCodePoint(Token& token, Location& current, Location end,210unsigned int& unicode);211bool decodeUnicodeEscapeSequence(Token& token, Location& current,212Location end, unsigned int& unicode);213bool addError(const String& message, Token& token, Location extra = nullptr);214bool recoverFromError(TokenType skipUntilToken);215bool addErrorAndRecover(const String& message, Token& token,216TokenType skipUntilToken);217void skipUntilSpace();218Value& currentValue();219Char getNextChar();220void getLocationLineAndColumn(Location location, int& line,221int& column) const;222String getLocationLineAndColumn(Location location) const;223void addComment(Location begin, Location end, CommentPlacement placement);224225static bool containsNewLine(Location begin, Location end);226static String normalizeEOL(Location begin, Location end);227228using Nodes = std::stack<Value*>;229Nodes nodes_;230Errors errors_;231String document_;232Location begin_{};233Location end_{};234Location current_{};235Location lastValueEnd_{};236Value* lastValue_{};237String commentsBefore_;238Features features_;239bool collectComments_{};240}; // Reader241242/** Interface for reading JSON from a char array.243*/244class JSON_API CharReader {245public:246struct JSON_API StructuredError {247ptrdiff_t offset_start;248ptrdiff_t offset_limit;249String message;250};251252virtual ~CharReader() = default;253/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>254* document. The document must be a UTF-8 encoded string containing the255* document to read.256*257* \param beginDoc Pointer on the beginning of the UTF-8 encoded string258* of the document to read.259* \param endDoc Pointer on the end of the UTF-8 encoded string of the260* document to read. Must be >= beginDoc.261* \param[out] root Contains the root value of the document if it was262* successfully parsed.263* \param[out] errs Formatted error messages (if not NULL) a user264* friendly string that lists errors in the parsed265* document.266* \return \c true if the document was successfully parsed, \c false if an267* error occurred.268*/269virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,270String* errs);271272/** \brief Returns a vector of structured errors encountered while parsing.273* Each parse call resets the stored list of errors.274*/275std::vector<StructuredError> getStructuredErrors() const;276277class JSON_API Factory {278public:279virtual ~Factory() = default;280/** \brief Allocate a CharReader via operator new().281* \throw std::exception if something goes wrong (e.g. invalid settings)282*/283virtual CharReader* newCharReader() const = 0;284}; // Factory285286protected:287class Impl {288public:289virtual ~Impl() = default;290virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,291String* errs) = 0;292virtual std::vector<StructuredError> getStructuredErrors() const = 0;293};294295explicit CharReader(std::unique_ptr<Impl> impl) : _impl(std::move(impl)) {}296297private:298std::unique_ptr<Impl> _impl;299}; // CharReader300301/** \brief Build a CharReader implementation.302*303* Usage:304* \code305* using namespace Json;306* CharReaderBuilder builder;307* builder["collectComments"] = false;308* Value value;309* String errs;310* bool ok = parseFromStream(builder, std::cin, &value, &errs);311* \endcode312*/313class JSON_API CharReaderBuilder : public CharReader::Factory {314public:315// Note: We use a Json::Value so that we can add data-members to this class316// without a major version bump.317/** Configuration of this builder.318* These are case-sensitive.319* Available settings (case-sensitive):320* - `"collectComments": false or true`321* - true to collect comment and allow writing them back during322* serialization, false to discard comments. This parameter is ignored323* if allowComments is false.324* - `"allowComments": false or true`325* - true if comments are allowed.326* - `"allowTrailingCommas": false or true`327* - true if trailing commas in objects and arrays are allowed.328* - `"strictRoot": false or true`329* - true if root must be either an array or an object value330* - `"allowDroppedNullPlaceholders": false or true`331* - true if dropped null placeholders are allowed. (See332* StreamWriterBuilder.)333* - `"allowNumericKeys": false or true`334* - true if numeric object keys are allowed.335* - `"allowSingleQuotes": false or true`336* - true if '' are allowed for strings (both keys and values)337* - `"stackLimit": integer`338* - Exceeding stackLimit (recursive depth of `readValue()`) will cause an339* exception.340* - This is a security issue (seg-faults caused by deeply nested JSON), so341* the default is low.342* - `"failIfExtra": false or true`343* - If true, `parse()` returns false when extra non-whitespace trails the344* JSON value in the input string.345* - `"rejectDupKeys": false or true`346* - If true, `parse()` returns false when a key is duplicated within an347* object.348* - `"allowSpecialFloats": false or true`349* - If true, special float values (NaNs and infinities) are allowed and350* their values are lossfree restorable.351* - `"skipBom": false or true`352* - If true, if the input starts with the Unicode byte order mark (BOM),353* it is skipped.354*355* You can examine 'settings_` yourself to see the defaults. You can also356* write and read them just like any JSON Value.357* \sa setDefaults()358*/359Json::Value settings_;360361CharReaderBuilder();362~CharReaderBuilder() override;363364CharReader* newCharReader() const override;365366/** \return true if 'settings' are legal and consistent;367* otherwise, indicate bad settings via 'invalid'.368*/369bool validate(Json::Value* invalid) const;370371/** A simple way to update a specific setting.372*/373Value& operator[](const String& key);374375/** Called by ctor, but you can use this to reset settings_.376* \pre 'settings' != NULL (but Json::null is fine)377* \remark Defaults:378* \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults379*/380static void setDefaults(Json::Value* settings);381/** Same as old Features::strictMode().382* \pre 'settings' != NULL (but Json::null is fine)383* \remark Defaults:384* \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode385*/386static void strictMode(Json::Value* settings);387/** ECMA-404 mode.388* \pre 'settings' != NULL (but Json::null is fine)389* \remark Defaults:390* \snippet src/lib_json/json_reader.cpp CharReaderBuilderECMA404Mode391*/392static void ecma404Mode(Json::Value* settings);393};394395/** Consume entire stream and use its begin/end.396* Someday we might have a real StreamReader, but for now this397* is convenient.398*/399bool JSON_API parseFromStream(CharReader::Factory const&, IStream&, Value* root,400String* errs);401402/** \brief Read from 'sin' into 'root'.403*404* Always keep comments from the input JSON.405*406* This can be used to read a file into a particular sub-object.407* For example:408* \code409* Json::Value root;410* cin >> root["dir"]["file"];411* cout << root;412* \endcode413* Result:414* \verbatim415* {416* "dir": {417* "file": {418* // The input stream JSON would be nested here.419* }420* }421* }422* \endverbatim423* \throw std::exception on parse error.424* \see Json::operator<<()425*/426JSON_API IStream& operator>>(IStream&, Value&);427428} // namespace Json429430#pragma pack(pop)431432#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)433#pragma warning(pop)434#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)435436#endif // JSON_READER_H_INCLUDED437438439