tizen 2.3 release
[external/buxton.git] / src / shared / util.c
1 /*
2  * This file is part of buxton.
3  *
4  * Copyright (C) 2013 Intel Corporation
5  *
6  * buxton is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1
9  * of the License, or (at your option) any later version.
10  */
11
12 #ifdef HAVE_CONFIG_H
13         #include "config.h"
14 #endif
15
16 #include <stdio.h>
17 #include <assert.h>
18 #include <errno.h>
19 #include <string.h>
20 #include <unistd.h>
21
22 #include "configurator.h"
23 #include "hashmap.h"
24 #include "log.h"
25 #include "util.h"
26
27 size_t page_size(void)
28 {
29         static __thread size_t pgsz = 0;
30         long r;
31
32         if (_likely_(pgsz > 0)) {
33                 return pgsz;
34         }
35
36         r = sysconf(_SC_PAGESIZE);
37         assert(r > 0);
38
39         pgsz = (size_t) r;
40         return pgsz;
41 }
42
43 void* greedy_realloc(void **p, size_t *allocated, size_t need)
44 {
45         size_t a;
46         void *q;
47
48         assert(p);
49         assert(allocated);
50
51         if (*allocated >= need) {
52                 return *p;
53         }
54
55         a = MAX(64u, need * 2);
56         q = realloc(*p, a);
57         if (!q) {
58                 return NULL;
59         }
60
61         *p = q;
62         *allocated = a;
63         return q;
64 }
65
66 char* get_layer_path(BuxtonLayer *layer)
67 {
68         char *path = NULL;
69         int r;
70         char uid[15];
71
72         assert(layer);
73
74         switch (layer->type) {
75         case LAYER_SYSTEM:
76                 r = asprintf(&path, "%s/%s.db", buxton_db_path(), layer->name.value);
77                 if (r == -1) {
78                         return NULL;
79                 }
80                 break;
81         case LAYER_USER:
82                 /* uid must already be set in layer before calling */
83                 sprintf(uid, "%d", (int)layer->uid);
84                 r = asprintf(&path, "%s/%s-%s.db", buxton_db_path(), layer->name.value, uid);
85                 if (r == -1) {
86                         return NULL;
87                 }
88                 break;
89         default:
90                 break;
91         }
92
93         return path;
94 }
95
96 bool buxton_data_copy(BuxtonData* original, BuxtonData *copy)
97 {
98         BuxtonDataStore store;
99
100         assert(original);
101         assert(copy);
102
103         switch (original->type) {
104         case STRING:
105                 store.d_string.value = malloc(original->store.d_string.length);
106                 if (!store.d_string.value) {
107                         goto fail;
108                 }
109                 memcpy(store.d_string.value, original->store.d_string.value, original->store.d_string.length);
110                 store.d_string.length = original->store.d_string.length;
111                 break;
112         case INT32:
113                 store.d_int32 = original->store.d_int32;
114                 break;
115         case UINT32:
116                 store.d_uint32 = original->store.d_uint32;
117                 break;
118         case INT64:
119                 store.d_int64 = original->store.d_int64;
120                 break;
121         case UINT64:
122                 store.d_uint64 = original->store.d_uint64;
123                 break;
124         case FLOAT:
125                 store.d_float = original->store.d_float;
126                 break;
127         case DOUBLE:
128                 store.d_double = original->store.d_double;
129                 break;
130         case BOOLEAN:
131                 store.d_boolean = original->store.d_boolean;
132                 break;
133         default:
134                 goto fail;
135         }
136
137         copy->type = original->type;
138         copy->store = store;
139
140         return true;
141
142 fail:
143         memset(copy, 0, sizeof(BuxtonData));
144         return false;
145 }
146
147 bool buxton_string_copy(BuxtonString *original, BuxtonString *copy)
148 {
149         if (!original || !copy) {
150                 return false;
151         }
152
153         copy->value = malloc0(original->length);
154         if (!copy->value) {
155                 return false;
156         }
157
158         memcpy(copy->value, original->value, original->length);
159         copy->length = original->length;
160
161         return true;
162 }
163
164 bool buxton_key_copy(_BuxtonKey *original, _BuxtonKey *copy)
165 {
166         if (!original || !copy) {
167                 return false;
168         }
169
170         if (original->group.value) {
171                 if (!buxton_string_copy(&original->group, &copy->group)) {
172                         goto fail;
173                 }
174         }
175         if (original->name.value) {
176                 if (!buxton_string_copy(&original->name, &copy->name)) {
177                         goto fail;
178                 }
179         }
180         if (original->layer.value) {
181                 if (!buxton_string_copy(&original->layer, &copy->layer)) {
182                         goto fail;
183                 }
184         }
185         copy->type = original->type;
186
187         return true;
188
189 fail:
190         if (original->group.value) {
191                 free(copy->group.value);
192         }
193         if (original->name.value) {
194                 free(copy->name.value);
195         }
196         if (original->layer.value) {
197                 free(copy->layer.value);
198         }
199         copy->type = BUXTON_TYPE_MIN;
200
201         return false;
202 }
203
204 bool buxton_copy_key_group(_BuxtonKey *original, _BuxtonKey *group)
205 {
206         if (!original || !group) {
207                 return false;
208         }
209
210         if (original->group.value) {
211                 if (!buxton_string_copy(&original->group, &group->group)) {
212                         goto fail;
213                 }
214         }
215         group->name = (BuxtonString){ NULL, 0 };
216         if (original->layer.value) {
217                 if (!buxton_string_copy(&original->layer, &group->layer)) {
218                         goto fail;
219                 }
220         }
221         group->type = STRING;
222
223         return true;
224
225 fail:
226         if (original->group.value) {
227                 free(group->group.value);
228         }
229         if (original->layer.value) {
230                 free(group->layer.value);
231         }
232         group->type = BUXTON_TYPE_MIN;
233
234         return false;
235 }
236
237 void data_free(BuxtonData *data)
238 {
239         if (!data) {
240                 return;
241         }
242
243         if (data->type == STRING && data->store.d_string.value) {
244                 free(data->store.d_string.value);
245         }
246         free(data);
247 }
248
249 void string_free(BuxtonString *string)
250 {
251         if (!string) {
252                 return;
253         }
254
255         if (string->value) {
256                 free(string->value);
257         }
258         free(string);
259 }
260
261 void key_free(_BuxtonKey *key)
262 {
263         if (!key) {
264                 return;
265         }
266
267         free(key->group.value);
268         free(key->name.value);
269         free(key->layer.value);
270         free(key);
271 }
272
273 const char* buxton_type_as_string(BuxtonDataType type)
274 {
275         switch (type) {
276         case STRING:
277                 return "string";
278         case INT32:
279                 return "int32_t";
280         case UINT32:
281                 return "uint32_t";
282         case INT64:
283                 return "int64_t";
284         case UINT64:
285                 return "uint64_t";
286         case FLOAT:
287                 return "float";
288         case DOUBLE:
289                 return "double";
290         case BOOLEAN:
291                 return "boolean";
292         default:
293                 return "[unknown]";
294         }
295 }
296
297 char *get_group(_BuxtonKey *key)
298 {
299         if (key && key->group.value) {
300                 return strdup(key->group.value);
301         }
302
303         return NULL;
304 }
305
306 char *get_name(_BuxtonKey *key)
307 {
308         if (key && key->name.value) {
309                 return strdup(key->name.value);
310         }
311
312         return NULL;
313 }
314
315 char *get_layer(_BuxtonKey *key)
316 {
317         if (key && key->layer.value) {
318                 return strdup(key->layer.value);
319         }
320
321         return NULL;
322 }
323
324 bool _write(int fd, uint8_t *buf, size_t nbytes)
325 {
326         size_t nbytes_out = 0;
327
328         while (nbytes_out != nbytes) {
329                 ssize_t b;
330                 b = write(fd, buf + nbytes_out, nbytes - nbytes_out);
331
332                 if (b == -1 && errno != EAGAIN) {
333                         buxton_debug("write error\n");
334                         return false;
335                 }
336                 nbytes_out += (size_t)b;
337         }
338
339         return true;
340 }
341
342 /*
343  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
344  *
345  * Local variables:
346  * c-basic-offset: 8
347  * tab-width: 8
348  * indent-tabs-mode: t
349  * End:
350  *
351  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
352  * :indentSize=8:tabSize=8:noTabs=false:
353  */