1// Copyright (C) 2013 Google Inc. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15#include "json.h" 16 17#include <libaddressinput/util/basictypes.h> 18#include <libaddressinput/util/scoped_ptr.h> 19 20#include <cassert> 21#include <cstddef> 22#include <string> 23#include <vector> 24 25#include <rapidjson/document.h> 26#include <rapidjson/reader.h> 27 28namespace i18n { 29namespace addressinput { 30 31using rapidjson::Document; 32using rapidjson::kParseValidateEncodingFlag; 33using rapidjson::Value; 34 35class Json::JsonImpl { 36 public: 37 explicit JsonImpl(const std::string& json) 38 : document_(new Document), 39 value_(document_.get()), 40 dictionaries_(), 41 valid_(false) { 42 document_->Parse<kParseValidateEncodingFlag>(json.c_str()); 43 valid_ = !document_->HasParseError() && document_->IsObject(); 44 } 45 46 ~JsonImpl() { 47 for (std::vector<const Json*>::const_iterator it = dictionaries_.begin(); 48 it != dictionaries_.end(); ++it) { 49 delete *it; 50 } 51 } 52 53 bool valid() const { return valid_; } 54 55 const std::vector<const Json*>& GetSubDictionaries() { 56 if (dictionaries_.empty()) { 57 for (Value::ConstMemberIterator member = value_->MemberBegin(); 58 member != value_->MemberEnd(); ++member) { 59 if (member->value.IsObject()) { 60 dictionaries_.push_back(new Json(new JsonImpl(&member->value))); 61 } 62 } 63 } 64 return dictionaries_; 65 } 66 67 bool GetStringValueForKey(const std::string& key, std::string* value) const { 68 assert(value != NULL); 69 70 Value::ConstMemberIterator member = value_->FindMember(key.c_str()); 71 if (member == NULL || !member->value.IsString()) { 72 return false; 73 } 74 75 value->assign(member->value.GetString(), 76 member->value.GetStringLength()); 77 return true; 78 } 79 80 private: 81 // Does not take ownership of |value|. 82 explicit JsonImpl(const Value* value) 83 : document_(), 84 value_(value), 85 dictionaries_(), 86 valid_(true) { 87 assert(value_ != NULL); 88 assert(value_->IsObject()); 89 } 90 91 // An owned JSON document. Can be NULL if the JSON document is not owned. 92 const scoped_ptr<Document> document_; 93 94 // A JSON document that is not owned. Cannot be NULL. Can point to document_. 95 const Value* const value_; 96 97 // Owned JSON objects of sub-dictionaries. 98 std::vector<const Json*> dictionaries_; 99 100 // True if the JSON object was parsed successfully. 101 bool valid_; 102 103 DISALLOW_COPY_AND_ASSIGN(JsonImpl); 104}; 105 106Json::Json() : impl_() {} 107 108Json::~Json() {} 109 110bool Json::ParseObject(const std::string& json) { 111 assert(impl_ == NULL); 112 impl_.reset(new JsonImpl(json)); 113 if (!impl_->valid()) { 114 impl_.reset(); 115 } 116 return impl_ != NULL; 117} 118 119const std::vector<const Json*>& Json::GetSubDictionaries() const { 120 assert(impl_ != NULL); 121 return impl_->GetSubDictionaries(); 122} 123 124bool Json::GetStringValueForKey(const std::string& key, 125 std::string* value) const { 126 assert(impl_ != NULL); 127 return impl_->GetStringValueForKey(key, value); 128} 129 130Json::Json(JsonImpl* impl) : impl_(impl) {} 131 132} // namespace addressinput 133} // namespace i18n 134