2e6f30bca0b817b5142f58c35ce65f65d9a1b6d8
[platform/core/base/bundle.git] / src / bundle_cpp.cc
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <dlog.h>
18
19 #include <memory>
20
21 #include "bundle_cpp_implementation.h"
22 #include "bundle_cpp.h"
23 #include "bundle_internal.h"
24
25
26 #ifdef LOG_TAG
27 #undef LOG_TAG
28 #endif
29
30 #define LOG_TAG "BUNDLE"
31
32 namespace tizen_base {
33 Bundle::Impl::Impl(Bundle* parent, bool copy, bool own)
34   : copy_(copy), own_(own), parent_(parent) {
35 }
36
37 Bundle::Impl::Impl(Bundle* parent) : parent_(parent) {
38 }
39
40 Bundle::Impl::~Impl() = default;
41
42 Bundle::Bundle()
43   : impl_(new Impl(this)) {
44   impl_->handle_ = bundle_create();
45   if (impl_->handle_ == nullptr)
46     throw std::bad_alloc();
47 }
48
49 Bundle::Bundle(BundleRaw raw)
50   : impl_(new Impl(this)) {
51   impl_->handle_ = bundle_decode(raw.first.get(), raw.second);
52   if (impl_->handle_ == nullptr)
53     throw std::bad_alloc();
54 }
55
56 Bundle::Bundle(const std::string& raw)
57   : impl_(new Impl(this)) {
58   impl_->handle_ = bundle_decode(reinterpret_cast<const bundle_raw*>(
59       raw.c_str()), raw.length());
60   if (impl_->handle_ == nullptr)
61     throw std::bad_alloc();
62 }
63
64 Bundle::Bundle(bundle* b, bool copy, bool own)
65   : impl_(new Impl(this, copy, own)) {
66   if (b == nullptr)
67     throw std::invalid_argument("b cannot be null");
68
69   if (!impl_->copy_) {
70     impl_->handle_ = b;
71   } else {
72     impl_->handle_ = bundle_dup(b);
73     if (impl_->handle_ == nullptr)
74       throw std::bad_alloc();
75   }
76 }
77
78 Bundle::~Bundle() {
79   if (impl_->handle_ && (impl_->own_ || impl_->copy_))
80     bundle_free(impl_->handle_);
81 }
82
83 Bundle::Bundle(const Bundle& b)
84   : impl_(new Impl(this)) {
85   impl_->handle_ = bundle_dup(b.impl_->handle_);
86   if (impl_->handle_ == nullptr)
87     throw std::bad_alloc();
88 }
89
90 Bundle::KeyInfo::KeyInfo(const bundle_keyval_t* handle, std::string name)
91   : impl_(new Impl(this, handle, std::move(name))) {
92 }
93
94 Bundle::KeyInfo::KeyInfo()
95   : impl_(new Impl(this)) {
96 }
97
98 Bundle::KeyInfo::~KeyInfo() {
99 }
100
101 Bundle::KeyInfo::Impl::~Impl() = default;
102 Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent,
103                             const bundle_keyval_t* handle,
104                             std::string name)
105   : handle_(handle), name_(name), parent_(parent) {
106 }
107
108 Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent) : parent_(parent) {
109 }
110
111 Bundle::KeyInfo::KeyInfo(const KeyInfo& k)
112     : impl_(new Impl(this)) {
113   impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
114   impl_->name_ = k.impl_->name_;
115   if (impl_->handle_ == nullptr)
116     throw std::bad_alloc();
117 }
118
119 Bundle::KeyInfo& Bundle::KeyInfo::operator = (const Bundle::KeyInfo& k) {
120   if (this != &k) {
121     impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
122     impl_->name_ = k.impl_->name_;
123     if (impl_->handle_ == nullptr)
124       throw std::bad_alloc();
125   }
126   return *this;
127 }
128
129 Bundle::KeyInfo::KeyInfo(Bundle::KeyInfo&& k) noexcept {
130   impl_ = std::unique_ptr<Impl>(new Impl(this));
131   impl_->handle_ = k.impl_->handle_;
132   impl_->name_ = k.impl_->name_;
133   k.impl_->handle_ = nullptr;
134   k.impl_->name_ = "";
135 }
136
137 Bundle::KeyInfo& Bundle::KeyInfo::operator = (Bundle::KeyInfo&& k) noexcept {
138   if (this != &k) {
139     impl_->handle_ = k.impl_->handle_;
140     impl_->name_ = k.impl_->name_;
141     k.impl_->handle_ = nullptr;
142     k.impl_->name_ = "";
143   }
144   return *this;
145 }
146
147 bundle_type Bundle::KeyInfo::GetType() const {
148   return static_cast<bundle_type>(
149       bundle_keyval_get_type(const_cast<bundle_keyval_t*>(impl_->handle_)));
150 }
151
152 bool Bundle::KeyInfo::IsArray() const {
153   return bundle_keyval_type_is_array(const_cast<bundle_keyval_t*>(
154       impl_->handle_));
155 }
156
157 const std::string& Bundle::KeyInfo::GetName() const {
158   return impl_->name_;
159 }
160
161 Bundle& Bundle::operator = (const Bundle& b) {
162   if (this != &b) {
163     impl_->handle_ = bundle_dup(b.impl_->handle_);
164     if (impl_->handle_ == nullptr)
165       throw std::bad_alloc();
166   }
167   return *this;
168 }
169
170 Bundle::Bundle(Bundle&& b) noexcept {
171   impl_ = std::unique_ptr<Impl>(new Impl(this));
172   impl_->handle_ = b.impl_->handle_;
173   b.impl_->handle_ = nullptr;
174 }
175
176 Bundle& Bundle::operator = (Bundle&& b) noexcept {
177   if (this != &b) {
178     impl_->handle_ = b.impl_->handle_;
179     b.impl_->handle_ = nullptr;
180   }
181   return *this;
182 }
183
184 std::vector<Bundle::KeyInfo> Bundle::GetKeys() {
185   std::vector<Bundle::KeyInfo> v;
186
187   bundle_foreach(impl_->handle_, [](const char *key, const int type,
188       const bundle_keyval_t *kv, void *user_data) {
189         auto* v = static_cast<std::vector<KeyInfo>*>(user_data);
190         v->emplace_back(kv, key);
191       }, &v);
192
193   return v;
194 }
195
196 int Bundle::Add(const std::string& key, const std::string& val) {
197   int ret = bundle_add_str(impl_->handle_, key.c_str(), val.c_str());
198   if (ret != BUNDLE_ERROR_NONE)
199     LOGE("Add fail key(%s), val(%s), ret(%d)", key.c_str(), val.c_str(), ret);
200   return ret;
201 }
202
203 int Bundle::Add(const std::string& key, const std::vector<std::string>& val) {
204   std::vector<const char*> v;
205   for (auto& i : val) {
206     v.push_back(i.c_str());
207   }
208
209   int ret = bundle_add_str_array(
210     impl_->handle_, key.c_str(), v.data(), v.size());
211   if (ret != BUNDLE_ERROR_NONE)
212     LOGE("Add fail key(%s), ret(%d)", key.c_str(), ret);
213
214   return ret;
215 }
216
217 int Bundle::Add(const std::string& key, const std::vector<unsigned char>& val) {
218   int ret = bundle_add_byte(impl_->handle_, key.c_str(), val.data(), val.size());
219   if (ret != BUNDLE_ERROR_NONE)
220     LOGE("Add fail key(%s), ret(%d)", key.c_str(), ret);
221   return ret;
222 }
223
224 int Bundle::Delete(const std::string& key) {
225   int ret = bundle_del(impl_->handle_, key.c_str());
226   if (ret != BUNDLE_ERROR_NONE)
227     LOGE("Add fail key(%s), ret(%d)", key.c_str(), ret);
228   return ret;
229 }
230
231 std::string Bundle::GetString(const std::string& key) const {
232   char* str = nullptr;
233   bundle_get_str(impl_->handle_, key.c_str(), &str);
234
235   if (!str)
236     return "";
237
238   return std::string(str);
239 }
240
241 std::vector<std::string> Bundle::GetStringArray(const std::string& key) const {
242   std::vector<std::string> v;
243
244   const char** str_array = nullptr;
245   int len = 0;
246
247   str_array = bundle_get_str_array(impl_->handle_, key.c_str(), &len);
248
249   for (int i = 0; i < len; i++) {
250     v.emplace_back(str_array[i]);
251   }
252
253   return v;
254 }
255
256 std::vector<unsigned char> Bundle::GetByte(const std::string& key) const {
257   size_t size;
258   unsigned char* bytes = nullptr;
259   bundle_get_byte(impl_->handle_, key.c_str(),
260       reinterpret_cast<void**>(&bytes), &size);
261   return std::vector<unsigned char>(bytes, bytes + size);
262 }
263
264 Bundle::BundleRaw Bundle::ToRaw() {
265   bundle_raw* raw = nullptr;
266   int len = 0;
267   int ret = bundle_encode(impl_->handle_, &raw, &len);
268   if (raw == nullptr) {
269     LOGE("Fail to encode data (%d)", ret);
270     throw std::bad_alloc();
271   }
272
273   return BundleRaw(
274       std::unique_ptr<bundle_raw, decltype(std::free)*>(raw, std::free), len);
275 }
276
277 int Bundle::GetCount() const {
278   return bundle_get_count(impl_->handle_);
279 }
280
281 bundle_type Bundle::GetType(const std::string& key) const {
282   return static_cast<bundle_type>(bundle_get_type(impl_->handle_, key.c_str()));
283 }
284
285 bundle* Bundle::GetHandle() const {
286   return impl_->handle_;
287 }
288
289 bundle* Bundle::Detach() {
290   auto* h = impl_->handle_;
291   impl_->handle_ = nullptr;
292   return h;
293 }
294
295 }  // namespace tizen_base