4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
31 #include "mm_attrs_private.h"
33 int mmf_value_init(mmf_value_t *value, int type)
35 return_val_if_fail(value, -1);
36 return_val_if_fail(MMF_IS_VALUE_TYPE(type), -1);
37 memset(value, 0, sizeof(*value));
42 int mmf_value_copy(mmf_value_t *dest, const mmf_value_t *src)
44 return_val_if_fail(dest && src && src->type == dest->type, -1);
46 case MM_ATTRS_TYPE_INT:
47 dest->value.i_val = src->value.i_val;
49 case MM_ATTRS_TYPE_DOUBLE:
50 dest->value.d_val = src->value.d_val;
52 case MM_ATTRS_TYPE_STRING:
53 if (dest->value.s_val) {
54 free(dest->value.s_val);
55 dest->value.s_val = NULL;
58 if (src->value.s_val) {
59 dest->value.s_val = strdup(src->value.s_val);
60 dest->size = src->size;
63 case MM_ATTRS_TYPE_DATA:
64 dest->value.p_val = src->value.p_val;
65 dest->size = src->size;
73 int mmf_value_set_int(mmf_value_t *v, int ival)
75 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_INT, -1);
76 v->value.i_val = ival;
80 int mmf_value_get_int(const mmf_value_t *v)
82 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_INT, -1);
83 return v->value.i_val;
86 int mmf_value_set_double(mmf_value_t *v, double dval)
88 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DOUBLE, -1);
89 v->value.d_val = dval;
93 double mmf_value_get_double(mmf_value_t *v)
95 return_val_if_fail(v->type == MMF_VALUE_TYPE_DOUBLE, -1);
96 return v->value.d_val;
99 int mmf_value_set_string(mmf_value_t *v, const char *sval, int size)
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;
108 v->value.s_val = strdup(sval);
111 v->value.s_val = NULL;
117 char* mmf_value_get_string(const mmf_value_t *v, int *size)
119 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_STRING, NULL);
121 return v->value.s_val;
124 int mmf_value_set_data(mmf_value_t *v, void *data, int size)
126 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DATA, -1);
127 v->value.p_val = data;
132 void* mmf_value_get_data(const mmf_value_t *v, int *size)
134 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DATA, NULL);
136 return v->value.p_val;
139 void mmf_value_dump(const mmf_value_t *value)
141 return_if_fail(value);
142 switch (value->type) {
143 case MMF_VALUE_TYPE_INT:
144 //mmf_debug(MMF_DEBUG_LOG, "value[int]: %d\n", value->value.i_val);
146 case MMF_VALUE_TYPE_DOUBLE:
147 //mmf_debug(MMF_DEBUG_LOG, "value[double]: %f\n", value->value.d_val);
149 case MMF_VALUE_TYPE_STRING:
150 //mmf_debug(MMF_DEBUG_LOG, "value[string]: %s\n", value->value.s_val);
152 case MMF_VALUE_TYPE_DATA:
153 //mmf_debug(MMF_DEBUG_LOG, "value[data]: %p\n", value->value.p_val);
156 //mmf_debug(MMF_DEBUG_LOG, "value invalid!!\n");
161 int mmf_value_clear(mmf_value_t *value)
163 return_val_if_fail(value, -1);
164 if (value->type == MMF_VALUE_TYPE_STRING) {
165 if (value->value.s_val) {
166 free(value->value.s_val);
167 value->value.s_val = NULL;
174 int mmf_value_spec_init(mmf_value_spec_t *vs, int vs_type)
176 return_val_if_fail(vs, -1);
177 memset(vs, 0, sizeof(*vs));
182 int mmf_value_spec_set_int_range(mmf_value_spec_t *vs, int min, int max, int dval)
184 return_val_if_fail(vs && vs->type == MMF_VALUE_SPEC_INT_RANGE, -1);
186 vs->spec.int_spec.range.min = min;
187 vs->spec.int_spec.range.max = max;
188 vs->spec.int_spec.range.dval = dval;
193 int mmf_value_spec_get_int_range(mmf_value_spec_t *vs, int *min, int *max, int *dval)
195 return_val_if_fail(vs && min && max && dval && vs->type == MMF_VALUE_SPEC_INT_RANGE, -1);
197 *min = vs->spec.int_spec.range.min;
198 *max = vs->spec.int_spec.range.max;
199 *dval = vs->spec.int_spec.range.dval;
204 int mmf_value_spec_set_int_array(mmf_value_spec_t *vs, const int *array, int count, int dval)
206 int *array_copy = NULL;
208 return_val_if_fail(vs && array && vs->type == MMF_VALUE_SPEC_INT_ARRAY && count > 0, -1);
210 array_copy = (int *) malloc(sizeof(int) * count);
211 if (array_copy == NULL) {
212 debug_error("malloc failed");
216 memcpy(array_copy, array, sizeof(int) * count);
217 vs->spec.int_spec.array.array = array_copy;
218 vs->spec.int_spec.array.count = count;
219 vs->spec.int_spec.array.dval = dval;
224 int mmf_value_spec_get_int_array(mmf_value_spec_t *vs, int **array, int *count, int *dval)
226 return_val_if_fail(vs && array && count && dval && vs->type == MMF_VALUE_SPEC_INT_ARRAY, -1);
228 *array = vs->spec.int_spec.array.array;
229 *count = vs->spec.int_spec.array.count;
230 *dval = vs->spec.int_spec.array.dval;
235 int mmf_value_spec_set_double_range(mmf_value_spec_t *vs, double min, double max, double dval)
237 return_val_if_fail(vs && vs->type == MMF_VALUE_SPEC_DOUBLE_RANGE, -1);
239 vs->spec.double_spec.range.min = min;
240 vs->spec.double_spec.range.max = max;
241 vs->spec.double_spec.range.dval = dval;
246 int mmf_value_spec_get_double_range(mmf_value_spec_t *vs, double *min, double *max, double *dval)
248 return_val_if_fail(vs && min && max && dval && vs->type == MMF_VALUE_SPEC_DOUBLE_RANGE, -1);
250 *min = vs->spec.double_spec.range.min;
251 *max = vs->spec.double_spec.range.max;
252 *dval = vs->spec.double_spec.range.dval;
257 int mmf_value_spec_set_double_array(mmf_value_spec_t *vs, const double *array, int count, double dval)
259 double *array_copy = NULL;
261 return_val_if_fail(vs && array && vs->type == MMF_VALUE_SPEC_DOUBLE_ARRAY && count > 0, -1);
263 array_copy = (double *) malloc(sizeof(double) * count);
264 if (array_copy == NULL) {
265 debug_error("malloc failed");
269 memcpy(array_copy, array, sizeof(double) * count);
270 vs->spec.double_spec.array.array = array_copy;
271 vs->spec.double_spec.array.count = count;
272 vs->spec.double_spec.array.dval = dval;
277 int mmf_value_spec_get_double_array(mmf_value_spec_t *vs, double **array, int *count, double *dval)
279 return_val_if_fail(vs && array && count && dval && vs->type == MMF_VALUE_SPEC_DOUBLE_ARRAY, -1);
281 *array = vs->spec.double_spec.array.array;
282 *count = vs->spec.double_spec.array.count;
283 *dval = vs->spec.double_spec.array.dval;
288 int mmf_value_spec_clear(mmf_value_spec_t *vs)
290 return_val_if_fail(vs, -1);
292 case MMF_VALUE_SPEC_INT_ARRAY:
293 if (vs->spec.int_spec.array.array) {
294 free(vs->spec.int_spec.array.array);
295 vs->spec.int_spec.array.array = NULL;
296 vs->spec.int_spec.array.count = 0;
297 vs->spec.int_spec.array.dval = 0;
300 case MMF_VALUE_SPEC_DOUBLE_ARRAY:
301 if (vs->spec.double_spec.array.array) {
302 free(vs->spec.double_spec.array.array);
303 vs->spec.double_spec.array.array = NULL;
304 vs->spec.double_spec.array.count = 0;
305 vs->spec.double_spec.array.dval = 0;
316 int mmf_attribute_init(mmf_attribute_t *item, const char *name, int value_type, int flags)
318 return_val_if_fail(item && name, -1);
320 item->name = strdup(name);
323 mmf_value_spec_init(&item->value_spec, MMF_VALUE_SPEC_NONE);
324 mmf_value_init(&item->value, value_type);
325 mmf_value_init(&item->tmpval, value_type);
330 bool mmf_attribute_check_flags(mmf_attribute_t *item, int flags)
332 return_val_if_fail(item, false);
333 return item->flags & flags;
336 bool mmf_attribute_validate_int(mmf_attribute_t *item, int val)
338 return_val_if_fail(item, false);
339 return_val_if_fail(item->value.type == MMF_VALUE_TYPE_INT, false);
344 switch (item->value_spec.type) {
345 case MMF_VALUE_SPEC_INT_RANGE:
346 if (val < item->value_spec.spec.int_spec.range.min ||
347 val > item->value_spec.spec.int_spec.range.max) {
349 debug_error("[mmf_attribute:%s] out of range[min %d, max %d, set %d]",
350 item->name, item->value_spec.spec.int_spec.range.min,
351 item->value_spec.spec.int_spec.range.max, val);
354 case MMF_VALUE_SPEC_INT_ARRAY:
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]) {
363 debug_error("[mmf_attribute:%s] out of array, set %d", item->name, val);
364 for (i = 0; i < item->value_spec.spec.int_spec.array.count; i++) {
365 debug_error("array[index %d] value [%d]",
366 i, item->value_spec.spec.int_spec.array.array[i]);
377 bool mmf_attribute_validate_double(mmf_attribute_t *item, double val)
379 return_val_if_fail(item, false);
380 return_val_if_fail(item->value.type == MMF_VALUE_TYPE_DOUBLE, false);
385 switch (item->value_spec.type) {
386 case MMF_VALUE_SPEC_DOUBLE_RANGE:
387 if (val < item->value_spec.spec.double_spec.range.min ||
388 val > item->value_spec.spec.double_spec.range.max) {
390 //mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of range\n", item->name);
393 case MMF_VALUE_SPEC_DOUBLE_ARRAY:
395 for (i = 0; i < item->value_spec.spec.double_spec.array.count; i++) {
396 if (val == item->value_spec.spec.double_spec.array.array[i]) {
402 //mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of array\n", item->name);
412 void mmf_attribute_clear(mmf_attribute_t *item)
420 mmf_value_clear(&item->tmpval);
421 mmf_value_clear(&item->value);
422 mmf_value_spec_clear(&item->value_spec);
423 pthread_mutex_destroy(&item->write_lock);
426 bool mmf_attribute_is_modified(mmf_attribute_t *item)
428 return_val_if_fail(item, false);
429 return (item->flags & MM_ATTRS_FLAG_MODIFIED);
432 void mmf_attribute_set_modified(mmf_attribute_t *item)
434 return_if_fail(item);
435 if (!(item->flags & MM_ATTRS_FLAG_MODIFIED)) {
436 mmf_value_copy(&item->tmpval, &item->value);
437 item->flags |= MM_ATTRS_FLAG_MODIFIED;
441 void mmf_attribute_set_readonly(mmf_attribute_t *item)
443 return_if_fail(item);
444 if (item->flags & MM_ATTRS_FLAG_WRITABLE)
445 item->flags -= MM_ATTRS_FLAG_WRITABLE;
448 void mmf_attribute_set_disabled(mmf_attribute_t *item)
450 return_if_fail(item);
451 if (item->flags & MM_ATTRS_FLAG_WRITABLE)
452 item->flags -= MM_ATTRS_FLAG_WRITABLE;
453 if (item->flags & MM_ATTRS_FLAG_READABLE)
454 item->flags -= MM_ATTRS_FLAG_READABLE;
455 if (item->flags & MM_ATTRS_FLAG_MODIFIED)
456 item->flags -= MM_ATTRS_FLAG_MODIFIED;
459 void mmf_attribute_commit(mmf_attribute_t *item)
461 return_if_fail(item);
462 if (item->flags & MM_ATTRS_FLAG_MODIFIED) {
463 mmf_value_copy(&item->value, &item->tmpval);
464 mmf_value_clear(&item->tmpval);
465 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
469 int mmf_attribute_set_int(mmf_attribute_t *item, int val)
471 return_val_if_fail(item, -1);
472 if (mmf_value_set_int(&item->tmpval, val) == 0) {
473 item->flags |= MM_ATTRS_FLAG_MODIFIED;
479 int mmf_attribute_set_double(mmf_attribute_t *item, double val)
481 return_val_if_fail(item, -1);
482 if (mmf_value_set_double(&item->tmpval, val) == 0) {
483 item->flags |= MM_ATTRS_FLAG_MODIFIED;
489 int mmf_attribute_set_string(mmf_attribute_t *item, const char *string, int size)
491 return_val_if_fail(item, -1);
493 if (mmf_value_set_string(&item->tmpval, string, size) == 0) {
494 item->flags |= MM_ATTRS_FLAG_MODIFIED;
500 int mmf_attribute_set_data(mmf_attribute_t *item, void *data, int size)
502 return_val_if_fail(item, -1);
504 if (mmf_value_set_data(&item->tmpval, data, size) == 0) {
505 item->flags |= MM_ATTRS_FLAG_MODIFIED;
511 MMHandleType mmf_attrs_new(int count)
513 return_val_if_fail(count > 0, 0);
515 attrs = (mmf_attrs_t *) malloc(sizeof(mmf_attrs_t));
518 debug_error("malloc failed");
522 attrs->count = count;
523 attrs->items = (mmf_attribute_t *) malloc(sizeof(mmf_attribute_t) * count);
524 if (attrs->items == NULL) {
525 debug_error("Failed to malloc for attrs->items.");
531 memset(attrs->items, 0, sizeof(mmf_attribute_t) * count);
533 return (MMHandleType) attrs;
536 MMHandleType mmf_attrs_new_from_data(const char *name,
537 mmf_attrs_construct_info_t *info,
539 mmf_attrs_commit_func_t commit_func,
542 return_val_if_fail(info && count > 0, 0);
546 h = mmf_attrs_new(count);
550 mmf_attrs_init(h, info, count);
551 attrs = (mmf_attrs_t *) h;
554 attrs->name = strdup(name);
555 attrs->commit_func = commit_func;
556 attrs->commit_param = commit_param;
560 void mmf_attrs_free(MMHandleType h)
563 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
571 for (i = 0; i < attrs->count; i++) {
572 mmf_attribute_clear(&attrs->items[i]);
581 int mmf_attrs_init(MMHandleType h, mmf_attrs_construct_info_t *info, int count)
583 return_val_if_fail(h && info && count > 0, -1);
584 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
585 mmf_attribute_t *item = NULL;
589 for (i = 0; i < count; i++) {
590 item = &attrs->items[i];
592 pthread_mutex_init(&item->write_lock, NULL);
594 mmf_attribute_init(item,
599 switch (info[i].value_type) {
600 case MMF_VALUE_TYPE_INT:
601 assert(item->value.value.i_val == 0);
602 mmf_value_set_int(&item->value,
603 (intptr_t)info[i].default_value);
605 case MMF_VALUE_TYPE_DOUBLE:
607 int i_val = (intptr_t)info[i].default_value;
608 double d_val = (double) i_val;
609 assert(item->value.value.d_val == 0);
610 mmf_value_set_double(&item->value, d_val);
613 case MMF_VALUE_TYPE_STRING:
614 assert(item->value.value.s_val == NULL);
615 if (info[i].default_value) {
616 size = strlen(info[i].default_value)+1;
618 mmf_value_set_string(&item->value,
619 (const char *)info[i].default_value, size);
621 case MMF_VALUE_TYPE_DATA:
622 assert(item->value.value.p_val == NULL);
623 if (info[i].default_value) {
624 size = sizeof(info[i].default_value)+1;
626 mmf_value_set_data(&item->value, info[i].default_value, size);
629 //mmf_debug(MMF_DEBUG_LOG, "ERROR: Invalid MMF_VALUE_TYPE\n");
638 int mmf_attrs_commit(MMHandleType h)
640 return_val_if_fail(h, -1);
642 mmf_attrs_t *attrs = (mmf_attrs_t *)h;
643 mmf_attribute_t *item = NULL;
647 for (i = 0; i < attrs->count; ++i) {
648 item = &attrs->items[i];
650 MM_ATTR_ITEM_WRITE_LOCK(item);
652 if (mmf_attribute_is_modified(item)) {
653 if (attrs->commit_func) {
654 if (attrs->commit_func(i, item->name,
656 attrs->commit_param)) {
657 mmf_attribute_commit(item);
659 /* without this, there is no way to solve modify when commit_func failed. */
660 if (item->flags & MM_ATTRS_FLAG_MODIFIED)
661 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
665 mmf_attribute_commit(item);
669 MM_ATTR_ITEM_WRITE_UNLOCK(item);
675 int mmf_attrs_commit_err(MMHandleType h, char **err_attr_name)
677 mmf_attrs_t *attrs = (mmf_attrs_t *)h;
678 mmf_attribute_t *item = NULL;
682 return_val_if_fail(h, -1);
684 for (i = 0; i < attrs->count; ++i) {
685 item = &attrs->items[i];
687 MM_ATTR_ITEM_WRITE_LOCK(item);
689 if (mmf_attribute_is_modified(item)) {
690 if (attrs->commit_func) {
691 if (attrs->commit_func(i, item->name,
693 attrs->commit_param)) {
694 mmf_attribute_commit(item);
696 /* without this, there is no way to solve modify when commit_func failed. */
697 if (item->flags & MM_ATTRS_FLAG_MODIFIED)
698 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
701 /* Set Error information */
703 *err_attr_name = strdup(item->name);
705 MM_ATTR_ITEM_WRITE_UNLOCK(item);
709 mmf_attribute_commit(item);
713 MM_ATTR_ITEM_WRITE_UNLOCK(item);
719 int mmf_attrs_set_valid_type(MMHandleType h, int idx, int v_type)
721 return_val_if_fail(h, -1);
722 return_val_if_fail(idx >= 0, -1);
723 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
724 return mmf_value_spec_init(&attrs->items[idx].value_spec, v_type);
727 int mmf_attrs_set_valid_range(MMHandleType h, int idx, int min, int max, int dval)
729 return_val_if_fail(h, -1);
730 return_val_if_fail(idx >= 0, -1);
731 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
732 mmf_value_spec_clear(&attrs->items[idx].value_spec);
733 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_RANGE);
734 return mmf_value_spec_set_int_range(&attrs->items[idx].value_spec, min, max, dval);
737 int mmf_attrs_set_valid_array(MMHandleType h, int idx, const int *array, int count, int dval)
739 return_val_if_fail(h, -1);
740 return_val_if_fail(idx >= 0, -1);
741 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
742 mmf_value_spec_clear(&attrs->items[idx].value_spec);
743 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_ARRAY);
744 return mmf_value_spec_set_int_array(&attrs->items[idx].value_spec, array, count, dval);
747 int mmf_attrs_set_valid_double_range(MMHandleType h, int idx, double min, double max, double dval)
749 return_val_if_fail(h, -1);
750 return_val_if_fail(idx >= 0, -1);
751 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
752 mmf_value_spec_clear(&attrs->items[idx].value_spec);
753 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_RANGE);
754 return mmf_value_spec_set_double_range(&attrs->items[idx].value_spec, min, max, dval);
757 int mmf_attrs_set_valid_double_array(MMHandleType h, int idx, const double *array, int count, double dval)
759 return_val_if_fail(h, -1);
760 return_val_if_fail(idx >= 0, -1);
761 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
762 mmf_value_spec_clear(&attrs->items[idx].value_spec);
763 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_ARRAY);
764 return mmf_value_spec_set_double_array(&attrs->items[idx].value_spec, array, count, dval);