Add IsEmpty() method
[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 #include "bundle_log.h"
25
26 namespace tizen_base {
27 Bundle::Impl::Impl(Bundle* parent, bool copy, bool own)
28   : copy_(copy), own_(own), parent_(parent) {
29 }
30
31 Bundle::Impl::Impl(Bundle* parent) : parent_(parent) {
32 }
33
34 Bundle::Impl::~Impl() = default;
35
36 Bundle::Bundle()
37   : impl_(new Impl(this)) {
38   impl_->handle_ = bundle_create();
39   if (impl_->handle_ == nullptr)
40     throw std::bad_alloc();
41 }
42
43 Bundle::Bundle(BundleRaw raw)
44   : impl_(new Impl(this)) {
45   impl_->handle_ = bundle_decode(raw.first.get(), raw.second);
46   if (impl_->handle_ == nullptr)
47     throw std::bad_alloc();
48 }
49
50 Bundle::Bundle(const std::string& raw)
51   : impl_(new Impl(this)) {
52   impl_->handle_ = bundle_decode(reinterpret_cast<const bundle_raw*>(
53       raw.c_str()), raw.length());
54   if (impl_->handle_ == nullptr)
55     throw std::bad_alloc();
56 }
57
58 Bundle::Bundle(bundle* b, bool copy, bool own)
59   : impl_(new Impl(this, copy, own)) {
60   if (b == nullptr)
61     throw std::invalid_argument("b cannot be null");
62
63   if (!impl_->copy_) {
64     impl_->handle_ = b;
65   } else {
66     impl_->handle_ = bundle_dup(b);
67     if (impl_->handle_ == nullptr)
68       throw std::bad_alloc();
69   }
70 }
71
72 Bundle::~Bundle() {
73   if (impl_ && impl_->handle_ && (impl_->own_ || impl_->copy_))
74     bundle_free(impl_->handle_);
75 }
76
77 Bundle::Bundle(const Bundle& b)
78   : impl_(new Impl(this)) {
79   impl_->handle_ = bundle_dup(b.impl_->handle_);
80   if (impl_->handle_ == nullptr)
81     throw std::bad_alloc();
82 }
83
84 Bundle::KeyInfo::KeyInfo(const bundle_keyval_t* handle, std::string name)
85   : impl_(new Impl(this, handle, std::move(name))) {
86 }
87
88 Bundle::KeyInfo::~KeyInfo() {
89 }
90
91 Bundle::KeyInfo::Impl::~Impl() = default;
92 Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent,
93                             const bundle_keyval_t* handle,
94                             std::string name)
95   : handle_(handle), name_(name), parent_(parent) {
96 }
97
98 Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent) : parent_(parent) {
99 }
100
101 Bundle::KeyInfo::KeyInfo(const KeyInfo& k)
102     : impl_(new Impl(this)) {
103   impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
104   impl_->name_ = k.impl_->name_;
105   if (impl_->handle_ == nullptr)
106     throw std::bad_alloc();
107 }
108
109 Bundle::KeyInfo& Bundle::KeyInfo::operator = (const Bundle::KeyInfo& k) {
110   if (this != &k) {
111     impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
112     impl_->name_ = k.impl_->name_;
113     if (impl_->handle_ == nullptr)
114       throw std::bad_alloc();
115   }
116   return *this;
117 }
118
119 Bundle::KeyInfo::KeyInfo(Bundle::KeyInfo&& k) noexcept {
120   impl_ = std::unique_ptr<Impl>(new Impl(this));
121   impl_->handle_ = k.impl_->handle_;
122   impl_->name_ = k.impl_->name_;
123   k.impl_->handle_ = nullptr;
124   k.impl_->name_ = "";
125 }
126
127 Bundle::KeyInfo& Bundle::KeyInfo::operator = (Bundle::KeyInfo&& k) noexcept {
128   if (this != &k) {
129     impl_->handle_ = k.impl_->handle_;
130     impl_->name_ = k.impl_->name_;
131     k.impl_->handle_ = nullptr;
132     k.impl_->name_ = "";
133   }
134   return *this;
135 }
136
137 bundle_type Bundle::KeyInfo::GetType() const {
138   return static_cast<bundle_type>(
139       bundle_keyval_get_type(const_cast<bundle_keyval_t*>(impl_->handle_)));
140 }
141
142 bool Bundle::KeyInfo::IsArray() const {
143   return bundle_keyval_type_is_array(const_cast<bundle_keyval_t*>(
144       impl_->handle_));
145 }
146
147 const std::string& Bundle::KeyInfo::GetName() const {
148   return impl_->name_;
149 }
150
151 Bundle& Bundle::operator = (const Bundle& b) {
152   if (this != &b) {
153     impl_->handle_ = bundle_dup(b.impl_->handle_);
154     if (impl_->handle_ == nullptr)
155       throw std::bad_alloc();
156   }
157   return *this;
158 }
159
160 Bundle::Bundle(Bundle&& b) noexcept {
161   impl_ = std::move(b.impl_);
162   impl_->parent_ = this;
163 }
164
165 Bundle& Bundle::operator = (Bundle&& b) noexcept {
166   if (this != &b) {
167     impl_->handle_ = b.impl_->handle_;
168     b.impl_->handle_ = nullptr;
169   }
170   return *this;
171 }
172
173 bool Bundle::IsEmpty() const noexcept {
174   return (bundle_get_count(impl_->handle_) == 0) ? true : false;
175 }
176
177 std::vector<Bundle::KeyInfo> Bundle::GetKeys() {
178   std::vector<Bundle::KeyInfo> v;
179
180   bundle_foreach(impl_->handle_, [](const char *key, const int type,
181       const bundle_keyval_t *kv, void *user_data) {
182         auto* v = static_cast<std::vector<KeyInfo>*>(user_data);
183         v->emplace_back(kv, key);
184       }, &v);
185
186   return v;
187 }
188
189 int Bundle::Add(const std::string& key, const std::string& val) {
190   int ret = bundle_add_str(impl_->handle_, key.c_str(), val.c_str());
191   if (ret != BUNDLE_ERROR_NONE)
192     LOGE("Add fail key(%s), val(%s), ret(%d)", key.c_str(), val.c_str(), ret);
193   return ret;
194 }
195
196 int Bundle::Add(const std::string& key, const std::vector<std::string>& val) {
197   std::vector<const char*> v;
198   for (auto& i : val) {
199     v.push_back(i.c_str());
200   }
201
202   int ret = bundle_add_str_array(
203     impl_->handle_, key.c_str(), v.data(), v.size());
204   if (ret != BUNDLE_ERROR_NONE)
205     LOGE("Add fail key(%s), ret(%d)", key.c_str(), ret);
206
207   return ret;
208 }
209
210 int Bundle::Add(const std::string& key, const std::vector<unsigned char>& val) {
211   int ret = bundle_add_byte(impl_->handle_, key.c_str(), val.data(), val.size());
212   if (ret != BUNDLE_ERROR_NONE)
213     LOGE("Add fail key(%s), ret(%d)", key.c_str(), ret);
214   return ret;
215 }
216
217 int Bundle::Delete(const std::string& key) {
218   int ret = bundle_del(impl_->handle_, key.c_str());
219   if (ret != BUNDLE_ERROR_NONE)
220     LOGE("Add fail key(%s), ret(%d)", key.c_str(), ret);
221   return ret;
222 }
223
224 std::string Bundle::GetString(const std::string& key) const {
225   char* str = nullptr;
226   bundle_get_str(impl_->handle_, key.c_str(), &str);
227
228   if (!str)
229     return "";
230
231   return std::string(str);
232 }
233
234 std::vector<std::string> Bundle::GetStringArray(const std::string& key) const {
235   std::vector<std::string> v;
236
237   const char** str_array = nullptr;
238   int len = 0;
239
240   str_array = bundle_get_str_array(impl_->handle_, key.c_str(), &len);
241
242   for (int i = 0; i < len; i++) {
243     v.emplace_back(str_array[i]);
244   }
245
246   return v;
247 }
248
249 std::vector<unsigned char> Bundle::GetByte(const std::string& key) const {
250   size_t size;
251   unsigned char* bytes = nullptr;
252   int ret = bundle_get_byte(impl_->handle_, key.c_str(),
253       reinterpret_cast<void**>(&bytes), &size);
254   if (ret != BUNDLE_ERROR_NONE) {
255     LOGE("bundle_get_byte() is failed");
256     return {};
257   }
258
259   return std::vector<unsigned char>(bytes, bytes + size);
260 }
261
262 Bundle::BundleRaw Bundle::ToRaw() {
263   bundle_raw* raw = nullptr;
264   int len = 0;
265   int ret = bundle_encode(impl_->handle_, &raw, &len);
266   if (raw == nullptr) {
267     LOGE("Fail to encode data (%d)", ret);
268     throw std::bad_alloc();
269   }
270
271   return BundleRaw(
272       std::unique_ptr<bundle_raw, decltype(std::free)*>(raw, std::free), len);
273 }
274
275 int Bundle::GetCount() const {
276   return bundle_get_count(impl_->handle_);
277 }
278
279 bundle_type Bundle::GetType(const std::string& key) const {
280   return static_cast<bundle_type>(bundle_get_type(impl_->handle_, key.c_str()));
281 }
282
283 bundle* Bundle::GetHandle() const {
284   return impl_->handle_;
285 }
286
287 bundle* Bundle::Detach() {
288   auto* h = impl_->handle_;
289   impl_->handle_ = nullptr;
290   return h;
291 }
292
293 }  // namespace tizen_base