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:
55 dest->value.s_val = strdup(src->value.s_val);
56 dest->size = src->size;
60 dest->value.s_val = NULL;
64 case MM_ATTRS_TYPE_DATA:
65 dest->value.p_val = src->value.p_val;
66 dest->size = src->size;
74 int mmf_value_set_int(mmf_value_t *v, int ival)
76 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_INT, -1);
77 v->value.i_val = ival;
81 int mmf_value_get_int(const mmf_value_t *v)
83 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_INT, -1);
84 return v->value.i_val;
87 int mmf_value_set_double(mmf_value_t *v, double dval)
89 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DOUBLE, -1);
90 v->value.d_val = dval;
94 double mmf_value_get_double(mmf_value_t *v)
96 return_val_if_fail(v->type == MMF_VALUE_TYPE_DOUBLE, -1);
97 return v->value.d_val;
100 int mmf_value_set_string(mmf_value_t *v, const char *sval,int size)
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;
109 v->value.s_val = strdup(sval);
113 v->value.s_val = NULL;
119 const char* mmf_value_get_string(const mmf_value_t *v, int *size)
121 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_STRING, NULL);
123 return v->value.s_val;
126 int mmf_value_set_data(mmf_value_t *v, void *data,int size)
128 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DATA, -1);
129 v->value.p_val = data;
134 void* mmf_value_get_data(const mmf_value_t *v,int *size)
136 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DATA, NULL);
138 return v->value.p_val;
141 void mmf_value_dump(const mmf_value_t *value)
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);
148 case MMF_VALUE_TYPE_DOUBLE:
149 mmf_debug(MMF_DEBUG_LOG, "value[double]: %f\n", value->value.d_val);
151 case MMF_VALUE_TYPE_STRING:
152 mmf_debug(MMF_DEBUG_LOG, "value[string]: %s\n", value->value.s_val);
154 case MMF_VALUE_TYPE_DATA:
155 mmf_debug(MMF_DEBUG_LOG, "value[data]: %p\n", value->value.p_val);
158 mmf_debug(MMF_DEBUG_LOG, "value invalid!!\n");
163 int mmf_value_clear(mmf_value_t *value)
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;
176 int mmf_value_spec_init(mmf_value_spec_t *vs, int vs_type)
178 return_val_if_fail(vs, -1);
179 memset(vs, 0, sizeof(*vs));
184 int mmf_value_spec_set_int_range(mmf_value_spec_t *vs, int min, int max, int dval)
186 return_val_if_fail(vs && vs->type == MMF_VALUE_SPEC_INT_RANGE, -1);
188 vs->spec.int_spec.range.min = min;
189 vs->spec.int_spec.range.max = max;
190 vs->spec.int_spec.range.dval = dval;
195 int mmf_value_spec_get_int_range(mmf_value_spec_t *vs, int *min, int *max, int *dval)
197 return_val_if_fail(vs && min && max && dval && vs->type == MMF_VALUE_SPEC_INT_RANGE, -1);
199 *min = vs->spec.int_spec.range.min;
200 *max = vs->spec.int_spec.range.max;
201 *dval = vs->spec.int_spec.range.dval;
206 int mmf_value_spec_set_int_array(mmf_value_spec_t *vs, const int *array, int count, int dval)
208 int *array_copy = NULL;
210 return_val_if_fail(vs && array && vs->type == MMF_VALUE_SPEC_INT_ARRAY && count > 0, -1);
212 array_copy = (int *) malloc(sizeof(int) * count);
213 if (array_copy == NULL) {
214 debug_error("malloc failed");
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;
226 int mmf_value_spec_get_int_array(mmf_value_spec_t *vs, int **array, int *count, int *dval)
228 return_val_if_fail(vs && array && count && dval && vs->type == MMF_VALUE_SPEC_INT_ARRAY, -1);
230 *array = vs->spec.int_spec.array.array;
231 *count = vs->spec.int_spec.array.count;
232 *dval = vs->spec.int_spec.array.dval;
237 int mmf_value_spec_set_double_range(mmf_value_spec_t *vs, double min, double max, double dval)
239 return_val_if_fail(vs && vs->type == MMF_VALUE_SPEC_DOUBLE_RANGE, -1);
241 vs->spec.double_spec.range.min = min;
242 vs->spec.double_spec.range.max = max;
243 vs->spec.double_spec.range.dval = dval;
248 int mmf_value_spec_get_double_range(mmf_value_spec_t *vs, double *min, double *max, double *dval)
250 return_val_if_fail(vs && min && max && dval && vs->type == MMF_VALUE_SPEC_DOUBLE_RANGE, -1);
252 *min = vs->spec.double_spec.range.min;
253 *max = vs->spec.double_spec.range.max;
254 *dval = vs->spec.double_spec.range.dval;
259 int mmf_value_spec_set_double_array(mmf_value_spec_t *vs, const double *array, int count, double dval)
261 double *array_copy = NULL;
263 return_val_if_fail(vs && array && vs->type == MMF_VALUE_SPEC_DOUBLE_ARRAY && count > 0, -1);
265 array_copy = (double *) malloc(sizeof(double) * count);
266 if (array_copy == NULL) {
267 debug_error("malloc failed");
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;
279 int mmf_value_spec_get_double_array(mmf_value_spec_t *vs, double **array, int *count, double *dval)
281 return_val_if_fail(vs && array && count && dval && vs->type == MMF_VALUE_SPEC_DOUBLE_ARRAY, -1);
283 *array = vs->spec.double_spec.array.array;
284 *count = vs->spec.double_spec.array.count;
285 *dval = vs->spec.double_spec.array.dval;
290 int mmf_value_spec_clear(mmf_value_spec_t *vs)
292 return_val_if_fail(vs, -1);
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;
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;
318 int mmf_attribute_init(mmf_attribute_t *item, const char *name, int value_type, int flags)
320 return_val_if_fail(item && name, -1);
322 item->name = strdup(name);
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);
332 bool mmf_attribute_check_flags(mmf_attribute_t *item, int flags)
334 return_val_if_fail(item, false);
335 return item->flags & flags;
338 bool mmf_attribute_validate_int(mmf_attribute_t *item, int val)
340 return_val_if_fail(item, false);
341 return_val_if_fail(item->value.type == MMF_VALUE_TYPE_INT, false);
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) {
351 mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of range\n", item->name);
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 mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of array\n", item->name);
373 bool mmf_attribute_validate_double(mmf_attribute_t *item, double val)
375 return_val_if_fail(item, false);
376 return_val_if_fail(item->value.type == MMF_VALUE_TYPE_DOUBLE, false);
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) {
386 mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of range\n", item->name);
389 case MMF_VALUE_SPEC_DOUBLE_ARRAY:
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]) {
398 mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of array\n", item->name);
408 void mmf_attribute_clear(mmf_attribute_t *item)
416 mmf_value_clear(&item->tmpval);
417 mmf_value_clear(&item->value);
418 mmf_value_spec_clear(&item->value_spec);
421 bool mmf_attribute_is_modified(mmf_attribute_t *item)
423 return_val_if_fail(item, false);
424 return (item->flags & MM_ATTRS_FLAG_MODIFIED);
427 void mmf_attribute_set_modified(mmf_attribute_t *item)
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;
436 void mmf_attribute_set_readonly(mmf_attribute_t *item)
438 return_if_fail(item);
439 if (item->flags & MM_ATTRS_FLAG_WRITABLE)
440 item->flags -= MM_ATTRS_FLAG_WRITABLE;
443 void mmf_attribute_set_disabled(mmf_attribute_t *item)
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;
454 void mmf_attribute_commit(mmf_attribute_t *item)
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;
464 int mmf_attribute_set_int(mmf_attribute_t *item, int val)
466 return_val_if_fail(item, -1);
467 if (mmf_value_set_int(&item->tmpval, val) == 0) {
468 item->flags |= MM_ATTRS_FLAG_MODIFIED;
474 int mmf_attribute_set_double(mmf_attribute_t *item, double val)
476 return_val_if_fail(item, -1);
477 if (mmf_value_set_double(&item->tmpval, val) == 0) {
478 item->flags |= MM_ATTRS_FLAG_MODIFIED;
484 int mmf_attribute_set_string(mmf_attribute_t *item, const char *string, int size)
486 return_val_if_fail(item, -1);
488 if (mmf_value_set_string(&item->tmpval, string,size) == 0) {
490 item->flags |= MM_ATTRS_FLAG_MODIFIED;
497 int mmf_attribute_set_data(mmf_attribute_t *item, void *data, int size)
499 return_val_if_fail(item, -1);
501 if (mmf_value_set_data(&item->tmpval, data,size) == 0) {
502 item->flags |= MM_ATTRS_FLAG_MODIFIED;
508 MMHandleType mmf_attrs_new(int count)
510 return_val_if_fail(count > 0, 0);
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);
517 if (pthread_mutex_init(&attrs->write_lock, NULL) != 0) {
518 mmf_debug(MMF_DEBUG_ERROR, "mutex init failed");
522 return (MMHandleType) attrs;
525 MMHandleType mmf_attrs_new_from_data(const char *name,
526 mmf_attrs_construct_info_t *info,
528 mmf_attrs_commit_func_t commit_func,
531 return_val_if_fail(info && count > 0, 0);
535 h = mmf_attrs_new(count);
536 mmf_attrs_init(h, info, count);
537 attrs = (mmf_attrs_t *) h;
540 attrs->name = strdup(name);
541 attrs->commit_func = commit_func;
542 attrs->commit_param = commit_param;
546 void mmf_attrs_free(MMHandleType h)
549 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
557 for (i = 0; i < attrs->count; i++) {
558 mmf_attribute_clear(&attrs->items[i]);
563 pthread_mutex_destroy(&attrs->write_lock);
568 int mmf_attrs_init(MMHandleType h, mmf_attrs_construct_info_t *info, int count)
570 return_val_if_fail(h && info && count > 0, -1);
571 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
575 for (i = 0; i < count; i++) {
576 mmf_attribute_init(&attrs->items[i],
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);
587 case MMF_VALUE_TYPE_DOUBLE:
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);
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;
600 mmf_value_set_string(&attrs->items[i].value,
601 (const char *)info[i].default_value,size);
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;
608 mmf_value_set_data(&attrs->items[i].value, info[i].default_value,size);
611 mmf_debug(MMF_DEBUG_LOG, "ERROR: Invalid MMF_VALUE_TYPE\n");
620 int mmf_attrs_commit(MMHandleType h)
622 return_val_if_fail(h, -1);
624 mmf_attrs_t *attrs = (mmf_attrs_t * )h;
628 MM_ATTRS_WRITE_LOCK(attrs);
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]);
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;
644 mmf_attribute_commit(&attrs->items[i]);
649 MM_ATTRS_WRITE_UNLOCK(attrs);
654 int mmf_attrs_commit_err(MMHandleType h, char **err_attr_name)
656 mmf_attrs_t *attrs = (mmf_attrs_t * )h;
660 return_val_if_fail(h, -1);
662 MM_ATTRS_WRITE_LOCK(attrs);
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]);
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;
677 /* Set Error information */
679 *err_attr_name = strdup(attrs->items[i].name);
684 mmf_attribute_commit(&attrs->items[i]);
689 MM_ATTRS_WRITE_UNLOCK(attrs);
694 int mmf_attrs_set_valid_type(MMHandleType h, int idx, int v_type)
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);
702 int mmf_attrs_set_valid_range(MMHandleType h, int idx, int min, int max, int dval)
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);
712 int mmf_attrs_set_valid_array(MMHandleType h, int idx, const int *array, int count, int dval)
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);
722 int mmf_attrs_set_valid_double_range(MMHandleType h, int idx, double min, double max, double dval)
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);
732 int mmf_attrs_set_valid_double_array(MMHandleType h, int idx, const double *array, int count, double dval)
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);