| Index: base/json_reader.cc
|
| diff --git a/base/json_reader.cc b/base/json_reader.cc
|
| index 2cea2393dfd277adfa61d55b98a0a09f08d83ad1..bf233a68004f9bb1951ae350434cb1ecca526ce4 100644
|
| --- a/base/json_reader.cc
|
| +++ b/base/json_reader.cc
|
| @@ -89,25 +89,24 @@ const char* JSONReader::kUnquotedDictionaryKey =
|
| "Dictionary keys must be quoted.";
|
|
|
| /* static */
|
| -bool JSONReader::Read(const std::string& json,
|
| - Value** root,
|
| - bool allow_trailing_comma) {
|
| - return ReadAndReturnError(json, root, allow_trailing_comma, NULL);
|
| +Value* JSONReader::Read(const std::string& json,
|
| + bool allow_trailing_comma) {
|
| + return ReadAndReturnError(json, allow_trailing_comma, NULL);
|
| }
|
|
|
| /* static */
|
| -bool JSONReader::ReadAndReturnError(const std::string& json,
|
| - Value** root,
|
| - bool allow_trailing_comma,
|
| - std::string *error_message_out) {
|
| +Value* JSONReader::ReadAndReturnError(const std::string& json,
|
| + bool allow_trailing_comma,
|
| + std::string *error_message_out) {
|
| JSONReader reader = JSONReader();
|
| - if (reader.JsonToValue(json, root, true, allow_trailing_comma)) {
|
| - return true;
|
| - } else {
|
| - if (error_message_out)
|
| - *error_message_out = reader.error_message();
|
| - return false;
|
| - }
|
| + Value* root = reader.JsonToValue(json, true, allow_trailing_comma);
|
| + if (root)
|
| + return root;
|
| +
|
| + if (error_message_out)
|
| + *error_message_out = reader.error_message();
|
| +
|
| + return NULL;
|
| }
|
|
|
| /* static */
|
| @@ -121,12 +120,12 @@ JSONReader::JSONReader()
|
| : start_pos_(NULL), json_pos_(NULL), stack_depth_(0),
|
| allow_trailing_comma_(false) {}
|
|
|
| -bool JSONReader::JsonToValue(const std::string& json, Value** root,
|
| - bool check_root, bool allow_trailing_comma) {
|
| +Value* JSONReader::JsonToValue(const std::string& json, bool check_root,
|
| + bool allow_trailing_comma) {
|
| // The input must be in UTF-8.
|
| if (!IsStringUTF8(json.c_str())) {
|
| error_message_ = kUnsupportedEncoding;
|
| - return false;
|
| + return NULL;
|
| }
|
|
|
| // The conversion from UTF8 to wstring removes null bytes for us
|
| @@ -148,13 +147,10 @@ bool JSONReader::JsonToValue(const std::string& json, Value** root,
|
| stack_depth_ = 0;
|
| error_message_.clear();
|
|
|
| - Value* temp_root = NULL;
|
| -
|
| - // Only modify root_ if we have valid JSON and nothing else.
|
| - if (BuildValue(&temp_root, check_root)) {
|
| + scoped_ptr<Value> root(BuildValue(check_root));
|
| + if (root.get()) {
|
| if (ParseToken().type == Token::END_OF_INPUT) {
|
| - *root = temp_root;
|
| - return true;
|
| + return root.release();
|
| } else {
|
| SetErrorMessage(kUnexpectedDataAfterRoot, json_pos_);
|
| }
|
| @@ -164,16 +160,14 @@ bool JSONReader::JsonToValue(const std::string& json, Value** root,
|
| if (error_message_.empty())
|
| SetErrorMessage(kSyntaxError, json_pos_);
|
|
|
| - if (temp_root)
|
| - delete temp_root;
|
| - return false;
|
| + return NULL;
|
| }
|
|
|
| -bool JSONReader::BuildValue(Value** node, bool is_root) {
|
| +Value* JSONReader::BuildValue(bool is_root) {
|
| ++stack_depth_;
|
| if (stack_depth_ > kStackLimit) {
|
| SetErrorMessage(kTooMuchNesting, json_pos_);
|
| - return false;
|
| + return NULL;
|
| }
|
|
|
| Token token = ParseToken();
|
| @@ -181,34 +175,38 @@ bool JSONReader::BuildValue(Value** node, bool is_root) {
|
| if (is_root && token.type != Token::OBJECT_BEGIN &&
|
| token.type != Token::ARRAY_BEGIN) {
|
| SetErrorMessage(kBadRootElementType, json_pos_);
|
| - return false;
|
| + return NULL;
|
| }
|
|
|
| + scoped_ptr<Value> node;
|
| +
|
| switch (token.type) {
|
| case Token::END_OF_INPUT:
|
| case Token::INVALID_TOKEN:
|
| - return false;
|
| + return NULL;
|
|
|
| case Token::NULL_TOKEN:
|
| - *node = Value::CreateNullValue();
|
| + node.reset(Value::CreateNullValue());
|
| break;
|
|
|
| case Token::BOOL_TRUE:
|
| - *node = Value::CreateBooleanValue(true);
|
| + node.reset(Value::CreateBooleanValue(true));
|
| break;
|
|
|
| case Token::BOOL_FALSE:
|
| - *node = Value::CreateBooleanValue(false);
|
| + node.reset(Value::CreateBooleanValue(false));
|
| break;
|
|
|
| case Token::NUMBER:
|
| - if (!DecodeNumber(token, node))
|
| - return false;
|
| + node.reset(DecodeNumber(token));
|
| + if (!node.get())
|
| + return NULL;
|
| break;
|
|
|
| case Token::STRING:
|
| - if (!DecodeString(token, node))
|
| - return false;
|
| + node.reset(DecodeString(token));
|
| + if (!node.get())
|
| + return NULL;
|
| break;
|
|
|
| case Token::ARRAY_BEGIN:
|
| @@ -216,14 +214,13 @@ bool JSONReader::BuildValue(Value** node, bool is_root) {
|
| json_pos_ += token.length;
|
| token = ParseToken();
|
|
|
| - ListValue* array = new ListValue;
|
| + node.reset(new ListValue());
|
| while (token.type != Token::ARRAY_END) {
|
| - Value* array_node = NULL;
|
| - if (!BuildValue(&array_node, false)) {
|
| - delete array;
|
| - return false;
|
| + Value* array_node = BuildValue(false);
|
| + if (!array_node) {
|
| + return NULL;
|
| }
|
| - array->Append(array_node);
|
| + static_cast<ListValue*>(node.get())->Append(array_node);
|
|
|
| // After a list value, we expect a comma or the end of the list.
|
| token = ParseToken();
|
| @@ -235,23 +232,19 @@ bool JSONReader::BuildValue(Value** node, bool is_root) {
|
| if (token.type == Token::ARRAY_END) {
|
| if (!allow_trailing_comma_) {
|
| SetErrorMessage(kTrailingComma, json_pos_);
|
| - delete array;
|
| - return false;
|
| + return NULL;
|
| }
|
| // Trailing comma OK, stop parsing the Array.
|
| break;
|
| }
|
| } else if (token.type != Token::ARRAY_END) {
|
| // Unexpected value after list value. Bail out.
|
| - delete array;
|
| - return false;
|
| + return NULL;
|
| }
|
| }
|
| if (token.type != Token::ARRAY_END) {
|
| - delete array;
|
| - return false;
|
| + return NULL;
|
| }
|
| - *node = array;
|
| break;
|
| }
|
|
|
| @@ -260,39 +253,32 @@ bool JSONReader::BuildValue(Value** node, bool is_root) {
|
| json_pos_ += token.length;
|
| token = ParseToken();
|
|
|
| - DictionaryValue* dict = new DictionaryValue;
|
| + node.reset(new DictionaryValue);
|
| while (token.type != Token::OBJECT_END) {
|
| if (token.type != Token::STRING) {
|
| SetErrorMessage(kUnquotedDictionaryKey, json_pos_);
|
| - delete dict;
|
| - return false;
|
| - }
|
| - Value* dict_key_value = NULL;
|
| - if (!DecodeString(token, &dict_key_value)) {
|
| - delete dict;
|
| - return false;
|
| + return NULL;
|
| }
|
| + scoped_ptr<Value> dict_key_value(DecodeString(token));
|
| + if (!dict_key_value.get())
|
| + return NULL;
|
| +
|
| // Convert the key into a wstring.
|
| std::wstring dict_key;
|
| bool success = dict_key_value->GetAsString(&dict_key);
|
| DCHECK(success);
|
| - delete dict_key_value;
|
|
|
| json_pos_ += token.length;
|
| token = ParseToken();
|
| - if (token.type != Token::OBJECT_PAIR_SEPARATOR) {
|
| - delete dict;
|
| - return false;
|
| - }
|
| + if (token.type != Token::OBJECT_PAIR_SEPARATOR)
|
| + return NULL;
|
|
|
| json_pos_ += token.length;
|
| token = ParseToken();
|
| - Value* dict_value = NULL;
|
| - if (!BuildValue(&dict_value, false)) {
|
| - delete dict;
|
| - return false;
|
| - }
|
| - dict->Set(dict_key, dict_value);
|
| + Value* dict_value = BuildValue(false);
|
| + if (!dict_value)
|
| + return NULL;
|
| + static_cast<DictionaryValue*>(node.get())->Set(dict_key, dict_value);
|
|
|
| // After a key/value pair, we expect a comma or the end of the
|
| // object.
|
| @@ -305,34 +291,30 @@ bool JSONReader::BuildValue(Value** node, bool is_root) {
|
| if (token.type == Token::OBJECT_END) {
|
| if (!allow_trailing_comma_) {
|
| SetErrorMessage(kTrailingComma, json_pos_);
|
| - delete dict;
|
| - return false;
|
| + return NULL;
|
| }
|
| // Trailing comma OK, stop parsing the Object.
|
| break;
|
| }
|
| } else if (token.type != Token::OBJECT_END) {
|
| // Unexpected value after last object value. Bail out.
|
| - delete dict;
|
| - return false;
|
| + return NULL;
|
| }
|
| }
|
| - if (token.type != Token::OBJECT_END) {
|
| - delete dict;
|
| - return false;
|
| - }
|
| - *node = dict;
|
| + if (token.type != Token::OBJECT_END)
|
| + return NULL;
|
| +
|
| break;
|
| }
|
|
|
| default:
|
| // We got a token that's not a value.
|
| - return false;
|
| + return NULL;
|
| }
|
| json_pos_ += token.length;
|
|
|
| --stack_depth_;
|
| - return true;
|
| + return node.release();
|
| }
|
|
|
| JSONReader::Token JSONReader::ParseNumberToken() {
|
| @@ -372,22 +354,18 @@ JSONReader::Token JSONReader::ParseNumberToken() {
|
| return token;
|
| }
|
|
|
| -bool JSONReader::DecodeNumber(const Token& token, Value** node) {
|
| +Value* JSONReader::DecodeNumber(const Token& token) {
|
| const std::wstring num_string(token.begin, token.length);
|
|
|
| int num_int;
|
| - if (StringToInt(num_string, &num_int)) {
|
| - *node = Value::CreateIntegerValue(num_int);
|
| - return true;
|
| - }
|
| + if (StringToInt(num_string, &num_int))
|
| + return Value::CreateIntegerValue(num_int);
|
|
|
| double num_double;
|
| - if (StringToDouble(num_string, &num_double) && base::IsFinite(num_double)) {
|
| - *node = Value::CreateRealValue(num_double);
|
| - return true;
|
| - }
|
| + if (StringToDouble(num_string, &num_double) && base::IsFinite(num_double))
|
| + return Value::CreateRealValue(num_double);
|
|
|
| - return false;
|
| + return NULL;
|
| }
|
|
|
| JSONReader::Token JSONReader::ParseStringToken() {
|
| @@ -435,7 +413,7 @@ JSONReader::Token JSONReader::ParseStringToken() {
|
| return kInvalidToken;
|
| }
|
|
|
| -bool JSONReader::DecodeString(const Token& token, Value** node) {
|
| +Value* JSONReader::DecodeString(const Token& token) {
|
| std::wstring decoded_str;
|
| decoded_str.reserve(token.length - 2);
|
|
|
| @@ -486,16 +464,14 @@ bool JSONReader::DecodeString(const Token& token, Value** node) {
|
| // We should only have valid strings at this point. If not,
|
| // ParseStringToken didn't do it's job.
|
| NOTREACHED();
|
| - return false;
|
| + return NULL;
|
| }
|
| } else {
|
| // Not escaped
|
| decoded_str.push_back(c);
|
| }
|
| }
|
| - *node = Value::CreateStringValue(decoded_str);
|
| -
|
| - return true;
|
| + return Value::CreateStringValue(decoded_str);
|
| }
|
|
|
| JSONReader::Token JSONReader::ParseToken() {
|
|
|