| Index: base/json/json_reader.h
|
| diff --git a/base/json/json_reader.h b/base/json/json_reader.h
|
| index 35ee7d3e1c67a8c4306ea144dd2041d47eb2cb76..e0811754b1957f36a4cd01b462aa835810671f25 100644
|
| --- a/base/json/json_reader.h
|
| +++ b/base/json/json_reader.h
|
| @@ -33,23 +33,18 @@
|
|
|
| #include "base/base_export.h"
|
| #include "base/basictypes.h"
|
| +#include "base/memory/scoped_ptr.h"
|
|
|
| -// Chromium and Chromium OS check out gtest to different places, so we're
|
| -// unable to compile on both if we include gtest_prod.h here. Instead, include
|
| -// its only contents -- this will need to be updated if the macro ever changes.
|
| -#define FRIEND_TEST(test_case_name, test_name)\
|
| -friend class test_case_name##_##test_name##_Test
|
| +namespace base {
|
| +class Value;
|
|
|
| -#define FRIEND_TEST_ALL_PREFIXES(test_case_name, test_name) \
|
| - FRIEND_TEST(test_case_name, test_name); \
|
| - FRIEND_TEST(test_case_name, DISABLED_##test_name); \
|
| - FRIEND_TEST(test_case_name, FLAKY_##test_name); \
|
| - FRIEND_TEST(test_case_name, FAILS_##test_name)
|
| +namespace internal {
|
| +class JSONParser;
|
| +}
|
| +}
|
|
|
| namespace base {
|
|
|
| -class Value;
|
| -
|
| enum JSONParserOptions {
|
| // Parses the input strictly according to RFC 4627, except for where noted
|
| // above.
|
| @@ -57,56 +52,22 @@ enum JSONParserOptions {
|
|
|
| // Allows commas to exist after the last element in structures.
|
| JSON_ALLOW_TRAILING_COMMAS = 1 << 0,
|
| +
|
| + // The parser can perform optimizations by placing hidden data in the root of
|
| + // the JSON object, which speeds up certain operations on children. However,
|
| + // if the child is Remove()d from root, it would result in use-after-free
|
| + // unless it is DeepCopy()ed or this option is used.
|
| + JSON_DETACHABLE_CHILDREN = 1 << 1,
|
| };
|
|
|
| class BASE_EXPORT JSONReader {
|
| public:
|
| - // A struct to hold a JS token.
|
| - class Token {
|
| - public:
|
| - enum Type {
|
| - OBJECT_BEGIN, // {
|
| - OBJECT_END, // }
|
| - ARRAY_BEGIN, // [
|
| - ARRAY_END, // ]
|
| - STRING,
|
| - NUMBER,
|
| - BOOL_TRUE, // true
|
| - BOOL_FALSE, // false
|
| - NULL_TOKEN, // null
|
| - LIST_SEPARATOR, // ,
|
| - OBJECT_PAIR_SEPARATOR, // :
|
| - END_OF_INPUT,
|
| - INVALID_TOKEN,
|
| - };
|
| -
|
| - Token(Type t, const char* b, int len)
|
| - : type(t), begin(b), length(len) {}
|
| -
|
| - // Get the character that's one past the end of this token.
|
| - char NextChar() {
|
| - return *(begin + length);
|
| - }
|
| -
|
| - static Token CreateInvalidToken() {
|
| - return Token(INVALID_TOKEN, 0, 0);
|
| - }
|
| -
|
| - Type type;
|
| -
|
| - // A pointer into JSONReader::json_pos_ that's the beginning of this token.
|
| - const char* begin;
|
| -
|
| - // End should be one char past the end of the token.
|
| - int length;
|
| - };
|
| -
|
| // Error codes during parsing.
|
| enum JsonParseError {
|
| JSON_NO_ERROR = 0,
|
| - JSON_BAD_ROOT_ELEMENT_TYPE,
|
| JSON_INVALID_ESCAPE,
|
| JSON_SYNTAX_ERROR,
|
| + JSON_UNEXPECTED_TOKEN,
|
| JSON_TRAILING_COMMA,
|
| JSON_TOO_MUCH_NESTING,
|
| JSON_UNEXPECTED_DATA_AFTER_ROOT,
|
| @@ -115,17 +76,23 @@ class BASE_EXPORT JSONReader {
|
| };
|
|
|
| // String versions of parse error codes.
|
| - static const char* kBadRootElementType;
|
| 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;
|
|
|
| + // Constructs a reader with the default options, JSON_PARSE_RFC.
|
| JSONReader();
|
|
|
| + // Constructs a reader with custom options.
|
| + explicit JSONReader(int options);
|
| +
|
| + ~JSONReader();
|
| +
|
| // Reads and parses |json|, returning a Value. The caller owns the returned
|
| // instance. If |json| is not a properly formed JSON string, returns NULL.
|
| static Value* Read(const std::string& json);
|
| @@ -148,106 +115,19 @@ class BASE_EXPORT JSONReader {
|
| // Returns an empty string if error_code is JSON_NO_ERROR.
|
| static std::string ErrorCodeToString(JsonParseError error_code);
|
|
|
| - // Returns the error code if the last call to JsonToValue() failed.
|
| + // Parses an input string into a Value that is owned by the caller.
|
| + Value* ReadToValue(const std::string& json);
|
| +
|
| + // Returns the error code if the last call to ReadToValue() failed.
|
| // Returns JSON_NO_ERROR otherwise.
|
| - JsonParseError error_code() const { return error_code_; }
|
| + JsonParseError error_code() const;
|
|
|
| // Converts error_code_ to a human-readable string, including line and column
|
| // numbers if appropriate.
|
| std::string GetErrorMessage() const;
|
|
|
| - // Reads and parses |json|, returning a Value. The caller owns the returned
|
| - // instance. If |json| is not a properly formed JSON string, returns NULL and
|
| - // a detailed error can be retrieved from |error_message()|.
|
| - // If |check_root| is true, we require that the root object be an object or
|
| - // array. Otherwise, it can be any valid JSON type.
|
| - // If |allow_trailing_comma| is true, we will ignore trailing commas in
|
| - // objects and arrays even though this goes against the RFC.
|
| - Value* JsonToValue(const std::string& json, bool check_root,
|
| - bool allow_trailing_comma);
|
| -
|
| private:
|
| - FRIEND_TEST_ALL_PREFIXES(JSONReaderTest, Reading);
|
| - FRIEND_TEST_ALL_PREFIXES(JSONReaderTest, ErrorMessages);
|
| -
|
| - static std::string FormatErrorMessage(int line, int column,
|
| - const std::string& description);
|
| -
|
| - // Recursively build Value. Returns NULL if we don't have a valid JSON
|
| - // string. If |is_root| is true, we verify that the root element is either
|
| - // an object or an array.
|
| - Value* BuildValue(bool is_root);
|
| -
|
| - // Parses a sequence of characters into a Token::NUMBER. If the sequence of
|
| - // characters is not a valid number, returns a Token::INVALID_TOKEN. Note
|
| - // that DecodeNumber is used to actually convert from a string to an
|
| - // int/double.
|
| - Token ParseNumberToken();
|
| -
|
| - // Try and convert the substring that token holds into an int or a double. If
|
| - // we can (ie., no overflow), return the value, else return NULL.
|
| - Value* DecodeNumber(const Token& token);
|
| -
|
| - // Parses a sequence of characters into a Token::STRING. If the sequence of
|
| - // characters is not a valid string, returns a Token::INVALID_TOKEN. Note
|
| - // that DecodeString is used to actually decode the escaped string into an
|
| - // actual wstring.
|
| - Token ParseStringToken();
|
| -
|
| - // Convert the substring into a value string. This should always succeed
|
| - // (otherwise ParseStringToken would have failed).
|
| - Value* DecodeString(const Token& token);
|
| -
|
| - // Helper function for DecodeString that consumes UTF16 [0,2] code units and
|
| - // convers them to UTF8 code untis. |token| is the string token in which the
|
| - // units should be read, |i| is the position in the token at which the first
|
| - // code unit starts, immediately after the |\u|. This will be mutated if code
|
| - // units are consumed. |dest_string| is a string to which the UTF8 code unit
|
| - // should be appended. Returns true on success and false if there's an
|
| - // encoding error.
|
| - bool ConvertUTF16Units(const Token& token,
|
| - int* i,
|
| - std::string* dest_string);
|
| -
|
| - // Grabs the next token in the JSON stream. This does not increment the
|
| - // stream so it can be used to look ahead at the next token.
|
| - Token ParseToken();
|
| -
|
| - // Increments |json_pos_| past leading whitespace and comments.
|
| - void EatWhitespaceAndComments();
|
| -
|
| - // If |json_pos_| is at the start of a comment, eat it, otherwise, returns
|
| - // false.
|
| - bool EatComment();
|
| -
|
| - // Checks if |json_pos_| matches str.
|
| - bool NextStringMatch(const char* str, size_t length);
|
| -
|
| - // Sets the error code that will be returned to the caller. The current
|
| - // line and column are determined and added into the final message.
|
| - void SetErrorCode(const JsonParseError error, const char* error_pos);
|
| -
|
| - // Pointer to the starting position in the input string.
|
| - const char* start_pos_;
|
| -
|
| - // Pointer to the current position in the input string.
|
| - const char* json_pos_;
|
| -
|
| - // Pointer to the last position in the input string.
|
| - const char* end_pos_;
|
| -
|
| - // Used to keep track of how many nested lists/dicts there are.
|
| - int stack_depth_;
|
| -
|
| - // A parser flag that allows trailing commas in objects and arrays.
|
| - bool allow_trailing_comma_;
|
| -
|
| - // Contains the error code for the last call to JsonToValue(), if any.
|
| - JsonParseError error_code_;
|
| - int error_line_;
|
| - int error_col_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(JSONReader);
|
| + scoped_ptr<internal::JSONParser> parser_;
|
| };
|
|
|
| } // namespace base
|
|
|