| OLD | NEW |
| 1 // Copyright (C) 2013 Google Inc. | 1 // Copyright (C) 2013 Google Inc. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with 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 | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
| 13 // limitations under the License. | 13 // limitations under the License. |
| 14 | 14 |
| 15 #include "json.h" | 15 #include "json.h" |
| 16 | 16 |
| 17 #include <libaddressinput/util/basictypes.h> | 17 #include <libaddressinput/util/basictypes.h> |
| 18 #include <libaddressinput/util/scoped_ptr.h> | 18 #include <libaddressinput/util/scoped_ptr.h> |
| 19 | 19 |
| 20 #include <cassert> | 20 #include <cassert> |
| 21 #include <cstddef> | 21 #include <cstddef> |
| 22 #include <cstring> |
| 22 #include <string> | 23 #include <string> |
| 23 | 24 |
| 24 #include <rapidjson/document.h> | 25 #include <rapidjson/document.h> |
| 25 #include <rapidjson/reader.h> | 26 #include <rapidjson/reader.h> |
| 26 | 27 |
| 27 namespace i18n { | 28 namespace i18n { |
| 28 namespace addressinput { | 29 namespace addressinput { |
| 29 | 30 |
| 30 namespace { | 31 namespace { |
| 31 | 32 |
| 32 class Rapidjson : public Json { | 33 class Rapidjson : public Json { |
| 33 public: | 34 public: |
| 34 Rapidjson() : document_(new rapidjson::Document), valid_(false) {} | 35 Rapidjson() : dict_() {} |
| 35 | 36 |
| 36 virtual ~Rapidjson() {} | 37 virtual ~Rapidjson() {} |
| 37 | 38 |
| 38 virtual bool ParseObject(const std::string& json) { | 39 virtual bool ParseObject(const std::string& json) { |
| 39 document_->Parse<rapidjson::kParseValidateEncodingFlag>(json.c_str()); | 40 scoped_ptr<rapidjson::Document> document(new rapidjson::Document); |
| 40 valid_ = !document_->HasParseError() && document_->IsObject(); | 41 document->Parse<rapidjson::kParseValidateEncodingFlag>(json.c_str()); |
| 41 return valid_; | 42 if (!document->HasParseError() && document->IsObject()) { |
| 43 dict_.reset(document.release()); |
| 44 return true; |
| 45 } |
| 46 return false; |
| 42 } | 47 } |
| 43 | 48 |
| 44 virtual bool GetStringValueForKey(const std::string& key, | 49 virtual bool GetStringValueForKey(const std::string& key, |
| 45 std::string* value) const { | 50 std::string* value) const { |
| 46 assert(valid_); | 51 assert(dict_ != NULL); |
| 47 const rapidjson::Value::Member* member = document_->FindMember(key.c_str()); | 52 |
| 53 // Owned by |dict_|. |
| 54 const rapidjson::Value::Member* member = dict_->FindMember(key.c_str()); |
| 48 if (member == NULL || !member->value.IsString()) { | 55 if (member == NULL || !member->value.IsString()) { |
| 49 return false; | 56 return false; |
| 50 } | 57 } |
| 51 | 58 |
| 52 if (value) { | 59 if (value) { |
| 53 value->assign(member->value.GetString(), member->value.GetStringLength()); | 60 value->assign(member->value.GetString(), member->value.GetStringLength()); |
| 54 } | 61 } |
| 55 | 62 |
| 56 return true; | 63 return true; |
| 57 } | 64 } |
| 58 | 65 |
| 66 virtual bool GetJsonValueForKey(const std::string& key, |
| 67 scoped_ptr<Json>* value) const { |
| 68 assert(dict_ != NULL); |
| 69 |
| 70 // Owned by |dict_|. |
| 71 const rapidjson::Value::Member* member = dict_->FindMember(key.c_str()); |
| 72 if (member == NULL || !member->value.IsObject()) { |
| 73 return false; |
| 74 } |
| 75 |
| 76 if (value) { |
| 77 scoped_ptr<rapidjson::Value> copy(new rapidjson::Value); |
| 78 |
| 79 // Rapidjson provides only move operations in public API, but implements |
| 80 // the move operation with a memcpy and delete: |
| 81 // |
| 82 // https://code.google.com/p/rapidjson/source/browse/trunk/include/rapidjs
on/document.h?r=131#173 |
| 83 // |
| 84 // We need a copy of the object, so we use memcpy manually. |
| 85 memcpy(copy.get(), &member->value, sizeof(rapidjson::Value)); |
| 86 |
| 87 value->reset(new Rapidjson(copy.Pass())); |
| 88 } |
| 89 |
| 90 return true; |
| 91 } |
| 92 |
| 59 protected: | 93 protected: |
| 60 // JSON document. | 94 explicit Rapidjson(scoped_ptr<rapidjson::Value> dict) |
| 61 scoped_ptr<rapidjson::Document> document_; | 95 : dict_(dict.Pass()) {} |
| 62 | 96 |
| 63 // True if the parsed string is a valid JSON object. | 97 // JSON value. |
| 64 bool valid_; | 98 scoped_ptr<rapidjson::Value> dict_; |
| 65 | 99 |
| 66 DISALLOW_COPY_AND_ASSIGN(Rapidjson); | 100 DISALLOW_COPY_AND_ASSIGN(Rapidjson); |
| 67 }; | 101 }; |
| 68 | 102 |
| 69 } // namespace | 103 } // namespace |
| 70 | 104 |
| 71 Json::~Json() {} | 105 Json::~Json() {} |
| 72 | 106 |
| 73 // static | 107 // static |
| 74 scoped_ptr<Json> Json::Build() { | 108 scoped_ptr<Json> Json::Build() { |
| 75 return scoped_ptr<Json>(new Rapidjson); | 109 return scoped_ptr<Json>(new Rapidjson); |
| 76 } | 110 } |
| 77 | 111 |
| 78 Json::Json() {} | 112 Json::Json() {} |
| 79 | 113 |
| 80 } // namespace addressinput | 114 } // namespace addressinput |
| 81 } // namespace i18n | 115 } // namespace i18n |
| OLD | NEW |