| // 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 "base/strings/string_piece.h" |
| |
| 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(StringPiece 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( |
| StringPiece 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(StringPiece 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_ |