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