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.
22 #include "include/bundle.h"
23 #include "include/bundle_internal.h"
25 #include "bundle-internal.h"
26 #include "exception-internal.h"
27 #include "export-api-internal.h"
28 #include "json-internal.h"
30 using namespace tizen_base::internal;
32 extern "C" EXPORT_API bundle* bundle_create(void) {
33 auto* h = new (std::nothrow) Bundle();
35 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
39 set_last_result(BUNDLE_ERROR_NONE);
40 return reinterpret_cast<bundle*>(h);
43 extern "C" EXPORT_API int bundle_free(bundle* b) {
45 return BUNDLE_ERROR_INVALID_PARAMETER;
47 auto* h = reinterpret_cast<Bundle*>(b);
49 return BUNDLE_ERROR_NONE;
52 extern "C" EXPORT_API int bundle_add_str(bundle* b,
53 const char* key, const char* str) {
54 if (b == nullptr || key == nullptr || strlen(key) == 0 || str == nullptr)
55 return BUNDLE_ERROR_INVALID_PARAMETER;
57 auto* h = reinterpret_cast<Bundle*>(b);
58 std::vector<unsigned char> value(str, str + (strlen(str) + 1));
62 key_info = new KeyInfo(BUNDLE_TYPE_STR, key, std::move(value));
63 } catch (const Exception& e) {
64 return e.GetErrorCode();
65 } catch (const std::bad_alloc& ba) {
66 return BUNDLE_ERROR_OUT_OF_MEMORY;
70 h->Add(std::shared_ptr<KeyInfo>(key_info));
71 } catch (const Exception& e) {
72 return e.GetErrorCode();
75 return BUNDLE_ERROR_NONE;
78 extern "C" EXPORT_API int bundle_get_str(bundle* b,
79 const char* key, char** str) {
80 if (b == nullptr || key == nullptr)
81 return BUNDLE_ERROR_INVALID_PARAMETER;
83 auto* h = reinterpret_cast<Bundle*>(b);
84 std::shared_ptr<KeyInfo> key_info;
86 key_info = h->Get(key);
87 } catch (const Exception& e) {
88 return e.GetErrorCode();
91 if (key_info->GetType() != BUNDLE_TYPE_STR)
92 return BUNDLE_ERROR_INVALID_PARAMETER;
95 auto& values = key_info->GetValues();
96 auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
97 *str = reinterpret_cast<char*>(&value[0]);
100 return BUNDLE_ERROR_NONE;
103 extern "C" EXPORT_API int bundle_add(bundle* b, const char* key,
105 return bundle_add_str(b, key, val);
108 extern "C" EXPORT_API int bundle_del(bundle* b, const char* key) {
109 if (b == nullptr || key == nullptr || strlen(key) == 0)
110 return BUNDLE_ERROR_INVALID_PARAMETER;
112 auto* h = reinterpret_cast<Bundle*>(b);
115 } catch (const Exception& e) {
116 return e.GetErrorCode();
119 return BUNDLE_ERROR_NONE;
122 extern "C" EXPORT_API const char* bundle_get_val(bundle* b, const char* key) {
124 int ret = bundle_get_str(b, key, &val);
125 set_last_result(ret);
129 extern "C" EXPORT_API int bundle_get_count(bundle* b) {
133 auto* h = reinterpret_cast<Bundle*>(b);
134 set_last_result(BUNDLE_ERROR_NONE);
138 extern "C" EXPORT_API void bundle_iterate(bundle* b,
139 bundle_iterate_cb_t callback, void* user_data) {
140 if (b == nullptr || callback == nullptr) {
141 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
145 auto* h = reinterpret_cast<Bundle*>(b);
146 for (const auto& [key, key_info] : h->GetMap()) {
147 auto& values = key_info->GetValues();
148 auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
149 auto* val = reinterpret_cast<char*>(&value[0]);
150 callback(key_info->GetKey().c_str(), val, user_data);
153 set_last_result(BUNDLE_ERROR_NONE);
156 extern "C" EXPORT_API void bundle_foreach(bundle* b,
157 bundle_iterator_t callback, void* user_data) {
158 if (b == nullptr || callback == nullptr) {
159 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
163 auto* h = reinterpret_cast<Bundle*>(b);
164 auto it = h->GetMap().begin();
165 while (it != h->GetMap().end()) {
166 auto& key_info = it->second;
168 callback(key_info->GetKey().c_str(), key_info->GetType(),
169 reinterpret_cast<bundle_keyval_t*>(key_info.get()), user_data);
172 set_last_result(BUNDLE_ERROR_NONE);
175 extern "C" EXPORT_API int bundle_keyval_get_type(bundle_keyval_t* kv) {
177 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
181 auto* key_info = reinterpret_cast<KeyInfo*>(kv);
182 set_last_result(BUNDLE_ERROR_NONE);
183 return key_info->GetType();
186 extern "C" EXPORT_API int bundle_keyval_type_is_array(bundle_keyval_t* kv) {
187 int type = bundle_keyval_get_type(kv);
191 set_last_result(BUNDLE_ERROR_NONE);
192 if (type & BUNDLE_TYPE_ARRAY)
198 extern "C" EXPORT_API int bundle_keyval_type_is_measurable(
199 bundle_keyval_t* kv) {
200 int type = bundle_keyval_get_type(kv);
204 set_last_result(BUNDLE_ERROR_NONE);
205 if (type & BUNDLE_TYPE_MEASURABLE)
211 extern "C" EXPORT_API int bundle_keyval_get_basic_val(bundle_keyval_t* kv,
212 void** val, size_t* size) {
214 return BUNDLE_ERROR_INVALID_PARAMETER;
216 auto* key_info = reinterpret_cast<KeyInfo*>(kv);
217 if (key_info->IsArray())
218 return BUNDLE_ERROR_INVALID_PARAMETER;
221 auto& values = key_info->GetValues();
222 auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
223 *val = reinterpret_cast<void*>(&value[0]);
227 auto& values_size = key_info->GetValuesSize();
228 *size = reinterpret_cast<size_t>(values_size[0]);
231 return BUNDLE_ERROR_NONE;
234 extern "C" EXPORT_API int bundle_keyval_get_array_val(bundle_keyval_t* kv,
235 void*** array_val, unsigned int* array_len, size_t** array_item_size) {
237 return BUNDLE_ERROR_INVALID_PARAMETER;
239 auto* key_info = reinterpret_cast<KeyInfo*>(kv);
240 if (!key_info->IsArray())
241 return BUNDLE_ERROR_INVALID_PARAMETER;
243 auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
244 key_info->GetValues());
247 *array_val = reinterpret_cast<void**>(&values[0]);
250 *array_len = static_cast<unsigned int>(values.size());
252 if (array_item_size) {
253 auto& values_size = const_cast<std::vector<std::size_t>&>(
254 key_info->GetValuesSize());
255 *array_item_size = reinterpret_cast<size_t*>(&values_size[0]);
258 return BUNDLE_ERROR_NONE;
261 extern "C" EXPORT_API bundle_keyval_t* bundle_keyval_dup(
262 const bundle_keyval_t* kv) {
264 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
268 auto* keyval = const_cast<bundle_keyval_t*>(kv);
269 auto* key_info = reinterpret_cast<KeyInfo*>(keyval);
273 k = new KeyInfo(*key_info);
274 } catch (const Exception& e) {
275 set_last_result(e.GetErrorCode());
277 } catch (const std::bad_alloc& ba) {
278 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
282 set_last_result(BUNDLE_ERROR_NONE);
283 return reinterpret_cast<bundle_keyval_t*>(k);
286 extern "C" EXPORT_API int bundle_keyval_free(bundle_keyval_t* kv) {
288 return BUNDLE_ERROR_INVALID_PARAMETER;
290 auto* key_info = reinterpret_cast<KeyInfo*>(kv);
292 return BUNDLE_ERROR_NONE;
295 extern "C" EXPORT_API bundle* bundle_dup(bundle* b_from) {
296 if (b_from == nullptr) {
297 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
301 auto* h = reinterpret_cast<Bundle*>(b_from);
302 auto* b = new (std::nothrow) Bundle(*h);
304 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
308 set_last_result(BUNDLE_ERROR_NONE);
309 return reinterpret_cast<bundle*>(b);
312 extern "C" EXPORT_API int bundle_encode(bundle *b, bundle_raw** raw, int* len) {
313 if (b == nullptr || raw == nullptr || len == nullptr)
314 return BUNDLE_ERROR_INVALID_PARAMETER;
316 auto* h = reinterpret_cast<Bundle*>(b);
318 *raw = reinterpret_cast<bundle_raw*>(h->Encode());
319 } catch (const Exception& e) {
321 return e.GetErrorCode();
324 *len = strlen(reinterpret_cast<char*>(*raw));
325 return BUNDLE_ERROR_NONE;
328 extern "C" EXPORT_API int bundle_free_encoded_rawdata(bundle_raw **r) {
329 if (r == nullptr || *r == nullptr)
330 return BUNDLE_ERROR_INVALID_PARAMETER;
334 return BUNDLE_ERROR_NONE;
337 extern "C" EXPORT_API bundle* bundle_decode(const bundle_raw* r,
338 const int data_size) {
340 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
346 auto* raw = const_cast<bundle_raw*>(r);
347 b = new Bundle(static_cast<unsigned char*>(raw), data_size);
348 } catch (const Exception& e) {
349 set_last_result(e.GetErrorCode());
351 } catch (const std::bad_alloc& ba) {
352 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
356 set_last_result(BUNDLE_ERROR_NONE);
357 return reinterpret_cast<bundle*>(b);
360 extern "C" EXPORT_API int bundle_encode_raw(bundle* b, bundle_raw** r,
362 if (b == nullptr || r == nullptr || len == nullptr)
363 return BUNDLE_ERROR_INVALID_PARAMETER;
365 auto* h = reinterpret_cast<Bundle*>(b);
367 *r = reinterpret_cast<bundle_raw*>(h->EncodeRaw(len));
368 } catch (const Exception& e) {
369 return e.GetErrorCode();
371 return BUNDLE_ERROR_NONE;
374 extern "C" EXPORT_API bundle* bundle_decode_raw(const bundle_raw* r,
375 const int data_size) {
377 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
383 auto* raw = const_cast<bundle_raw*>(r);
384 b = new Bundle(static_cast<unsigned char*>(raw), data_size, false);
385 } catch (const Exception& e) {
386 set_last_result(e.GetErrorCode());
388 } catch (const std::bad_alloc& ba) {
389 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
393 set_last_result(BUNDLE_ERROR_NONE);
394 return reinterpret_cast<bundle*>(b);
397 extern "C" EXPORT_API int bundle_get_type(bundle* b, const char* key) {
398 if (b == nullptr || key == nullptr) {
399 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
400 return BUNDLE_TYPE_NONE;
403 auto* h = reinterpret_cast<Bundle*>(b);
404 std::shared_ptr<KeyInfo> key_info;
406 key_info = h->Get(key);
407 } catch (const Exception& e) {
408 set_last_result(e.GetErrorCode());
409 return BUNDLE_TYPE_NONE;
412 set_last_result(BUNDLE_ERROR_NONE);
413 return key_info->GetType();
416 extern "C" EXPORT_API int bundle_add_str_array(bundle* b, const char* key,
417 const char** str_array, const int len) {
418 if (b == nullptr || key == nullptr || strlen(key) == 0)
419 return BUNDLE_ERROR_INVALID_PARAMETER;
421 auto* h = reinterpret_cast<Bundle*>(b);
422 std::vector<std::vector<unsigned char>> values(len);
424 for (int i = 0; i < len; ++i) {
425 std::vector<unsigned char> value(str_array[i],
426 str_array[i] + (strlen(str_array[i]) + 1));
427 values[i] = std::move(value);
432 auto key_info = std::make_shared<KeyInfo>(
433 (BUNDLE_TYPE_STR_ARRAY | BUNDLE_TYPE_ARRAY), key, values);
434 h->Add(std::move(key_info));
435 } catch (const Exception& e) {
436 return e.GetErrorCode();
437 } catch (const std::bad_alloc& ba) {
438 return BUNDLE_ERROR_OUT_OF_MEMORY;
441 return BUNDLE_ERROR_NONE;
444 extern "C" EXPORT_API const char** bundle_get_str_array(bundle* b,
445 const char* key, int* len) {
446 if (b == nullptr || key == nullptr) {
447 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
451 auto* h = reinterpret_cast<Bundle*>(b);
452 std::shared_ptr<KeyInfo> key_info;
454 key_info = h->Get(key);
455 } catch (const Exception& e) {
456 set_last_result(e.GetErrorCode());
460 if (key_info->GetType() != BUNDLE_TYPE_STR_ARRAY) {
461 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
465 set_last_result(BUNDLE_ERROR_NONE);
467 auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
468 key_info->GetValues());
471 *len = static_cast<int>(raw_values.size());
473 if (raw_values.size() == 0)
476 auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
477 return const_cast<const char**>(reinterpret_cast<char**>(values));
480 extern "C" EXPORT_API int bundle_add_byte(bundle* b, const char* key,
481 const void* bytes, const size_t size) {
482 if (b == nullptr || key == nullptr || strlen(key) == 0)
483 return BUNDLE_ERROR_INVALID_PARAMETER;
485 auto* h = reinterpret_cast<Bundle*>(b);
486 auto* p = reinterpret_cast<const unsigned char*>(bytes);
487 std::vector<unsigned char> value;
489 value.insert(value.end(), p, p + size);
493 key_info = new KeyInfo(BUNDLE_TYPE_BYTE, key, std::move(value));
494 } catch (const Exception& e) {
495 return e.GetErrorCode();
496 } catch (const std::bad_alloc& ba) {
497 return BUNDLE_ERROR_OUT_OF_MEMORY;
501 h->Add(std::shared_ptr<KeyInfo>(key_info));
502 } catch (const Exception& e) {
503 return e.GetErrorCode();
506 return BUNDLE_ERROR_NONE;
509 extern "C" EXPORT_API int bundle_get_byte(bundle* b, const char* key,
510 void** bytes, size_t* size) {
511 if (b == nullptr || key == nullptr)
512 return BUNDLE_ERROR_INVALID_PARAMETER;
514 auto* h = reinterpret_cast<Bundle*>(b);
515 std::shared_ptr<KeyInfo> key_info;
517 key_info = h->Get(key);
518 } catch (const Exception& e) {
519 return e.GetErrorCode();
522 if (key_info->GetType() != BUNDLE_TYPE_BYTE)
523 return BUNDLE_ERROR_INVALID_PARAMETER;
526 auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
527 key_info->GetValues());
528 if (values.size() == 0) {
531 auto& value = values[0];
532 *bytes = reinterpret_cast<void*>(&value[0]);
537 auto& values_size = key_info->GetValuesSize();
538 *size = reinterpret_cast<size_t>(values_size[0]);
541 return BUNDLE_ERROR_NONE;
544 extern "C" EXPORT_API int bundle_export_to_argv(bundle* b, char*** argv) {
545 if (b == nullptr || argv == nullptr) {
546 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
550 auto* h = reinterpret_cast<Bundle*>(b);
551 std::vector<std::string> exported_vt;
553 exported_vt = h->Export();
554 } catch (const Exception& e) {
555 set_last_result(e.GetErrorCode());
559 int argc = exported_vt.size();
560 auto** exported_argv = reinterpret_cast<char**>(
561 calloc(argc + 1, sizeof(char*)));
562 if (exported_argv == nullptr) {
563 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
567 exported_argv[1] = const_cast<char*>(TAG_IMPORT_EXPORT_CHECK);
568 for (unsigned int idx = 2; idx < exported_vt.size(); idx += 2) {
569 exported_argv[idx] = strdup(exported_vt[idx].c_str());
570 if (exported_argv[idx] == nullptr) {
571 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
572 bundle_free_exported_argv(idx + 1, &exported_argv);
576 exported_argv[idx + 1] = strdup(exported_vt[idx + 1].c_str());
577 if (exported_argv[idx + 1] == nullptr) {
578 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
579 bundle_free_exported_argv(idx + 2, &exported_argv);
584 *argv = exported_argv;
585 set_last_result(BUNDLE_ERROR_NONE);
589 extern "C" EXPORT_API int bundle_free_exported_argv(int argc, char*** argv) {
590 if (argc < 2 || !argv || !*argv)
591 return BUNDLE_ERROR_INVALID_PARAMETER;
593 for (int i = 2; i < argc; i++)
594 std::free((*argv)[i]);
599 return BUNDLE_ERROR_NONE;
602 extern "C" EXPORT_API bundle* bundle_import_from_argv(int argc, char** argv) {
603 if (argv == nullptr) {
604 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
610 b = new (std::nothrow) Bundle(argc, argv);
611 } catch (const Exception& e) {
612 set_last_result(e.GetErrorCode());
616 set_last_result(BUNDLE_ERROR_NONE);
617 return reinterpret_cast<bundle*>(b);
620 extern "C" EXPORT_API int bundle_compare(bundle* b1, bundle* b2) {
621 if (b1 == nullptr || b2 == nullptr)
624 auto* h1 = reinterpret_cast<Bundle*>(b1);
625 auto* h2 = reinterpret_cast<Bundle*>(b2);
632 extern "C" EXPORT_API int bundle_set_str_array_element(bundle* b,
633 const char* key, const unsigned int idx, const char* val) {
634 if (b == nullptr || key == nullptr || val == nullptr)
635 return BUNDLE_ERROR_INVALID_PARAMETER;
637 auto len = strlen(val) + 1;
638 auto* p = reinterpret_cast<unsigned char*>(const_cast<char*>(val));
639 std::vector<unsigned char> value(p, p + len);
641 auto* h = reinterpret_cast<Bundle*>(b);
643 h->Set(key, idx, std::move(value));
644 } catch (const Exception& e) {
645 return e.GetErrorCode();
648 return BUNDLE_ERROR_NONE;
651 extern "C" EXPORT_API int bundle_add_byte_array(bundle* b,
652 const char* key, const unsigned int len) {
653 return bundle_init_byte_array(b, key, len);
656 extern "C" EXPORT_API int bundle_init_byte_array(bundle* b,
657 const char* key, const unsigned int len) {
658 if (b == nullptr || key == nullptr || strlen(key) == 0)
659 return BUNDLE_ERROR_INVALID_PARAMETER;
661 auto* h = reinterpret_cast<Bundle*>(b);
665 std::vector<std::vector<unsigned char>> values(len);
666 key_info = new KeyInfo(Bundle::Type::ByteArray, key, std::move(values));
667 } catch (const Exception& e) {
668 return e.GetErrorCode();
669 } catch (const std::bad_alloc& ba) {
670 return BUNDLE_ERROR_OUT_OF_MEMORY;
671 } catch (const std::length_error&) {
672 return BUNDLE_ERROR_OUT_OF_MEMORY;
676 h->Add(std::shared_ptr<KeyInfo>(key_info));
677 } catch (const Exception& e) {
678 return e.GetErrorCode();
681 return BUNDLE_ERROR_NONE;
684 extern "C" EXPORT_API int bundle_get_byte_array(bundle* b,
685 const char* key, void*** bytes_array, unsigned int* len,
686 unsigned int** array_element_size) {
687 if (b == nullptr || key == nullptr)
688 return BUNDLE_ERROR_INVALID_PARAMETER;
690 auto* h = reinterpret_cast<Bundle*>(b);
691 std::shared_ptr<KeyInfo> key_info;
693 key_info = h->Get(key);
694 } catch (const Exception& e) {
695 return e.GetErrorCode();
698 if (key_info->GetType() != BUNDLE_TYPE_BYTE_ARRAY)
699 return BUNDLE_ERROR_INVALID_PARAMETER;
701 auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
702 key_info->GetValues());
705 auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
706 *bytes_array = reinterpret_cast<void**>(values);
710 *len = static_cast<unsigned int>(raw_values.size());
712 if (array_element_size) {
713 auto& raw_values_size = const_cast<std::vector<unsigned int>&>(
714 key_info->GetUValuesSize());
715 *array_element_size = reinterpret_cast<unsigned int*>(&raw_values_size[0]);
718 return BUNDLE_ERROR_NONE;
721 extern "C" EXPORT_API int bundle_set_byte_array_element(bundle* b,
722 const char* key, const unsigned int idx,
723 const void* bytes, const size_t size) {
724 if (b == nullptr || key == nullptr || size <= 0)
725 return BUNDLE_ERROR_INVALID_PARAMETER;
727 std::vector<unsigned char> value;
729 auto* p = reinterpret_cast<unsigned char*>(const_cast<void*>(bytes));
730 value.insert(value.end(), p, p + size);
733 auto* h = reinterpret_cast<Bundle*>(b);
735 h->Set(key, idx, std::move(value));
736 } catch (const Exception& e) {
737 return e.GetErrorCode();
740 return BUNDLE_ERROR_NONE;
743 extern "C" EXPORT_API int bundle_to_json(bundle* b, char** json) {
744 if (b == nullptr || json == nullptr)
745 return BUNDLE_ERROR_INVALID_PARAMETER;
747 auto* h = reinterpret_cast<Bundle*>(b);
750 *json = strdup(js.ToString().c_str());
751 } catch (const Exception& e) {
752 return e.GetErrorCode();
755 return BUNDLE_ERROR_NONE;
758 extern "C" EXPORT_API int bundle_from_json(const char* json, bundle** b) {
759 if (json == nullptr || b == nullptr)
760 return BUNDLE_ERROR_INVALID_PARAMETER;
764 *b = reinterpret_cast<bundle*>(js.ToBundle());
765 } catch (const Exception& e) {
766 return e.GetErrorCode();
769 return BUNDLE_ERROR_NONE;