Merge "Add bundle cpp APIs" into tizen
[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 }
46
47 Bundle::Bundle(BundleRaw raw)
48   : impl_(new Impl(this)) {
49   impl_->handle_ = bundle_decode(raw.first.get(), raw.second);
50 }
51
52 Bundle::Bundle(const std::string& raw)
53   : impl_(new Impl(this)) {
54   impl_->handle_ = bundle_decode(reinterpret_cast<const bundle_raw*>(
55       raw.c_str()), raw.length());
56 }
57
58 Bundle::Bundle(bundle* b, bool copy, bool own)
59   : impl_(new Impl(this, copy, own)) {
60   if (!impl_->copy_)
61     impl_->handle_ = b;
62   else
63     impl_->handle_ = bundle_dup(b);
64 }
65
66 Bundle::~Bundle() {
67   if (impl_->handle_ && (impl_->own_ || impl_->copy_))
68     bundle_free(impl_->handle_);
69 }
70
71 Bundle::Bundle(const Bundle& b)
72   : impl_(new Impl(this)) {
73   impl_->handle_ = bundle_dup(b.impl_->handle_);
74 }
75
76 Bundle::KeyInfo::KeyInfo(const bundle_keyval_t* handle, std::string name)
77   : impl_(new Impl(this, handle, std::move(name))) {
78 }
79
80 Bundle::KeyInfo::KeyInfo()
81   : impl_(new Impl(this)) {
82 }
83
84 Bundle::KeyInfo::~KeyInfo() {
85 }
86
87 Bundle::KeyInfo::Impl::~Impl() = default;
88 Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent,
89                             const bundle_keyval_t* handle,
90                             std::string name)
91   : handle_(handle), name_(name), parent_(parent) {
92 }
93
94 Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent) : parent_(parent) {
95 }
96
97 Bundle::KeyInfo::KeyInfo(const KeyInfo& k)
98     : impl_(new Impl(this)) {
99   impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
100   impl_->name_ = k.impl_->name_;
101 }
102
103 Bundle::KeyInfo& Bundle::KeyInfo::operator = (const Bundle::KeyInfo& k) {
104   if (this != &k) {
105     impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
106     impl_->name_ = k.impl_->name_;
107   }
108   return *this;
109 }
110
111 Bundle::KeyInfo::KeyInfo(Bundle::KeyInfo&& k) noexcept {
112   impl_ = std::unique_ptr<Impl>(new Impl(this));
113   impl_->handle_ = k.impl_->handle_;
114   impl_->name_ = k.impl_->name_;
115   k.impl_->handle_ = nullptr;
116   k.impl_->name_ = "";
117 }
118
119 Bundle::KeyInfo& Bundle::KeyInfo::operator = (Bundle::KeyInfo&& k) noexcept {
120   if (this != &k) {
121     impl_->handle_ = k.impl_->handle_;
122     impl_->name_ = k.impl_->name_;
123     k.impl_->handle_ = nullptr;
124     k.impl_->name_ = "";
125   }
126   return *this;
127 }
128
129 bundle_type Bundle::KeyInfo::GetType() const {
130   return static_cast<bundle_type>(
131       bundle_keyval_get_type(const_cast<bundle_keyval_t*>(impl_->handle_)));
132 }
133
134 bool Bundle::KeyInfo::IsArray() const {
135   return bundle_keyval_type_is_array(const_cast<bundle_keyval_t*>(
136       impl_->handle_));
137 }
138
139 const std::string& Bundle::KeyInfo::GetName() const {
140   return impl_->name_;
141 }
142
143 Bundle& Bundle::operator = (const Bundle& b) {
144   if (this != &b) {
145     impl_->handle_ = bundle_dup(b.impl_->handle_);
146   }
147   return *this;
148 }
149
150 Bundle::Bundle(Bundle&& b) noexcept {
151   impl_ = std::unique_ptr<Impl>(new Impl(this));
152   impl_->handle_ = b.impl_->handle_;
153   b.impl_->handle_ = nullptr;
154 }
155
156 Bundle& Bundle::operator = (Bundle&& b) noexcept {
157   if (this != &b) {
158     impl_->handle_ = b.impl_->handle_;
159     b.impl_->handle_ = nullptr;
160   }
161   return *this;
162 }
163
164 std::vector<Bundle::KeyInfo> Bundle::GetKeys() {
165   std::vector<Bundle::KeyInfo> v;
166
167   bundle_foreach(impl_->handle_, [](const char *key, const int type,
168       const bundle_keyval_t *kv, void *user_data) {
169         auto* v = static_cast<std::vector<KeyInfo>*>(user_data);
170         v->emplace_back(kv, key);
171       }, &v);
172
173   return v;
174 }
175
176 int Bundle::Add(const std::string& key, const std::string& val) {
177   return bundle_add_str(impl_->handle_, key.c_str(), val.c_str());
178 }
179
180 int Bundle::Add(const std::string& key, const std::vector<std::string>& val) {
181   std::vector<const char*> v;
182   for (auto& i : val) {
183     v.push_back(i.c_str());
184   }
185
186   return bundle_add_str_array(impl_->handle_, key.c_str(), v.data(), v.size());
187 }
188
189 int Bundle::Add(const std::string& key, const std::vector<unsigned char>& val) {
190   return bundle_add_byte(impl_->handle_, key.c_str(), val.data(), val.size());
191 }
192
193 int Bundle::Delete(const std::string& key) {
194   return bundle_del(impl_->handle_, key.c_str());
195 }
196
197 std::string Bundle::GetString(const std::string& key) const {
198   char* str = nullptr;
199   bundle_get_str(impl_->handle_, key.c_str(), &str);
200
201   if (!str)
202     return "";
203
204   return std::string(str);
205 }
206
207 std::vector<std::string> Bundle::GetStringArray(const std::string& key) const {
208   std::vector<std::string> v;
209
210   const char** str_array = nullptr;
211   int len = 0;
212
213   str_array = bundle_get_str_array(impl_->handle_, key.c_str(), &len);
214
215   for (int i = 0; i < len; i++) {
216     v.emplace_back(str_array[i]);
217   }
218
219   return v;
220 }
221
222 std::vector<unsigned char> Bundle::GetByte(const std::string& key) const {
223   size_t size;
224   unsigned char* bytes = nullptr;
225   bundle_get_byte(impl_->handle_, key.c_str(),
226       reinterpret_cast<void**>(&bytes), &size);
227   return std::vector<unsigned char>(bytes, bytes + size);
228 }
229
230 Bundle::BundleRaw Bundle::ToRaw() {
231   bundle_raw* raw = nullptr;
232   int len = 0;
233   bundle_encode(impl_->handle_, &raw, &len);
234
235   return BundleRaw(
236       std::unique_ptr<bundle_raw, decltype(std::free)*>(raw, std::free), len);
237 }
238
239 int Bundle::GetCount() const {
240   return bundle_get_count(impl_->handle_);
241 }
242
243 bundle_type Bundle::GetType(const std::string& key) const {
244   return static_cast<bundle_type>(bundle_get_type(impl_->handle_, key.c_str()));
245 }
246
247 bundle* Bundle::GetHandle() const {
248   return impl_->handle_;
249 }
250
251 bundle* Bundle::Detach() {
252   auto* h = impl_->handle_;
253   impl_->handle_ = nullptr;
254   return h;
255 }
256
257 }  // namespace tizen_base