16d528ed9Sopenharmony_ci// Copyright (c) 2012 The Chromium Authors. All rights reserved. 26d528ed9Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 36d528ed9Sopenharmony_ci// found in the LICENSE file. 46d528ed9Sopenharmony_ci// 56d528ed9Sopenharmony_ci// A JSON parser. Converts strings of JSON into a Value object (see 66d528ed9Sopenharmony_ci// base/values.h). 76d528ed9Sopenharmony_ci// http://www.ietf.org/rfc/rfc4627.txt?number=4627 86d528ed9Sopenharmony_ci// 96d528ed9Sopenharmony_ci// Known limitations/deviations from the RFC: 106d528ed9Sopenharmony_ci// - Only knows how to parse ints within the range of a signed 32 bit int and 116d528ed9Sopenharmony_ci// decimal numbers within a double. 126d528ed9Sopenharmony_ci// - Assumes input is encoded as UTF8. The spec says we should allow UTF-16 136d528ed9Sopenharmony_ci// (BE or LE) and UTF-32 (BE or LE) as well. 146d528ed9Sopenharmony_ci// - We limit nesting to 100 levels to prevent stack overflow (this is allowed 156d528ed9Sopenharmony_ci// by the RFC). 166d528ed9Sopenharmony_ci// - A Unicode FAQ ("http://unicode.org/faq/utf_bom.html") writes a data 176d528ed9Sopenharmony_ci// stream may start with a Unicode Byte-Order-Mark (U+FEFF), i.e. the input 186d528ed9Sopenharmony_ci// UTF-8 string for the JSONReader::JsonToValue() function may start with a 196d528ed9Sopenharmony_ci// UTF-8 BOM (0xEF, 0xBB, 0xBF). 206d528ed9Sopenharmony_ci// To avoid the function from mis-treating a UTF-8 BOM as an invalid 216d528ed9Sopenharmony_ci// character, the function skips a Unicode BOM at the beginning of the 226d528ed9Sopenharmony_ci// Unicode string (converted from the input UTF-8 string) before parsing it. 236d528ed9Sopenharmony_ci// 246d528ed9Sopenharmony_ci// TODO(tc): Add a parsing option to to relax object keys being wrapped in 256d528ed9Sopenharmony_ci// double quotes 266d528ed9Sopenharmony_ci// TODO(tc): Add an option to disable comment stripping 276d528ed9Sopenharmony_ci 286d528ed9Sopenharmony_ci#ifndef BASE_JSON_JSON_READER_H_ 296d528ed9Sopenharmony_ci#define BASE_JSON_JSON_READER_H_ 306d528ed9Sopenharmony_ci 316d528ed9Sopenharmony_ci#include <memory> 326d528ed9Sopenharmony_ci#include <string> 336d528ed9Sopenharmony_ci#include <string_view> 346d528ed9Sopenharmony_ci 356d528ed9Sopenharmony_cinamespace base { 366d528ed9Sopenharmony_ci 376d528ed9Sopenharmony_ciclass Value; 386d528ed9Sopenharmony_ci 396d528ed9Sopenharmony_cinamespace internal { 406d528ed9Sopenharmony_ciclass JSONParser; 416d528ed9Sopenharmony_ci} 426d528ed9Sopenharmony_ci 436d528ed9Sopenharmony_cienum JSONParserOptions { 446d528ed9Sopenharmony_ci // Parses the input strictly according to RFC 4627, except for where noted 456d528ed9Sopenharmony_ci // above. 466d528ed9Sopenharmony_ci JSON_PARSE_RFC = 0, 476d528ed9Sopenharmony_ci 486d528ed9Sopenharmony_ci // Allows commas to exist after the last element in structures. 496d528ed9Sopenharmony_ci JSON_ALLOW_TRAILING_COMMAS = 1 << 0, 506d528ed9Sopenharmony_ci 516d528ed9Sopenharmony_ci // If set the parser replaces invalid characters with the Unicode replacement 526d528ed9Sopenharmony_ci // character (U+FFFD). If not set, invalid characters trigger a hard error and 536d528ed9Sopenharmony_ci // parsing fails. 546d528ed9Sopenharmony_ci JSON_REPLACE_INVALID_CHARACTERS = 1 << 1, 556d528ed9Sopenharmony_ci}; 566d528ed9Sopenharmony_ci 576d528ed9Sopenharmony_ciclass JSONReader { 586d528ed9Sopenharmony_ci public: 596d528ed9Sopenharmony_ci static const int kStackMaxDepth; 606d528ed9Sopenharmony_ci 616d528ed9Sopenharmony_ci // Error codes during parsing. 626d528ed9Sopenharmony_ci enum JsonParseError { 636d528ed9Sopenharmony_ci JSON_NO_ERROR = 0, 646d528ed9Sopenharmony_ci JSON_INVALID_ESCAPE, 656d528ed9Sopenharmony_ci JSON_SYNTAX_ERROR, 666d528ed9Sopenharmony_ci JSON_UNEXPECTED_TOKEN, 676d528ed9Sopenharmony_ci JSON_TRAILING_COMMA, 686d528ed9Sopenharmony_ci JSON_TOO_MUCH_NESTING, 696d528ed9Sopenharmony_ci JSON_UNEXPECTED_DATA_AFTER_ROOT, 706d528ed9Sopenharmony_ci JSON_UNSUPPORTED_ENCODING, 716d528ed9Sopenharmony_ci JSON_UNQUOTED_DICTIONARY_KEY, 726d528ed9Sopenharmony_ci JSON_TOO_LARGE, 736d528ed9Sopenharmony_ci JSON_PARSE_ERROR_COUNT 746d528ed9Sopenharmony_ci }; 756d528ed9Sopenharmony_ci 766d528ed9Sopenharmony_ci // String versions of parse error codes. 776d528ed9Sopenharmony_ci static const char kInvalidEscape[]; 786d528ed9Sopenharmony_ci static const char kSyntaxError[]; 796d528ed9Sopenharmony_ci static const char kUnexpectedToken[]; 806d528ed9Sopenharmony_ci static const char kTrailingComma[]; 816d528ed9Sopenharmony_ci static const char kTooMuchNesting[]; 826d528ed9Sopenharmony_ci static const char kUnexpectedDataAfterRoot[]; 836d528ed9Sopenharmony_ci static const char kUnsupportedEncoding[]; 846d528ed9Sopenharmony_ci static const char kUnquotedDictionaryKey[]; 856d528ed9Sopenharmony_ci static const char kInputTooLarge[]; 866d528ed9Sopenharmony_ci 876d528ed9Sopenharmony_ci // Constructs a reader. 886d528ed9Sopenharmony_ci JSONReader(int options = JSON_PARSE_RFC, int max_depth = kStackMaxDepth); 896d528ed9Sopenharmony_ci 906d528ed9Sopenharmony_ci ~JSONReader(); 916d528ed9Sopenharmony_ci 926d528ed9Sopenharmony_ci // Reads and parses |json|, returning a Value. 936d528ed9Sopenharmony_ci // If |json| is not a properly formed JSON string, returns nullptr. 946d528ed9Sopenharmony_ci // Wrap this in base::FooValue::From() to check the Value is of type Foo and 956d528ed9Sopenharmony_ci // convert to a FooValue at the same time. 966d528ed9Sopenharmony_ci static std::unique_ptr<Value> Read(std::string_view json, 976d528ed9Sopenharmony_ci int options = JSON_PARSE_RFC, 986d528ed9Sopenharmony_ci int max_depth = kStackMaxDepth); 996d528ed9Sopenharmony_ci 1006d528ed9Sopenharmony_ci // Reads and parses |json| like Read(). |error_code_out| and |error_msg_out| 1016d528ed9Sopenharmony_ci // are optional. If specified and nullptr is returned, they will be populated 1026d528ed9Sopenharmony_ci // an error code and a formatted error message (including error location if 1036d528ed9Sopenharmony_ci // appropriate). Otherwise, they will be unmodified. 1046d528ed9Sopenharmony_ci static std::unique_ptr<Value> ReadAndReturnError( 1056d528ed9Sopenharmony_ci std::string_view json, 1066d528ed9Sopenharmony_ci int options, // JSONParserOptions 1076d528ed9Sopenharmony_ci int* error_code_out, 1086d528ed9Sopenharmony_ci std::string* error_msg_out, 1096d528ed9Sopenharmony_ci int* error_line_out = nullptr, 1106d528ed9Sopenharmony_ci int* error_column_out = nullptr); 1116d528ed9Sopenharmony_ci 1126d528ed9Sopenharmony_ci // Converts a JSON parse error code into a human readable message. 1136d528ed9Sopenharmony_ci // Returns an empty string if error_code is JSON_NO_ERROR. 1146d528ed9Sopenharmony_ci static std::string ErrorCodeToString(JsonParseError error_code); 1156d528ed9Sopenharmony_ci 1166d528ed9Sopenharmony_ci // Non-static version of Read() above. 1176d528ed9Sopenharmony_ci std::unique_ptr<Value> ReadToValue(std::string_view json); 1186d528ed9Sopenharmony_ci 1196d528ed9Sopenharmony_ci // Returns the error code if the last call to ReadToValue() failed. 1206d528ed9Sopenharmony_ci // Returns JSON_NO_ERROR otherwise. 1216d528ed9Sopenharmony_ci JsonParseError error_code() const; 1226d528ed9Sopenharmony_ci 1236d528ed9Sopenharmony_ci // Converts error_code_ to a human-readable string, including line and column 1246d528ed9Sopenharmony_ci // numbers if appropriate. 1256d528ed9Sopenharmony_ci std::string GetErrorMessage() const; 1266d528ed9Sopenharmony_ci 1276d528ed9Sopenharmony_ci private: 1286d528ed9Sopenharmony_ci std::unique_ptr<internal::JSONParser> parser_; 1296d528ed9Sopenharmony_ci}; 1306d528ed9Sopenharmony_ci 1316d528ed9Sopenharmony_ci} // namespace base 1326d528ed9Sopenharmony_ci 1336d528ed9Sopenharmony_ci#endif // BASE_JSON_JSON_READER_H_ 134