2 * Copyright (c) 2019 - 2020 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "bundle_cpp.h"
20 #include "bundle_cpp_implementation.h"
21 #include "bundle_internal.h"
22 #include "log-private.h"
24 namespace tizen_base {
25 Bundle::Impl::Impl(Bundle* parent, bool copy, bool own)
26 : copy_(copy), own_(own), parent_(parent) {
29 Bundle::Impl::Impl(Bundle* parent) : parent_(parent) {
32 Bundle::Impl::~Impl() = default;
35 : impl_(new Impl(this)) {
36 impl_->handle_ = bundle_create();
37 if (impl_->handle_ == nullptr)
38 throw std::bad_alloc();
41 Bundle::Bundle(BundleRaw raw, bool base64)
42 : impl_(new Impl(this)) {
44 impl_->handle_ = bundle_decode(raw.first.get(), raw.second);
46 impl_->handle_ = bundle_decode_raw(raw.first.get(), raw.second);
47 if (impl_->handle_ == nullptr)
48 throw std::bad_alloc();
51 Bundle::Bundle(const std::string& raw)
52 : impl_(new Impl(this)) {
53 impl_->handle_ = bundle_decode(reinterpret_cast<const bundle_raw*>(
54 raw.c_str()), raw.length());
55 if (impl_->handle_ == nullptr)
56 throw std::bad_alloc();
59 Bundle::Bundle(bundle* b, bool copy, bool own)
60 : impl_(new Impl(this, copy, own)) {
62 throw std::invalid_argument("b cannot be null");
67 impl_->handle_ = bundle_dup(b);
68 if (impl_->handle_ == nullptr)
69 throw std::bad_alloc();
74 if (impl_ && impl_->handle_ && (impl_->own_ || impl_->copy_))
75 bundle_free(impl_->handle_);
78 Bundle::Bundle(const Bundle& b)
79 : impl_(new Impl(this)) {
80 impl_->handle_ = bundle_dup(b.impl_->handle_);
81 if (impl_->handle_ == nullptr)
82 throw std::bad_alloc();
85 Bundle::KeyInfo::KeyInfo(const bundle_keyval_t* handle, std::string name,
87 : impl_(new Impl(this, handle, std::move(name), own)) {
90 Bundle::KeyInfo::~KeyInfo() {
91 if (impl_ && impl_->handle_ && impl_->own_)
92 bundle_keyval_free(const_cast<bundle_keyval_t*>(impl_->handle_));
95 Bundle::KeyInfo::Impl::~Impl() = default;
97 Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent,
98 const bundle_keyval_t* handle,
101 : handle_(handle), name_(name), parent_(parent), own_(own) {
104 Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent) : parent_(parent) {
107 Bundle::KeyInfo::KeyInfo(const KeyInfo& k)
108 : impl_(new Impl(this)) {
109 impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
110 impl_->name_ = k.impl_->name_;
111 if (impl_->handle_ == nullptr)
112 throw std::bad_alloc();
115 Bundle::KeyInfo& Bundle::KeyInfo::operator = (const Bundle::KeyInfo& k) {
117 if (impl_->handle_ && impl_->own_)
118 bundle_keyval_free(const_cast<bundle_keyval_t*>(impl_->handle_));
120 impl_->handle_ = bundle_keyval_dup(k.impl_->handle_);
121 impl_->name_ = k.impl_->name_;
122 if (impl_->handle_ == nullptr)
123 throw std::bad_alloc();
130 Bundle::KeyInfo::KeyInfo(Bundle::KeyInfo&& k) noexcept {
131 impl_ = std::move(k.impl_);
132 impl_->parent_ = this;
135 Bundle::KeyInfo& Bundle::KeyInfo::operator = (Bundle::KeyInfo&& k) noexcept {
137 if (impl_->handle_ && impl_->own_)
138 bundle_keyval_free(const_cast<bundle_keyval_t*>(impl_->handle_));
140 impl_->handle_ = k.impl_->handle_;
141 impl_->name_ = k.impl_->name_;
142 impl_->own_ = k.impl_->own_;
143 k.impl_->handle_ = nullptr;
145 k.impl_->own_ = false;
150 bundle_type Bundle::KeyInfo::GetType() const {
151 return static_cast<bundle_type>(
152 bundle_keyval_get_type(const_cast<bundle_keyval_t*>(impl_->handle_)));
155 bool Bundle::KeyInfo::IsArray() const {
156 return bundle_keyval_type_is_array(const_cast<bundle_keyval_t*>(
160 const std::string& Bundle::KeyInfo::GetName() const {
164 Bundle& Bundle::operator = (const Bundle& b) {
166 if (impl_->handle_ && (impl_->own_ || impl_->copy_))
167 bundle_free(impl_->handle_);
169 impl_->handle_ = bundle_dup(b.impl_->handle_);
170 if (impl_->handle_ == nullptr)
171 throw std::bad_alloc();
179 Bundle::Bundle(Bundle&& b) noexcept {
180 impl_ = std::move(b.impl_);
181 impl_->parent_ = this;
184 Bundle& Bundle::operator = (Bundle&& b) noexcept {
186 if (impl_->handle_ && (impl_->own_ || impl_->copy_))
187 bundle_free(impl_->handle_);
189 impl_->handle_ = b.impl_->handle_;
190 b.impl_->handle_ = nullptr;
191 impl_->own_ = b.impl_->own_;
192 b.impl_->own_ = false;
193 impl_->copy_ = b.impl_->copy_;
194 b.impl_->copy_ = false;
199 bool Bundle::IsEmpty() const noexcept {
200 return (bundle_get_count(impl_->handle_) == 0) ? true : false;
203 std::vector<Bundle::KeyInfo> Bundle::GetKeys() {
204 std::vector<Bundle::KeyInfo> v;
206 bundle_foreach(impl_->handle_, [](const char *key, const int type,
207 const bundle_keyval_t *kv, void *user_data) {
208 auto* v = static_cast<std::vector<KeyInfo>*>(user_data);
209 v->emplace_back(kv, key, false);
215 int Bundle::Add(const std::string& key, const std::string& val) {
216 int ret = bundle_add_str(impl_->handle_, key.c_str(), val.c_str());
217 if (ret != BUNDLE_ERROR_NONE)
218 LOGE("Add fail key(%s), val(%s), ret(%d)", key.c_str(), val.c_str(), ret);
222 int Bundle::Add(const std::string& key, const std::vector<std::string>& val) {
223 std::vector<const char*> v;
224 for (auto& i : val) {
225 v.push_back(i.c_str());
228 int ret = bundle_add_str_array(
229 impl_->handle_, key.c_str(), v.data(), v.size());
230 if (ret != BUNDLE_ERROR_NONE)
231 LOGE("Add fail key(%s), ret(%d)", key.c_str(), ret);
236 int Bundle::Add(const std::string& key, const std::vector<unsigned char>& val) {
237 int ret = bundle_add_byte(impl_->handle_, key.c_str(), val.data(), val.size());
238 if (ret != BUNDLE_ERROR_NONE)
239 LOGE("Add fail key(%s), ret(%d)", key.c_str(), ret);
243 int Bundle::Delete(const std::string& key) {
244 int ret = bundle_del(impl_->handle_, key.c_str());
245 if (ret != BUNDLE_ERROR_NONE)
246 LOGE("Delete fail key(%s), ret(%d)", key.c_str(), ret);
250 std::string Bundle::GetString(const std::string& key) const {
252 bundle_get_str(impl_->handle_, key.c_str(), &str);
257 return std::string(str);
260 std::vector<std::string> Bundle::GetStringArray(const std::string& key) const {
261 std::vector<std::string> v;
263 const char** str_array = nullptr;
266 str_array = bundle_get_str_array(impl_->handle_, key.c_str(), &len);
268 for (int i = 0; i < len; i++) {
269 v.emplace_back(str_array[i]);
275 std::vector<unsigned char> Bundle::GetByte(const std::string& key) const {
277 unsigned char* bytes = nullptr;
278 int ret = bundle_get_byte(impl_->handle_, key.c_str(),
279 reinterpret_cast<void**>(&bytes), &size);
280 if (ret != BUNDLE_ERROR_NONE) {
281 LOGE("bundle_get_byte() is failed");
285 return std::vector<unsigned char>(bytes, bytes + size);
288 Bundle::BundleRaw Bundle::ToRaw(bool base64) {
289 bundle_raw* raw = nullptr;
293 ret = bundle_encode(impl_->handle_, &raw, &len);
295 ret = bundle_encode_raw(impl_->handle_, &raw, &len);
296 if (raw == nullptr) {
297 LOGE("Fail to encode data (%d)", ret);
298 throw std::bad_alloc();
302 std::unique_ptr<bundle_raw, decltype(std::free)*>(raw, std::free), len);
305 int Bundle::GetCount() const {
306 return bundle_get_count(impl_->handle_);
309 bundle_type Bundle::GetType(const std::string& key) const {
310 return static_cast<bundle_type>(bundle_get_type(impl_->handle_, key.c_str()));
313 bundle* Bundle::GetHandle() const {
314 return impl_->handle_;
317 bundle* Bundle::Detach() {
318 auto* h = impl_->handle_;
319 impl_->handle_ = nullptr;
323 } // namespace tizen_base