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 "cpp/src/util/json.h" 6 7 #include "base/basictypes.h" 8 #include "base/json/json_reader.h" 9 #include "base/logging.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/values.h" 12 13 namespace i18n { 14 namespace addressinput { 15 16 namespace { 17 18 // A base class for Chrome Json objects. JSON gets parsed into a 19 // base::DictionaryValue and data is accessed via the Json interface. 20 class ChromeJson : public Json { 21 public: 22 virtual bool GetStringValueForKey(const std::string& key, std::string* value) 23 const OVERRIDE; 24 virtual bool GetJsonValueForKey(const std::string& key, 25 scoped_ptr<Json>* value) const OVERRIDE; 26 protected: 27 ChromeJson() {} 28 virtual ~ChromeJson() {} 29 30 virtual const base::DictionaryValue* GetDict() const = 0; 31 32 DISALLOW_COPY_AND_ASSIGN(ChromeJson); 33 }; 34 35 // A Json object that will parse a string and own the parsed data. 36 class JsonDataOwner : public ChromeJson { 37 public: 38 JsonDataOwner() {} 39 virtual ~JsonDataOwner() {} 40 41 virtual bool ParseObject(const std::string& json) OVERRIDE { 42 dict_.reset(); 43 44 // |json| is converted to a |c_str()| here because rapidjson and other parts 45 // of the standalone library use char* rather than std::string. 46 scoped_ptr<base::Value> parsed(base::JSONReader::Read(json.c_str())); 47 if (parsed && parsed->IsType(base::Value::TYPE_DICTIONARY)) 48 dict_.reset(static_cast<base::DictionaryValue*>(parsed.release())); 49 50 return !!dict_; 51 } 52 53 protected: 54 virtual const base::DictionaryValue* GetDict() const OVERRIDE { 55 return dict_.get(); 56 } 57 58 private: 59 scoped_ptr<base::DictionaryValue> dict_; 60 61 DISALLOW_COPY_AND_ASSIGN(JsonDataOwner); 62 }; 63 64 // A Json object which will point to data that's been parsed by a different 65 // ChromeJson. It does not own its data and is only valid as long as its parent 66 // ChromeJson is valid. 67 class JsonDataCopy : public ChromeJson { 68 public: 69 explicit JsonDataCopy(const base::DictionaryValue* dict) : 70 dict_(dict) {} 71 virtual ~JsonDataCopy() {} 72 73 virtual bool ParseObject(const std::string& json) OVERRIDE { 74 NOTREACHED(); 75 return false; 76 } 77 78 protected: 79 virtual const base::DictionaryValue* GetDict() const OVERRIDE { 80 return dict_; 81 } 82 83 private: 84 const base::DictionaryValue* dict_; // weak reference. 85 86 DISALLOW_COPY_AND_ASSIGN(JsonDataCopy); 87 }; 88 89 // ChromeJson ------------------------------------------------------------------ 90 91 bool ChromeJson::GetStringValueForKey(const std::string& key, 92 std::string* value) const { 93 return GetDict()->GetStringWithoutPathExpansion(key, value); 94 } 95 96 bool ChromeJson::GetJsonValueForKey(const std::string& key, 97 scoped_ptr<Json>* value) const { 98 const base::DictionaryValue* sub_dict = NULL; 99 if (!GetDict()->GetDictionaryWithoutPathExpansion(key, &sub_dict) || 100 !sub_dict) { 101 return false; 102 } 103 104 if (value) 105 value->reset(new JsonDataCopy(sub_dict)); 106 107 return true; 108 } 109 110 } // namespace 111 112 Json::~Json() {} 113 114 // static 115 scoped_ptr<Json> Json::Build() { 116 return scoped_ptr<Json>(new JsonDataOwner); 117 } 118 119 Json::Json() {} 120 121 } // namespace addressinput 122 } // namespace i18n 123