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 *v, int type)
35 return_val_if_fail(v, -1);
36 return_val_if_fail(MMF_IS_VALUE_TYPE(type), -1);
38 memset(v, 0, sizeof(*v));
43 int mmf_value_copy(mmf_value_t *dest, const mmf_value_t *src)
45 return_val_if_fail(dest && src && src->type == dest->type, -1);
48 case MM_ATTRS_TYPE_INT:
49 dest->value.i_val = src->value.i_val;
51 case MM_ATTRS_TYPE_DOUBLE:
52 dest->value.d_val = src->value.d_val;
54 case MM_ATTRS_TYPE_STRING:
55 if (dest->value.s_val) {
56 free(dest->value.s_val);
57 dest->value.s_val = NULL;
60 if (src->value.s_val) {
61 dest->value.s_val = strdup(src->value.s_val);
62 dest->size = src->size;
65 case MM_ATTRS_TYPE_DATA:
66 dest->value.p_val = src->value.p_val;
67 dest->size = src->size;
75 int mmf_value_set_int(mmf_value_t *v, int ival)
77 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_INT, -1);
79 v->value.i_val = ival;
83 int mmf_value_get_int(const mmf_value_t *v)
85 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_INT, -1);
87 return v->value.i_val;
90 int mmf_value_set_double(mmf_value_t *v, double dval)
92 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DOUBLE, -1);
94 v->value.d_val = dval;
98 double mmf_value_get_double(mmf_value_t *v)
100 return_val_if_fail(v->type == MMF_VALUE_TYPE_DOUBLE, -1);
102 return v->value.d_val;
105 int mmf_value_set_string(mmf_value_t *v, const char *sval, int size)
107 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_STRING, -1);
109 if (v->value.s_val != NULL) {
110 free(v->value.s_val);
111 v->value.s_val = NULL;
115 v->value.s_val = strdup(sval);
118 v->value.s_val = NULL;
124 char* mmf_value_get_string(const mmf_value_t *v, int *size)
126 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_STRING, NULL);
129 return v->value.s_val;
132 int mmf_value_set_data(mmf_value_t *v, void *data, int size)
134 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DATA, -1);
136 v->value.p_val = data;
141 void* mmf_value_get_data(const mmf_value_t *v, int *size)
143 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DATA, NULL);
146 return v->value.p_val;
149 void mmf_value_dump(const mmf_value_t *v)
154 case MMF_VALUE_TYPE_INT:
155 //mmf_debug(MMF_DEBUG_LOG, "value[int]: %d\n", v->value.i_val);
157 case MMF_VALUE_TYPE_DOUBLE:
158 //mmf_debug(MMF_DEBUG_LOG, "value[double]: %f\n", v->value.d_val);
160 case MMF_VALUE_TYPE_STRING:
161 //mmf_debug(MMF_DEBUG_LOG, "value[string]: %s\n", v->value.s_val);
163 case MMF_VALUE_TYPE_DATA:
164 //mmf_debug(MMF_DEBUG_LOG, "value[data]: %p\n", v->value.p_val);
167 //mmf_debug(MMF_DEBUG_LOG, "value invalid!!\n");
172 int mmf_value_clear(mmf_value_t *v)
174 return_val_if_fail(v, -1);
176 if (v->type == MMF_VALUE_TYPE_STRING) {
177 if (v->value.s_val) {
178 free(v->value.s_val);
179 v->value.s_val = NULL;
186 int mmf_value_spec_init(mmf_value_spec_t *vs, int vs_type)
188 return_val_if_fail(vs, -1);
190 memset(vs, 0, sizeof(*vs));
195 int mmf_value_spec_set_int_range(mmf_value_spec_t *vs, int min, int max, int dval)
197 return_val_if_fail(vs && vs->type == MMF_VALUE_SPEC_INT_RANGE, -1);
199 vs->spec.int_spec.range.min = min;
200 vs->spec.int_spec.range.max = max;
201 vs->spec.int_spec.range.dval = dval;
206 int mmf_value_spec_get_int_range(mmf_value_spec_t *vs, int *min, int *max, int *dval)
208 return_val_if_fail(vs && min && max && dval && vs->type == MMF_VALUE_SPEC_INT_RANGE, -1);
210 *min = vs->spec.int_spec.range.min;
211 *max = vs->spec.int_spec.range.max;
212 *dval = vs->spec.int_spec.range.dval;
217 int mmf_value_spec_set_int_array(mmf_value_spec_t *vs, const int *array, int count, int dval)
219 int *array_copy = NULL;
221 return_val_if_fail(vs && array && vs->type == MMF_VALUE_SPEC_INT_ARRAY && count > 0, -1);
223 array_copy = (int *) malloc(sizeof(int) * count);
224 if (array_copy == NULL) {
225 debug_error("malloc failed");
229 memcpy(array_copy, array, sizeof(int) * count);
230 vs->spec.int_spec.array.array = array_copy;
231 vs->spec.int_spec.array.count = count;
232 vs->spec.int_spec.array.dval = dval;
237 int mmf_value_spec_get_int_array(mmf_value_spec_t *vs, int **array, int *count, int *dval)
239 return_val_if_fail(vs && array && count && dval && vs->type == MMF_VALUE_SPEC_INT_ARRAY, -1);
241 *array = vs->spec.int_spec.array.array;
242 *count = vs->spec.int_spec.array.count;
243 *dval = vs->spec.int_spec.array.dval;
248 int mmf_value_spec_set_double_range(mmf_value_spec_t *vs, double min, double max, double dval)
250 return_val_if_fail(vs && vs->type == MMF_VALUE_SPEC_DOUBLE_RANGE, -1);
252 vs->spec.double_spec.range.min = min;
253 vs->spec.double_spec.range.max = max;
254 vs->spec.double_spec.range.dval = dval;
259 int mmf_value_spec_get_double_range(mmf_value_spec_t *vs, double *min, double *max, double *dval)
261 return_val_if_fail(vs && min && max && dval && vs->type == MMF_VALUE_SPEC_DOUBLE_RANGE, -1);
263 *min = vs->spec.double_spec.range.min;
264 *max = vs->spec.double_spec.range.max;
265 *dval = vs->spec.double_spec.range.dval;
270 int mmf_value_spec_set_double_array(mmf_value_spec_t *vs, const double *array, int count, double dval)
272 double *array_copy = NULL;
274 return_val_if_fail(vs && array && vs->type == MMF_VALUE_SPEC_DOUBLE_ARRAY && count > 0, -1);
276 array_copy = (double *) malloc(sizeof(double) * count);
277 if (array_copy == NULL) {
278 debug_error("malloc failed");
282 memcpy(array_copy, array, sizeof(double) * count);
283 vs->spec.double_spec.array.array = array_copy;
284 vs->spec.double_spec.array.count = count;
285 vs->spec.double_spec.array.dval = dval;
290 int mmf_value_spec_get_double_array(mmf_value_spec_t *vs, double **array, int *count, double *dval)
292 return_val_if_fail(vs && array && count && dval && vs->type == MMF_VALUE_SPEC_DOUBLE_ARRAY, -1);
294 *array = vs->spec.double_spec.array.array;
295 *count = vs->spec.double_spec.array.count;
296 *dval = vs->spec.double_spec.array.dval;
301 int mmf_value_spec_clear(mmf_value_spec_t *vs)
303 return_val_if_fail(vs, -1);
306 case MMF_VALUE_SPEC_INT_ARRAY:
307 if (vs->spec.int_spec.array.array) {
308 free(vs->spec.int_spec.array.array);
309 vs->spec.int_spec.array.array = NULL;
310 vs->spec.int_spec.array.count = 0;
311 vs->spec.int_spec.array.dval = 0;
314 case MMF_VALUE_SPEC_DOUBLE_ARRAY:
315 if (vs->spec.double_spec.array.array) {
316 free(vs->spec.double_spec.array.array);
317 vs->spec.double_spec.array.array = NULL;
318 vs->spec.double_spec.array.count = 0;
319 vs->spec.double_spec.array.dval = 0;
330 int mmf_attribute_init(mmf_attribute_t *item, const char *name, int value_type, int flags)
332 return_val_if_fail(item && name, -1);
334 item->name = strdup(name);
337 mmf_value_spec_init(&item->value_spec, MMF_VALUE_SPEC_NONE);
338 mmf_value_init(&item->value, value_type);
339 mmf_value_init(&item->tmpval, value_type);
344 bool mmf_attribute_check_flags(mmf_attribute_t *item, int flags)
346 return_val_if_fail(item, false);
348 return item->flags & flags;
351 bool mmf_attribute_validate_int(mmf_attribute_t *item, int val)
356 return_val_if_fail(item, false);
357 return_val_if_fail(item->value.type == MMF_VALUE_TYPE_INT, false);
359 switch (item->value_spec.type) {
360 case MMF_VALUE_SPEC_INT_RANGE:
361 if (val < item->value_spec.spec.int_spec.range.min ||
362 val > item->value_spec.spec.int_spec.range.max) {
364 debug_error("[mmf_attribute:%s] out of range[min %d, max %d, set %d]",
365 item->name, item->value_spec.spec.int_spec.range.min,
366 item->value_spec.spec.int_spec.range.max, val);
369 case MMF_VALUE_SPEC_INT_ARRAY:
371 for (i = 0; i < item->value_spec.spec.int_spec.array.count; i++) {
372 if (val == item->value_spec.spec.int_spec.array.array[i]) {
378 debug_error("[mmf_attribute:%s] out of array, set %d", item->name, val);
379 for (i = 0; i < item->value_spec.spec.int_spec.array.count; i++) {
380 debug_error("array[index %d] value [%d]",
381 i, item->value_spec.spec.int_spec.array.array[i]);
392 bool mmf_attribute_validate_double(mmf_attribute_t *item, double val)
397 return_val_if_fail(item, false);
398 return_val_if_fail(item->value.type == MMF_VALUE_TYPE_DOUBLE, false);
400 switch (item->value_spec.type) {
401 case MMF_VALUE_SPEC_DOUBLE_RANGE:
402 if (val < item->value_spec.spec.double_spec.range.min ||
403 val > item->value_spec.spec.double_spec.range.max) {
405 //mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of range\n", item->name);
408 case MMF_VALUE_SPEC_DOUBLE_ARRAY:
410 for (i = 0; i < item->value_spec.spec.double_spec.array.count; i++) {
411 if (val == item->value_spec.spec.double_spec.array.array[i]) {
417 //mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of array\n", item->name);
427 void mmf_attribute_clear(mmf_attribute_t *item)
436 mmf_value_clear(&item->tmpval);
437 mmf_value_clear(&item->value);
438 mmf_value_spec_clear(&item->value_spec);
439 pthread_mutex_destroy(&item->write_lock);
442 bool mmf_attribute_is_modified(mmf_attribute_t *item)
444 return_val_if_fail(item, false);
446 return (item->flags & MM_ATTRS_FLAG_MODIFIED);
449 void mmf_attribute_set_modified(mmf_attribute_t *item)
451 return_if_fail(item);
453 if (!(item->flags & MM_ATTRS_FLAG_MODIFIED)) {
454 mmf_value_copy(&item->tmpval, &item->value);
455 item->flags |= MM_ATTRS_FLAG_MODIFIED;
459 void mmf_attribute_set_readonly(mmf_attribute_t *item)
461 return_if_fail(item);
463 if (item->flags & MM_ATTRS_FLAG_WRITABLE)
464 item->flags -= MM_ATTRS_FLAG_WRITABLE;
467 void mmf_attribute_set_disabled(mmf_attribute_t *item)
469 return_if_fail(item);
471 if (item->flags & MM_ATTRS_FLAG_WRITABLE)
472 item->flags -= MM_ATTRS_FLAG_WRITABLE;
473 if (item->flags & MM_ATTRS_FLAG_READABLE)
474 item->flags -= MM_ATTRS_FLAG_READABLE;
475 if (item->flags & MM_ATTRS_FLAG_MODIFIED)
476 item->flags -= MM_ATTRS_FLAG_MODIFIED;
479 void mmf_attribute_commit(mmf_attribute_t *item)
481 return_if_fail(item);
483 if (item->flags & MM_ATTRS_FLAG_MODIFIED) {
484 mmf_value_copy(&item->value, &item->tmpval);
485 mmf_value_clear(&item->tmpval);
486 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
490 int mmf_attribute_set_int(mmf_attribute_t *item, int val)
492 return_val_if_fail(item, -1);
494 if (mmf_value_set_int(&item->tmpval, val) == 0) {
495 item->flags |= MM_ATTRS_FLAG_MODIFIED;
501 int mmf_attribute_set_double(mmf_attribute_t *item, double val)
503 return_val_if_fail(item, -1);
505 if (mmf_value_set_double(&item->tmpval, val) == 0) {
506 item->flags |= MM_ATTRS_FLAG_MODIFIED;
512 int mmf_attribute_set_string(mmf_attribute_t *item, const char *string, int size)
514 return_val_if_fail(item, -1);
516 if (mmf_value_set_string(&item->tmpval, string, size) == 0) {
517 item->flags |= MM_ATTRS_FLAG_MODIFIED;
523 int mmf_attribute_set_data(mmf_attribute_t *item, void *data, int size)
525 return_val_if_fail(item, -1);
527 if (mmf_value_set_data(&item->tmpval, data, size) == 0) {
528 item->flags |= MM_ATTRS_FLAG_MODIFIED;
534 MMHandleType mmf_attrs_new(int count)
538 return_val_if_fail(count > 0, 0);
540 attrs = (mmf_attrs_t *) malloc(sizeof(mmf_attrs_t));
542 debug_error("malloc failed");
546 attrs->count = count;
547 attrs->items = (mmf_attribute_t *) malloc(sizeof(mmf_attribute_t) * count);
548 if (attrs->items == NULL) {
549 debug_error("Failed to malloc for attrs->items.");
555 memset(attrs->items, 0, sizeof(mmf_attribute_t) * count);
557 return (MMHandleType) attrs;
560 MMHandleType mmf_attrs_new_from_data(const char *name,
561 mmf_attrs_construct_info_t *info,
563 mmf_attrs_commit_func_t commit_func,
569 return_val_if_fail(info && count > 0, NULL);
571 h = mmf_attrs_new(count);
575 mmf_attrs_init(h, info, count);
576 attrs = (mmf_attrs_t *) h;
579 attrs->name = strdup(name);
580 attrs->commit_func = commit_func;
581 attrs->commit_param = commit_param;
585 void mmf_attrs_free(MMHandleType h)
587 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
598 for (i = 0; i < attrs->count; i++) {
599 mmf_attribute_clear(&attrs->items[i]);
608 int mmf_attrs_init(MMHandleType h, mmf_attrs_construct_info_t *info, int count)
610 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
611 mmf_attribute_t *item = NULL;
615 return_val_if_fail(h && info && count > 0, -1);
617 for (i = 0; i < count; i++) {
618 item = &attrs->items[i];
620 pthread_mutex_init(&item->write_lock, NULL);
622 mmf_attribute_init(item,
627 switch (info[i].value_type) {
628 case MMF_VALUE_TYPE_INT:
629 assert(item->value.value.i_val == 0);
630 mmf_value_set_int(&item->value,
631 (intptr_t)info[i].default_value);
633 case MMF_VALUE_TYPE_DOUBLE:
635 int i_val = (intptr_t)info[i].default_value;
636 double d_val = (double) i_val;
637 assert(item->value.value.d_val == 0);
638 mmf_value_set_double(&item->value, d_val);
641 case MMF_VALUE_TYPE_STRING:
642 assert(item->value.value.s_val == NULL);
643 if (info[i].default_value) {
644 size = strlen(info[i].default_value)+1;
646 mmf_value_set_string(&item->value,
647 (const char *)info[i].default_value, size);
649 case MMF_VALUE_TYPE_DATA:
650 assert(item->value.value.p_val == NULL);
651 if (info[i].default_value) {
652 size = sizeof(info[i].default_value)+1;
654 mmf_value_set_data(&item->value, info[i].default_value, size);
657 //mmf_debug(MMF_DEBUG_LOG, "ERROR: Invalid MMF_VALUE_TYPE\n");
666 int mmf_attrs_commit(MMHandleType h)
668 mmf_attrs_t *attrs = (mmf_attrs_t *)h;
669 mmf_attribute_t *item = NULL;
673 return_val_if_fail(h, -1);
675 for (i = 0; i < attrs->count; ++i) {
676 item = &attrs->items[i];
678 MM_ATTR_ITEM_WRITE_LOCK(item);
680 if (mmf_attribute_is_modified(item)) {
681 if (attrs->commit_func) {
682 if (attrs->commit_func(i, item->name,
684 attrs->commit_param)) {
685 mmf_attribute_commit(item);
687 /* without this, there is no way to solve modify when commit_func failed. */
688 if (item->flags & MM_ATTRS_FLAG_MODIFIED)
689 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
693 mmf_attribute_commit(item);
697 MM_ATTR_ITEM_WRITE_UNLOCK(item);
703 int mmf_attrs_commit_err(MMHandleType h, char **err_attr_name)
705 mmf_attrs_t *attrs = (mmf_attrs_t *)h;
706 mmf_attribute_t *item = NULL;
710 return_val_if_fail(h, -1);
712 for (i = 0; i < attrs->count; ++i) {
713 item = &attrs->items[i];
715 MM_ATTR_ITEM_WRITE_LOCK(item);
717 if (mmf_attribute_is_modified(item)) {
718 if (attrs->commit_func) {
719 if (attrs->commit_func(i, item->name,
721 attrs->commit_param)) {
722 mmf_attribute_commit(item);
724 /* without this, there is no way to solve modify when commit_func failed. */
725 if (item->flags & MM_ATTRS_FLAG_MODIFIED)
726 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
729 /* Set Error information */
731 *err_attr_name = strdup(item->name);
733 MM_ATTR_ITEM_WRITE_UNLOCK(item);
737 mmf_attribute_commit(item);
741 MM_ATTR_ITEM_WRITE_UNLOCK(item);
747 int mmf_attrs_set_valid_type(MMHandleType h, int idx, int v_type)
749 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
751 return_val_if_fail(h, -1);
752 return_val_if_fail(idx >= 0, -1);
754 return mmf_value_spec_init(&attrs->items[idx].value_spec, v_type);
757 int mmf_attrs_set_valid_range(MMHandleType h, int idx, int min, int max, int dval)
759 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
761 return_val_if_fail(h, -1);
762 return_val_if_fail(idx >= 0, -1);
764 mmf_value_spec_clear(&attrs->items[idx].value_spec);
765 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_RANGE);
766 return mmf_value_spec_set_int_range(&attrs->items[idx].value_spec, min, max, dval);
769 int mmf_attrs_set_valid_array(MMHandleType h, int idx, const int *array, int count, int dval)
771 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
773 return_val_if_fail(h, -1);
774 return_val_if_fail(idx >= 0, -1);
776 mmf_value_spec_clear(&attrs->items[idx].value_spec);
777 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_ARRAY);
778 return mmf_value_spec_set_int_array(&attrs->items[idx].value_spec, array, count, dval);
781 int mmf_attrs_set_valid_double_range(MMHandleType h, int idx, double min, double max, double dval)
783 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
785 return_val_if_fail(h, -1);
786 return_val_if_fail(idx >= 0, -1);
788 mmf_value_spec_clear(&attrs->items[idx].value_spec);
789 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_RANGE);
791 if (mmf_value_spec_set_double_range(&attrs->items[idx].value_spec, min, max, dval) != 0)
794 return mmf_value_set_double(&attrs->items[idx].value, dval);
797 int mmf_attrs_set_valid_double_array(MMHandleType h, int idx, const double *array, int count, double dval)
799 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
801 return_val_if_fail(h, -1);
802 return_val_if_fail(idx >= 0, -1);
804 mmf_value_spec_clear(&attrs->items[idx].value_spec);
805 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_ARRAY);
807 if (mmf_value_spec_set_double_array(&attrs->items[idx].value_spec, array, count, dval) != 0)
810 return mmf_value_set_double(&attrs->items[idx].value, dval);