cleanup specfile for packaging
[profile/ivi/bundle.git] / src / keyval.c
1 /*
2  * bundle
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7  * Jaeho Lee <jaeho81.lee@samsung.com>
8  *
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
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
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.
20  *
21  */
22
23
24 /**
25  * keyval.c
26  * Implementation of keyval object
27  */
28
29 #include "keyval_type.h"
30 #include "keyval.h"
31 #include "bundle_log.h"
32 #include <stdlib.h>
33 #include <errno.h>
34 extern int errno;
35
36 static keyval_method_collection_t method = {
37         keyval_free,
38         keyval_compare,
39         keyval_get_encoded_size,
40         keyval_encode,
41         keyval_decode
42 };
43
44 keyval_t *
45 keyval_new(keyval_t *kv, const char *key, const int type, const void *val, const size_t size)
46 {
47         int must_free_obj;
48         must_free_obj = kv ? 0 : 1;
49
50         if(!kv) {       
51                 kv = calloc(1, sizeof(keyval_t));
52                 if(!kv) {
53                         //errno = ENOMEM;       // set by calloc
54                         return NULL;
55                 }
56         }
57
58         // key
59         if(kv->key) {
60                 keyval_free(kv, must_free_obj);
61                 return NULL;
62         }
63         kv->key = strdup(key);
64         if(!kv->key) {
65                 //errno = ENOMEM;       // set by strdup
66                 keyval_free(kv, must_free_obj);
67                 return NULL;
68         }
69
70         // elementa of primitive types
71         kv->type = type;
72         kv->size = size;
73         
74         if(size) {
75                 kv->val = calloc(1, size);              // allocate memory unconditionally !
76                 if(!kv->val) {
77                         errno = ENOMEM;
78                         keyval_free(kv, 1);
79                         return NULL;
80                 }
81                 if(val) {
82                         memcpy(kv->val, val, size);
83                 }
84         }
85
86         // Set methods
87         kv->method = &method;
88
89         return kv;
90 }
91
92 void
93 keyval_free(keyval_t *kv, int do_free_object)
94 {
95         //int i;
96
97         if(NULL == kv) return;
98
99         if(kv->key) { 
100                 free(kv->key);
101                 kv->key = NULL;
102         }
103
104         if(NULL != kv->val) {
105                 free(kv->val);
106                 kv->val = NULL;
107         }
108
109         if(do_free_object) free(kv);
110
111         return;
112 }
113
114 int
115 keyval_get_data(keyval_t *kv, int *type, void **val, size_t *size)
116 {
117         if(!kv) return -EINVAL;
118         if(keyval_type_is_array(kv->type)) return -EINVAL;
119
120         if(type) *type = kv->type;
121         if(val) *val = kv->val;
122         if(size) *size = kv->size;
123
124         return 0;
125 }
126
127 int
128 keyval_compare(keyval_t *kv1, keyval_t *kv2)
129 {
130         if(!kv1 || !kv2) return -1;
131
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;
135
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;
139
140         return 0;
141 }
142
143 size_t
144 keyval_get_encoded_size(keyval_t *kv)
145 {
146         if(!kv) return 0;
147
148         size_t encoded_size 
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
154                 + kv->size;                     // val
155
156         return encoded_size;
157 }
158
159 /**
160  * encode a keyval to byte
161  *
162  * @pre                 kv must be valid.
163  * @post                byte must be freed.
164  * @param[in]   kv
165  * @param[out]  byte
166  * @param[out]  byte_len
167  * @return byte_len
168  */
169 size_t
170 keyval_encode(keyval_t *kv, unsigned char **byte, size_t *byte_len)
171 {
172         /*
173          * type
174          * key size
175          * key
176          * val size
177          * val
178          */
179
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;
185
186         *byte_len = keyval_get_encoded_size(kv);
187
188         *byte = calloc(1, *byte_len);
189         if(!*byte) return 0;
190
191         unsigned char *p = *byte;
192         
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;
199
200         return *byte_len;
201 }
202
203 /**
204  * decode a byte stream to a keyval
205  *
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.
211  */
212 size_t
213 keyval_decode(unsigned char *byte, keyval_t **kv)
214 {
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);
219
220         unsigned char *p = byte;
221
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;
228
229         if(kv) *kv = keyval_new(*kv, key, type, val, size);     // If *kv != NULL, use given kv
230
231         return byte_len;
232 }
233
234
235 int
236 keyval_get_type_from_encoded_byte(unsigned char *byte)
237 {
238         // skip total size (== sizeof(size_t))
239         static const size_t sz_byte_len = sizeof(size_t);
240
241         unsigned char *p=byte;
242          p += sz_byte_len;
243         int type = *((int *)p);
244         return type; 
245
246         //return (int )*(byte + sizeof(size_t));
247 }
248