ADDED THE FIMC1 STUFF FOR NOTHING
[exynos_camera.git] / exynos_param.c
1 /*
2  * Copyright (C) 2013 Paul Kocialkowski
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <malloc.h>
23 #include <ctype.h>
24
25 #define LOG_TAG "exynos_param"
26 #include <utils/Log.h>
27
28 #include "exynos_camera.h"
29
30 int list_head_insert(struct list_head *list, struct list_head *prev,
31         struct list_head *next)
32 {
33         if (list == NULL)
34                 return -EINVAL;
35
36         list->prev = prev;
37         list->next = next;
38
39         if(prev != NULL)
40                 prev->next = list;
41         if(next != NULL)
42                 next->prev = list;
43
44         return 0;
45 }
46
47 void list_head_remove(struct list_head *list)
48 {
49         if(list == NULL)
50                 return;
51
52         if(list->next != NULL)
53                 list->next->prev = list->prev;
54         if(list->prev != NULL)
55                 list->prev->next = list->next;
56 }
57
58 int exynos_param_register(struct exynos_camera *exynos_camera, char *key,
59         union exynos_param_data data, enum exynos_param_type type)
60 {
61         struct list_head *list_end;
62         struct list_head *list;
63         struct exynos_param *param;
64
65         if (exynos_camera == NULL || key == NULL)
66                 return -EINVAL;
67
68         param = (struct exynos_param *) calloc(1, sizeof(struct exynos_param));
69         if (param == NULL)
70                 return -ENOMEM;
71
72         param->key = strdup(key);
73         switch (type) {
74                 case EXYNOS_PARAM_INT:
75                         param->data.integer = data.integer;
76                         break;
77                 case EXYNOS_PARAM_FLOAT:
78                         param->data.floating = data.floating;
79                         break;
80                 case EXYNOS_PARAM_STRING:
81                         param->data.string = strdup(data.string);
82                         break;
83                 default:
84                         LOGE("%s: Invalid type", __func__);
85                         goto error;
86         }
87         param->type = type;
88
89         list_end = (struct list_head *) exynos_camera->params;
90         while (list_end != NULL && list_end->next != NULL)
91                 list_end = list_end->next;
92
93         list = (struct list_head *) param;
94         list_head_insert(list, list_end, NULL);
95
96         if (exynos_camera->params == NULL)
97                 exynos_camera->params = param;
98
99         return 0;
100
101 error:
102         if (param != NULL) {
103                 if (param->key != NULL)
104                         free(param->key);
105
106                 free(param);
107         }
108
109         return -1;
110 }
111
112 void exynos_param_unregister(struct exynos_camera *exynos_camera,
113         struct exynos_param *param)
114 {
115         struct list_head *list;
116
117         if (exynos_camera == NULL || param == NULL)
118                 return;
119
120         list = (struct list_head *) exynos_camera->params;
121         while (list != NULL) {
122                 if ((void *) list == (void *) param) {
123                         list_head_remove(list);
124
125                         if ((void *) list == (void *) exynos_camera->params)
126                                 exynos_camera->params = (struct exynos_param *) list->next;
127
128                         if (param->type == EXYNOS_PARAM_STRING && param->data.string != NULL)
129                                 free(param->data.string);
130
131                         memset(param, 0, sizeof(struct exynos_param));
132                         free(param);
133
134                         break;
135                 }
136
137 list_continue:
138                 list = list->next;
139         }
140 }
141
142 struct exynos_param *exynos_param_find_key(struct exynos_camera *exynos_camera,
143         char *key)
144 {
145         struct exynos_param *param;
146         struct list_head *list;
147
148         if (exynos_camera == NULL || key == NULL)
149                 return NULL;
150
151         list = (struct list_head *) exynos_camera->params;
152         while (list != NULL) {
153                 param = (struct exynos_param *) list;
154                 if (param->key == NULL)
155                         goto list_continue;
156
157                 if (strcmp(param->key, key) == 0)
158                         return param;
159
160 list_continue:
161                 list = list->next;
162         }
163
164         return NULL;
165 }
166
167 int exynos_param_data_set(struct exynos_camera *exynos_camera, char *key,
168         union exynos_param_data data, enum exynos_param_type type)
169 {
170         struct exynos_param *param;
171
172         if (exynos_camera == NULL || key == NULL)
173                 return -EINVAL;
174
175
176         if (strchr(key, '=') || strchr(key, ';'))
177                 return -EINVAL;
178
179         if (type == EXYNOS_PARAM_STRING && data.string != NULL &&
180                 (strchr(data.string, '=') || strchr(data.string, ';')))
181                 return -EINVAL;
182
183         param = exynos_param_find_key(exynos_camera, key);
184         if (param == NULL) {
185                 // The key isn't in the list yet
186                 exynos_param_register(exynos_camera, key, data, type);
187                 return 0;
188         }
189
190         if (param->type != type)
191                 LOGE("%s: Mismatching types for key %s", __func__, key);
192
193         if (param->type == EXYNOS_PARAM_STRING && param->data.string != NULL)
194                 free(param->data.string);
195
196         switch (type) {
197                 case EXYNOS_PARAM_INT:
198                         param->data.integer = data.integer;
199                         break;
200                 case EXYNOS_PARAM_FLOAT:
201                         param->data.floating = data.floating;
202                         break;
203                 case EXYNOS_PARAM_STRING:
204                         param->data.string = strdup(data.string);
205                         break;
206                 default:
207                         LOGE("%s: Invalid type", __func__);
208                         return -1;
209         }
210         param->type = type;
211
212         return 0;
213 }
214
215 int exynos_param_data_get(struct exynos_camera *exynos_camera, char *key,
216         union exynos_param_data *data, enum exynos_param_type type)
217 {
218         struct exynos_param *param;
219
220         if (exynos_camera == NULL || key == NULL || data == NULL)
221                 return -EINVAL;
222
223         param = exynos_param_find_key(exynos_camera, key);
224         if (param == NULL || param->type != type)
225                 return -1;
226
227         memcpy(data, &param->data, sizeof(param->data));
228
229         return 0;
230 }
231
232 int exynos_param_int_get(struct exynos_camera *exynos_camera,
233         char *key)
234 {
235         union exynos_param_data data;
236         int rc;
237
238         if (exynos_camera == NULL || key == NULL)
239                 return -EINVAL;
240
241         rc = exynos_param_data_get(exynos_camera, key, &data, EXYNOS_PARAM_INT);
242         if (rc < 0) {
243                 LOGE("%s: Unable to get data for key %s", __func__, key);
244                 return -1;
245         }
246
247         return data.integer;
248 }
249
250 float exynos_param_float_get(struct exynos_camera *exynos_camera,
251         char *key)
252 {
253         union exynos_param_data data;
254         int rc;
255
256         if (exynos_camera == NULL || key == NULL)
257                 return -EINVAL;
258
259         rc = exynos_param_data_get(exynos_camera, key, &data, EXYNOS_PARAM_FLOAT);
260         if (rc < 0) {
261                 LOGE("%s: Unable to get data for key %s", __func__, key);
262                 return -1;
263         }
264
265         return data.floating;
266 }
267
268 char *exynos_param_string_get(struct exynos_camera *exynos_camera,
269         char *key)
270 {
271         union exynos_param_data data;
272         int rc;
273
274         if (exynos_camera == NULL || key == NULL)
275                 return NULL;
276
277         rc = exynos_param_data_get(exynos_camera, key, &data, EXYNOS_PARAM_STRING);
278         if (rc < 0) {
279                 LOGE("%s: Unable to get data for key %s", __func__, key);
280                 return NULL;
281         }
282
283         return data.string;
284 }
285
286 int exynos_param_int_set(struct exynos_camera *exynos_camera,
287         char *key, int integer)
288 {
289         union exynos_param_data data;
290         int rc;
291
292         if (exynos_camera == NULL || key == NULL)
293                 return -EINVAL;
294
295         data.integer = integer;
296
297         rc = exynos_param_data_set(exynos_camera, key, data, EXYNOS_PARAM_INT);
298         if (rc < 0) {
299                 LOGE("%s: Unable to set data for key %s", __func__, key);
300                 return -1;
301         }
302
303         return 0;
304 }
305
306 int exynos_param_float_set(struct exynos_camera *exynos_camera,
307         char *key, float floating)
308 {
309         union exynos_param_data data;
310         int rc;
311
312         if (exynos_camera == NULL || key == NULL)
313                 return -EINVAL;
314
315         data.floating = floating;
316
317         rc = exynos_param_data_set(exynos_camera, key, data, EXYNOS_PARAM_FLOAT);
318         if (rc < 0) {
319                 LOGE("%s: Unable to set data for key %s", __func__, key);
320                 return -1;
321         }
322
323         return 0;
324 }
325
326 int exynos_param_string_set(struct exynos_camera *exynos_camera,
327         char *key, char *string)
328 {
329         union exynos_param_data data;
330         int rc;
331
332         if (exynos_camera == NULL || key == NULL || string == NULL)
333                 return -EINVAL;
334
335         data.string = string;
336
337         rc = exynos_param_data_set(exynos_camera, key, data, EXYNOS_PARAM_STRING);
338         if (rc < 0) {
339                 LOGE("%s: Unable to set data for key %s", __func__, key);
340                 return -1;
341         }
342
343         return 0;
344 }
345
346 char *exynos_params_string_get(struct exynos_camera *exynos_camera)
347 {
348         struct exynos_param *param;
349         struct list_head *list;
350         char *string = NULL;
351         char *s = NULL;
352         int length = 0;
353         int l = 0;
354
355         if (exynos_camera == NULL)
356                 return NULL;
357
358         list = (struct list_head *) exynos_camera->params;
359         while (list != NULL) {
360                 param = (struct exynos_param *) list;
361                 if (param->key == NULL)
362                         goto list_continue_length;
363
364                 length += strlen(param->key);
365                 length++;
366
367                 switch (param->type) {
368                         case EXYNOS_PARAM_INT:
369                         case EXYNOS_PARAM_FLOAT:
370                                 length += 16;
371                                 break;
372                         case EXYNOS_PARAM_STRING:
373                                 length += strlen(param->data.string);
374                                 break;
375                         default:
376                                 LOGE("%s: Invalid type", __func__);
377                                 return NULL;
378                 }
379
380                 length++;
381
382 list_continue_length:
383                 list = list->next;
384         }
385
386         if (length == 0)
387                 return NULL;
388
389         string = calloc(1, length);
390         s = string;
391
392         list = (struct list_head *) exynos_camera->params;
393         while (list != NULL) {
394                 param = (struct exynos_param *) list;
395                 if (param->key == NULL)
396                         goto list_continue;
397
398                 l = sprintf(s, "%s=", param->key);
399                 s += l;
400
401                 switch (param->type) {
402                         case EXYNOS_PARAM_INT:
403                                 l = snprintf(s, 16, "%d", param->data.integer);
404                                 s += l;
405                                 break;
406                         case EXYNOS_PARAM_FLOAT:
407                                 l = snprintf(s, 16, "%g", param->data.floating);
408                                 s += l;
409                                 break;
410                         case EXYNOS_PARAM_STRING:
411                                 l = sprintf(s, "%s", param->data.string);
412                                 s += l;
413                                 break;
414                         default:
415                                 LOGE("%s: Invalid type", __func__);
416                                 return NULL;
417                 }
418
419                 if (list->next != NULL) {
420                         *s = ';';
421                         s++;
422                 } else {
423                         *s = '\0';
424                         break;
425                 }
426
427 list_continue:
428                 list = list->next;
429         }
430
431         return string;
432 }
433
434 int exynos_params_string_set(struct exynos_camera *exynos_camera, char *string)
435 {
436         union exynos_param_data data;
437         enum exynos_param_type type;
438
439         char *d = NULL;
440         char *s = NULL;
441         char *k = NULL;
442         char *v = NULL;
443
444         char *key;
445         char *value;
446
447         int rc;
448         int i;
449
450         if (exynos_camera == NULL || string == NULL)
451                 return -1;
452
453         d = strdup(string);
454         s = d;
455
456         while (1) {
457                 k = strchr(s, '=');
458                 if (k == NULL)
459                         break;
460                 *k = '\0';
461                 key = s;
462
463                 v = strchr(k+1, ';');
464                 if (v != NULL)
465                         *v = '\0';
466                 value = k+1;
467
468                 k = value;
469                 if (isdigit(k[0]) || k[0] == '-') {
470                         type = EXYNOS_PARAM_INT;
471
472                         for (i=0 ; k[i] != '\0' ; i++) {
473                                 if (k[i] == '.') {
474                                         type = EXYNOS_PARAM_FLOAT;
475                                 } else if (!isdigit(k[i])) {
476                                         type = EXYNOS_PARAM_STRING;
477                                         break;
478                                 }
479                         }
480                 } else {
481                         type = EXYNOS_PARAM_STRING;
482                 }
483
484                 switch (type) {
485                         case EXYNOS_PARAM_INT:
486                                 data.integer = atoi(value);
487                                 break;
488                         case EXYNOS_PARAM_FLOAT:
489                                 data.floating = atof(value);
490                                 break;
491                         case EXYNOS_PARAM_STRING:
492                                 data.string = value;
493                                 break;
494                         default:
495                                 LOGE("%s: Invalid type", __func__);
496                                 goto error;
497                 }
498
499                 rc = exynos_param_data_set(exynos_camera, key, data, type);
500                 if (rc < 0) {
501                         LOGE("%s: Unable to set data for key %s", __func__, key);
502                         goto error;
503                 }
504
505                 if (v == NULL)
506                         break;
507
508                 s = v+1;
509         }
510
511         if (d != NULL)
512                 free(d);
513
514         return 0;
515
516 error:
517         if (d != NULL)
518                 free(d);
519
520         return -1;
521 }