2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
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.
20 #include "include/bundle.h"
21 #include "include/bundle_internal.h"
23 #include "bundle-internal.h"
24 #include "exception-internal.h"
25 #include "export-api-internal.h"
26 #include "json-internal.h"
28 using namespace tizen_base::internal;
30 extern "C" EXPORT_API bundle* bundle_create(void) {
31 auto* h = new (std::nothrow) Bundle();
33 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
37 set_last_result(BUNDLE_ERROR_NONE);
38 return reinterpret_cast<bundle*>(h);
41 extern "C" EXPORT_API int bundle_free(bundle* b) {
43 return BUNDLE_ERROR_INVALID_PARAMETER;
45 auto* h = reinterpret_cast<Bundle*>(b);
47 return BUNDLE_ERROR_NONE;
50 extern "C" EXPORT_API int bundle_add_str(bundle* b,
51 const char* key, const char* str) {
52 if (b == nullptr || key == nullptr || strlen(key) == 0 || str == nullptr)
53 return BUNDLE_ERROR_INVALID_PARAMETER;
55 auto* h = reinterpret_cast<Bundle*>(b);
56 std::vector<unsigned char> value(str, str + (strlen(str) + 1));
60 key_info = new KeyInfo(BUNDLE_TYPE_STR, key, value);
61 } catch (Exception& e) {
62 return e.GetErrorCode();
63 } catch (const std::bad_alloc& ba) {
64 return BUNDLE_ERROR_OUT_OF_MEMORY;
68 h->Add(std::shared_ptr<KeyInfo>(key_info));
69 } catch (Exception& e) {
70 return e.GetErrorCode();
73 return BUNDLE_ERROR_NONE;
76 extern "C" EXPORT_API int bundle_get_str(bundle* b,
77 const char* key, char** str) {
78 if (b == nullptr || key == nullptr)
79 return BUNDLE_ERROR_INVALID_PARAMETER;
81 auto* h = reinterpret_cast<Bundle*>(b);
82 std::shared_ptr<KeyInfo> key_info;
84 key_info = h->Get(key);
85 } catch (Exception& e) {
86 return e.GetErrorCode();
89 if (key_info->GetType() != BUNDLE_TYPE_STR)
90 return BUNDLE_ERROR_INVALID_PARAMETER;
93 auto& values = key_info->GetValues();
94 auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
95 *str = reinterpret_cast<char*>(&value[0]);
98 return BUNDLE_ERROR_NONE;
101 extern "C" EXPORT_API int bundle_add(bundle* b, const char* key,
103 return bundle_add_str(b, key, val);
106 extern "C" EXPORT_API int bundle_del(bundle* b, const char* key) {
107 if (b == nullptr || key == nullptr || strlen(key) == 0)
108 return BUNDLE_ERROR_INVALID_PARAMETER;
110 auto* h = reinterpret_cast<Bundle*>(b);
113 } catch (Exception& e) {
114 return e.GetErrorCode();
117 return BUNDLE_ERROR_NONE;
120 extern "C" EXPORT_API const char* bundle_get_val(bundle* b, const char* key) {
122 int ret = bundle_get_str(b, key, &val);
123 set_last_result(ret);
127 extern "C" EXPORT_API int bundle_get_count(bundle* b) {
131 auto* h = reinterpret_cast<Bundle*>(b);
132 set_last_result(BUNDLE_ERROR_NONE);
136 extern "C" EXPORT_API void bundle_iterate(bundle* b,
137 bundle_iterate_cb_t callback, void* user_data) {
138 if (b == nullptr || callback == nullptr) {
139 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
143 auto* h = reinterpret_cast<Bundle*>(b);
144 for (const auto& kv : h->GetMap()) {
145 auto& key_info = kv.second;
146 auto& values = key_info->GetValues();
147 auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
148 auto* val = reinterpret_cast<char*>(&value[0]);
149 callback(key_info->GetKey().c_str(), val, user_data);
152 set_last_result(BUNDLE_ERROR_NONE);
155 extern "C" EXPORT_API void bundle_foreach(bundle* b,
156 bundle_iterator_t callback, void* user_data) {
157 if (b == nullptr || callback == nullptr) {
158 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
162 auto* h = reinterpret_cast<Bundle*>(b);
163 for (const auto& kv : h->GetMap()) {
164 auto& key_info = kv.second;
165 callback(key_info->GetKey().c_str(), key_info->GetType(),
166 reinterpret_cast<bundle_keyval_t*>(key_info.get()), user_data);
169 set_last_result(BUNDLE_ERROR_NONE);
172 extern "C" EXPORT_API int bundle_keyval_get_type(bundle_keyval_t* kv) {
174 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
178 auto* key_info = reinterpret_cast<KeyInfo*>(kv);
179 set_last_result(BUNDLE_ERROR_NONE);
180 return key_info->GetType();
183 extern "C" EXPORT_API int bundle_keyval_type_is_array(bundle_keyval_t* kv) {
184 int type = bundle_keyval_get_type(kv);
188 set_last_result(BUNDLE_ERROR_NONE);
189 if (type & BUNDLE_TYPE_ARRAY)
195 extern "C" EXPORT_API int bundle_keyval_type_is_measurable(
196 bundle_keyval_t* kv) {
197 int type = bundle_keyval_get_type(kv);
201 set_last_result(BUNDLE_ERROR_NONE);
202 if (type & BUNDLE_TYPE_MEASURABLE)
208 extern "C" EXPORT_API int bundle_keyval_get_basic_val(bundle_keyval_t* kv,
209 void** val, size_t* size) {
211 return BUNDLE_ERROR_INVALID_PARAMETER;
213 auto* key_info = reinterpret_cast<KeyInfo*>(kv);
214 if (key_info->IsArray())
215 return BUNDLE_ERROR_INVALID_PARAMETER;
218 auto& values = key_info->GetValues();
219 auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
220 *val = reinterpret_cast<void*>(&value[0]);
224 auto& values_size = key_info->GetValuesSize();
225 *size = reinterpret_cast<size_t>(values_size[0]);
228 return BUNDLE_ERROR_NONE;
231 extern "C" EXPORT_API int bundle_keyval_get_array_val(bundle_keyval_t* kv,
232 void*** array_val, unsigned int* array_len, size_t** array_item_size) {
234 return BUNDLE_ERROR_INVALID_PARAMETER;
236 auto* key_info = reinterpret_cast<KeyInfo*>(kv);
237 if (!key_info->IsArray())
238 return BUNDLE_ERROR_INVALID_PARAMETER;
240 auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
241 key_info->GetValues());
244 *array_val = reinterpret_cast<void**>(&values[0]);
247 *array_len = static_cast<unsigned int>(values.size());
249 if (array_item_size) {
250 auto& values_size = const_cast<std::vector<std::size_t>&>(
251 key_info->GetValuesSize());
252 *array_item_size = reinterpret_cast<size_t*>(&values_size[0]);
255 return BUNDLE_ERROR_NONE;
258 extern "C" EXPORT_API bundle_keyval_t* bundle_keyval_dup(
259 const bundle_keyval_t* kv) {
261 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
265 auto* keyval = const_cast<bundle_keyval_t*>(kv);
266 auto* key_info = reinterpret_cast<KeyInfo*>(keyval);
270 k = new KeyInfo(*key_info);
271 } catch (Exception& e) {
272 set_last_result(e.GetErrorCode());
274 } catch (const std::bad_alloc& ba) {
275 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
279 set_last_result(BUNDLE_ERROR_NONE);
280 return reinterpret_cast<bundle_keyval_t*>(k);
283 extern "C" EXPORT_API int bundle_keyval_free(bundle_keyval_t* kv) {
285 return BUNDLE_ERROR_INVALID_PARAMETER;
287 auto* key_info = reinterpret_cast<KeyInfo*>(kv);
289 return BUNDLE_ERROR_NONE;
292 extern "C" EXPORT_API bundle* bundle_dup(bundle* b_from) {
293 if (b_from == nullptr) {
294 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
298 auto* h = reinterpret_cast<Bundle*>(b_from);
299 auto* b = new (std::nothrow) Bundle(*h);
301 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
305 set_last_result(BUNDLE_ERROR_NONE);
306 return reinterpret_cast<bundle*>(b);
309 extern "C" EXPORT_API int bundle_encode(bundle *b, bundle_raw** raw, int* len) {
310 if (b == nullptr || raw == nullptr || len == nullptr)
311 return BUNDLE_ERROR_INVALID_PARAMETER;
313 auto* h = reinterpret_cast<Bundle*>(b);
314 *raw = reinterpret_cast<bundle_raw*>(h->Encode());
315 *len = strlen(reinterpret_cast<char*>(*raw));
316 return BUNDLE_ERROR_NONE;
319 extern "C" EXPORT_API int bundle_free_encoded_rawdata(bundle_raw **r) {
320 if (r == nullptr || *r == nullptr)
321 return BUNDLE_ERROR_INVALID_PARAMETER;
325 return BUNDLE_ERROR_NONE;
328 extern "C" EXPORT_API bundle* bundle_decode(const bundle_raw* r,
329 const int data_size) {
331 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
337 auto* raw = const_cast<bundle_raw*>(r);
338 b = new Bundle(static_cast<unsigned char*>(raw), data_size);
339 } catch (Exception& e) {
340 set_last_result(e.GetErrorCode());
342 } catch (const std::bad_alloc& ba) {
343 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
347 set_last_result(BUNDLE_ERROR_NONE);
348 return reinterpret_cast<bundle*>(b);
351 extern "C" EXPORT_API int bundle_encode_raw(bundle* b, bundle_raw** r,
353 if (b == nullptr || r == nullptr || len == nullptr)
354 return BUNDLE_ERROR_INVALID_PARAMETER;
356 auto* h = reinterpret_cast<Bundle*>(b);
358 *r = reinterpret_cast<bundle_raw*>(h->EncodeRaw(len));
359 } catch (Exception& e) {
360 return e.GetErrorCode();
362 return BUNDLE_ERROR_NONE;
365 extern "C" EXPORT_API bundle* bundle_decode_raw(const bundle_raw* r,
366 const int data_size) {
368 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
374 auto* raw = const_cast<bundle_raw*>(r);
375 b = new Bundle(static_cast<unsigned char*>(raw), data_size, false);
376 } catch (Exception& e) {
377 set_last_result(e.GetErrorCode());
379 } catch (const std::bad_alloc& ba) {
380 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
384 set_last_result(BUNDLE_ERROR_NONE);
385 return reinterpret_cast<bundle*>(b);
388 extern "C" EXPORT_API int bundle_get_type(bundle* b, const char* key) {
389 if (b == nullptr || key == nullptr) {
390 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
391 return BUNDLE_TYPE_NONE;
394 auto* h = reinterpret_cast<Bundle*>(b);
395 std::shared_ptr<KeyInfo> key_info;
397 key_info = h->Get(key);
398 } catch (Exception& e) {
399 set_last_result(e.GetErrorCode());
400 return BUNDLE_TYPE_NONE;
403 set_last_result(BUNDLE_ERROR_NONE);
404 return key_info->GetType();
407 extern "C" EXPORT_API int bundle_add_str_array(bundle* b, const char* key,
408 const char** str_array, const int len) {
409 if (b == nullptr || key == nullptr || strlen(key) == 0)
410 return BUNDLE_ERROR_INVALID_PARAMETER;
412 auto* h = reinterpret_cast<Bundle*>(b);
413 std::vector<std::vector<unsigned char>> values(len);
415 for (int i = 0; i < len; ++i) {
416 std::vector<unsigned char> value(str_array[i],
417 str_array[i] + (strlen(str_array[i]) + 1));
418 values[i] = std::move(value);
424 key_info = new KeyInfo((BUNDLE_TYPE_STR_ARRAY | BUNDLE_TYPE_ARRAY),
426 } catch (Exception& e) {
427 return e.GetErrorCode();
431 h->Add(std::shared_ptr<KeyInfo>(key_info));
432 } catch (Exception& e) {
433 return e.GetErrorCode();
436 return BUNDLE_ERROR_NONE;
439 extern "C" EXPORT_API const char** bundle_get_str_array(bundle* b,
440 const char* key, int* len) {
441 if (b == nullptr || key == nullptr) {
442 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
446 auto* h = reinterpret_cast<Bundle*>(b);
447 std::shared_ptr<KeyInfo> key_info;
449 key_info = h->Get(key);
450 } catch (Exception& e) {
451 set_last_result(e.GetErrorCode());
455 if (key_info->GetType() != BUNDLE_TYPE_STR_ARRAY) {
456 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
460 set_last_result(BUNDLE_ERROR_NONE);
462 auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
463 key_info->GetValues());
466 *len = static_cast<int>(raw_values.size());
468 if (raw_values.size() == 0)
471 auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
472 return const_cast<const char**>(reinterpret_cast<char**>(values));
475 extern "C" EXPORT_API int bundle_add_byte(bundle* b, const char* key,
476 const void* bytes, const size_t size) {
477 if (b == nullptr || key == nullptr || strlen(key) == 0)
478 return BUNDLE_ERROR_INVALID_PARAMETER;
480 auto* h = reinterpret_cast<Bundle*>(b);
481 auto* p = reinterpret_cast<const unsigned char*>(bytes);
482 std::vector<unsigned char> value;
484 std::copy(p, p + size, std::back_inserter(value));
488 key_info = new KeyInfo(BUNDLE_TYPE_BYTE, key, value);
489 } catch (Exception& e) {
490 return e.GetErrorCode();
491 } catch (const std::bad_alloc& ba) {
492 return BUNDLE_ERROR_OUT_OF_MEMORY;
496 h->Add(std::shared_ptr<KeyInfo>(key_info));
497 } catch (Exception& e) {
498 return e.GetErrorCode();
501 return BUNDLE_ERROR_NONE;
504 extern "C" EXPORT_API int bundle_get_byte(bundle* b, const char* key,
505 void** bytes, size_t* size) {
506 if (b == nullptr || key == nullptr)
507 return BUNDLE_ERROR_INVALID_PARAMETER;
509 auto* h = reinterpret_cast<Bundle*>(b);
510 std::shared_ptr<KeyInfo> key_info;
512 key_info = h->Get(key);
513 } catch (Exception& e) {
514 return e.GetErrorCode();
517 if (key_info->GetType() != BUNDLE_TYPE_BYTE)
518 return BUNDLE_ERROR_INVALID_PARAMETER;
521 auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
522 key_info->GetValues());
523 if (values.size() == 0) {
526 auto& value = values[0];
527 *bytes = reinterpret_cast<void*>(&value[0]);
532 auto& values_size = key_info->GetValuesSize();
533 *size = reinterpret_cast<size_t>(values_size[0]);
536 return BUNDLE_ERROR_NONE;
539 extern "C" EXPORT_API int bundle_export_to_argv(bundle* b, char*** argv) {
540 if (b == nullptr || argv == nullptr) {
541 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
545 auto* h = reinterpret_cast<Bundle*>(b);
546 std::vector<std::string> exported_vt;
548 exported_vt = h->Export();
549 } catch (Exception& e) {
550 set_last_result(e.GetErrorCode());
554 int argc = exported_vt.size();
555 auto** exported_argv = reinterpret_cast<char**>(
556 calloc(argc + 1, sizeof(char*)));
557 if (exported_argv == nullptr) {
558 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
562 exported_argv[1] = const_cast<char*>(TAG_IMPORT_EXPORT_CHECK);
563 for (unsigned int idx = 2; idx < exported_vt.size(); idx += 2) {
564 exported_argv[idx] = strdup(exported_vt[idx].c_str());
565 if (exported_argv[idx] == nullptr) {
566 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
567 bundle_free_exported_argv(idx + 1, &exported_argv);
571 exported_argv[idx + 1] = strdup(exported_vt[idx + 1].c_str());
572 if (exported_argv[idx + 1] == nullptr) {
573 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
574 bundle_free_exported_argv(idx + 2, &exported_argv);
579 *argv = exported_argv;
580 set_last_result(BUNDLE_ERROR_NONE);
584 extern "C" EXPORT_API int bundle_free_exported_argv(int argc, char*** argv) {
585 if (argc < 2 || !argv || !*argv)
586 return BUNDLE_ERROR_INVALID_PARAMETER;
588 for (int i = 2; i < argc; i++)
589 std::free((*argv)[i]);
594 return BUNDLE_ERROR_NONE;
597 extern "C" EXPORT_API bundle* bundle_import_from_argv(int argc, char** argv) {
598 if (argv == nullptr) {
599 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
605 b = new (std::nothrow) Bundle(argc, argv);
606 } catch (Exception& e) {
607 set_last_result(e.GetErrorCode());
611 set_last_result(BUNDLE_ERROR_NONE);
612 return reinterpret_cast<bundle*>(b);
615 extern "C" EXPORT_API int bundle_compare(bundle* b1, bundle* b2) {
616 if (b1 == nullptr || b2 == nullptr)
619 auto* h1 = reinterpret_cast<Bundle*>(b1);
620 auto* h2 = reinterpret_cast<Bundle*>(b2);
627 extern "C" EXPORT_API int bundle_set_str_array_element(bundle* b,
628 const char* key, const unsigned int idx, const char* val) {
629 if (b == nullptr || key == nullptr || val == nullptr)
630 return BUNDLE_ERROR_INVALID_PARAMETER;
632 auto len = strlen(val) + 1;
633 auto* p = reinterpret_cast<unsigned char*>(const_cast<char*>(val));
634 std::vector<unsigned char> value(p, p + len);
636 auto* h = reinterpret_cast<Bundle*>(b);
638 h->Set(key, idx, value);
639 } catch (Exception& e) {
640 return e.GetErrorCode();
643 return BUNDLE_ERROR_NONE;
646 extern "C" EXPORT_API int bundle_add_byte_array(bundle* b,
647 const char* key, const unsigned int len) {
648 return bundle_init_byte_array(b, key, len);
651 extern "C" EXPORT_API int bundle_init_byte_array(bundle* b,
652 const char* key, const unsigned int len) {
653 if (b == nullptr || key == nullptr || strlen(key) == 0)
654 return BUNDLE_ERROR_INVALID_PARAMETER;
656 auto* h = reinterpret_cast<Bundle*>(b);
660 std::vector<std::vector<unsigned char>> values(len);
661 key_info = new KeyInfo(Bundle::Type::ByteArray, key, std::move(values));
662 } catch (Exception& e) {
663 return e.GetErrorCode();
664 } catch (const std::bad_alloc& ba) {
665 return BUNDLE_ERROR_OUT_OF_MEMORY;
666 } catch (const std::length_error&) {
667 return BUNDLE_ERROR_OUT_OF_MEMORY;
671 h->Add(std::shared_ptr<KeyInfo>(key_info));
672 } catch (Exception& e) {
673 return e.GetErrorCode();
676 return BUNDLE_ERROR_NONE;
679 extern "C" EXPORT_API int bundle_get_byte_array(bundle* b,
680 const char* key, void*** bytes_array, unsigned int* len,
681 unsigned int** array_element_size) {
682 if (b == nullptr || key == nullptr)
683 return BUNDLE_ERROR_INVALID_PARAMETER;
685 auto* h = reinterpret_cast<Bundle*>(b);
686 std::shared_ptr<KeyInfo> key_info;
688 key_info = h->Get(key);
689 } catch (Exception& e) {
690 return e.GetErrorCode();
693 if (key_info->GetType() != BUNDLE_TYPE_BYTE_ARRAY)
694 return BUNDLE_ERROR_INVALID_PARAMETER;
696 auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
697 key_info->GetValues());
700 auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
701 *bytes_array = reinterpret_cast<void**>(values);
705 *len = static_cast<unsigned int>(raw_values.size());
707 if (array_element_size) {
708 auto& raw_values_size = const_cast<std::vector<unsigned int>&>(
709 key_info->GetUValuesSize());
710 *array_element_size = reinterpret_cast<unsigned int*>(&raw_values_size[0]);
713 return BUNDLE_ERROR_NONE;
716 extern "C" EXPORT_API int bundle_set_byte_array_element(bundle* b,
717 const char* key, const unsigned int idx,
718 const void* bytes, const size_t size) {
719 if (b == nullptr || key == nullptr || size <= 0)
720 return BUNDLE_ERROR_INVALID_PARAMETER;
722 std::vector<unsigned char> value;
724 auto* p = reinterpret_cast<unsigned char*>(const_cast<void*>(bytes));
725 std::copy(p, p + size, std::back_inserter(value));
728 auto* h = reinterpret_cast<Bundle*>(b);
730 h->Set(key, idx, value);
731 } catch (Exception& e) {
732 return e.GetErrorCode();
735 return BUNDLE_ERROR_NONE;
738 extern "C" EXPORT_API int bundle_to_json(bundle* b, char** json) {
739 if (b == nullptr || json == nullptr)
740 return BUNDLE_ERROR_INVALID_PARAMETER;
742 auto* h = reinterpret_cast<Bundle*>(b);
745 *json = strdup(js.ToString().c_str());
746 } catch (Exception& e) {
747 return e.GetErrorCode();
750 return BUNDLE_ERROR_NONE;
753 extern "C" EXPORT_API int bundle_from_json(const char* json, bundle** b) {
754 if (json == nullptr || b == nullptr)
755 return BUNDLE_ERROR_INVALID_PARAMETER;
759 *b = reinterpret_cast<bundle*>(js.ToBundle());
760 } catch (Exception& e) {
761 return e.GetErrorCode();
764 return BUNDLE_ERROR_NONE;