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.
26 * Implementation of keyval_array object
29 #include "keyval_array.h"
31 #include "keyval_type.h"
33 #include "bundle_log.h"
40 static keyval_method_collection_t method = {
41 (keyval_method_free_t) keyval_array_free,
42 (keyval_method_compare_t) keyval_array_compare,
43 (keyval_method_get_encoded_size_t) keyval_array_get_encoded_size,
44 (keyval_method_encode_t) keyval_array_encode,
45 (keyval_method_decode_t) keyval_array_decode
49 keyval_array_new(keyval_array_t *kva, const char *key, const int type, const void **array_val, const unsigned int len)
52 must_free_obj = kva ? 0 : 1;
55 kva = calloc(1, sizeof(keyval_array_t));
56 if(unlikely(NULL==kva)) {
63 keyval_t *kv = keyval_new((keyval_t *)kva, key, type, NULL, 0);
64 if(unlikely(NULL==kv))
70 kv->type = kv->type | BUNDLE_TYPE_ARRAY;
74 // Set array value, if exist
77 if(must_free_obj) keyval_array_free(kva, 1);
80 kva->array_val = calloc(len, sizeof(void *));
81 if(!(kva->array_val)) {
83 keyval_array_free(kva, 1);
87 kva->array_element_size = calloc(len, sizeof(size_t));
88 if(!(kva->array_element_size)) {
90 keyval_array_free(kva, 1);
93 // If avaliable, copy array val
95 && keyval_type_is_measurable(type)
96 && keyval_type_get_measure_size_func(type)) {
97 // array_val have original data array. copy it!
99 if(keyval_array_copy_array((keyval_array_t*)kv,
102 keyval_type_get_measure_size_func(type))
104 keyval_array_free(kva, 1);
110 kv->method = &method;
116 keyval_array_free(keyval_array_t *kva, int do_free_object)
120 // free keyval_array elements
121 free(kva->array_element_size);
123 for(i=0; i<kva->len; i++) {
124 if(kva->array_val[i]) free(kva->array_val[i]);
126 free(kva->array_val);
129 keyval_free((keyval_t *)kva, 0);
132 if(do_free_object) free(kva);
136 keyval_array_compare(keyval_array_t *kva1, keyval_array_t *kva2)
139 if(!kva1 || !kva2) return -1;
141 kv1 = (keyval_t *)kva1;
142 kv2 = (keyval_t *)kva2;
144 if(0 != strcmp(kv1->key, kv2->key)) return 1;
145 if(kv1->type != kv2->type) return 1;
146 if(kva1->len != kva2->len) return 1;
148 for(i=0; i<kva1->len; i++) {
149 if(kva1->array_val[i] == NULL && kva2->array_val[i] == NULL) continue;
150 if(kva1->array_val[i] == NULL || kva2->array_val[i] == NULL) return 1;
151 if(0 != memcmp(kva1->array_val[i], kva2->array_val[i], kva1->array_element_size[i])) return 1;
158 keyval_array_copy_array(keyval_array_t *kva, void **array_val, unsigned int array_len, size_t (*measure_val_len)(void * val))
160 keyval_t *kv = (keyval_t *)kva;
162 // Get measure_size function of the value type
163 keyval_type_measure_size_func_t measure_size = keyval_type_get_measure_size_func(kv->type);
164 if(!measure_size) return -1;
166 // Copy each array item
168 for(i=0; i < array_len; i++) {
169 kva->array_val[i] = malloc(measure_size(array_val[i]));
170 if(!(kva->array_val[i])) {
174 memcpy(kva->array_val[i], array_val[i], measure_size(array_val[i]));
175 kva->array_element_size[i] = measure_size(array_val[i]);
180 for(i=0; i<array_len; i++) {
181 if(kva->array_val[i]) {
182 free(kva->array_val[i]);
183 kva->array_val[i] = NULL;
190 keyval_array_is_idx_valid(keyval_array_t *kva, int idx)
192 //keyval_t *kv = (keyval_t *)kva;
193 if(kva && kva->len > idx && 0 <= idx) return 1;
198 keyval_array_set_element(keyval_array_t *kva, int idx, void *val, size_t size)
200 if(kva->array_val[idx]) { // An element is already exist in the idx!
201 if(!val) { // val==NULL means 'Free this element!'
202 free(kva->array_val[idx]);
203 kva->array_val[idx] = NULL;
204 kva->array_element_size[idx] = 0;
213 // Normal case. Copy value into the array.
214 kva->array_val[idx] = malloc(size);
215 if(!(kva->array_val[idx])) {
220 memcpy(kva->array_val[idx], val, size); // val
221 kva->array_element_size[idx] = size; // size
229 keyval_array_get_data(keyval_array_t *kva, int *type,
230 void ***array_val, unsigned int *len, size_t **array_element_size)
232 if(!kva) return -EINVAL;
233 keyval_t *kv = (keyval_t *)kva;
234 if(!keyval_type_is_array(kv->type)) return -EINVAL;
237 if(type) *type = kv->type;
238 if(array_val) *array_val = kva->array_val;
239 if(len) *len = kva->len;
240 if(array_element_size) *array_element_size = kva->array_element_size;
246 keyval_array_get_encoded_size(keyval_array_t *kva)
248 size_t sum_array_element_size = 0;
250 for(i=0; i < kva->len; i++) {
251 sum_array_element_size += kva->array_element_size[i];
254 = sizeof(size_t) // total size
255 + sizeof(int) // type
256 + sizeof(size_t) // keysize
257 + strlen(((keyval_t *)kva)->key) + 1 // key (+ null byte)
259 + kva->len * sizeof(size_t) // array_element_size
260 + sum_array_element_size;
266 keyval_array_encode(keyval_array_t *kva, void **byte, size_t *byte_len)
268 keyval_t *kv = (keyval_t *)kva;
271 // Calculate memory size for kva
272 static const size_t sz_type = sizeof(int);
273 static const size_t sz_keysize = sizeof(size_t);
274 size_t sz_key = strlen(kv->key) + 1;
275 static const unsigned int sz_len = sizeof(int);
276 size_t sz_array_element_size = kva->len * sizeof(size_t);
277 size_t sz_array_val = 0;
278 for(i=0; i < kva->len; i++) {
279 sz_array_val += kva->array_element_size[i];
283 *byte_len = keyval_array_get_encoded_size(kva);
284 *byte = calloc(1, *byte_len);
288 unsigned char *p = *byte;
290 memcpy(p, byte_len, sizeof(size_t)); p += sizeof(size_t);
291 memcpy(p, &(kv->type), sz_type); p += sz_type;
292 memcpy(p, &sz_key, sz_keysize); p += sz_keysize;
293 memcpy(p, kv->key, sz_key); p += sz_key;
294 memcpy(p, &(kva->len), sz_len); p += sz_len;
295 memcpy(p, kva->array_element_size, sz_array_element_size); p += sz_array_element_size;
296 for(i=0; i < kva->len; i++) {
297 memcpy(p, kva->array_val[i], kva->array_element_size[i]);
298 p += kva->array_element_size[i];
305 keyval_array_decode(void *byte, keyval_array_t **kva)
307 static const size_t sz_byte_len = sizeof(size_t);
308 static const size_t sz_type = sizeof(int);
309 static const size_t sz_keysize = sizeof(size_t);
310 static const int sz_len = sizeof(unsigned int);
312 unsigned char *p = byte;
315 size_t byte_len = *((size_t *)p); p += sz_byte_len;
316 int type = *((int *)p); p += sz_type;
317 size_t keysize = *((size_t *)p); p += sz_keysize;
318 char *key = (char *)p; p += keysize;
319 unsigned int len = *((unsigned int *)p); p += sz_len;
320 size_t *array_element_size = (size_t *) p; p += sizeof(size_t) * len;
321 void *array_val = (void *)p;
323 *kva = keyval_array_new(NULL, key, type, NULL, len);
325 size_t elem_size = 0;
326 for(i=0; i < len; i++) {
327 elem_size += i ? array_element_size[i-1] : 0;
328 if(keyval_array_set_element(*kva, i, (void *)(array_val+elem_size), array_element_size[i])) {
329 keyval_array_free(*kva, 1);