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 object
29 #include "keyval_type.h"
31 #include "bundle_log.h"
36 static keyval_method_collection_t method = {
39 keyval_get_encoded_size,
45 keyval_new(keyval_t *kv, const char *key, const int type, const void *val, const size_t size)
48 must_free_obj = kv ? 0 : 1;
51 kv = calloc(1, sizeof(keyval_t));
53 //errno = ENOMEM; // set by calloc
60 keyval_free(kv, must_free_obj);
63 kv->key = strdup(key);
65 //errno = ENOMEM; // set by strdup
66 keyval_free(kv, must_free_obj);
70 // elementa of primitive types
75 kv->val = calloc(1, size); // allocate memory unconditionally !
82 memcpy(kv->val, val, size);
93 keyval_free(keyval_t *kv, int do_free_object)
97 if(NULL == kv) return;
104 if(NULL != kv->val) {
109 if(do_free_object) free(kv);
115 keyval_get_data(keyval_t *kv, int *type, void **val, size_t *size)
117 if(!kv) return -EINVAL;
118 if(keyval_type_is_array(kv->type)) return -EINVAL;
120 if(type) *type = kv->type;
121 if(val) *val = kv->val;
122 if(size) *size = kv->size;
128 keyval_compare(keyval_t *kv1, keyval_t *kv2)
130 if(!kv1 || !kv2) return -1;
132 if(0 != strcmp(kv1->key, kv2->key)) return 1;
133 if(kv1->type != kv2->type) return 1;
134 if(kv1->size != kv2->size) return 1;
136 if(kv1->val == NULL && kv2->val == NULL) return 0;
137 if(kv1->val == NULL || kv2->val == NULL) return 1;
138 if(0 != memcmp(kv1->val, kv2->val, kv1->size)) return 1;
144 keyval_get_encoded_size(keyval_t *kv)
149 = sizeof(size_t) // total size
150 + sizeof(int) // type
151 + sizeof(size_t) // key size
152 + strlen(kv->key) + 1 // key (+ null byte)
153 + sizeof(size_t) // size
160 * encode a keyval to byte
162 * @pre kv must be valid.
163 * @post byte must be freed.
166 * @param[out] byte_len
170 keyval_encode(keyval_t *kv, unsigned char **byte, size_t *byte_len)
180 static const size_t sz_type = sizeof(int);
181 static const size_t sz_keysize = sizeof(size_t);
182 size_t sz_key = strlen(kv->key) + 1;
183 static const size_t sz_size = sizeof(size_t);
184 size_t sz_val = kv->size;
186 *byte_len = keyval_get_encoded_size(kv);
188 *byte = calloc(1, *byte_len);
191 unsigned char *p = *byte;
193 memcpy(p, byte_len, sizeof(size_t)); p += sizeof(size_t);
194 memcpy(p, &(kv->type), sz_type); p += sz_type;
195 memcpy(p, &sz_key, sz_keysize); p += sz_keysize;
196 memcpy(p, kv->key, sz_key); p += sz_key;
197 memcpy(p, &(kv->size), sz_size); p += sz_size;
198 memcpy(p, kv->val, sz_val); p += sz_val;
204 * decode a byte stream to a keyval
206 * @param[in] byte byte stream.
207 * @param[in|out] kv keyval.
208 * If kv is NULL, new keyval_t object comes.
209 * If kv is not NULL, given kv is used. (No new kv is created.)
210 * @return Number of bytes read from byte.
213 keyval_decode(unsigned char *byte, keyval_t **kv)
215 static const size_t sz_byte_len = sizeof(size_t);
216 static const size_t sz_type = sizeof(int);
217 static const size_t sz_keysize = sizeof(size_t);
218 static const size_t sz_size = sizeof(size_t);
220 unsigned char *p = byte;
222 size_t byte_len = *((size_t *)p); p += sz_byte_len;
223 int type = *((int *)p); p += sz_type;
224 size_t keysize = *((size_t *)p); p += sz_keysize;
225 char *key = (char *)p; p += keysize;
226 size_t size = *((size_t *)p); p += sz_size;
227 void *val = (void *)p; p += size;
229 if(kv) *kv = keyval_new(*kv, key, type, val, size); // If *kv != NULL, use given kv
236 keyval_get_type_from_encoded_byte(unsigned char *byte)
238 // skip total size (== sizeof(size_t))
239 static const size_t sz_byte_len = sizeof(size_t);
241 unsigned char *p=byte;
243 int type = *((int *)p);
246 //return (int )*(byte + sizeof(size_t));