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