9f555b6980608ad9cb58b5d905879bdfbdeec0bf
[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 <stdexcept>
21
22 #include "include/bundle.h"
23 #include "include/bundle_internal.h"
24
25 #include "bundle-internal.h"
26 #include "exception-internal.h"
27 #include "export-api-internal.h"
28 #include "json-internal.h"
29
30 using namespace tizen_base::internal;
31
32 extern "C" EXPORT_API bundle* bundle_create(void) {
33   auto* h = new (std::nothrow) Bundle();
34   if (h == nullptr) {
35     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
36     return nullptr;
37   }
38
39   set_last_result(BUNDLE_ERROR_NONE);
40   return reinterpret_cast<bundle*>(h);
41 }
42
43 extern "C" EXPORT_API int bundle_free(bundle* b) {
44   if (b == nullptr)
45     return BUNDLE_ERROR_INVALID_PARAMETER;
46
47   auto* h = reinterpret_cast<Bundle*>(b);
48   delete h;
49   return BUNDLE_ERROR_NONE;
50 }
51
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;
56
57   auto* h = reinterpret_cast<Bundle*>(b);
58   std::vector<unsigned char> value(str, str + (strlen(str) + 1));
59
60   KeyInfo* key_info;
61   try {
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;
67   }
68
69   try {
70     h->Add(std::shared_ptr<KeyInfo>(key_info));
71   } catch (const Exception& e) {
72     return e.GetErrorCode();
73   }
74
75   return BUNDLE_ERROR_NONE;
76 }
77
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;
82
83   auto* h = reinterpret_cast<Bundle*>(b);
84   std::shared_ptr<KeyInfo> key_info;
85   try {
86     key_info = h->Get(key);
87   } catch (const Exception& e) {
88     return e.GetErrorCode();
89   }
90
91   if (key_info->GetType() != BUNDLE_TYPE_STR)
92     return BUNDLE_ERROR_INVALID_PARAMETER;
93
94   if (str) {
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]);
98   }
99
100   return BUNDLE_ERROR_NONE;
101 }
102
103 extern "C" EXPORT_API int bundle_add(bundle* b, const char* key,
104     const char* val) {
105   return bundle_add_str(b, key, val);
106 }
107
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;
111
112   auto* h = reinterpret_cast<Bundle*>(b);
113   try {
114     h->Remove(key);
115   } catch (const Exception& e) {
116     return e.GetErrorCode();
117   }
118
119   return BUNDLE_ERROR_NONE;
120 }
121
122 extern "C" EXPORT_API const char* bundle_get_val(bundle* b, const char* key) {
123   char* val = nullptr;
124   int ret = bundle_get_str(b, key, &val);
125   set_last_result(ret);
126   return val;
127 }
128
129 extern "C" EXPORT_API int bundle_get_count(bundle* b) {
130   if (b == nullptr)
131     return 0;
132
133   auto* h = reinterpret_cast<Bundle*>(b);
134   set_last_result(BUNDLE_ERROR_NONE);
135   return h->GetSize();
136 }
137
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);
142     return;
143   }
144
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);
151   }
152
153   set_last_result(BUNDLE_ERROR_NONE);
154 }
155
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);
160     return;
161   }
162
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;
167     ++it;
168     callback(key_info->GetKey().c_str(), key_info->GetType(),
169              reinterpret_cast<bundle_keyval_t*>(key_info.get()), user_data);
170   }
171
172   set_last_result(BUNDLE_ERROR_NONE);
173 }
174
175 extern "C" EXPORT_API int bundle_keyval_get_type(bundle_keyval_t* kv) {
176   if (kv == nullptr) {
177     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
178     return -1;
179   }
180
181   auto* key_info = reinterpret_cast<KeyInfo*>(kv);
182   set_last_result(BUNDLE_ERROR_NONE);
183   return key_info->GetType();
184 }
185
186 extern "C" EXPORT_API int bundle_keyval_type_is_array(bundle_keyval_t* kv) {
187   int type = bundle_keyval_get_type(kv);
188   if (type == -1)
189     return -1;
190
191   set_last_result(BUNDLE_ERROR_NONE);
192   if (type & BUNDLE_TYPE_ARRAY)
193     return 1;
194
195   return 0;
196 }
197
198 extern "C" EXPORT_API int bundle_keyval_type_is_measurable(
199     bundle_keyval_t* kv) {
200   int type = bundle_keyval_get_type(kv);
201   if (type == -1)
202     return -1;
203
204   set_last_result(BUNDLE_ERROR_NONE);
205   if (type & BUNDLE_TYPE_MEASURABLE)
206     return 1;
207
208   return 0;
209 }
210
211 extern "C" EXPORT_API int bundle_keyval_get_basic_val(bundle_keyval_t* kv,
212     void** val, size_t* size) {
213   if (kv == nullptr)
214     return BUNDLE_ERROR_INVALID_PARAMETER;
215
216   auto* key_info = reinterpret_cast<KeyInfo*>(kv);
217   if (key_info->IsArray())
218     return BUNDLE_ERROR_INVALID_PARAMETER;
219
220   if (val) {
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]);
224   }
225
226   if (size) {
227     auto& values_size = key_info->GetValuesSize();
228     *size = reinterpret_cast<size_t>(values_size[0]);
229   }
230
231   return BUNDLE_ERROR_NONE;
232 }
233
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) {
236   if (kv == nullptr)
237     return BUNDLE_ERROR_INVALID_PARAMETER;
238
239   auto* key_info = reinterpret_cast<KeyInfo*>(kv);
240   if (!key_info->IsArray())
241     return BUNDLE_ERROR_INVALID_PARAMETER;
242
243   auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
244       key_info->GetValues());
245
246   if (array_val)
247     *array_val = reinterpret_cast<void**>(&values[0]);
248
249   if (array_len)
250     *array_len = static_cast<unsigned int>(values.size());
251
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]);
256   }
257
258   return BUNDLE_ERROR_NONE;
259 }
260
261 extern "C" EXPORT_API bundle_keyval_t* bundle_keyval_dup(
262     const bundle_keyval_t* kv) {
263   if (kv == nullptr) {
264     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
265     return nullptr;
266   }
267
268   auto* keyval = const_cast<bundle_keyval_t*>(kv);
269   auto* key_info = reinterpret_cast<KeyInfo*>(keyval);
270
271   KeyInfo* k;
272   try {
273     k = new KeyInfo(*key_info);
274   } catch (const Exception& e) {
275     set_last_result(e.GetErrorCode());
276     return nullptr;
277   } catch (const std::bad_alloc& ba) {
278     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
279     return nullptr;
280   }
281
282   set_last_result(BUNDLE_ERROR_NONE);
283   return reinterpret_cast<bundle_keyval_t*>(k);
284 }
285
286 extern "C" EXPORT_API int bundle_keyval_free(bundle_keyval_t* kv) {
287   if (kv == nullptr)
288     return BUNDLE_ERROR_INVALID_PARAMETER;
289
290   auto* key_info = reinterpret_cast<KeyInfo*>(kv);
291   delete key_info;
292   return BUNDLE_ERROR_NONE;
293 }
294
295 extern "C" EXPORT_API bundle* bundle_dup(bundle* b_from) {
296   if (b_from == nullptr) {
297     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
298     return nullptr;
299   }
300
301   auto* h = reinterpret_cast<Bundle*>(b_from);
302   auto* b = new (std::nothrow) Bundle(*h);
303   if (b == nullptr) {
304     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
305     return nullptr;
306   }
307
308   set_last_result(BUNDLE_ERROR_NONE);
309   return reinterpret_cast<bundle*>(b);
310 }
311
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;
315
316   auto* h = reinterpret_cast<Bundle*>(b);
317   try {
318     *raw = reinterpret_cast<bundle_raw*>(h->Encode());
319   } catch (const Exception& e) {
320     *raw = nullptr;
321     return e.GetErrorCode();
322   }
323
324   *len = strlen(reinterpret_cast<char*>(*raw));
325   return BUNDLE_ERROR_NONE;
326 }
327
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;
331
332   free(*r);
333   *r = nullptr;
334   return BUNDLE_ERROR_NONE;
335 }
336
337 extern "C" EXPORT_API bundle* bundle_decode(const bundle_raw* r,
338     const int data_size) {
339   if (r == nullptr) {
340     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
341     return nullptr;
342   }
343
344   Bundle* b = nullptr;
345   try {
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());
350     return nullptr;
351   } catch (const std::bad_alloc& ba) {
352     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
353     return nullptr;
354   }
355
356   set_last_result(BUNDLE_ERROR_NONE);
357   return reinterpret_cast<bundle*>(b);
358 }
359
360 extern "C" EXPORT_API int bundle_encode_raw(bundle* b, bundle_raw** r,
361     int* len) {
362   if (b == nullptr || r == nullptr || len == nullptr)
363     return BUNDLE_ERROR_INVALID_PARAMETER;
364
365   auto* h = reinterpret_cast<Bundle*>(b);
366   try {
367     *r = reinterpret_cast<bundle_raw*>(h->EncodeRaw(len));
368   } catch (const Exception& e) {
369     return e.GetErrorCode();
370   }
371   return BUNDLE_ERROR_NONE;
372 }
373
374 extern "C" EXPORT_API bundle* bundle_decode_raw(const bundle_raw* r,
375     const int data_size) {
376   if (r == nullptr) {
377     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
378     return nullptr;
379   }
380
381   Bundle* b = nullptr;
382   try {
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());
387     return nullptr;
388   } catch (const std::bad_alloc& ba) {
389     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
390     return nullptr;
391   }
392
393   set_last_result(BUNDLE_ERROR_NONE);
394   return reinterpret_cast<bundle*>(b);
395 }
396
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;
401   }
402
403   auto* h = reinterpret_cast<Bundle*>(b);
404   std::shared_ptr<KeyInfo> key_info;
405   try {
406     key_info = h->Get(key);
407   } catch (const Exception& e) {
408     set_last_result(e.GetErrorCode());
409     return BUNDLE_TYPE_NONE;
410   }
411
412   set_last_result(BUNDLE_ERROR_NONE);
413   return key_info->GetType();
414 }
415
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;
420
421   auto* h = reinterpret_cast<Bundle*>(b);
422   std::vector<std::vector<unsigned char>> values(len);
423   if (str_array) {
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);
428     }
429   }
430
431   try {
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;
439   }
440
441   return BUNDLE_ERROR_NONE;
442 }
443
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);
448     return nullptr;
449   }
450
451   auto* h = reinterpret_cast<Bundle*>(b);
452   std::shared_ptr<KeyInfo> key_info;
453   try {
454     key_info = h->Get(key);
455   } catch (const Exception& e) {
456     set_last_result(e.GetErrorCode());
457     return nullptr;
458   }
459
460   if (key_info->GetType() != BUNDLE_TYPE_STR_ARRAY) {
461     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
462     return nullptr;
463   }
464
465   set_last_result(BUNDLE_ERROR_NONE);
466
467   auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
468       key_info->GetValues());
469
470   if (len)
471     *len = static_cast<int>(raw_values.size());
472
473   if (raw_values.size() == 0)
474     return nullptr;
475
476   auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
477   return const_cast<const char**>(reinterpret_cast<char**>(values));
478 }
479
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;
484
485   auto* h = reinterpret_cast<Bundle*>(b);
486   auto* p = reinterpret_cast<const unsigned char*>(bytes);
487   std::vector<unsigned char> value;
488   if (bytes)
489     value.insert(value.end(), p, p + size);
490
491   KeyInfo* key_info;
492   try {
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;
498   }
499
500   try {
501     h->Add(std::shared_ptr<KeyInfo>(key_info));
502   } catch (const Exception& e) {
503     return e.GetErrorCode();
504   }
505
506   return BUNDLE_ERROR_NONE;
507 }
508
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;
513
514   auto* h = reinterpret_cast<Bundle*>(b);
515   std::shared_ptr<KeyInfo> key_info;
516   try {
517     key_info = h->Get(key);
518   } catch (const Exception& e) {
519     return e.GetErrorCode();
520   }
521
522   if (key_info->GetType() != BUNDLE_TYPE_BYTE)
523     return BUNDLE_ERROR_INVALID_PARAMETER;
524
525   if (bytes) {
526     auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
527         key_info->GetValues());
528     if (values.size() == 0) {
529       *bytes = nullptr;
530     } else {
531       auto& value = values[0];
532       *bytes = reinterpret_cast<void*>(&value[0]);
533     }
534   }
535
536   if (size) {
537     auto& values_size = key_info->GetValuesSize();
538     *size = reinterpret_cast<size_t>(values_size[0]);
539   }
540
541   return BUNDLE_ERROR_NONE;
542 }
543
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);
547     return -1;
548   }
549
550   auto* h = reinterpret_cast<Bundle*>(b);
551   std::vector<std::string> exported_vt;
552   try {
553     exported_vt = h->Export();
554   } catch (const Exception& e) {
555     set_last_result(e.GetErrorCode());
556     return -1;
557   }
558
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);
564     return -1;
565   }
566
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);
573       return -1;
574     }
575
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);
580       return -1;
581     }
582   }
583
584   *argv = exported_argv;
585   set_last_result(BUNDLE_ERROR_NONE);
586   return argc;
587 }
588
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;
592
593   for (int i = 2; i < argc; i++)
594     std::free((*argv)[i]);
595
596   std::free(*argv);
597   *argv = nullptr;
598
599   return BUNDLE_ERROR_NONE;
600 }
601
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);
605     return nullptr;
606   }
607
608   Bundle* b = nullptr;
609   try {
610     b = new (std::nothrow) Bundle(argc, argv);
611   } catch (const Exception& e) {
612     set_last_result(e.GetErrorCode());
613     return nullptr;
614   }
615
616   set_last_result(BUNDLE_ERROR_NONE);
617   return reinterpret_cast<bundle*>(b);
618 }
619
620 extern "C" EXPORT_API int bundle_compare(bundle* b1, bundle* b2) {
621   if (b1 == nullptr || b2 == nullptr)
622     return -1;
623
624   auto* h1 = reinterpret_cast<Bundle*>(b1);
625   auto* h2 = reinterpret_cast<Bundle*>(b2);
626   if (*h1 == *h2)
627     return 0;
628
629   return 1;
630 }
631
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;
636
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);
640
641   auto* h = reinterpret_cast<Bundle*>(b);
642   try {
643     h->Set(key, idx, std::move(value));
644   } catch (const Exception& e) {
645     return e.GetErrorCode();
646   }
647
648   return BUNDLE_ERROR_NONE;
649 }
650
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);
654 }
655
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;
660
661   auto* h = reinterpret_cast<Bundle*>(b);
662
663   KeyInfo* key_info;
664   try {
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;
673   }
674
675   try {
676     h->Add(std::shared_ptr<KeyInfo>(key_info));
677   } catch (const Exception& e) {
678     return e.GetErrorCode();
679   }
680
681   return BUNDLE_ERROR_NONE;
682 }
683
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;
689
690   auto* h = reinterpret_cast<Bundle*>(b);
691   std::shared_ptr<KeyInfo> key_info;
692   try {
693     key_info = h->Get(key);
694   } catch (const Exception& e) {
695     return e.GetErrorCode();
696   }
697
698   if (key_info->GetType() != BUNDLE_TYPE_BYTE_ARRAY)
699     return BUNDLE_ERROR_INVALID_PARAMETER;
700
701   auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
702       key_info->GetValues());
703
704   if (bytes_array) {
705     auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
706     *bytes_array = reinterpret_cast<void**>(values);
707   }
708
709   if (len)
710     *len = static_cast<unsigned int>(raw_values.size());
711
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]);
716   }
717
718   return BUNDLE_ERROR_NONE;
719 }
720
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;
726
727   std::vector<unsigned char> value;
728   if (bytes) {
729     auto* p = reinterpret_cast<unsigned char*>(const_cast<void*>(bytes));
730     value.insert(value.end(), p, p + size);
731   }
732
733   auto* h = reinterpret_cast<Bundle*>(b);
734   try {
735     h->Set(key, idx, std::move(value));
736   } catch (const Exception& e) {
737     return e.GetErrorCode();
738   }
739
740   return BUNDLE_ERROR_NONE;
741 }
742
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;
746
747   auto* h = reinterpret_cast<Bundle*>(b);
748   Json js(h);
749   try {
750     *json = strdup(js.ToString().c_str());
751   } catch (const Exception& e) {
752     return e.GetErrorCode();
753   }
754
755   return BUNDLE_ERROR_NONE;
756 }
757
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;
761
762   Json js(json);
763   try {
764     *b = reinterpret_cast<bundle*>(js.ToBundle());
765   } catch (const Exception& e) {
766     return e.GetErrorCode();
767   }
768
769   return BUNDLE_ERROR_NONE;
770 }