4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7 * Jaeho Lee <jaeho81.lee@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
31 #include "keyval_array.h"
32 #include "keyval_type.h"
33 #include "bundle_log.h"
34 #include <glib/gbase64.h>
36 #include <stdlib.h> /* calloc, free */
37 #include <string.h> /* strdup */
49 * Find a kv from bundle
52 _bundle_find_kv(bundle *b, const char *key)
56 if(NULL == b) { errno = EINVAL; return NULL; }
57 if(NULL == key) { errno = EKEYREJECTED; return NULL; }
61 if(0 == strcmp(key, kv->key)) return kv;
70 * Append kv into bundle
73 _bundle_append_kv(bundle *b, keyval_t *new_kv)
77 if (NULL == b->kv_head) b->kv_head = new_kv;
80 while (NULL != kv->next) kv = kv->next;
87 _bundle_add_kv(bundle *b, const char *key, const void *val, const size_t size, const int type, const unsigned int len)
89 /* basic value check */
90 if(NULL == b) { errno = EINVAL; return -1; }
91 if(NULL == key) { errno = EKEYREJECTED; return -1; }
92 if(0 == strlen(key)) { errno = EKEYREJECTED; return -1; }
94 keyval_t *kv = _bundle_find_kv(b, key);
95 if(kv) { /* Key already exists */
101 keyval_t *new_kv = NULL;
102 if(keyval_type_is_array(type)) {
104 keyval_array_t *kva = keyval_array_new(NULL, key, type, (const void **) val, len);
105 new_kv = (keyval_t *)kva;
109 new_kv = keyval_new(NULL, key, type, val, size);
112 // NOTE: errno is already set. (ENOMEM, ...)
116 _bundle_append_kv(b, new_kv);
123 _bundle_get_val(bundle *b, const char *key, const int type, void **val, size_t *size, unsigned int *len, size_t **array_element_size)
125 keyval_t *kv = _bundle_find_kv(b, key);
126 if(!kv) { /* Key doesn't exist */
127 /* NOTE: errno is already set. */
130 if(BUNDLE_TYPE_ANY != type && type != kv->type) {
135 if(keyval_type_is_array(type)) {
136 keyval_array_t *kva = (keyval_array_t *)kv;
137 keyval_array_get_data(kva, NULL, (void ***)val, len, array_element_size);
140 keyval_get_data(kv, NULL, val, size);
146 /** global initialization
150 _bundle_global_init(void)
152 static int _is_done = 0;
155 // Run init functions
169 _bundle_global_init();
171 b = calloc(1, sizeof(bundle)); /* fill mem with NULL */
173 BUNDLE_EXCEPTION_PRINT("Unable to allocate memory for bundle\n");
181 if(NULL != b) bundle_free(b);
186 bundle_free(bundle *b)
188 keyval_t *kv, *tmp_kv;
191 BUNDLE_EXCEPTION_PRINT("Bundle is already freed\n");
196 /* Free keyval list */
201 tmp_kv->method->free(tmp_kv, 1);
211 bundle_add_str(bundle *b, const char *key, const char *str)
213 if(!str) { errno = EINVAL; return -1; }
214 return _bundle_add_kv(b, key, str, strlen(str)+1, BUNDLE_TYPE_STR, 1);
218 bundle_get_str(bundle *b, const char *key, char **str)
220 return _bundle_get_val(b, key, BUNDLE_TYPE_STR, (void **) str, NULL, NULL, NULL);
224 bundle_add(bundle *b, const char *key, const char *val)
226 return bundle_add_str(b, key, val);
230 bundle_del(bundle *b, const char *key)
232 keyval_t *kv = NULL, *prev_kv = NULL;
234 /* basic value check */
235 if(NULL == b) { errno = EINVAL; return -1; }
236 if(NULL == key) { errno = EKEYREJECTED; return -1; }
237 if(0 == strlen(key)) { errno = EKEYREJECTED; return -1; }
241 if(0 == strcmp(key, kv->key)) break;
245 if (NULL == kv) { errno = ENOKEY; return -1; }
247 if(NULL != prev_kv) {
248 prev_kv->next = kv->next;
250 if(kv == b->kv_head) b->kv_head = kv->next;
251 kv->method->free(kv, 1);
258 bundle_get_val(bundle *b, const char *key)
263 r = bundle_get_str(b, key, &val);
269 * @brief used by bundle_get_count() API, to count number of items in a bundle
272 _bundle_get_count_iter(const char *k, const int type, const bundle_keyval_t *kv, void *user_data)
274 int *count = (int *)user_data;
279 bundle_get_count (bundle *b)
282 if (NULL == b) return count;
283 bundle_foreach(b, _bundle_get_count_iter, &count);
288 bundle_iterate(bundle *b, bundle_iterate_cb_t callback, void *data)
290 keyval_t *kv = b->kv_head;
293 callback(kv->key, kv->val, data);
300 bundle_foreach(bundle *b, bundle_iterator_t iter, void *user_data)
304 return; /*TC_FIX if b=NULL- error handling */
306 keyval_t *kv = b->kv_head;
309 iter(kv->key, kv->type, kv, user_data);
315 /* keyval functions */
317 bundle_keyval_get_type(bundle_keyval_t *kv)
323 bundle_keyval_type_is_array(bundle_keyval_t *kv)
325 return keyval_type_is_array(kv->type);
329 bundle_keyval_get_basic_val(bundle_keyval_t *kv, void **val, size_t *size)
331 return keyval_get_data(kv, NULL, val, size);
335 bundle_keyval_get_array_val(bundle_keyval_t *kv, void ***array_val, unsigned int *array_len, size_t **array_item_size)
337 return keyval_array_get_data((keyval_array_t *)kv, NULL, array_val, array_len, array_item_size);
342 _iter_do_bundle_dup(const char *key, const void *val, const int type, const size_t size, const unsigned int len, void *user_data)
345 bundle *b_to = (bundle *)user_data;
347 _bundle_add_kv(b_to, key, val, size, type, len);
352 bundle_dup(bundle *b_from)
357 if(NULL == b_from) { errno = EINVAL; return NULL; }
358 b_to = bundle_create();
359 if(NULL == b_to) return NULL;
361 keyval_t *kv_from = b_from->kv_head;
362 keyval_t *kv_to = NULL;
363 while(kv_from != NULL) {
364 if(keyval_type_is_array(kv_from->type)) {
365 keyval_array_t *kva_from = (keyval_array_t *)kv_from;
366 kv_to = (keyval_t *) keyval_array_new(NULL, kv_from->key, kv_from->type, NULL, kva_from->len);
367 if(!kv_to) goto ERR_CLEANUP;
368 for(i=0; i < kva_from->len; i++) {
369 if(((keyval_array_t *)kv_from)->array_val[i]) {
370 keyval_array_set_element((keyval_array_t*)kv_to, i, ((keyval_array_t *)kv_from)->array_val[i], ((keyval_array_t *)kv_from)->array_element_size[i]);
373 _bundle_append_kv(b_to, kv_to);
376 if(_bundle_add_kv(b_to, kv_from->key, kv_from->val, kv_from->size, kv_from->type, 0)) goto ERR_CLEANUP;
379 kv_from = kv_from->next;
390 bundle_encode(bundle *b, bundle_raw **r, int *len)
399 /* calculate memory size */
400 size_t msize = 0; // Sum of required size
404 msize += kv->method->get_encoded_size(kv);
407 unsigned char *m = calloc(msize, sizeof(unsigned char));
408 if ( NULL == m ) { errno = ENOMEM; return -1; }
410 unsigned char *p_m = m; /* temporary pointer */
420 kv->method->encode(kv, &byte, &byte_len);
421 memcpy(p_m, byte, byte_len);
430 *r =(unsigned char*)g_base64_encode(m, msize);
431 if ( NULL != len ) *len = strlen((char*)*r);
439 bundle_free_encoded_rawdata(bundle_raw **r)
441 if(!*r) return -1; /*TC_FIX - double free sigabrt handling */
449 bundle_decode(const bundle_raw *r, const int data_size)
461 d_r = g_base64_decode((char*)r, &d_len);
463 /* re-construct bundle */
466 p_r = (bundle_raw *)d_r;
471 while(p_r < d_r + d_len - 1) {
472 kv = NULL; // To get a new kv
474 // Find type, and use decode function according to type
475 int type = keyval_get_type_from_encoded_byte(p_r);
477 if(keyval_type_is_array(type)) {
478 bytes_read = keyval_array_decode(p_r, (keyval_array_t **) &kv);
481 bytes_read = keyval_decode(p_r, &kv);
484 if(kv) _bundle_append_kv(b, kv);
502 _iter_export_to_argv(const char *key, const int type, const keyval_t *kv, void *user_data)
504 struct _argv_idx *vi = (struct _argv_idx *)user_data;
506 vi->argv[vi->idx] = (char *)key;
508 unsigned char *byte = NULL, *encoded_byte = NULL;
511 if(0 == kv->method->encode((struct keyval_t *)kv, &byte, &byte_len)) {
512 // TODO: encode FAILED!
513 BUNDLE_EXCEPTION_PRINT("bundle: FAILED to encode keyval: %s\n", key);
518 encoded_byte =(unsigned char *) g_base64_encode(byte, byte_len);
519 if(NULL == encoded_byte) {
520 BUNDLE_EXCEPTION_PRINT("bundle: failed to encode byte\n");
524 vi->argv[vi->idx + 1] =(char*)encoded_byte;
531 bundle_export_to_argv(bundle *b, char ***argv)
533 int argc, item_count;
535 item_count = bundle_get_count(b);
536 argc = 2 * item_count + 2; /* 2 more count for argv[0] and arv[1] = encoded */
537 *argv = calloc(argc + 1, sizeof(char *));
538 if(!*argv) return -1;
543 vi.idx = 2; /* start from index 2*/
544 vi.argv[1]="`zaybxcwdveuftgsh`"; /* set argv[1] as encoded*/
545 /*BUNDLE_LOG_PRINT("\nargument 1 is %s",vi.argv[1]);*/
547 bundle_foreach(b, _iter_export_to_argv, &vi);
552 int bundle_free_exported_argv(int argc, char ***argv)
554 if(!*argv) return -1; /*TC_FIX : fix for double free- sigabrt */
557 for(i=1; i < argc; i+=2) {
567 bundle_import_from_argv(int argc, char **argv)
569 if(!argv) return NULL; /* TC_FIX error handling for argv =NULL*/
571 bundle *b = bundle_create();
577 for(i=0; i<argc; i++) {
578 BUNDLE_LOG_PRINT("[bundle-dbg] argv[%d]='%s'\n", i, argv[i]);
582 if(!argv[1]||strcmp(argv[1],"`zaybxcwdveuftgsh`"))
584 /*BUNDLE_LOG_PRINT("\nit is not encoded");*/
586 for (idx = 1; idx < argc; idx = idx + 2) { /*start idx from one as argv[1] is user given argument*/
587 bundle_add(b, argv[idx], argv[idx + 1]);
591 /*BUNDLE_LOG_PRINT("\nit is encoded");*/
594 keyval_array_t *kva = NULL;
595 unsigned char *byte = NULL;
597 unsigned int byte_size;
598 for(idx = 2; idx < argc; idx = idx+2) { // start idx from 2 as argv[1] is encoded
602 encoded_byte = argv[idx+1];
605 byte = g_base64_decode(encoded_byte, &byte_size);
606 if(NULL == byte) goto err_cleanup;
608 type = keyval_get_type_from_encoded_byte(byte);
609 if(keyval_type_is_array(type)) {
610 if(0 == keyval_array_decode(byte, &kva)) {
612 BUNDLE_EXCEPTION_PRINT("Unable to Decode array\n");
614 kv = (keyval_t *)kva;
617 if(0 == keyval_decode(byte, &kv)) {
619 BUNDLE_EXCEPTION_PRINT("Unable to Decode\n");
622 _bundle_append_kv(b, kv);
631 if(b) bundle_free(b);
639 bundle_get_type(bundle *b, const char *key)
641 keyval_t *kv = _bundle_find_kv(b, key);
642 if(kv) return kv->type;
645 return BUNDLE_TYPE_NONE;
650 /** Get length of an array
653 bundle_get_array_len(bundle *b, const char *key)
658 /** Get size of an item in byte, of given pointer
661 bundle_get_array_val_size(bundle *b, const char *key, const void *val_ptr)
666 bundle_set_array_val(bundle *b, const char *key, const int type, const unsigned int idx, const void *val, const size_t size)
668 //void **array = NULL;
670 keyval_t *kv = _bundle_find_kv(b, key);
671 if(NULL == kv) return -1;
673 if(type != kv->type) {
678 if(! keyval_type_is_array(kv->type)) { // TODO: Is this needed?
683 keyval_array_t *kva = (keyval_array_t *)kv;
685 if(! keyval_array_is_idx_valid(kva, idx)) {
690 if(!kva->array_val) { // NULL value test (TODO: is this needed?)
695 return keyval_array_set_element(kva, idx, val, size);
700 bundle_add_str_array(bundle *b, const char *key, const char **str_array, const int len)
702 return _bundle_add_kv(b, key, str_array, 0, BUNDLE_TYPE_STR_ARRAY, len);
707 bundle_get_val_array(bundle *b, const char *key, char ***str_array, int *len)
709 return _bundle_get_val(b, key, BUNDLE_TYPE_STR_ARRAY, (void **) str_array, NULL,(unsigned int *)len, NULL);
712 const char ** bundle_get_str_array(bundle *b, const char *key,int *len)
714 const char **arr_val = NULL;
717 r = bundle_get_val_array(b,key,(char***)&arr_val,len);
724 bundle_compare(bundle *b1, bundle *b2)
726 if(!b1 || !b2) return -1;
729 //keyval_array_t *kva1, *kva2;
732 if(bundle_get_count(b1) != bundle_get_count(b2)) return 1;
733 for(kv1 = b1->kv_head; kv1 != NULL; kv1 = kv1->next) {
734 kv2 = _bundle_find_kv(b2, kv1->key);
736 if(kv1->method->compare(kv1, kv2)) return 1;
745 bundle_set_str_array_element(bundle *b, const char *key, const unsigned int idx, const char *val)
751 return bundle_set_array_val(b, key, BUNDLE_TYPE_STR_ARRAY, idx, val, strlen(val)+1);
757 bundle_add_byte(bundle *b, const char *key, const void *byte, const size_t size)
759 return _bundle_add_kv(b, key, byte, size, BUNDLE_TYPE_BYTE, 1);
763 bundle_get_byte(bundle *b, const char *key, void **byte, size_t *size)
765 return _bundle_get_val(b, key, BUNDLE_TYPE_BYTE, (void **) byte, size, NULL, NULL);
769 bundle_add_byte_array(bundle *b, const char *key, void **byte_array, const unsigned int len)
771 return _bundle_add_kv(b, key, byte_array, 0, BUNDLE_TYPE_BYTE_ARRAY, len);
775 bundle_get_byte_array(bundle *b, const char *key, void ***byte_array, unsigned int *len, unsigned int **array_element_size)
777 return _bundle_get_val(b, key, BUNDLE_TYPE_BYTE_ARRAY, (void **)byte_array, NULL, len, array_element_size);
782 bundle_set_byte_array_element(bundle *b, const char *key, const unsigned int idx, const void *val, const size_t size)
784 return bundle_set_array_val(b, key, BUNDLE_TYPE_BYTE_ARRAY, idx, val, size);