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