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