2afd86ddeb8bfa2d64430c6aa40a9a041c740d03
[platform/core/multimedia/libmm-common.git] / mm_attrs_private.c
1 /*
2  * libmm-common
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <malloc.h>
28 #include <assert.h>
29 #include <stdbool.h>
30 #include "mm_debug.h"
31 #include "mm_attrs_private.h"
32
33 int mmf_value_init(mmf_value_t *value, int type)
34 {
35         return_val_if_fail(value, -1);
36         return_val_if_fail(MMF_IS_VALUE_TYPE(type), -1);
37         memset(value, 0, sizeof(*value));
38         value->type = type;
39         return 0;
40 }
41
42 int mmf_value_copy(mmf_value_t *dest, const mmf_value_t *src)
43 {
44         return_val_if_fail(dest && src && src->type == dest->type, -1);
45         switch (src->type) {
46         case MM_ATTRS_TYPE_INT:
47                 dest->value.i_val = src->value.i_val;
48                 break;
49         case MM_ATTRS_TYPE_DOUBLE:
50                 dest->value.d_val = src->value.d_val;
51                 break;
52         case MM_ATTRS_TYPE_STRING:
53                 if (dest->value.s_val) {
54                         free(dest->value.s_val);
55                         dest->value.s_val = NULL;
56                         dest->size = 0;
57                 }
58                 if (src->value.s_val) {
59                         dest->value.s_val = strdup(src->value.s_val);
60                         dest->size = src->size;
61                 }
62                 break;
63         case MM_ATTRS_TYPE_DATA:
64                 dest->value.p_val = src->value.p_val;
65                 dest->size = src->size;
66                 break;
67         default:
68                 break;
69         }
70         return 0;
71 }
72
73 int mmf_value_set_int(mmf_value_t *v, int ival)
74 {
75         return_val_if_fail(v && v->type == MMF_VALUE_TYPE_INT, -1);
76         v->value.i_val = ival;
77         return 0;
78 }
79
80 int mmf_value_get_int(const mmf_value_t *v)
81 {
82         return_val_if_fail(v && v->type == MMF_VALUE_TYPE_INT, -1);
83         return v->value.i_val;
84 }
85
86 int mmf_value_set_double(mmf_value_t *v, double dval)
87 {
88         return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DOUBLE, -1);
89         v->value.d_val = dval;
90         return 0;
91 }
92
93 double mmf_value_get_double(mmf_value_t *v)
94 {
95         return_val_if_fail(v->type == MMF_VALUE_TYPE_DOUBLE, -1);
96         return v->value.d_val;
97 }
98
99 int mmf_value_set_string(mmf_value_t *v, const char *sval, int size)
100 {
101         return_val_if_fail(v && v->type == MMF_VALUE_TYPE_STRING, -1);
102         if (v->value.s_val != NULL) {
103                 free(v->value.s_val);
104                 v->value.s_val = NULL;
105                 v->size = 0;
106         }
107         if (sval) {
108                 v->value.s_val = strdup(sval);
109                 v->size = size;
110         } else {
111                 v->value.s_val = NULL;
112                 v->size = 0;
113         }
114         return 0;
115 }
116
117 char* mmf_value_get_string(const mmf_value_t *v, int *size)
118 {
119         return_val_if_fail(v && v->type == MMF_VALUE_TYPE_STRING, NULL);
120         *size = v->size;
121         return v->value.s_val;
122 }
123
124 int mmf_value_set_data(mmf_value_t *v, void *data, int size)
125 {
126         return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DATA, -1);
127         v->value.p_val = data;
128         v->size = size;
129         return 0;
130 }
131
132 void* mmf_value_get_data(const mmf_value_t *v, int *size)
133 {
134         return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DATA, NULL);
135         *size = v->size;
136         return v->value.p_val;
137 }
138
139 void mmf_value_dump(const mmf_value_t *value)
140 {
141         return_if_fail(value);
142         switch (value->type) {
143         case MMF_VALUE_TYPE_INT:
144                 //mmf_debug(MMF_DEBUG_LOG, "value[int]: %d\n", value->value.i_val);
145                 break;
146         case MMF_VALUE_TYPE_DOUBLE:
147                 //mmf_debug(MMF_DEBUG_LOG, "value[double]: %f\n", value->value.d_val);
148                 break;
149         case MMF_VALUE_TYPE_STRING:
150                 //mmf_debug(MMF_DEBUG_LOG, "value[string]: %s\n", value->value.s_val);
151                 break;
152         case MMF_VALUE_TYPE_DATA:
153                 //mmf_debug(MMF_DEBUG_LOG, "value[data]: %p\n", value->value.p_val);
154                 break;
155         default:
156                 //mmf_debug(MMF_DEBUG_LOG, "value invalid!!\n");
157                 break;
158         }
159 }
160
161 int mmf_value_clear(mmf_value_t *value)
162 {
163         return_val_if_fail(value, -1);
164         if (value->type == MMF_VALUE_TYPE_STRING) {
165                 if (value->value.s_val) {
166                         free(value->value.s_val);
167                         value->value.s_val = NULL;
168                         value->size = 0;
169                 }
170         }
171         return 0;
172 }
173
174 int mmf_value_spec_init(mmf_value_spec_t *vs, int vs_type)
175 {
176         return_val_if_fail(vs, -1);
177         memset(vs, 0, sizeof(*vs));
178         vs->type = vs_type;
179         return 0;
180 }
181
182 int mmf_value_spec_set_int_range(mmf_value_spec_t *vs, int min, int max, int dval)
183 {
184         return_val_if_fail(vs && vs->type == MMF_VALUE_SPEC_INT_RANGE, -1);
185
186         vs->spec.int_spec.range.min = min;
187         vs->spec.int_spec.range.max = max;
188         vs->spec.int_spec.range.dval = dval;
189
190         return 0;
191 }
192
193 int mmf_value_spec_get_int_range(mmf_value_spec_t *vs, int *min, int *max, int *dval)
194 {
195         return_val_if_fail(vs && min && max && dval && vs->type == MMF_VALUE_SPEC_INT_RANGE, -1);
196
197         *min = vs->spec.int_spec.range.min;
198         *max = vs->spec.int_spec.range.max;
199         *dval = vs->spec.int_spec.range.dval;
200
201         return 0;
202 }
203
204 int mmf_value_spec_set_int_array(mmf_value_spec_t *vs, const int *array, int count, int dval)
205 {
206         int *array_copy = NULL;
207
208         return_val_if_fail(vs && array && vs->type == MMF_VALUE_SPEC_INT_ARRAY && count > 0, -1);
209
210         array_copy = (int *) malloc(sizeof(int) * count);
211         if (array_copy == NULL) {
212                 debug_error("malloc failed");
213                 return -1;
214         }
215
216         memcpy(array_copy, array, sizeof(int) * count);
217         vs->spec.int_spec.array.array = array_copy;
218         vs->spec.int_spec.array.count = count;
219         vs->spec.int_spec.array.dval = dval;
220
221         return 0;
222 }
223
224 int mmf_value_spec_get_int_array(mmf_value_spec_t *vs, int **array, int *count, int *dval)
225 {
226         return_val_if_fail(vs && array && count && dval && vs->type == MMF_VALUE_SPEC_INT_ARRAY, -1);
227
228         *array = vs->spec.int_spec.array.array;
229         *count = vs->spec.int_spec.array.count;
230         *dval = vs->spec.int_spec.array.dval;
231
232         return 0;
233 }
234
235 int mmf_value_spec_set_double_range(mmf_value_spec_t *vs, double min, double max, double dval)
236 {
237         return_val_if_fail(vs && vs->type == MMF_VALUE_SPEC_DOUBLE_RANGE, -1);
238
239         vs->spec.double_spec.range.min = min;
240         vs->spec.double_spec.range.max = max;
241         vs->spec.double_spec.range.dval = dval;
242
243         return 0;
244 }
245
246 int mmf_value_spec_get_double_range(mmf_value_spec_t *vs, double *min, double *max, double *dval)
247 {
248         return_val_if_fail(vs && min && max && dval && vs->type == MMF_VALUE_SPEC_DOUBLE_RANGE, -1);
249
250         *min = vs->spec.double_spec.range.min;
251         *max = vs->spec.double_spec.range.max;
252         *dval = vs->spec.double_spec.range.dval;
253
254         return 0;
255 }
256
257 int mmf_value_spec_set_double_array(mmf_value_spec_t *vs, const double *array, int count, double dval)
258 {
259         double *array_copy = NULL;
260
261         return_val_if_fail(vs && array && vs->type == MMF_VALUE_SPEC_DOUBLE_ARRAY && count > 0, -1);
262
263         array_copy = (double *) malloc(sizeof(double) * count);
264         if (array_copy == NULL) {
265                 debug_error("malloc failed");
266                 return -1;
267         }
268
269         memcpy(array_copy, array, sizeof(double) * count);
270         vs->spec.double_spec.array.array = array_copy;
271         vs->spec.double_spec.array.count = count;
272         vs->spec.double_spec.array.dval = dval;
273
274         return 0;
275 }
276
277 int mmf_value_spec_get_double_array(mmf_value_spec_t *vs, double **array, int *count, double *dval)
278 {
279         return_val_if_fail(vs && array && count && dval && vs->type == MMF_VALUE_SPEC_DOUBLE_ARRAY, -1);
280
281         *array = vs->spec.double_spec.array.array;
282         *count = vs->spec.double_spec.array.count;
283         *dval = vs->spec.double_spec.array.dval;
284
285         return 0;
286 }
287
288 int mmf_value_spec_clear(mmf_value_spec_t *vs)
289 {
290         return_val_if_fail(vs, -1);
291         switch (vs->type) {
292         case MMF_VALUE_SPEC_INT_ARRAY:
293                 if (vs->spec.int_spec.array.array) {
294                         free(vs->spec.int_spec.array.array);
295                         vs->spec.int_spec.array.array = NULL;
296                         vs->spec.int_spec.array.count = 0;
297                         vs->spec.int_spec.array.dval = 0;
298                 }
299                 break;
300         case MMF_VALUE_SPEC_DOUBLE_ARRAY:
301                 if (vs->spec.double_spec.array.array) {
302                         free(vs->spec.double_spec.array.array);
303                         vs->spec.double_spec.array.array = NULL;
304                         vs->spec.double_spec.array.count = 0;
305                         vs->spec.double_spec.array.dval = 0;
306                 }
307                 break;
308
309         default:
310                 break;
311         }
312
313         return 0;
314 }
315
316 int mmf_attribute_init(mmf_attribute_t *item, const char *name, int value_type, int flags)
317 {
318         return_val_if_fail(item && name, -1);
319
320         item->name = strdup(name);
321         item->flags = flags;
322
323         mmf_value_spec_init(&item->value_spec, MMF_VALUE_SPEC_NONE);
324         mmf_value_init(&item->value, value_type);
325         mmf_value_init(&item->tmpval, value_type);
326
327         return 0;
328 }
329
330 bool mmf_attribute_check_flags(mmf_attribute_t *item, int flags)
331 {
332         return_val_if_fail(item, false);
333         return item->flags & flags;
334 }
335
336 bool mmf_attribute_validate_int(mmf_attribute_t *item, int val)
337 {
338         return_val_if_fail(item, false);
339         return_val_if_fail(item->value.type == MMF_VALUE_TYPE_INT, false);
340
341         bool valid = true;
342         int i = 0;
343
344         switch (item->value_spec.type) {
345         case MMF_VALUE_SPEC_INT_RANGE:
346                 if (val < item->value_spec.spec.int_spec.range.min ||
347                                 val > item->value_spec.spec.int_spec.range.max) {
348                         valid = false;
349                         debug_error("[mmf_attribute:%s] out of range[min %d, max %d, set %d]",
350                                 item->name, item->value_spec.spec.int_spec.range.min,
351                                 item->value_spec.spec.int_spec.range.max, val);
352                 }
353                 break;
354         case MMF_VALUE_SPEC_INT_ARRAY:
355                 valid = false;
356                 for (i = 0; i < item->value_spec.spec.int_spec.array.count; i++) {
357                         if (val == item->value_spec.spec.int_spec.array.array[i]) {
358                                 valid = true;
359                                 break;
360                         }
361                 }
362                 if (!valid) {
363                         debug_error("[mmf_attribute:%s] out of array, set %d", item->name, val);
364                         for (i = 0; i < item->value_spec.spec.int_spec.array.count; i++) {
365                                 debug_error("array[index %d] value [%d]",
366                                         i, item->value_spec.spec.int_spec.array.array[i]);
367                         }
368                 }
369                 break;
370         default:
371                 break;
372         }
373
374         return valid;
375 }
376
377 bool mmf_attribute_validate_double(mmf_attribute_t *item, double val)
378 {
379         return_val_if_fail(item, false);
380         return_val_if_fail(item->value.type == MMF_VALUE_TYPE_DOUBLE, false);
381
382         bool valid = true;
383         int i = 0;
384
385         switch (item->value_spec.type) {
386         case MMF_VALUE_SPEC_DOUBLE_RANGE:
387                 if (val < item->value_spec.spec.double_spec.range.min ||
388                                 val > item->value_spec.spec.double_spec.range.max) {
389                         valid = false;
390                         //mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of range\n", item->name);
391                 }
392                 break;
393         case MMF_VALUE_SPEC_DOUBLE_ARRAY:
394                 valid = false;
395                 for (i = 0; i < item->value_spec.spec.double_spec.array.count; i++) {
396                         if (val == item->value_spec.spec.double_spec.array.array[i]) {
397                                 valid = true;
398                                 break;
399                         }
400                 }
401                 if (!valid) {
402                         //mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of array\n", item->name);
403                 }
404                 break;
405         default:
406                 break;
407         }
408
409         return valid;
410 }
411
412 void mmf_attribute_clear(mmf_attribute_t *item)
413 {
414         assert(item);
415         if (item->name) {
416                 free(item->name);
417                 item->name = NULL;
418         }
419
420         mmf_value_clear(&item->tmpval);
421         mmf_value_clear(&item->value);
422         mmf_value_spec_clear(&item->value_spec);
423         pthread_mutex_destroy(&item->write_lock);
424 }
425
426 bool mmf_attribute_is_modified(mmf_attribute_t *item)
427 {
428         return_val_if_fail(item, false);
429         return (item->flags & MM_ATTRS_FLAG_MODIFIED);
430 }
431
432 void mmf_attribute_set_modified(mmf_attribute_t *item)
433 {
434         return_if_fail(item);
435         if (!(item->flags & MM_ATTRS_FLAG_MODIFIED)) {
436                 mmf_value_copy(&item->tmpval, &item->value);
437                 item->flags |= MM_ATTRS_FLAG_MODIFIED;
438         }
439 }
440
441 void mmf_attribute_set_readonly(mmf_attribute_t *item)
442 {
443         return_if_fail(item);
444         if (item->flags & MM_ATTRS_FLAG_WRITABLE)
445                 item->flags -= MM_ATTRS_FLAG_WRITABLE;
446 }
447
448 void mmf_attribute_set_disabled(mmf_attribute_t *item)
449 {
450         return_if_fail(item);
451         if (item->flags & MM_ATTRS_FLAG_WRITABLE)
452                 item->flags -= MM_ATTRS_FLAG_WRITABLE;
453         if (item->flags & MM_ATTRS_FLAG_READABLE)
454                 item->flags -= MM_ATTRS_FLAG_READABLE;
455         if (item->flags & MM_ATTRS_FLAG_MODIFIED)
456                 item->flags -= MM_ATTRS_FLAG_MODIFIED;
457 }
458
459 void mmf_attribute_commit(mmf_attribute_t *item)
460 {
461         return_if_fail(item);
462         if (item->flags & MM_ATTRS_FLAG_MODIFIED) {
463                 mmf_value_copy(&item->value, &item->tmpval);
464                 mmf_value_clear(&item->tmpval);
465                 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
466         }
467 }
468
469 int mmf_attribute_set_int(mmf_attribute_t *item, int val)
470 {
471         return_val_if_fail(item, -1);
472         if (mmf_value_set_int(&item->tmpval, val) == 0) {
473                 item->flags |= MM_ATTRS_FLAG_MODIFIED;
474                 return 0;
475         }
476         return -1;
477 }
478
479 int mmf_attribute_set_double(mmf_attribute_t *item, double val)
480 {
481         return_val_if_fail(item, -1);
482         if (mmf_value_set_double(&item->tmpval, val) == 0) {
483                 item->flags |= MM_ATTRS_FLAG_MODIFIED;
484                 return 0;
485         }
486         return -1;
487 }
488
489 int mmf_attribute_set_string(mmf_attribute_t *item, const char *string, int size)
490 {
491         return_val_if_fail(item, -1);
492
493         if (mmf_value_set_string(&item->tmpval, string, size) == 0) {
494                 item->flags |= MM_ATTRS_FLAG_MODIFIED;
495                 return 0;
496         }
497         return -1;
498 }
499
500 int mmf_attribute_set_data(mmf_attribute_t *item, void *data, int size)
501 {
502         return_val_if_fail(item, -1);
503
504         if (mmf_value_set_data(&item->tmpval, data, size) == 0) {
505                 item->flags |= MM_ATTRS_FLAG_MODIFIED;
506                 return 0;
507         }
508         return -1;
509 }
510
511 MMHandleType mmf_attrs_new(int count)
512 {
513         return_val_if_fail(count > 0, 0);
514         mmf_attrs_t *attrs;
515         attrs = (mmf_attrs_t *) malloc(sizeof(mmf_attrs_t));
516
517         if (attrs == NULL) {
518                 debug_error("malloc failed");
519                 return 0;
520         }
521
522         attrs->count = count;
523         attrs->items = (mmf_attribute_t *) malloc(sizeof(mmf_attribute_t) * count);
524         if (attrs->items == NULL) {
525                 debug_error("Failed to malloc for attrs->items.");
526                 free(attrs);
527                 attrs = NULL;
528                 return 0;
529         }
530
531         memset(attrs->items, 0, sizeof(mmf_attribute_t) * count);
532
533         return (MMHandleType) attrs;
534 }
535
536 MMHandleType mmf_attrs_new_from_data(const char *name,
537                                                                         mmf_attrs_construct_info_t *info,
538                                                                         int count,
539                                                                         mmf_attrs_commit_func_t commit_func,
540                                                                         void *commit_param)
541 {
542         return_val_if_fail(info && count > 0, 0);
543         MMHandleType h;
544         mmf_attrs_t *attrs;
545
546         h = mmf_attrs_new(count);
547         if (!h) {
548                 return 0;
549         }
550         mmf_attrs_init(h, info, count);
551         attrs = (mmf_attrs_t *) h;
552         attrs->name = NULL;
553         if (name)
554                 attrs->name = strdup(name);
555         attrs->commit_func = commit_func;
556         attrs->commit_param = commit_param;
557         return h;
558 }
559
560 void mmf_attrs_free(MMHandleType h)
561 {
562         return_if_fail(h);
563         mmf_attrs_t *attrs = (mmf_attrs_t *) h;
564         if (attrs) {
565                 if (attrs->name) {
566                         free(attrs->name);
567                         attrs->name = NULL;
568                 }
569                 if (attrs->items) {
570                         int i;
571                         for (i = 0; i < attrs->count; i++) {
572                                 mmf_attribute_clear(&attrs->items[i]);
573                         }
574                         free(attrs->items);
575                         attrs->items = NULL;
576                 }
577                 free(attrs);
578         }
579 }
580
581 int mmf_attrs_init(MMHandleType h, mmf_attrs_construct_info_t *info, int count)
582 {
583         return_val_if_fail(h && info && count > 0, -1);
584         mmf_attrs_t *attrs = (mmf_attrs_t *) h;
585         mmf_attribute_t *item = NULL;
586         int i;
587         int size = 0;
588
589         for (i = 0; i < count; i++) {
590                 item = &attrs->items[i];
591
592                 pthread_mutex_init(&item->write_lock, NULL);
593
594                 mmf_attribute_init(item,
595                                                 info[i].name,
596                                                 info[i].value_type,
597                                                 info[i].flags);
598
599                 switch (info[i].value_type) {
600                 case MMF_VALUE_TYPE_INT:
601                         assert(item->value.value.i_val == 0);
602                         mmf_value_set_int(&item->value,
603                                                         (intptr_t)info[i].default_value);
604                         break;
605                 case MMF_VALUE_TYPE_DOUBLE:
606                 {
607                         int i_val = (intptr_t)info[i].default_value;
608                         double d_val = (double) i_val;
609                         assert(item->value.value.d_val == 0);
610                         mmf_value_set_double(&item->value, d_val);
611                         break;
612                 }
613                 case MMF_VALUE_TYPE_STRING:
614                         assert(item->value.value.s_val == NULL);
615                         if (info[i].default_value) {
616                                 size = strlen(info[i].default_value)+1;
617                         }
618                         mmf_value_set_string(&item->value,
619                                                         (const char *)info[i].default_value, size);
620                         break;
621                 case MMF_VALUE_TYPE_DATA:
622                         assert(item->value.value.p_val == NULL);
623                         if (info[i].default_value) {
624                                 size = sizeof(info[i].default_value)+1;
625                         }
626                         mmf_value_set_data(&item->value, info[i].default_value, size);
627                         break;
628                 default:
629                         //mmf_debug(MMF_DEBUG_LOG, "ERROR: Invalid MMF_VALUE_TYPE\n");
630                         assert(0);
631                         break;
632                 }
633         }
634
635         return 0;
636 }
637
638 int mmf_attrs_commit(MMHandleType h)
639 {
640         return_val_if_fail(h, -1);
641
642         mmf_attrs_t *attrs = (mmf_attrs_t *)h;
643         mmf_attribute_t *item = NULL;
644         int i;
645         int ret = 0;
646
647         for (i = 0; i < attrs->count; ++i) {
648                 item = &attrs->items[i];
649
650                 MM_ATTR_ITEM_WRITE_LOCK(item);
651
652                 if (mmf_attribute_is_modified(item)) {
653                         if (attrs->commit_func) {
654                                 if (attrs->commit_func(i, item->name,
655                                                                                 &item->tmpval,
656                                                                                 attrs->commit_param)) {
657                                         mmf_attribute_commit(item);
658                                 } else {
659                                         /* without this, there is no way to solve modify when commit_func failed. */
660                                         if (item->flags & MM_ATTRS_FLAG_MODIFIED)
661                                                 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
662                                         ret = -1;
663                                 }
664                         } else {
665                                 mmf_attribute_commit(item);
666                         }
667                 }
668
669                 MM_ATTR_ITEM_WRITE_UNLOCK(item);
670         }
671
672         return ret;
673 }
674
675 int mmf_attrs_commit_err(MMHandleType h, char **err_attr_name)
676 {
677         mmf_attrs_t *attrs = (mmf_attrs_t *)h;
678         mmf_attribute_t *item = NULL;
679         int i;
680         int ret = 0;
681
682         return_val_if_fail(h, -1);
683
684         for (i = 0; i < attrs->count; ++i) {
685                 item = &attrs->items[i];
686
687                 MM_ATTR_ITEM_WRITE_LOCK(item);
688
689                 if (mmf_attribute_is_modified(item)) {
690                         if (attrs->commit_func) {
691                                 if (attrs->commit_func(i, item->name,
692                                                                                 &item->tmpval,
693                                                                                 attrs->commit_param)) {
694                                         mmf_attribute_commit(item);
695                                 } else {
696                                         /* without this, there is no way to solve modify when commit_func failed. */
697                                         if (item->flags & MM_ATTRS_FLAG_MODIFIED)
698                                                 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
699                                         ret = -1;
700
701                                         /* Set Error information */
702                                         if (err_attr_name)
703                                                 *err_attr_name = strdup(item->name);
704
705                                         MM_ATTR_ITEM_WRITE_UNLOCK(item);
706                                         break;
707                                 }
708                         } else {
709                                 mmf_attribute_commit(item);
710                         }
711                 }
712
713                 MM_ATTR_ITEM_WRITE_UNLOCK(item);
714         }
715
716         return ret;
717 }
718
719 int mmf_attrs_set_valid_type(MMHandleType h, int idx, int v_type)
720 {
721         return_val_if_fail(h, -1);
722         return_val_if_fail(idx >= 0, -1);
723         mmf_attrs_t *attrs = (mmf_attrs_t *) h;
724         return mmf_value_spec_init(&attrs->items[idx].value_spec, v_type);
725 }
726
727 int mmf_attrs_set_valid_range(MMHandleType h, int idx, int min, int max, int dval)
728 {
729         return_val_if_fail(h, -1);
730         return_val_if_fail(idx >= 0, -1);
731         mmf_attrs_t *attrs = (mmf_attrs_t *) h;
732         mmf_value_spec_clear(&attrs->items[idx].value_spec);
733         assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_RANGE);
734         return mmf_value_spec_set_int_range(&attrs->items[idx].value_spec, min, max, dval);
735 }
736
737 int mmf_attrs_set_valid_array(MMHandleType h, int idx, const int *array, int count, int dval)
738 {
739         return_val_if_fail(h, -1);
740         return_val_if_fail(idx >= 0, -1);
741         mmf_attrs_t *attrs = (mmf_attrs_t *) h;
742         mmf_value_spec_clear(&attrs->items[idx].value_spec);
743         assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_ARRAY);
744         return mmf_value_spec_set_int_array(&attrs->items[idx].value_spec, array, count, dval);
745 }
746
747 int mmf_attrs_set_valid_double_range(MMHandleType h, int idx, double min, double max, double dval)
748 {
749         return_val_if_fail(h, -1);
750         return_val_if_fail(idx >= 0, -1);
751         mmf_attrs_t *attrs = (mmf_attrs_t *) h;
752         mmf_value_spec_clear(&attrs->items[idx].value_spec);
753         assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_RANGE);
754         return mmf_value_spec_set_double_range(&attrs->items[idx].value_spec, min, max, dval);
755 }
756
757 int mmf_attrs_set_valid_double_array(MMHandleType h, int idx, const double *array, int count, double dval)
758 {
759         return_val_if_fail(h, -1);
760         return_val_if_fail(idx >= 0, -1);
761         mmf_attrs_t *attrs = (mmf_attrs_t *) h;
762         mmf_value_spec_clear(&attrs->items[idx].value_spec);
763         assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_ARRAY);
764         return mmf_value_spec_set_double_array(&attrs->items[idx].value_spec, array, count, dval);
765 }