| Index: third_party/libaddressinput/chromium/json.cc
|
| diff --git a/third_party/libaddressinput/chromium/json.cc b/third_party/libaddressinput/chromium/json.cc
|
| index 5437e1e55056ef4d2eec6158e54acf85c9f536ea..faafd2320be7d369a41a48acf88259c9f470ae95 100644
|
| --- a/third_party/libaddressinput/chromium/json.cc
|
| +++ b/third_party/libaddressinput/chromium/json.cc
|
| @@ -2,121 +2,176 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "cpp/src/util/json.h"
|
| +// Use "base/basictypes.h" instead.
|
| +#define I18N_ADDRESSINPUT_UTIL_BASICTYPES_H_
|
| +
|
| +// Use "base/memory/scoped_ptr.h" instead.
|
| +#define I18N_ADDRESSINPUT_UTIL_SCOPED_PTR_H_
|
| +
|
| +#include <map>
|
| +#include <utility>
|
|
|
| #include "base/basictypes.h"
|
| #include "base/json/json_reader.h"
|
| #include "base/logging.h"
|
| +// Must be before json.h to be used in the Json class.
|
| #include "base/memory/scoped_ptr.h"
|
| +#include "base/stl_util.h"
|
| #include "base/values.h"
|
| +#include "third_party/libaddressinput/src/cpp/src/util/json.h"
|
|
|
| namespace i18n {
|
| namespace addressinput {
|
|
|
| -namespace {
|
| -
|
| -// A base class for Chrome Json objects. JSON gets parsed into a
|
| -// base::DictionaryValue and data is accessed via the Json interface.
|
| -class ChromeJson : public Json {
|
| +class Json::JsonImpl {
|
| public:
|
| - virtual bool GetStringValueForKey(const std::string& key, std::string* value)
|
| - const OVERRIDE;
|
| - virtual bool GetJsonValueForKey(const std::string& key,
|
| - scoped_ptr<Json>* value) const OVERRIDE;
|
| - protected:
|
| - ChromeJson() {}
|
| - virtual ~ChromeJson() {}
|
| + explicit JsonImpl(scoped_ptr<const base::DictionaryValue> to_take_ownership)
|
| + : owned_(to_take_ownership.Pass()), not_owned_(owned_.get()) {
|
| + DCHECK(not_owned_);
|
| + InitKeys();
|
| + }
|
|
|
| - virtual const base::DictionaryValue* GetDict() const = 0;
|
| + explicit JsonImpl(const base::DictionaryValue* do_not_take_ownership)
|
| + : not_owned_(do_not_take_ownership) {
|
| + DCHECK(not_owned_);
|
| + InitKeys();
|
| + }
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(ChromeJson);
|
| -};
|
| + ~JsonImpl() {
|
| + STLDeleteValues(&dictionaries_);
|
| + }
|
|
|
| -// A Json object that will parse a string and own the parsed data.
|
| -class JsonDataOwner : public ChromeJson {
|
| - public:
|
| - JsonDataOwner() {}
|
| - virtual ~JsonDataOwner() {}
|
| + const std::vector<std::string>& GetKeys() const {
|
| + return keys_;
|
| + }
|
|
|
| - virtual bool ParseObject(const std::string& json) OVERRIDE {
|
| - dict_.reset();
|
| + bool GetStringValueForKey(const std::string& key, std::string* value) const {
|
| + return not_owned_->GetStringWithoutPathExpansion(key, value);
|
| + }
|
|
|
| - // |json| is converted to a |c_str()| here because rapidjson and other parts
|
| - // of the standalone library use char* rather than std::string.
|
| - scoped_ptr<base::Value> parsed(base::JSONReader::Read(json.c_str()));
|
| - if (parsed && parsed->IsType(base::Value::TYPE_DICTIONARY))
|
| - dict_.reset(static_cast<base::DictionaryValue*>(parsed.release()));
|
| + bool GetDictionaryValueForKey(const std::string& key,
|
| + const base::DictionaryValue** value) const {
|
| + return not_owned_->GetDictionaryWithoutPathExpansion(key, value);
|
| + }
|
|
|
| - return !!dict_;
|
| + // The caller does not own the result. The result can be NULL if there's no
|
| + // dictionary for |key|.
|
| + const Json* FindDictionary(const std::string& key) const {
|
| + std::map<std::string, const Json*>::const_iterator it =
|
| + dictionaries_.find(key);
|
| + return it != dictionaries_.end() ? it->second : NULL;
|
| }
|
|
|
| - protected:
|
| - virtual const base::DictionaryValue* GetDict() const OVERRIDE {
|
| - return dict_.get();
|
| + // Takes ownership of |dictionary|. Should be called only once per |key| and
|
| + // per |dictionary|.
|
| + void AddDictionary(const std::string& key, const Json* dictionary) {
|
| + bool inserted =
|
| + dictionaries_.insert(std::make_pair(key, dictionary)).second;
|
| + // Cannot do work inside of DCHECK(), because the compiler can optimize it
|
| + // away.
|
| + DCHECK(inserted);
|
| + // Avoid unused variable warning when DCHECK() is optimized away.
|
| + (void)inserted;
|
| }
|
|
|
| private:
|
| - scoped_ptr<base::DictionaryValue> dict_;
|
| + void InitKeys() {
|
| + DCHECK(keys_.empty());
|
| + for (base::DictionaryValue::Iterator it(*not_owned_); !it.IsAtEnd();
|
| + it.Advance()) {
|
| + keys_.push_back(it.key());
|
| + }
|
| + }
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(JsonDataOwner);
|
| -};
|
| + const scoped_ptr<const base::DictionaryValue> owned_;
|
| + const base::DictionaryValue* const not_owned_;
|
|
|
| -// A Json object which will point to data that's been parsed by a different
|
| -// ChromeJson. It does not own its data and is only valid as long as its parent
|
| -// ChromeJson is valid.
|
| -class JsonDataCopy : public ChromeJson {
|
| - public:
|
| - explicit JsonDataCopy(const base::DictionaryValue* dict) :
|
| - dict_(dict) {}
|
| - virtual ~JsonDataCopy() {}
|
| + // Owned JSON objects.
|
| + std::map<std::string, const Json*> dictionaries_;
|
|
|
| - virtual bool ParseObject(const std::string& json) OVERRIDE {
|
| - NOTREACHED();
|
| - return false;
|
| - }
|
| + std::vector<std::string> keys_;
|
|
|
| - protected:
|
| - virtual const base::DictionaryValue* GetDict() const OVERRIDE {
|
| - return dict_;
|
| - }
|
| + DISALLOW_COPY_AND_ASSIGN(JsonImpl);
|
| +};
|
|
|
| - private:
|
| - const base::DictionaryValue* dict_; // weak reference.
|
| +Json::Json() {}
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(JsonDataCopy);
|
| -};
|
| +Json::~Json() {}
|
| +
|
| +bool Json::ParseObject(const std::string& json) {
|
| + DCHECK(!impl_);
|
|
|
| -// ChromeJson ------------------------------------------------------------------
|
| + // |json| is converted to a |c_str()| here because rapidjson and other parts
|
| + // of the standalone library use char* rather than std::string.
|
| + scoped_ptr<base::Value> parsed(base::JSONReader::Read(json.c_str()));
|
| + if (parsed && parsed->IsType(base::Value::TYPE_DICTIONARY)) {
|
| + impl_.reset(
|
| + new JsonImpl(static_cast<base::DictionaryValue*>(parsed.release())));
|
| + }
|
|
|
| -bool ChromeJson::GetStringValueForKey(const std::string& key,
|
| - std::string* value) const {
|
| - return GetDict()->GetStringWithoutPathExpansion(key, value);
|
| + return !!impl_;
|
| }
|
|
|
| -bool ChromeJson::GetJsonValueForKey(const std::string& key,
|
| - scoped_ptr<Json>* value) const {
|
| - const base::DictionaryValue* sub_dict = NULL;
|
| - if (!GetDict()->GetDictionaryWithoutPathExpansion(key, &sub_dict) ||
|
| - !sub_dict) {
|
| - return false;
|
| - }
|
| +const std::vector<std::string>& Json::GetKeys() const {
|
| + DCHECK(impl_);
|
| + return impl_->GetKeys();
|
| +}
|
|
|
| - if (value)
|
| - value->reset(new JsonDataCopy(sub_dict));
|
| +bool Json::HasStringValueForKey(const std::string& key) const {
|
| + DCHECK(impl_);
|
| + std::string not_used;
|
| + return impl_->GetStringValueForKey(key, ¬_used);
|
| +}
|
|
|
| - return true;
|
| +std::string Json::GetStringValueForKey(const std::string& key) const {
|
| + DCHECK(impl_);
|
| + std::string value;
|
| + bool found = impl_->GetStringValueForKey(key, &value);
|
| + // Do not work inside of a DCHECK(), because it can be optimized away.
|
| + DCHECK(found);
|
| + // Avoid a compiler warning about unused variable when DCHECK() is optimized
|
| + // away.
|
| + (void)found;
|
| + return value;
|
| }
|
|
|
| -} // namespace
|
| +bool Json::HasDictionaryValueForKey(const std::string& key) const {
|
| + DCHECK(impl_);
|
|
|
| -Json::~Json() {}
|
| + // The value returned by FindDictionary() is owned by impl_.
|
| + if (impl_->FindDictionary(key))
|
| + return true;
|
|
|
| -// static
|
| -scoped_ptr<Json> Json::Build() {
|
| - return scoped_ptr<Json>(new JsonDataOwner);
|
| + // Value is owned by impl_.
|
| + const base::DictionaryValue* value = NULL;
|
| + return impl_->GetDictionaryValueForKey(key, &value) && value;
|
| }
|
|
|
| -Json::Json() {}
|
| +const Json& Json::GetDictionaryValueForKey(const std::string& key) const {
|
| + DCHECK(impl_);
|
| +
|
| + // The value returned by FindDictionary() is owned by impl_.
|
| + const Json* existing_dictionary = impl_->FindDictionary(key);
|
| + if (existing_dictionary)
|
| + return *existing_dictionary;
|
| +
|
| + // Value is owned by impl_.
|
| + const base::DictionaryValue* value = NULL;
|
| + bool found = impl_->GetDictionaryValueForKey(key, &value);
|
| + // Cannot do work inside of DCHECK(), because it can be optimized by the
|
| + // compiler.
|
| + DCHECK(found);
|
| + // Avoid a compiler warning about an unused variable when the DCHECK() is
|
| + // optimized away.
|
| + (void)found;
|
| + DCHECK(value);
|
| +
|
| + // Dictionary is owned by impl_.
|
| + Json* dictionary = new Json;
|
| + dictionary->impl_.reset(new JsonImpl(value));
|
| + impl_->AddDictionary(key, dictionary);
|
| + return *dictionary;
|
| +}
|
|
|
| } // namespace addressinput
|
| } // namespace i18n
|
|
|