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"
39 static keyval_method_collection_t method = {
40 (keyval_method_free_t) keyval_array_free,
41 (keyval_method_compare_t) keyval_array_compare,
42 (keyval_method_get_encoded_size_t) keyval_array_get_encoded_size,
43 (keyval_method_encode_t) keyval_array_encode,
44 (keyval_method_decode_t) keyval_array_decode
48 keyval_array_new(keyval_array_t *kva, const char *key, const int type,
49 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)) {
57 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
63 keyval_t *kv = keyval_new((keyval_t *)kva, key, type, NULL, 0);
64 if (unlikely(NULL == kv)) {
65 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
69 kv->type = kv->type | BUNDLE_TYPE_ARRAY;
73 /* Set array value, if exist */
75 set_last_result(BUNDLE_ERROR_INVALID_PARAMETER);
77 keyval_array_free(kva, 1);
80 kva->array_val = calloc(len, sizeof(void *));
81 if (!(kva->array_val)) {
82 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
83 keyval_array_free(kva, 1);
86 /* array_element_size */
87 kva->array_element_size = calloc(len, sizeof(size_t));
88 if (!(kva->array_element_size)) {
89 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
90 keyval_array_free(kva, 1);
93 /* If available, 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)
121 /* free keyval_array elements */
122 free(kva->array_element_size);
124 for (i = 0; i < kva->len; i++) {
125 if (kva->array_val[i])
126 free(kva->array_val[i]);
128 free(kva->array_val);
131 keyval_free((keyval_t *)kva, 0);
139 keyval_array_compare(keyval_array_t *kva1, keyval_array_t *kva2)
145 kv1 = (keyval_t *)kva1;
146 kv2 = (keyval_t *)kva2;
148 if (0 != strcmp(kv1->key, kv2->key))
150 if (kv1->type != kv2->type)
152 if (kva1->len != kva2->len)
155 for (i = 0; i < kva1->len; i++) {
156 if (kva1->array_val[i] == NULL && kva2->array_val[i] == NULL)
158 if (kva1->array_val[i] == NULL || kva2->array_val[i] == NULL)
160 if (0 != memcmp(kva1->array_val[i], kva2->array_val[i],
161 kva1->array_element_size[i]))
169 keyval_array_copy_array(keyval_array_t *kva, void **array_val,
170 unsigned int array_len, size_t (*measure_val_len)(void *val))
172 keyval_t *kv = (keyval_t *)kva;
175 /* Get measure_size function of the value type */
176 keyval_type_measure_size_func_t measure_size =
177 keyval_type_get_measure_size_func(kv->type);
181 /* Copy each array item */
182 for (i = 0; i < array_len; i++) {
183 kva->array_val[i] = malloc(measure_size(array_val[i]));
184 if (!(kva->array_val[i])) {
185 set_last_result(BUNDLE_ERROR_OUT_OF_MEMORY);
188 memcpy(kva->array_val[i], array_val[i],
189 measure_size(array_val[i]));
190 kva->array_element_size[i] = measure_size(array_val[i]);
195 for (i = 0; i < array_len; i++) {
196 if (kva->array_val[i]) {
197 free(kva->array_val[i]);
198 kva->array_val[i] = NULL;
205 keyval_array_is_idx_valid(keyval_array_t *kva, int idx)
207 if (kva && kva->len > idx && 0 <= idx)
213 keyval_array_set_element(keyval_array_t *kva, int idx, void *val, size_t size)
215 /* An element is already exist in the idx! */
216 if (kva->array_val[idx]) {
217 /* val==NULL means 'Free this element!' */
219 free(kva->array_val[idx]);
220 kva->array_val[idx] = NULL;
221 kva->array_element_size[idx] = 0;
224 return BUNDLE_ERROR_INVALID_PARAMETER;
227 /* Normal case. Copy value into the array. */
228 kva->array_val[idx] = malloc(size);
229 if (!(kva->array_val[idx]))
230 return BUNDLE_ERROR_OUT_OF_MEMORY;
232 memcpy(kva->array_val[idx], val, size);
233 kva->array_element_size[idx] = size;
237 return BUNDLE_ERROR_NONE;
241 keyval_array_get_data(keyval_array_t *kva, int *type,
242 void ***array_val, unsigned int *len, size_t **array_element_size)
245 return BUNDLE_ERROR_INVALID_PARAMETER;
246 keyval_t *kv = (keyval_t *)kva;
247 if (!keyval_type_is_array(kv->type))
248 return BUNDLE_ERROR_INVALID_PARAMETER;
254 *array_val = kva->array_val;
257 if (array_element_size)
258 *array_element_size = kva->array_element_size;
260 return BUNDLE_ERROR_NONE;
264 keyval_array_get_encoded_size(keyval_array_t *kva)
266 size_t sum_array_element_size = 0;
268 for (i = 0; i < kva->len; i++) {
269 sum_array_element_size += kva->array_element_size[i];
272 = sizeof(size_t) /* total size */
273 + sizeof(int) /* type */
274 + sizeof(size_t) /* keysize */
275 + strlen(((keyval_t *)kva)->key) + 1 /* key (+ null byte) */
276 + sizeof(int) /* len */
277 + kva->len * sizeof(size_t) /* array_element_size */
278 + sum_array_element_size;
284 keyval_array_encode(keyval_array_t *kva, void **byte, size_t *byte_len)
286 keyval_t *kv = (keyval_t *)kva;
289 /* Calculate memory size for kva */
290 static const size_t sz_type = sizeof(int);
291 static const size_t sz_keysize = sizeof(size_t);
292 size_t sz_key = strlen(kv->key) + 1;
293 static const unsigned int sz_len = sizeof(int);
294 size_t sz_array_element_size = kva->len * sizeof(size_t);
295 size_t sz_array_val = 0;
296 for (i = 0; i < kva->len; i++) {
297 sz_array_val += kva->array_element_size[i];
300 /* Allocate memory */
301 *byte_len = keyval_array_get_encoded_size(kva);
302 *byte = calloc(1, *byte_len);
307 unsigned char *p = *byte;
309 memcpy(p, byte_len, sizeof(size_t)); p += sizeof(size_t);
310 memcpy(p, &(kv->type), sz_type); p += sz_type;
311 memcpy(p, &sz_key, sz_keysize); p += sz_keysize;
312 memcpy(p, kv->key, sz_key); p += sz_key;
313 memcpy(p, &(kva->len), sz_len); p += sz_len;
314 memcpy(p, kva->array_element_size, sz_array_element_size);
315 p += sz_array_element_size;
316 for (i = 0; i < kva->len; i++) {
317 memcpy(p, kva->array_val[i], kva->array_element_size[i]);
318 p += kva->array_element_size[i];
325 keyval_array_decode(void *byte, keyval_array_t **kva)
327 static const size_t sz_byte_len = sizeof(size_t);
328 static const size_t sz_type = sizeof(int);
329 static const size_t sz_keysize = sizeof(size_t);
330 static const int sz_len = sizeof(unsigned int);
332 unsigned char *p = byte;
335 size_t byte_len = *((size_t *)p); p += sz_byte_len;
336 int type = *((int *)p); p += sz_type;
337 size_t keysize = *((size_t *)p); p += sz_keysize;
338 char *key = (char *)p; p += keysize;
339 unsigned int len = *((unsigned int *)p); p += sz_len;
340 size_t *array_element_size = (size_t *) p; p += sizeof(size_t) * len;
341 void *array_val = (void *)p;
343 *kva = keyval_array_new(NULL, key, type, NULL, len);
345 size_t elem_size = 0;
346 for (i = 0; i < len; i++) {
347 elem_size += i ? array_element_size[i-1] : 0;
348 if (keyval_array_set_element(*kva, i,
349 (void *)(array_val+elem_size),
350 array_element_size[i])) {
351 keyval_array_free(*kva, 1);