Fix wrong implementation about encoding & decoding bundle raw
[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 = bundle_create();
373   if (b == nullptr)
374     return nullptr;
375
376   auto* h = reinterpret_cast<Bundle*>(b);
377   auto* raw = const_cast<bundle_raw*>(r);
378   int ret = h->DecodeRaw(static_cast<unsigned char*>(raw), data_size);
379   if (ret != BUNDLE_ERROR_NONE) {
380     bundle_free(b);
381     set_last_result(ret);
382     return nullptr;
383   }
384
385   set_last_result(BUNDLE_ERROR_NONE);
386   return b;
387 }
388
389 extern "C" EXPORT_API int bundle_get_type(bundle* b, const char* key) {
390   if (b == nullptr || key == nullptr) {
391     set_last_result(BUNDLE_ERROR_KEY_NOT_AVAILABLE);
392     return BUNDLE_TYPE_NONE;
393   }
394
395   auto* h = reinterpret_cast<Bundle*>(b);
396   std::shared_ptr<KeyInfo> key_info;
397   try {
398     key_info = h->Get(key);
399   } catch (Exception& e) {
400     set_last_result(e.GetErrorCode());
401     return BUNDLE_TYPE_NONE;
402   }
403
404   set_last_result(BUNDLE_ERROR_NONE);
405   return key_info->GetType();
406 }
407
408 extern "C" EXPORT_API int bundle_add_str_array(bundle* b, const char* key,
409     const char** str_array, const int len) {
410   if (b == nullptr || key == nullptr || strlen(key) == 0)
411     return BUNDLE_ERROR_INVALID_PARAMETER;
412
413   auto* h = reinterpret_cast<Bundle*>(b);
414   std::vector<std::vector<unsigned char>> values(len);
415   if (str_array) {
416     for (int i = 0; i < len; ++i) {
417       std::vector<unsigned char> value(str_array[i],
418           str_array[i] + (strlen(str_array[i]) + 1));
419       values[i] = std::move(value);
420     }
421   }
422
423   KeyInfo* key_info;
424   try {
425     key_info = new KeyInfo((BUNDLE_TYPE_STR_ARRAY | BUNDLE_TYPE_ARRAY),
426         key, values);
427   } catch (Exception& e) {
428     return e.GetErrorCode();
429   }
430
431   try {
432     h->Add(std::shared_ptr<KeyInfo>(key_info));
433   } catch (Exception& e) {
434     return e.GetErrorCode();
435   }
436
437   return BUNDLE_ERROR_NONE;
438 }
439
440 extern "C" EXPORT_API const char** bundle_get_str_array(bundle* b,
441     const char* key, int* len) {
442   if (b == nullptr || key == nullptr) {
443     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
444     return nullptr;
445   }
446
447   auto* h = reinterpret_cast<Bundle*>(b);
448   std::shared_ptr<KeyInfo> key_info;
449   try {
450     key_info = h->Get(key);
451   } catch (Exception& e) {
452     set_last_result(e.GetErrorCode());
453     return nullptr;
454   }
455
456   if (key_info->GetType() != BUNDLE_TYPE_STR_ARRAY) {
457     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
458     return nullptr;
459   }
460
461   set_last_result(BUNDLE_ERROR_NONE);
462
463   auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
464       key_info->GetValues());
465
466   if (len)
467     *len = static_cast<int>(raw_values.size());
468
469   if (raw_values.size() == 0)
470     return nullptr;
471
472   auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
473   return const_cast<const char**>(reinterpret_cast<char**>(values));
474 }
475
476 extern "C" EXPORT_API int bundle_add_byte(bundle* b, const char* key,
477     const void* bytes, const size_t size) {
478   if (b == nullptr || key == nullptr || strlen(key) == 0)
479     return BUNDLE_ERROR_INVALID_PARAMETER;
480
481   auto* h = reinterpret_cast<Bundle*>(b);
482   auto* p = reinterpret_cast<const unsigned char*>(bytes);
483   std::vector<unsigned char> value;
484   if (bytes)
485     std::copy(p, p + size, std::back_inserter(value));
486
487   KeyInfo* key_info;
488   try {
489     key_info = new KeyInfo(BUNDLE_TYPE_BYTE, key, value);
490   } catch (Exception& e) {
491     return e.GetErrorCode();
492   } catch (const std::bad_alloc& ba) {
493     return BUNDLE_ERROR_OUT_OF_MEMORY;
494   }
495
496   try {
497     h->Add(std::shared_ptr<KeyInfo>(key_info));
498   } catch (Exception& e) {
499     return e.GetErrorCode();
500   }
501
502   return BUNDLE_ERROR_NONE;
503 }
504
505 extern "C" EXPORT_API int bundle_get_byte(bundle* b, const char* key,
506     void** bytes, size_t* size) {
507   if (b == nullptr || key == nullptr)
508     return BUNDLE_ERROR_INVALID_PARAMETER;
509
510   auto* h = reinterpret_cast<Bundle*>(b);
511   std::shared_ptr<KeyInfo> key_info;
512   try {
513     key_info = h->Get(key);
514   } catch (Exception& e) {
515     return e.GetErrorCode();
516   }
517
518   if (key_info->GetType() != BUNDLE_TYPE_BYTE)
519     return BUNDLE_ERROR_INVALID_PARAMETER;
520
521   if (bytes) {
522     auto& values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
523         key_info->GetValues());
524     if (values.size() == 0) {
525       *bytes = nullptr;
526     } else {
527       auto& value = values[0];
528       *bytes = reinterpret_cast<void*>(&value[0]);
529     }
530   }
531
532   if (size) {
533     auto& values_size = key_info->GetValuesSize();
534     *size = reinterpret_cast<size_t>(values_size[0]);
535   }
536
537   return BUNDLE_ERROR_NONE;
538 }
539
540 extern "C" EXPORT_API int bundle_export_to_argv(bundle* b, char*** argv) {
541   if (b == nullptr || argv == nullptr) {
542     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
543     return -1;
544   }
545
546   auto* h = reinterpret_cast<Bundle*>(b);
547   std::vector<std::string> exported_vt;
548   try {
549     exported_vt = h->Export();
550   } catch (Exception& e) {
551     set_last_result(e.GetErrorCode());
552     return -1;
553   }
554
555   int argc = exported_vt.size();
556   auto** exported_argv = reinterpret_cast<char**>(
557       calloc(argc + 1, sizeof(char*)));
558   if (exported_argv == nullptr) {
559     set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
560     return -1;
561   }
562
563   exported_argv[1] = const_cast<char*>(TAG_IMPORT_EXPORT_CHECK);
564   for (unsigned int idx = 2; idx < exported_vt.size(); idx += 2) {
565     exported_argv[idx] = strdup(exported_vt[idx].c_str());
566     if (exported_argv[idx] == nullptr) {
567       set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
568       bundle_free_exported_argv(argc, &exported_argv);
569       return -1;
570     }
571
572     exported_argv[idx + 1] = strdup(exported_vt[idx + 1].c_str());
573     if (exported_argv[idx + 1] == nullptr) {
574       set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
575       bundle_free_exported_argv(argc, &exported_argv);
576       return -1;
577     }
578   }
579
580   *argv = exported_argv;
581   set_last_result(BUNDLE_ERROR_NONE);
582   return argc;
583 }
584
585 extern "C" EXPORT_API int bundle_free_exported_argv(int argc, char*** argv) {
586   if (argc < 2 || !argv || !*argv)
587     return BUNDLE_ERROR_INVALID_PARAMETER;
588
589   for (int i = 2; i < argc; i++)
590     std::free((*argv)[i]);
591
592   std::free(*argv);
593   *argv = nullptr;
594
595   return BUNDLE_ERROR_NONE;
596 }
597
598 extern "C" EXPORT_API bundle* bundle_import_from_argv(int argc, char** argv) {
599   if (argv == nullptr) {
600     set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
601     return nullptr;
602   }
603
604   Bundle* b = nullptr;
605   try {
606     b = new (std::nothrow) Bundle(argc, argv);
607   } catch (Exception& e) {
608     set_last_result(e.GetErrorCode());
609     return nullptr;
610   }
611
612   set_last_result(BUNDLE_ERROR_NONE);
613   return reinterpret_cast<bundle*>(b);
614 }
615
616 extern "C" EXPORT_API int bundle_compare(bundle* b1, bundle* b2) {
617   if (b1 == nullptr || b2 == nullptr)
618     return -1;
619
620   auto* h1 = reinterpret_cast<Bundle*>(b1);
621   auto* h2 = reinterpret_cast<Bundle*>(b2);
622   if (*h1 == *h2)
623     return 0;
624
625   return 1;
626 }
627
628 extern "C" EXPORT_API int bundle_set_str_array_element(bundle* b,
629     const char* key, const unsigned int idx, const char* val) {
630   if (b == nullptr || key == nullptr || val == nullptr)
631     return BUNDLE_ERROR_INVALID_PARAMETER;
632
633   auto len = strlen(val) + 1;
634   auto* p = reinterpret_cast<unsigned char*>(const_cast<char*>(val));
635   std::vector<unsigned char> value(p, p + len);
636
637   auto* h = reinterpret_cast<Bundle*>(b);
638   try {
639     h->Set(key, idx, value);
640   } catch (Exception& e) {
641     return e.GetErrorCode();
642   }
643
644   return BUNDLE_ERROR_NONE;
645 }
646
647 extern "C" EXPORT_API int bundle_add_byte_array(bundle* b,
648     const char* key, const unsigned int len) {
649   return bundle_init_byte_array(b, key, len);
650 }
651
652 extern "C" EXPORT_API int bundle_init_byte_array(bundle* b,
653     const char* key, const unsigned int len) {
654   if (b == nullptr || key == nullptr || strlen(key) == 0)
655     return BUNDLE_ERROR_INVALID_PARAMETER;
656
657   auto* h = reinterpret_cast<Bundle*>(b);
658
659   KeyInfo* key_info;
660   try {
661     std::vector<std::vector<unsigned char>> values(len);
662     key_info = new KeyInfo(Bundle::Type::ByteArray, key, values);
663   } catch (Exception& e) {
664     return e.GetErrorCode();
665   } catch (const std::bad_alloc& ba) {
666     return BUNDLE_ERROR_OUT_OF_MEMORY;
667   }
668
669   try {
670     h->Add(std::shared_ptr<KeyInfo>(key_info));
671   } catch (Exception& e) {
672     return e.GetErrorCode();
673   }
674
675   return BUNDLE_ERROR_NONE;
676 }
677
678 extern "C" EXPORT_API int bundle_get_byte_array(bundle* b,
679     const char* key, void*** bytes_array, unsigned int* len,
680     unsigned int** array_element_size) {
681   if (b == nullptr || key == nullptr)
682     return BUNDLE_ERROR_INVALID_PARAMETER;
683
684   auto* h = reinterpret_cast<Bundle*>(b);
685   std::shared_ptr<KeyInfo> key_info;
686   try {
687     key_info = h->Get(key);
688   } catch (Exception& e) {
689     return e.GetErrorCode();
690   }
691
692   if (key_info->GetType() != BUNDLE_TYPE_BYTE_ARRAY)
693     return BUNDLE_ERROR_INVALID_PARAMETER;
694
695   auto& raw_values = const_cast<std::vector<std::unique_ptr<unsigned char[]>>&>(
696       key_info->GetValues());
697
698   if (bytes_array) {
699     auto** values = reinterpret_cast<unsigned char**>(&raw_values[0]);
700     *bytes_array = reinterpret_cast<void**>(values);
701   }
702
703   if (len)
704     *len = static_cast<unsigned int>(raw_values.size());
705
706   if (array_element_size) {
707     auto& raw_values_size = const_cast<std::vector<unsigned int>&>(
708         key_info->GetUValuesSize());
709     *array_element_size = reinterpret_cast<unsigned int*>(&raw_values_size[0]);
710   }
711
712   return BUNDLE_ERROR_NONE;
713 }
714
715 extern "C" EXPORT_API int bundle_set_byte_array_element(bundle* b,
716     const char* key, const unsigned int idx,
717     const void* bytes, const size_t size) {
718   if (b == nullptr || key == nullptr || size <= 0)
719     return BUNDLE_ERROR_INVALID_PARAMETER;
720
721   std::vector<unsigned char> value;
722   if (bytes) {
723     auto* p = reinterpret_cast<unsigned char*>(const_cast<void*>(bytes));
724     std::copy(p, p + size, std::back_inserter(value));
725   }
726
727   auto* h = reinterpret_cast<Bundle*>(b);
728   try {
729     h->Set(key, idx, value);
730   } catch (Exception& e) {
731     return e.GetErrorCode();
732   }
733
734   return BUNDLE_ERROR_NONE;
735 }
736
737 extern "C" EXPORT_API int bundle_to_json(bundle* b, char** json) {
738   if (b == nullptr || json == nullptr)
739     return BUNDLE_ERROR_INVALID_PARAMETER;
740
741   auto* h = reinterpret_cast<Bundle*>(b);
742   Json js(h);
743   try {
744     *json = strdup(js.ToString().c_str());
745   } catch (Exception& e) {
746     return e.GetErrorCode();
747   }
748
749   return BUNDLE_ERROR_NONE;
750 }
751
752 extern "C" EXPORT_API int bundle_from_json(const char* json, bundle** b) {
753   if (json == nullptr || b == nullptr)
754     return BUNDLE_ERROR_INVALID_PARAMETER;
755
756   Json js(json);
757   try {
758     *b = reinterpret_cast<bundle*>(js.ToBundle());
759   } catch (Exception& e) {
760     return e.GetErrorCode();
761   }
762
763   return BUNDLE_ERROR_NONE;
764 }