• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ChromeJson()27   ChromeJson() {}
~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:
JsonDataOwner()38   JsonDataOwner() {}
~JsonDataOwner()39   virtual ~JsonDataOwner() {}
40 
ParseObject(const std::string & json)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:
GetDict() const54   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:
JsonDataCopy(const base::DictionaryValue * dict)69   explicit JsonDataCopy(const base::DictionaryValue* dict) :
70       dict_(dict) {}
~JsonDataCopy()71   virtual ~JsonDataCopy() {}
72 
ParseObject(const std::string & json)73   virtual bool ParseObject(const std::string& json) OVERRIDE {
74     NOTREACHED();
75     return false;
76   }
77 
78  protected:
GetDict() const79   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 
GetStringValueForKey(const std::string & key,std::string * value) const91 bool ChromeJson::GetStringValueForKey(const std::string& key,
92                                       std::string* value) const {
93   return GetDict()->GetStringWithoutPathExpansion(key, value);
94 }
95 
GetJsonValueForKey(const std::string & key,scoped_ptr<Json> * value) const96 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 
~Json()112 Json::~Json() {}
113 
114 // static
Build()115 scoped_ptr<Json> Json::Build() {
116   return scoped_ptr<Json>(new JsonDataOwner);
117 }
118 
Json()119 Json::Json() {}
120 
121 }  // namespace addressinput
122 }  // namespace i18n
123