Home | History | Annotate | Download | only in chromium
      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