1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "third_party/libaddressinput/src/cpp/src/util/json.h" 6 7#include <map> 8#include <utility> 9 10#include "base/basictypes.h" 11#include "base/json/json_reader.h" 12#include "base/logging.h" 13#include "base/memory/scoped_ptr.h" 14#include "base/stl_util.h" 15#include "base/values.h" 16 17namespace i18n { 18namespace addressinput { 19 20namespace { 21 22// Returns |json| parsed into a JSON dictionary. Sets |parser_error| to true if 23// parsing failed. 24::scoped_ptr<const base::DictionaryValue> Parse(const std::string& json, 25 bool* parser_error) { 26 DCHECK(parser_error); 27 ::scoped_ptr<const base::DictionaryValue> result; 28 29 // |json| is converted to a |c_str()| here because rapidjson and other parts 30 // of the standalone library use char* rather than std::string. 31 ::scoped_ptr<const base::Value> parsed(base::JSONReader::Read(json.c_str())); 32 *parser_error = !parsed || !parsed->IsType(base::Value::TYPE_DICTIONARY); 33 34 if (*parser_error) 35 result.reset(new base::DictionaryValue); 36 else 37 result.reset(static_cast<const base::DictionaryValue*>(parsed.release())); 38 39 return result.Pass(); 40} 41 42} // namespace 43 44// Implementation of JSON parser for libaddressinput using JSON parser in 45// Chrome. 46class Json::JsonImpl { 47 public: 48 explicit JsonImpl(const std::string& json) 49 : owned_(Parse(json, &parser_error_)), 50 dict_(*owned_) {} 51 52 ~JsonImpl() { STLDeleteElements(&sub_dicts_); } 53 54 bool parser_error() const { return parser_error_; } 55 56 const std::vector<const Json*>& GetSubDictionaries() { 57 if (sub_dicts_.empty()) { 58 for (base::DictionaryValue::Iterator it(dict_); !it.IsAtEnd(); 59 it.Advance()) { 60 if (it.value().IsType(base::Value::TYPE_DICTIONARY)) { 61 const base::DictionaryValue* sub_dict = NULL; 62 it.value().GetAsDictionary(&sub_dict); 63 sub_dicts_.push_back(new Json(new JsonImpl(*sub_dict))); 64 } 65 } 66 } 67 return sub_dicts_; 68 } 69 70 bool GetStringValueForKey(const std::string& key, std::string* value) const { 71 return dict_.GetStringWithoutPathExpansion(key, value); 72 } 73 74 private: 75 explicit JsonImpl(const base::DictionaryValue& dict) 76 : parser_error_(false), dict_(dict) {} 77 78 const ::scoped_ptr<const base::DictionaryValue> owned_; 79 bool parser_error_; 80 const base::DictionaryValue& dict_; 81 std::vector<const Json*> sub_dicts_; 82 83 DISALLOW_COPY_AND_ASSIGN(JsonImpl); 84}; 85 86Json::Json() {} 87 88Json::~Json() {} 89 90bool Json::ParseObject(const std::string& json) { 91 DCHECK(!impl_); 92 impl_.reset(new JsonImpl(json)); 93 if (impl_->parser_error()) 94 impl_.reset(); 95 return !!impl_; 96} 97 98const std::vector<const Json*>& Json::GetSubDictionaries() const { 99 return impl_->GetSubDictionaries(); 100} 101 102bool Json::GetStringValueForKey(const std::string& key, 103 std::string* value) const { 104 return impl_->GetStringValueForKey(key, value); 105} 106 107Json::Json(JsonImpl* impl) : impl_(impl) {} 108 109} // namespace addressinput 110} // namespace i18n 111