540ca4c1bcbe50a9d134ce91488972148442b0e3
[platform/core/base/bundle.git] / src / stub.cc
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
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 <tizen.h>
18 #include <glib.h>
19
20 #include "include/bundle.h"
21 #include "include/bundle_internal.h"
22
23 #include "bundle-internal.h"
24 #include "exception-internal.h"
25 #include "export-api-internal.h"
26 #include "json-internal.h"
27
28 using namespace tizen_base::internal;
29
30 extern "C" EXPORT_API bundle* bundle_create(void) {
31   auto* h = new (std::nothrow) Bundle();
32   if (h == nullptr) {
33     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
34     return nullptr;
35   }
36
37   set_last_result(BUNDLE_ERROR_NONE);
38   return reinterpret_cast<bundle*>(h);
39 }
40
41 extern "C" EXPORT_API int bundle_free(bundle* b) {
42   if (b == nullptr)
43     return BUNDLE_ERROR_INVALID_PARAMETER;
44
45   auto* h = reinterpret_cast<Bundle*>(b);
46   delete h;
47   return BUNDLE_ERROR_NONE;
48 }
49
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;
54
55   auto* h = reinterpret_cast<Bundle*>(b);
56   std::vector<unsigned char> value(str, str + (strlen(str) + 1));
57
58   KeyInfo* key_info;
59   try {
60     key_info = new KeyInfo(BUNDLE_TYPE_STR, key, std::move(value));
61   } catch (const Exception& e) {
62     return e.GetErrorCode();
63   } catch (const std::bad_alloc& ba) {
64     return BUNDLE_ERROR_OUT_OF_MEMORY;
65   }
66
67   try {
68     h->Add(std::shared_ptr<KeyInfo>(key_info));
69   } catch (const Exception& e) {
70     return e.GetErrorCode();
71   }
72
73   return BUNDLE_ERROR_NONE;
74 }
75
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;
80
81   auto* h = reinterpret_cast<Bundle*>(b);
82   std::shared_ptr<KeyInfo> key_info;
83   try {
84     key_info = h->Get(key);
85   } catch (const Exception& e) {
86     return e.GetErrorCode();
87   }
88
89   if (key_info->GetType() != BUNDLE_TYPE_STR)
90     return BUNDLE_ERROR_INVALID_PARAMETER;
91
92   if (str) {
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]);
96   }
97
98   return BUNDLE_ERROR_NONE;
99 }
100
101 extern "C" EXPORT_API int bundle_add(bundle* b, const char* key,
102     const char* val) {
103   return bundle_add_str(b, key, val);
104 }
105
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;
109
110   auto* h = reinterpret_cast<Bundle*>(b);
111   try {
112     h->Remove(key);
113   } catch (const Exception& e) {
114     return e.GetErrorCode();
115   }
116
117   return BUNDLE_ERROR_NONE;
118 }
119
120 extern "C" EXPORT_API const char* bundle_get_val(bundle* b, const char* key) {
121   char* val = nullptr;
122   int ret = bundle_get_str(b, key, &val);
123   set_last_result(ret);
124   return val;
125 }
126
127 extern "C" EXPORT_API int bundle_get_count(bundle* b) {
128   if (b == nullptr)
129     return 0;
130
131   auto* h = reinterpret_cast<Bundle*>(b);
132   set_last_result(BUNDLE_ERROR_NONE);
133   return h->GetSize();
134 }
135
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);
140     return;
141   }
142
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);
150   }
151
152   set_last_result(BUNDLE_ERROR_NONE);
153 }
154
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);
159     return;
160   }
161
162   auto* h = reinterpret_cast<Bundle*>(b);
163   auto it = h->GetMap().begin();
164   while (it != h->GetMap().end()) {
165     auto& key_info = it->second;
166     ++it;
167     callback(key_info->GetKey().c_str(), key_info->GetType(),
168              reinterpret_cast<bundle_keyval_t*>(key_info.get()), user_data);
169   }
170
171   set_last_result(BUNDLE_ERROR_NONE);
172 }
173
174 extern "C" EXPORT_API int bundle_keyval_get_type(bundle_keyval_t* kv) {
175   if (kv == nullptr) {
176     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
177     return -1;
178   }
179
180   auto* key_info = reinterpret_cast<KeyInfo*>(kv);
181   set_last_result(BUNDLE_ERROR_NONE);
182   return key_info->GetType();
183 }
184
185 extern "C" EXPORT_API int bundle_keyval_type_is_array(bundle_keyval_t* kv) {
186   int type = bundle_keyval_get_type(kv);
187   if (type == -1)
188     return -1;
189
190   set_last_result(BUNDLE_ERROR_NONE);
191   if (type & BUNDLE_TYPE_ARRAY)
192     return 1;
193
194   return 0;
195 }
196
197 extern "C" EXPORT_API int bundle_keyval_type_is_measurable(
198     bundle_keyval_t* kv) {
199   int type = bundle_keyval_get_type(kv);
200   if (type == -1)
201     return -1;
202
203   set_last_result(BUNDLE_ERROR_NONE);
204   if (type & BUNDLE_TYPE_MEASURABLE)
205     return 1;
206
207   return 0;
208 }
209
210 extern "C" EXPORT_API int bundle_keyval_get_basic_val(bundle_keyval_t* kv,
211     void** val, size_t* size) {
212   if (kv == nullptr)
213     return BUNDLE_ERROR_INVALID_PARAMETER;
214
215   auto* key_info = reinterpret_cast<KeyInfo*>(kv);
216   if (key_info->IsArray())
217     return BUNDLE_ERROR_INVALID_PARAMETER;
218
219   if (val) {
220     auto& values = key_info->GetValues();
221     auto& value = const_cast<std::unique_ptr<unsigned char[]>&>(values[0]);
222     *val = reinterpret_cast<void*>(&value[0]);
223   }
224
225   if (size) {
226     auto& values_size = key_info->GetValuesSize();
227     *size = reinterpret_cast<size_t>(values_size[0]);
228   }
229
230   return BUNDLE_ERROR_NONE;
231 }
232
233 extern "C" EXPORT_API int bundle_keyval_get_array_val(bundle_keyval_t* kv,
234     void*** array_val, unsigned int* array_len, size_t** array_item_size) {
235   if (kv == nullptr)
236     return BUNDLE_ERROR_INVALID_PARAMETER;
237
238   auto* key_info = reinterpret_cast<KeyInfo*>(kv);
239   if (!key_info->IsArray())
240     return BUNDLE_ERROR_INVALID_PARAMETER;
241
242   auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
243       key_info->GetValues());
244
245   if (array_val)
246     *array_val = reinterpret_cast<void**>(&values[0]);
247
248   if (array_len)
249     *array_len = static_cast<unsigned int>(values.size());
250
251   if (array_item_size) {
252     auto& values_size = const_cast<std::vector<std::size_t>&>(
253       key_info->GetValuesSize());
254     *array_item_size = reinterpret_cast<size_t*>(&values_size[0]);
255   }
256
257   return BUNDLE_ERROR_NONE;
258 }
259
260 extern "C" EXPORT_API bundle_keyval_t* bundle_keyval_dup(
261     const bundle_keyval_t* kv) {
262   if (kv == nullptr) {
263     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
264     return nullptr;
265   }
266
267   auto* keyval = const_cast<bundle_keyval_t*>(kv);
268   auto* key_info = reinterpret_cast<KeyInfo*>(keyval);
269
270   KeyInfo* k;
271   try {
272     k = new KeyInfo(*key_info);
273   } catch (const Exception& e) {
274     set_last_result(e.GetErrorCode());
275     return nullptr;
276   } catch (const std::bad_alloc& ba) {
277     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
278     return nullptr;
279   }
280
281   set_last_result(BUNDLE_ERROR_NONE);
282   return reinterpret_cast<bundle_keyval_t*>(k);
283 }
284
285 extern "C" EXPORT_API int bundle_keyval_free(bundle_keyval_t* kv) {
286   if (kv == nullptr)
287     return BUNDLE_ERROR_INVALID_PARAMETER;
288
289   auto* key_info = reinterpret_cast<KeyInfo*>(kv);
290   delete key_info;
291   return BUNDLE_ERROR_NONE;
292 }
293
294 extern "C" EXPORT_API bundle* bundle_dup(bundle* b_from) {
295   if (b_from == nullptr) {
296     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
297     return nullptr;
298   }
299
300   auto* h = reinterpret_cast<Bundle*>(b_from);
301   auto* b = new (std::nothrow) Bundle(*h);
302   if (b == nullptr) {
303     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
304     return nullptr;
305   }
306
307   set_last_result(BUNDLE_ERROR_NONE);
308   return reinterpret_cast<bundle*>(b);
309 }
310
311 extern "C" EXPORT_API int bundle_encode(bundle *b, bundle_raw** raw, int* len) {
312   if (b == nullptr || raw == nullptr || len == nullptr)
313     return BUNDLE_ERROR_INVALID_PARAMETER;
314
315   auto* h = reinterpret_cast<Bundle*>(b);
316   *raw = reinterpret_cast<bundle_raw*>(h->Encode());
317   *len = strlen(reinterpret_cast<char*>(*raw));
318   return BUNDLE_ERROR_NONE;
319 }
320
321 extern "C" EXPORT_API int bundle_free_encoded_rawdata(bundle_raw **r) {
322   if (r == nullptr || *r == nullptr)
323     return BUNDLE_ERROR_INVALID_PARAMETER;
324
325   free(*r);
326   *r = nullptr;
327   return BUNDLE_ERROR_NONE;
328 }
329
330 extern "C" EXPORT_API bundle* bundle_decode(const bundle_raw* r,
331     const int data_size) {
332   if (r == nullptr) {
333     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
334     return nullptr;
335   }
336
337   Bundle* b = nullptr;
338   try {
339     auto* raw = const_cast<bundle_raw*>(r);
340     b = new Bundle(static_cast<unsigned char*>(raw), data_size);
341   } catch (const Exception& e) {
342     set_last_result(e.GetErrorCode());
343     return nullptr;
344   } catch (const std::bad_alloc& ba) {
345     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
346     return nullptr;
347   }
348
349   set_last_result(BUNDLE_ERROR_NONE);
350   return reinterpret_cast<bundle*>(b);
351 }
352
353 extern "C" EXPORT_API int bundle_encode_raw(bundle* b, bundle_raw** r,
354     int* len) {
355   if (b == nullptr || r == nullptr || len == nullptr)
356     return BUNDLE_ERROR_INVALID_PARAMETER;
357
358   auto* h = reinterpret_cast<Bundle*>(b);
359   try {
360     *r = reinterpret_cast<bundle_raw*>(h->EncodeRaw(len));
361   } catch (const Exception& e) {
362     return e.GetErrorCode();
363   }
364   return BUNDLE_ERROR_NONE;
365 }
366
367 extern "C" EXPORT_API bundle* bundle_decode_raw(const bundle_raw* r,
368     const int data_size) {
369   if (r == nullptr) {
370     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
371     return nullptr;
372   }
373
374   Bundle* b = nullptr;
375   try {
376     auto* raw = const_cast<bundle_raw*>(r);
377     b = new Bundle(static_cast<unsigned char*>(raw), data_size, false);
378   } catch (const Exception& e) {
379     set_last_result(e.GetErrorCode());
380     return nullptr;
381   } catch (const std::bad_alloc& ba) {
382     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
383     return nullptr;
384   }
385
386   set_last_result(BUNDLE_ERROR_NONE);
387   return reinterpret_cast<bundle*>(b);
388 }
389
390 extern "C" EXPORT_API int bundle_get_type(bundle* b, const char* key) {
391   if (b == nullptr || key == nullptr) {
392     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
393     return BUNDLE_TYPE_NONE;
394   }
395
396   auto* h = reinterpret_cast<Bundle*>(b);
397   std::shared_ptr<KeyInfo> key_info;
398   try {
399     key_info = h->Get(key);
400   } catch (const Exception& e) {
401     set_last_result(e.GetErrorCode());
402     return BUNDLE_TYPE_NONE;
403   }
404
405   set_last_result(BUNDLE_ERROR_NONE);
406   return key_info->GetType();
407 }
408
409 extern "C" EXPORT_API int bundle_add_str_array(bundle* b, const char* key,
410     const char** str_array, const int len) {
411   if (b == nullptr || key == nullptr || strlen(key) == 0)
412     return BUNDLE_ERROR_INVALID_PARAMETER;
413
414   auto* h = reinterpret_cast<Bundle*>(b);
415   std::vector<std::vector<unsigned char>> values(len);
416   if (str_array) {
417     for (int i = 0; i < len; ++i) {
418       std::vector<unsigned char> value(str_array[i],
419           str_array[i] + (strlen(str_array[i]) + 1));
420       values[i] = std::move(value);
421     }
422   }
423
424   KeyInfo* key_info;
425   try {
426     key_info = new KeyInfo((BUNDLE_TYPE_STR_ARRAY | BUNDLE_TYPE_ARRAY),
427         key, values);
428   } catch (const Exception& e) {
429     return e.GetErrorCode();
430   }
431
432   try {
433     h->Add(std::shared_ptr<KeyInfo>(key_info));
434   } catch (const Exception& e) {
435     return e.GetErrorCode();
436   }
437
438   return BUNDLE_ERROR_NONE;
439 }
440
441 extern "C" EXPORT_API const char** bundle_get_str_array(bundle* b,
442     const char* key, int* len) {
443   if (b == nullptr || key == nullptr) {
444     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
445     return nullptr;
446   }
447
448   auto* h = reinterpret_cast<Bundle*>(b);
449   std::shared_ptr<KeyInfo> key_info;
450   try {
451     key_info = h->Get(key);
452   } catch (const Exception& e) {
453     set_last_result(e.GetErrorCode());
454     return nullptr;
455   }
456
457   if (key_info->GetType() != BUNDLE_TYPE_STR_ARRAY) {
458     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
459     return nullptr;
460   }
461
462   set_last_result(BUNDLE_ERROR_NONE);
463
464   auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
465       key_info->GetValues());
466
467   if (len)
468     *len = static_cast<int>(raw_values.size());
469
470   if (raw_values.size() == 0)
471     return nullptr;
472
473   auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
474   return const_cast<const char**>(reinterpret_cast<char**>(values));
475 }
476
477 extern "C" EXPORT_API int bundle_add_byte(bundle* b, const char* key,
478     const void* bytes, const size_t size) {
479   if (b == nullptr || key == nullptr || strlen(key) == 0)
480     return BUNDLE_ERROR_INVALID_PARAMETER;
481
482   auto* h = reinterpret_cast<Bundle*>(b);
483   auto* p = reinterpret_cast<const unsigned char*>(bytes);
484   std::vector<unsigned char> value;
485   if (bytes)
486     value.insert(value.end(), p, p + size);
487
488   KeyInfo* key_info;
489   try {
490     key_info = new KeyInfo(BUNDLE_TYPE_BYTE, key, std::move(value));
491   } catch (const Exception& e) {
492     return e.GetErrorCode();
493   } catch (const std::bad_alloc& ba) {
494     return BUNDLE_ERROR_OUT_OF_MEMORY;
495   }
496
497   try {
498     h->Add(std::shared_ptr<KeyInfo>(key_info));
499   } catch (const Exception& e) {
500     return e.GetErrorCode();
501   }
502
503   return BUNDLE_ERROR_NONE;
504 }
505
506 extern "C" EXPORT_API int bundle_get_byte(bundle* b, const char* key,
507     void** bytes, size_t* size) {
508   if (b == nullptr || key == nullptr)
509     return BUNDLE_ERROR_INVALID_PARAMETER;
510
511   auto* h = reinterpret_cast<Bundle*>(b);
512   std::shared_ptr<KeyInfo> key_info;
513   try {
514     key_info = h->Get(key);
515   } catch (const Exception& e) {
516     return e.GetErrorCode();
517   }
518
519   if (key_info->GetType() != BUNDLE_TYPE_BYTE)
520     return BUNDLE_ERROR_INVALID_PARAMETER;
521
522   if (bytes) {
523     auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
524         key_info->GetValues());
525     if (values.size() == 0) {
526       *bytes = nullptr;
527     } else {
528       auto& value = values[0];
529       *bytes = reinterpret_cast<void*>(&value[0]);
530     }
531   }
532
533   if (size) {
534     auto& values_size = key_info->GetValuesSize();
535     *size = reinterpret_cast<size_t>(values_size[0]);
536   }
537
538   return BUNDLE_ERROR_NONE;
539 }
540
541 extern "C" EXPORT_API int bundle_export_to_argv(bundle* b, char*** argv) {
542   if (b == nullptr || argv == nullptr) {
543     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
544     return -1;
545   }
546
547   auto* h = reinterpret_cast<Bundle*>(b);
548   std::vector<std::string> exported_vt;
549   try {
550     exported_vt = h->Export();
551   } catch (const Exception& e) {
552     set_last_result(e.GetErrorCode());
553     return -1;
554   }
555
556   int argc = exported_vt.size();
557   auto** exported_argv = reinterpret_cast<char**>(
558       calloc(argc + 1, sizeof(char*)));
559   if (exported_argv == nullptr) {
560     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
561     return -1;
562   }
563
564   exported_argv[1] = const_cast<char*>(TAG_IMPORT_EXPORT_CHECK);
565   for (unsigned int idx = 2; idx < exported_vt.size(); idx += 2) {
566     exported_argv[idx] = strdup(exported_vt[idx].c_str());
567     if (exported_argv[idx] == nullptr) {
568       set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
569       bundle_free_exported_argv(idx + 1, &exported_argv);
570       return -1;
571     }
572
573     exported_argv[idx + 1] = strdup(exported_vt[idx + 1].c_str());
574     if (exported_argv[idx + 1] == nullptr) {
575       set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
576       bundle_free_exported_argv(idx + 2, &exported_argv);
577       return -1;
578     }
579   }
580
581   *argv = exported_argv;
582   set_last_result(BUNDLE_ERROR_NONE);
583   return argc;
584 }
585
586 extern "C" EXPORT_API int bundle_free_exported_argv(int argc, char*** argv) {
587   if (argc < 2 || !argv || !*argv)
588     return BUNDLE_ERROR_INVALID_PARAMETER;
589
590   for (int i = 2; i < argc; i++)
591     std::free((*argv)[i]);
592
593   std::free(*argv);
594   *argv = nullptr;
595
596   return BUNDLE_ERROR_NONE;
597 }
598
599 extern "C" EXPORT_API bundle* bundle_import_from_argv(int argc, char** argv) {
600   if (argv == nullptr) {
601     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
602     return nullptr;
603   }
604
605   Bundle* b = nullptr;
606   try {
607     b = new (std::nothrow) Bundle(argc, argv);
608   } catch (const Exception& e) {
609     set_last_result(e.GetErrorCode());
610     return nullptr;
611   }
612
613   set_last_result(BUNDLE_ERROR_NONE);
614   return reinterpret_cast<bundle*>(b);
615 }
616
617 extern "C" EXPORT_API int bundle_compare(bundle* b1, bundle* b2) {
618   if (b1 == nullptr || b2 == nullptr)
619     return -1;
620
621   auto* h1 = reinterpret_cast<Bundle*>(b1);
622   auto* h2 = reinterpret_cast<Bundle*>(b2);
623   if (*h1 == *h2)
624     return 0;
625
626   return 1;
627 }
628
629 extern "C" EXPORT_API int bundle_set_str_array_element(bundle* b,
630     const char* key, const unsigned int idx, const char* val) {
631   if (b == nullptr || key == nullptr || val == nullptr)
632     return BUNDLE_ERROR_INVALID_PARAMETER;
633
634   auto len = strlen(val) + 1;
635   auto* p = reinterpret_cast<unsigned char*>(const_cast<char*>(val));
636   std::vector<unsigned char> value(p, p + len);
637
638   auto* h = reinterpret_cast<Bundle*>(b);
639   try {
640     h->Set(key, idx, std::move(value));
641   } catch (const Exception& e) {
642     return e.GetErrorCode();
643   }
644
645   return BUNDLE_ERROR_NONE;
646 }
647
648 extern "C" EXPORT_API int bundle_add_byte_array(bundle* b,
649     const char* key, const unsigned int len) {
650   return bundle_init_byte_array(b, key, len);
651 }
652
653 extern "C" EXPORT_API int bundle_init_byte_array(bundle* b,
654     const char* key, const unsigned int len) {
655   if (b == nullptr || key == nullptr || strlen(key) == 0)
656     return BUNDLE_ERROR_INVALID_PARAMETER;
657
658   auto* h = reinterpret_cast<Bundle*>(b);
659
660   KeyInfo* key_info;
661   try {
662     std::vector<std::vector<unsigned char>> values(len);
663     key_info = new KeyInfo(Bundle::Type::ByteArray, key, std::move(values));
664   } catch (const Exception& e) {
665     return e.GetErrorCode();
666   } catch (const std::bad_alloc& ba) {
667     return BUNDLE_ERROR_OUT_OF_MEMORY;
668   } catch (const std::length_error&) {
669     return BUNDLE_ERROR_OUT_OF_MEMORY;
670   }
671
672   try {
673     h->Add(std::shared_ptr<KeyInfo>(key_info));
674   } catch (const Exception& e) {
675     return e.GetErrorCode();
676   }
677
678   return BUNDLE_ERROR_NONE;
679 }
680
681 extern "C" EXPORT_API int bundle_get_byte_array(bundle* b,
682     const char* key, void*** bytes_array, unsigned int* len,
683     unsigned int** array_element_size) {
684   if (b == nullptr || key == nullptr)
685     return BUNDLE_ERROR_INVALID_PARAMETER;
686
687   auto* h = reinterpret_cast<Bundle*>(b);
688   std::shared_ptr<KeyInfo> key_info;
689   try {
690     key_info = h->Get(key);
691   } catch (const Exception& e) {
692     return e.GetErrorCode();
693   }
694
695   if (key_info->GetType() != BUNDLE_TYPE_BYTE_ARRAY)
696     return BUNDLE_ERROR_INVALID_PARAMETER;
697
698   auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
699       key_info->GetValues());
700
701   if (bytes_array) {
702     auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
703     *bytes_array = reinterpret_cast<void**>(values);
704   }
705
706   if (len)
707     *len = static_cast<unsigned int>(raw_values.size());
708
709   if (array_element_size) {
710     auto& raw_values_size = const_cast<std::vector<unsigned int>&>(
711         key_info->GetUValuesSize());
712     *array_element_size = reinterpret_cast<unsigned int*>(&raw_values_size[0]);
713   }
714
715   return BUNDLE_ERROR_NONE;
716 }
717
718 extern "C" EXPORT_API int bundle_set_byte_array_element(bundle* b,
719     const char* key, const unsigned int idx,
720     const void* bytes, const size_t size) {
721   if (b == nullptr || key == nullptr || size <= 0)
722     return BUNDLE_ERROR_INVALID_PARAMETER;
723
724   std::vector<unsigned char> value;
725   if (bytes) {
726     auto* p = reinterpret_cast<unsigned char*>(const_cast<void*>(bytes));
727     value.insert(value.end(), p, p + size);
728   }
729
730   auto* h = reinterpret_cast<Bundle*>(b);
731   try {
732     h->Set(key, idx, std::move(value));
733   } catch (const Exception& e) {
734     return e.GetErrorCode();
735   }
736
737   return BUNDLE_ERROR_NONE;
738 }
739
740 extern "C" EXPORT_API int bundle_to_json(bundle* b, char** json) {
741   if (b == nullptr || json == nullptr)
742     return BUNDLE_ERROR_INVALID_PARAMETER;
743
744   auto* h = reinterpret_cast<Bundle*>(b);
745   Json js(h);
746   try {
747     *json = strdup(js.ToString().c_str());
748   } catch (const Exception& e) {
749     return e.GetErrorCode();
750   }
751
752   return BUNDLE_ERROR_NONE;
753 }
754
755 extern "C" EXPORT_API int bundle_from_json(const char* json, bundle** b) {
756   if (json == nullptr || b == nullptr)
757     return BUNDLE_ERROR_INVALID_PARAMETER;
758
759   Json js(json);
760   try {
761     *b = reinterpret_cast<bundle*>(js.ToBundle());
762   } catch (const Exception& e) {
763     return e.GetErrorCode();
764   }
765
766   return BUNDLE_ERROR_NONE;
767 }