| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // | |
| // A JSON parser. Converts strings of JSON into a Value object (see | |
| // base/values.h). | |
| // http://www.ietf.org/rfc/rfc4627.txt?number=4627 | |
| // | |
| // Known limitations/deviations from the RFC: | |
| // - Only knows how to parse ints within the range of a signed 32 bit int and | |
| // decimal numbers within a double. | |
| // - Assumes input is encoded as UTF8. The spec says we should allow UTF-16 | |
| // (BE or LE) and UTF-32 (BE or LE) as well. | |
| // - We limit nesting to 100 levels to prevent stack overflow (this is allowed | |
| // by the RFC). | |
| // - A Unicode FAQ ("http://unicode.org/faq/utf_bom.html") writes a data | |
| // stream may start with a Unicode Byte-Order-Mark (U+FEFF), i.e. the input | |
| // UTF-8 string for the JSONReader::JsonToValue() function may start with a | |
| // UTF-8 BOM (0xEF, 0xBB, 0xBF). | |
| // To avoid the function from mis-treating a UTF-8 BOM as an invalid | |
| // character, the function skips a Unicode BOM at the beginning of the | |
| // Unicode string (converted from the input UTF-8 string) before parsing it. | |
| // | |
| // TODO(tc): Add a parsing option to to relax object keys being wrapped in | |
| // double quotes | |
| // TODO(tc): Add an option to disable comment stripping | |
| #ifndef BASE_JSON_JSON_READER_H_ | |
| #define BASE_JSON_JSON_READER_H_ | |
| #include <memory> | |
| #include <string> | |
| #include <string_view> | |
| namespace base { | |
| class Value; | |
| namespace internal { | |
| class JSONParser; | |
| } | |
| enum JSONParserOptions { | |
| // Parses the input strictly according to RFC 4627, except for where noted | |
| // above. | |
| JSON_PARSE_RFC = 0, | |
| // Allows commas to exist after the last element in structures. | |
| JSON_ALLOW_TRAILING_COMMAS = 1 << 0, | |
| // If set the parser replaces invalid characters with the Unicode replacement | |
| // character (U+FFFD). If not set, invalid characters trigger a hard error and | |
| // parsing fails. | |
| JSON_REPLACE_INVALID_CHARACTERS = 1 << 1, | |
| }; | |
| class JSONReader { | |
| public: | |
| static const int kStackMaxDepth; | |
| // Error codes during parsing. | |
| enum JsonParseError { | |
| JSON_NO_ERROR = 0, | |
| JSON_INVALID_ESCAPE, | |
| JSON_SYNTAX_ERROR, | |
| JSON_UNEXPECTED_TOKEN, | |
| JSON_TRAILING_COMMA, | |
| JSON_TOO_MUCH_NESTING, | |
| JSON_UNEXPECTED_DATA_AFTER_ROOT, | |
| JSON_UNSUPPORTED_ENCODING, | |
| JSON_UNQUOTED_DICTIONARY_KEY, | |
| JSON_TOO_LARGE, | |
| JSON_PARSE_ERROR_COUNT | |
| }; | |
| // String versions of parse error codes. | |
| static const char kInvalidEscape[]; | |
| static const char kSyntaxError[]; | |
| static const char kUnexpectedToken[]; | |
| static const char kTrailingComma[]; | |
| static const char kTooMuchNesting[]; | |
| static const char kUnexpectedDataAfterRoot[]; | |
| static const char kUnsupportedEncoding[]; | |
| static const char kUnquotedDictionaryKey[]; | |
| static const char kInputTooLarge[]; | |
| // Constructs a reader. | |
| JSONReader(int options = JSON_PARSE_RFC, int max_depth = kStackMaxDepth); | |
| ~JSONReader(); | |
| // Reads and parses |json|, returning a Value. | |
| // If |json| is not a properly formed JSON string, returns nullptr. | |
| // Wrap this in base::FooValue::From() to check the Value is of type Foo and | |
| // convert to a FooValue at the same time. | |
| static std::unique_ptr<Value> Read(std::string_view json, | |
| int options = JSON_PARSE_RFC, | |
| int max_depth = kStackMaxDepth); | |
| // Reads and parses |json| like Read(). |error_code_out| and |error_msg_out| | |
| // are optional. If specified and nullptr is returned, they will be populated | |
| // an error code and a formatted error message (including error location if | |
| // appropriate). Otherwise, they will be unmodified. | |
| static std::unique_ptr<Value> ReadAndReturnError( | |
| std::string_view json, | |
| int options, // JSONParserOptions | |
| int* error_code_out, | |
| std::string* error_msg_out, | |
| int* error_line_out = nullptr, | |
| int* error_column_out = nullptr); | |
| // Converts a JSON parse error code into a human readable message. | |
| // Returns an empty string if error_code is JSON_NO_ERROR. | |
| static std::string ErrorCodeToString(JsonParseError error_code); | |
| // Non-static version of Read() above. | |
| std::unique_ptr<Value> ReadToValue(std::string_view json); | |
| // Returns the error code if the last call to ReadToValue() failed. | |
| // Returns JSON_NO_ERROR otherwise. | |
| JsonParseError error_code() const; | |
| // Converts error_code_ to a human-readable string, including line and column | |
| // numbers if appropriate. | |
| std::string GetErrorMessage() const; | |
| private: | |
| std::unique_ptr<internal::JSONParser> parser_; | |
| }; | |
| } // namespace base | |
| #endif // BASE_JSON_JSON_READER_H_ |