Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Unified Diff: third_party/libaddressinput/chromium/json.cc

Issue 298863012: Use upstream libaddressinput in Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase on top of https://codereview.chromium.org/359213002/ Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..b2b868735e07adc091869d4b87966976ae434b27 100644
--- a/third_party/libaddressinput/chromium/json.cc
+++ b/third_party/libaddressinput/chromium/json.cc
@@ -2,121 +2,172 @@
// 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"
+#include "third_party/libaddressinput/src/cpp/src/util/json.h"
+
+#include <map>
+#include <utility>
#include "base/basictypes.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/stl_util.h"
#include "base/values.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() {}
+ // ::scoped_ptr is from "base/memory/scoped_ptr.h", which does not interfere
+ // with ::i18n::addressinput::scoped_ptr from
+ // <libaddressinput/util/scoped_ptr.h>
+ 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<const base::Value> parsed(base::JSONReader::Read(json.c_str()));
+ if (parsed && parsed->IsType(base::Value::TYPE_DICTIONARY)) {
+ ::scoped_ptr<const base::DictionaryValue> dict(
+ static_cast<const base::DictionaryValue*>(parsed.release()));
+ impl_.reset(new JsonImpl(dict.Pass()));
+ }
-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, &not_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

Powered by Google App Engine
This is Rietveld 408576698