f8b94c056159d1db46abdf92b2a671557d3dc520
[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, value);
61   } catch (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 (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 (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 (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   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);
167   }
168
169   set_last_result(BUNDLE_ERROR_NONE);
170 }
171
172 extern "C" EXPORT_API int bundle_keyval_get_type(bundle_keyval_t* kv) {
173   if (kv == nullptr) {
174     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
175     return -1;
176   }
177
178   auto* key_info = reinterpret_cast<KeyInfo*>(kv);
179   set_last_result(BUNDLE_ERROR_NONE);
180   return key_info->GetType();
181 }
182
183 extern "C" EXPORT_API int bundle_keyval_type_is_array(bundle_keyval_t* kv) {
184   int type = bundle_keyval_get_type(kv);
185   if (type == -1)
186     return -1;
187
188   set_last_result(BUNDLE_ERROR_NONE);
189   if (type & BUNDLE_TYPE_ARRAY)
190     return 1;
191
192   return 0;
193 }
194
195 extern "C" EXPORT_API int bundle_keyval_type_is_measurable(
196     bundle_keyval_t* kv) {
197   int type = bundle_keyval_get_type(kv);
198   if (type == -1)
199     return -1;
200
201   set_last_result(BUNDLE_ERROR_NONE);
202   if (type & BUNDLE_TYPE_MEASURABLE)
203     return 1;
204
205   return 0;
206 }
207
208 extern "C" EXPORT_API int bundle_keyval_get_basic_val(bundle_keyval_t* kv,
209     void** val, size_t* size) {
210   if (kv == nullptr)
211     return BUNDLE_ERROR_INVALID_PARAMETER;
212
213   auto* key_info = reinterpret_cast<KeyInfo*>(kv);
214   if (key_info->IsArray())
215     return BUNDLE_ERROR_INVALID_PARAMETER;
216
217   if (val) {
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]);
221   }
222
223   if (size) {
224     auto& values_size = key_info->GetValuesSize();
225     *size = reinterpret_cast<size_t>(values_size[0]);
226   }
227
228   return BUNDLE_ERROR_NONE;
229 }
230
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) {
233   if (kv == nullptr)
234     return BUNDLE_ERROR_INVALID_PARAMETER;
235
236   auto* key_info = reinterpret_cast<KeyInfo*>(kv);
237   if (!key_info->IsArray())
238     return BUNDLE_ERROR_INVALID_PARAMETER;
239
240   auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
241       key_info->GetValues());
242
243   if (array_val)
244     *array_val = reinterpret_cast<void**>(&values[0]);
245
246   if (array_len)
247     *array_len = static_cast<unsigned int>(values.size());
248
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]);
253   }
254
255   return BUNDLE_ERROR_NONE;
256 }
257
258 extern "C" EXPORT_API bundle_keyval_t* bundle_keyval_dup(
259     const bundle_keyval_t* kv) {
260   if (kv == nullptr) {
261     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
262     return nullptr;
263   }
264
265   auto* keyval = const_cast<bundle_keyval_t*>(kv);
266   auto* key_info = reinterpret_cast<KeyInfo*>(keyval);
267
268   KeyInfo* k;
269   try {
270     k = new KeyInfo(*key_info);
271   } catch (Exception& e) {
272     set_last_result(e.GetErrorCode());
273     return nullptr;
274   } catch (const std::bad_alloc& ba) {
275     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
276     return nullptr;
277   }
278
279   set_last_result(BUNDLE_ERROR_NONE);
280   return reinterpret_cast<bundle_keyval_t*>(k);
281 }
282
283 extern "C" EXPORT_API int bundle_keyval_free(bundle_keyval_t* kv) {
284   if (kv == nullptr)
285     return BUNDLE_ERROR_INVALID_PARAMETER;
286
287   auto* key_info = reinterpret_cast<KeyInfo*>(kv);
288   delete key_info;
289   return BUNDLE_ERROR_NONE;
290 }
291
292 extern "C" EXPORT_API bundle* bundle_dup(bundle* b_from) {
293   if (b_from == nullptr) {
294     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
295     return nullptr;
296   }
297
298   auto* h = reinterpret_cast<Bundle*>(b_from);
299   auto* b = new (std::nothrow) Bundle(*h);
300   if (b == nullptr) {
301     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
302     return nullptr;
303   }
304
305   set_last_result(BUNDLE_ERROR_NONE);
306   return reinterpret_cast<bundle*>(b);
307 }
308
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;
312
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;
317 }
318
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;
322
323   free(*r);
324   *r = nullptr;
325   return BUNDLE_ERROR_NONE;
326 }
327
328 extern "C" EXPORT_API bundle* bundle_decode(const bundle_raw* r,
329     const int data_size) {
330   if (r == nullptr) {
331     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
332     return nullptr;
333   }
334
335   Bundle* b = nullptr;
336   try {
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());
341     return nullptr;
342   } catch (const std::bad_alloc& ba) {
343     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
344     return nullptr;
345   }
346
347   set_last_result(BUNDLE_ERROR_NONE);
348   return reinterpret_cast<bundle*>(b);
349 }
350
351 extern "C" EXPORT_API int bundle_encode_raw(bundle* b, bundle_raw** r,
352     int* len) {
353   if (b == nullptr || r == nullptr || len == nullptr)
354     return BUNDLE_ERROR_INVALID_PARAMETER;
355
356   auto* h = reinterpret_cast<Bundle*>(b);
357   try {
358     *r = reinterpret_cast<bundle_raw*>(h->EncodeRaw(len));
359   } catch (Exception& e) {
360     return e.GetErrorCode();
361   }
362   return BUNDLE_ERROR_NONE;
363 }
364
365 extern "C" EXPORT_API bundle* bundle_decode_raw(const bundle_raw* r,
366     const int data_size) {
367   if (r == nullptr) {
368     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
369     return nullptr;
370   }
371
372   Bundle* b = nullptr;
373   try {
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());
378     return nullptr;
379   } catch (const std::bad_alloc& ba) {
380     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
381     return nullptr;
382   }
383
384   set_last_result(BUNDLE_ERROR_NONE);
385   return reinterpret_cast<bundle*>(b);
386 }
387
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;
392   }
393
394   auto* h = reinterpret_cast<Bundle*>(b);
395   std::shared_ptr<KeyInfo> key_info;
396   try {
397     key_info = h->Get(key);
398   } catch (Exception& e) {
399     set_last_result(e.GetErrorCode());
400     return BUNDLE_TYPE_NONE;
401   }
402
403   set_last_result(BUNDLE_ERROR_NONE);
404   return key_info->GetType();
405 }
406
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;
411
412   auto* h = reinterpret_cast<Bundle*>(b);
413   std::vector<std::vector<unsigned char>> values(len);
414   if (str_array) {
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);
419     }
420   }
421
422   KeyInfo* key_info;
423   try {
424     key_info = new KeyInfo((BUNDLE_TYPE_STR_ARRAY | BUNDLE_TYPE_ARRAY),
425         key, values);
426   } catch (Exception& e) {
427     return e.GetErrorCode();
428   }
429
430   try {
431     h->Add(std::shared_ptr<KeyInfo>(key_info));
432   } catch (Exception& e) {
433     return e.GetErrorCode();
434   }
435
436   return BUNDLE_ERROR_NONE;
437 }
438
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);
443     return nullptr;
444   }
445
446   auto* h = reinterpret_cast<Bundle*>(b);
447   std::shared_ptr<KeyInfo> key_info;
448   try {
449     key_info = h->Get(key);
450   } catch (Exception& e) {
451     set_last_result(e.GetErrorCode());
452     return nullptr;
453   }
454
455   if (key_info->GetType() != BUNDLE_TYPE_STR_ARRAY) {
456     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
457     return nullptr;
458   }
459
460   set_last_result(BUNDLE_ERROR_NONE);
461
462   auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
463       key_info->GetValues());
464
465   if (len)
466     *len = static_cast<int>(raw_values.size());
467
468   if (raw_values.size() == 0)
469     return nullptr;
470
471   auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
472   return const_cast<const char**>(reinterpret_cast<char**>(values));
473 }
474
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;
479
480   auto* h = reinterpret_cast<Bundle*>(b);
481   auto* p = reinterpret_cast<const unsigned char*>(bytes);
482   std::vector<unsigned char> value;
483   if (bytes)
484     std::copy(p, p + size, std::back_inserter(value));
485
486   KeyInfo* key_info;
487   try {
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;
493   }
494
495   try {
496     h->Add(std::shared_ptr<KeyInfo>(key_info));
497   } catch (Exception& e) {
498     return e.GetErrorCode();
499   }
500
501   return BUNDLE_ERROR_NONE;
502 }
503
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;
508
509   auto* h = reinterpret_cast<Bundle*>(b);
510   std::shared_ptr<KeyInfo> key_info;
511   try {
512     key_info = h->Get(key);
513   } catch (Exception& e) {
514     return e.GetErrorCode();
515   }
516
517   if (key_info->GetType() != BUNDLE_TYPE_BYTE)
518     return BUNDLE_ERROR_INVALID_PARAMETER;
519
520   if (bytes) {
521     auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
522         key_info->GetValues());
523     if (values.size() == 0) {
524       *bytes = nullptr;
525     } else {
526       auto& value = values[0];
527       *bytes = reinterpret_cast<void*>(&value[0]);
528     }
529   }
530
531   if (size) {
532     auto& values_size = key_info->GetValuesSize();
533     *size = reinterpret_cast<size_t>(values_size[0]);
534   }
535
536   return BUNDLE_ERROR_NONE;
537 }
538
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);
542     return -1;
543   }
544
545   auto* h = reinterpret_cast<Bundle*>(b);
546   std::vector<std::string> exported_vt;
547   try {
548     exported_vt = h->Export();
549   } catch (Exception& e) {
550     set_last_result(e.GetErrorCode());
551     return -1;
552   }
553
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);
559     return -1;
560   }
561
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);
568       return -1;
569     }
570
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);
575       return -1;
576     }
577   }
578
579   *argv = exported_argv;
580   set_last_result(BUNDLE_ERROR_NONE);
581   return argc;
582 }
583
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;
587
588   for (int i = 2; i < argc; i++)
589     std::free((*argv)[i]);
590
591   std::free(*argv);
592   *argv = nullptr;
593
594   return BUNDLE_ERROR_NONE;
595 }
596
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);
600     return nullptr;
601   }
602
603   Bundle* b = nullptr;
604   try {
605     b = new (std::nothrow) Bundle(argc, argv);
606   } catch (Exception& e) {
607     set_last_result(e.GetErrorCode());
608     return nullptr;
609   }
610
611   set_last_result(BUNDLE_ERROR_NONE);
612   return reinterpret_cast<bundle*>(b);
613 }
614
615 extern "C" EXPORT_API int bundle_compare(bundle* b1, bundle* b2) {
616   if (b1 == nullptr || b2 == nullptr)
617     return -1;
618
619   auto* h1 = reinterpret_cast<Bundle*>(b1);
620   auto* h2 = reinterpret_cast<Bundle*>(b2);
621   if (*h1 == *h2)
622     return 0;
623
624   return 1;
625 }
626
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;
631
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);
635
636   auto* h = reinterpret_cast<Bundle*>(b);
637   try {
638     h->Set(key, idx, value);
639   } catch (Exception& e) {
640     return e.GetErrorCode();
641   }
642
643   return BUNDLE_ERROR_NONE;
644 }
645
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);
649 }
650
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;
655
656   auto* h = reinterpret_cast<Bundle*>(b);
657
658   KeyInfo* key_info;
659   try {
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;
668   }
669
670   try {
671     h->Add(std::shared_ptr<KeyInfo>(key_info));
672   } catch (Exception& e) {
673     return e.GetErrorCode();
674   }
675
676   return BUNDLE_ERROR_NONE;
677 }
678
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;
684
685   auto* h = reinterpret_cast<Bundle*>(b);
686   std::shared_ptr<KeyInfo> key_info;
687   try {
688     key_info = h->Get(key);
689   } catch (Exception& e) {
690     return e.GetErrorCode();
691   }
692
693   if (key_info->GetType() != BUNDLE_TYPE_BYTE_ARRAY)
694     return BUNDLE_ERROR_INVALID_PARAMETER;
695
696   auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
697       key_info->GetValues());
698
699   if (bytes_array) {
700     auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
701     *bytes_array = reinterpret_cast<void**>(values);
702   }
703
704   if (len)
705     *len = static_cast<unsigned int>(raw_values.size());
706
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]);
711   }
712
713   return BUNDLE_ERROR_NONE;
714 }
715
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;
721
722   std::vector<unsigned char> value;
723   if (bytes) {
724     auto* p = reinterpret_cast<unsigned char*>(const_cast<void*>(bytes));
725     std::copy(p, p + size, std::back_inserter(value));
726   }
727
728   auto* h = reinterpret_cast<Bundle*>(b);
729   try {
730     h->Set(key, idx, value);
731   } catch (Exception& e) {
732     return e.GetErrorCode();
733   }
734
735   return BUNDLE_ERROR_NONE;
736 }
737
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;
741
742   auto* h = reinterpret_cast<Bundle*>(b);
743   Json js(h);
744   try {
745     *json = strdup(js.ToString().c_str());
746   } catch (Exception& e) {
747     return e.GetErrorCode();
748   }
749
750   return BUNDLE_ERROR_NONE;
751 }
752
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;
756
757   Json js(json);
758   try {
759     *b = reinterpret_cast<bundle*>(js.ToBundle());
760   } catch (Exception& e) {
761     return e.GetErrorCode();
762   }
763
764   return BUNDLE_ERROR_NONE;
765 }