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);
112 v->value.s_val = NULL;
118 char* mmf_value_get_string(const mmf_value_t *v, int *size)
120 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_STRING, NULL);
122 return v->value.s_val;
125 int mmf_value_set_data(mmf_value_t *v, void *data,int size)
127 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DATA, -1);
128 v->value.p_val = data;
133 void* mmf_value_get_data(const mmf_value_t *v,int *size)
135 return_val_if_fail(v && v->type == MMF_VALUE_TYPE_DATA, NULL);
137 return v->value.p_val;
140 void mmf_value_dump(const mmf_value_t *value)
142 return_if_fail(value);
143 switch (value->type) {
144 case MMF_VALUE_TYPE_INT:
145 //mmf_debug(MMF_DEBUG_LOG, "value[int]: %d\n", value->value.i_val);
147 case MMF_VALUE_TYPE_DOUBLE:
148 //mmf_debug(MMF_DEBUG_LOG, "value[double]: %f\n", value->value.d_val);
150 case MMF_VALUE_TYPE_STRING:
151 //mmf_debug(MMF_DEBUG_LOG, "value[string]: %s\n", value->value.s_val);
153 case MMF_VALUE_TYPE_DATA:
154 //mmf_debug(MMF_DEBUG_LOG, "value[data]: %p\n", value->value.p_val);
157 //mmf_debug(MMF_DEBUG_LOG, "value invalid!!\n");
162 int mmf_value_clear(mmf_value_t *value)
164 return_val_if_fail(value, -1);
165 if (value->type == MMF_VALUE_TYPE_STRING) {
166 if (value->value.s_val) {
167 free(value->value.s_val);
168 value->value.s_val = NULL;
175 int mmf_value_spec_init(mmf_value_spec_t *vs, int vs_type)
177 return_val_if_fail(vs, -1);
178 memset(vs, 0, sizeof(*vs));
183 int mmf_value_spec_set_int_range(mmf_value_spec_t *vs, int min, int max, int dval)
185 return_val_if_fail(vs && vs->type == MMF_VALUE_SPEC_INT_RANGE, -1);
187 vs->spec.int_spec.range.min = min;
188 vs->spec.int_spec.range.max = max;
189 vs->spec.int_spec.range.dval = dval;
194 int mmf_value_spec_get_int_range(mmf_value_spec_t *vs, int *min, int *max, int *dval)
196 return_val_if_fail(vs && min && max && dval && vs->type == MMF_VALUE_SPEC_INT_RANGE, -1);
198 *min = vs->spec.int_spec.range.min;
199 *max = vs->spec.int_spec.range.max;
200 *dval = vs->spec.int_spec.range.dval;
205 int mmf_value_spec_set_int_array(mmf_value_spec_t *vs, const int *array, int count, int dval)
207 int *array_copy = NULL;
209 return_val_if_fail(vs && array && vs->type == MMF_VALUE_SPEC_INT_ARRAY && count > 0, -1);
211 array_copy = (int *) malloc(sizeof(int) * count);
212 if (array_copy == NULL) {
213 debug_error("malloc failed");
217 memcpy(array_copy, array, sizeof(int) * count);
218 vs->spec.int_spec.array.array = array_copy;
219 vs->spec.int_spec.array.count = count;
220 vs->spec.int_spec.array.dval = dval;
225 int mmf_value_spec_get_int_array(mmf_value_spec_t *vs, int **array, int *count, int *dval)
227 return_val_if_fail(vs && array && count && dval && vs->type == MMF_VALUE_SPEC_INT_ARRAY, -1);
229 *array = vs->spec.int_spec.array.array;
230 *count = vs->spec.int_spec.array.count;
231 *dval = vs->spec.int_spec.array.dval;
236 int mmf_value_spec_set_double_range(mmf_value_spec_t *vs, double min, double max, double dval)
238 return_val_if_fail(vs && vs->type == MMF_VALUE_SPEC_DOUBLE_RANGE, -1);
240 vs->spec.double_spec.range.min = min;
241 vs->spec.double_spec.range.max = max;
242 vs->spec.double_spec.range.dval = dval;
247 int mmf_value_spec_get_double_range(mmf_value_spec_t *vs, double *min, double *max, double *dval)
249 return_val_if_fail(vs && min && max && dval && vs->type == MMF_VALUE_SPEC_DOUBLE_RANGE, -1);
251 *min = vs->spec.double_spec.range.min;
252 *max = vs->spec.double_spec.range.max;
253 *dval = vs->spec.double_spec.range.dval;
258 int mmf_value_spec_set_double_array(mmf_value_spec_t *vs, const double *array, int count, double dval)
260 double *array_copy = NULL;
262 return_val_if_fail(vs && array && vs->type == MMF_VALUE_SPEC_DOUBLE_ARRAY && count > 0, -1);
264 array_copy = (double *) malloc(sizeof(double) * count);
265 if (array_copy == NULL) {
266 debug_error("malloc failed");
270 memcpy(array_copy, array, sizeof(double) * count);
271 vs->spec.double_spec.array.array = array_copy;
272 vs->spec.double_spec.array.count = count;
273 vs->spec.double_spec.array.dval = dval;
278 int mmf_value_spec_get_double_array(mmf_value_spec_t *vs, double **array, int *count, double *dval)
280 return_val_if_fail(vs && array && count && dval && vs->type == MMF_VALUE_SPEC_DOUBLE_ARRAY, -1);
282 *array = vs->spec.double_spec.array.array;
283 *count = vs->spec.double_spec.array.count;
284 *dval = vs->spec.double_spec.array.dval;
289 int mmf_value_spec_clear(mmf_value_spec_t *vs)
291 return_val_if_fail(vs, -1);
293 case MMF_VALUE_SPEC_INT_ARRAY:
294 if (vs->spec.int_spec.array.array) {
295 free(vs->spec.int_spec.array.array);
296 vs->spec.int_spec.array.array = NULL;
297 vs->spec.int_spec.array.count = 0;
298 vs->spec.int_spec.array.dval = 0;
301 case MMF_VALUE_SPEC_DOUBLE_ARRAY:
302 if (vs->spec.double_spec.array.array) {
303 free(vs->spec.double_spec.array.array);
304 vs->spec.double_spec.array.array = NULL;
305 vs->spec.double_spec.array.count = 0;
306 vs->spec.double_spec.array.dval = 0;
317 int mmf_attribute_init(mmf_attribute_t *item, const char *name, int value_type, int flags)
319 return_val_if_fail(item && name, -1);
321 item->name = strdup(name);
324 mmf_value_spec_init(&item->value_spec, MMF_VALUE_SPEC_NONE);
325 mmf_value_init(&item->value, value_type);
326 mmf_value_init(&item->tmpval, value_type);
331 bool mmf_attribute_check_flags(mmf_attribute_t *item, int flags)
333 return_val_if_fail(item, false);
334 return item->flags & flags;
337 bool mmf_attribute_validate_int(mmf_attribute_t *item, int val)
339 return_val_if_fail(item, false);
340 return_val_if_fail(item->value.type == MMF_VALUE_TYPE_INT, false);
345 switch (item->value_spec.type) {
346 case MMF_VALUE_SPEC_INT_RANGE:
347 if (val < item->value_spec.spec.int_spec.range.min ||
348 val > item->value_spec.spec.int_spec.range.max) {
350 debug_error("[mmf_attribute:%s] out of range[min %d, max %d, set %d]",
351 item->name, item->value_spec.spec.int_spec.range.min,
352 item->value_spec.spec.int_spec.range.max, val);
355 case MMF_VALUE_SPEC_INT_ARRAY:
357 for (i = 0; i < item->value_spec.spec.int_spec.array.count; i++) {
358 if (val == item->value_spec.spec.int_spec.array.array[i]) {
364 debug_error("[mmf_attribute:%s] out of array, set %d", item->name, val);
365 for (i = 0; i < item->value_spec.spec.int_spec.array.count; i++) {
366 debug_error("array[index %d] value [%d]",
367 i, item->value_spec.spec.int_spec.array.array[i]);
378 bool mmf_attribute_validate_double(mmf_attribute_t *item, double val)
380 return_val_if_fail(item, false);
381 return_val_if_fail(item->value.type == MMF_VALUE_TYPE_DOUBLE, false);
386 switch (item->value_spec.type) {
387 case MMF_VALUE_SPEC_DOUBLE_RANGE:
388 if (val < item->value_spec.spec.double_spec.range.min ||
389 val > item->value_spec.spec.double_spec.range.max) {
391 //mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of range\n", item->name);
394 case MMF_VALUE_SPEC_DOUBLE_ARRAY:
396 for (i = 0; i < item->value_spec.spec.double_spec.array.count; i++) {
397 if (val == item->value_spec.spec.double_spec.array.array[i]) {
403 //mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of array\n", item->name);
413 void mmf_attribute_clear(mmf_attribute_t *item)
421 mmf_value_clear(&item->tmpval);
422 mmf_value_clear(&item->value);
423 mmf_value_spec_clear(&item->value_spec);
424 pthread_mutex_destroy(&item->write_lock);
427 bool mmf_attribute_is_modified(mmf_attribute_t *item)
429 return_val_if_fail(item, false);
430 return (item->flags & MM_ATTRS_FLAG_MODIFIED);
433 void mmf_attribute_set_modified(mmf_attribute_t *item)
435 return_if_fail(item);
436 if (!(item->flags & MM_ATTRS_FLAG_MODIFIED)) {
437 mmf_value_copy(&item->tmpval, &item->value);
438 item->flags |= MM_ATTRS_FLAG_MODIFIED;
442 void mmf_attribute_set_readonly(mmf_attribute_t *item)
444 return_if_fail(item);
445 if (item->flags & MM_ATTRS_FLAG_WRITABLE)
446 item->flags -= MM_ATTRS_FLAG_WRITABLE;
449 void mmf_attribute_set_disabled(mmf_attribute_t *item)
451 return_if_fail(item);
452 if (item->flags & MM_ATTRS_FLAG_WRITABLE)
453 item->flags -= MM_ATTRS_FLAG_WRITABLE;
454 if (item->flags & MM_ATTRS_FLAG_READABLE)
455 item->flags -= MM_ATTRS_FLAG_READABLE;
456 if (item->flags & MM_ATTRS_FLAG_MODIFIED)
457 item->flags -= MM_ATTRS_FLAG_MODIFIED;
460 void mmf_attribute_commit(mmf_attribute_t *item)
462 return_if_fail(item);
463 if (item->flags & MM_ATTRS_FLAG_MODIFIED) {
464 mmf_value_copy(&item->value, &item->tmpval);
465 mmf_value_clear(&item->tmpval);
466 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
470 int mmf_attribute_set_int(mmf_attribute_t *item, int val)
472 return_val_if_fail(item, -1);
473 if (mmf_value_set_int(&item->tmpval, val) == 0) {
474 item->flags |= MM_ATTRS_FLAG_MODIFIED;
480 int mmf_attribute_set_double(mmf_attribute_t *item, double val)
482 return_val_if_fail(item, -1);
483 if (mmf_value_set_double(&item->tmpval, val) == 0) {
484 item->flags |= MM_ATTRS_FLAG_MODIFIED;
490 int mmf_attribute_set_string(mmf_attribute_t *item, const char *string, int size)
492 return_val_if_fail(item, -1);
494 if (mmf_value_set_string(&item->tmpval, string,size) == 0) {
496 item->flags |= MM_ATTRS_FLAG_MODIFIED;
503 int mmf_attribute_set_data(mmf_attribute_t *item, void *data, int size)
505 return_val_if_fail(item, -1);
507 if (mmf_value_set_data(&item->tmpval, data,size) == 0) {
508 item->flags |= MM_ATTRS_FLAG_MODIFIED;
514 MMHandleType mmf_attrs_new(int count)
516 return_val_if_fail(count > 0, 0);
518 attrs = (mmf_attrs_t *) malloc (sizeof(mmf_attrs_t));
521 debug_error("malloc failed");
525 attrs->count = count;
526 attrs->items = (mmf_attribute_t *) malloc (sizeof(mmf_attribute_t) * count);
527 if(attrs->items == NULL) {
528 debug_error("Failed to malloc for attrs->items.");
534 memset(attrs->items, 0, sizeof(mmf_attribute_t) * count);
536 return (MMHandleType) attrs;
539 MMHandleType mmf_attrs_new_from_data(const char *name,
540 mmf_attrs_construct_info_t *info,
542 mmf_attrs_commit_func_t commit_func,
545 return_val_if_fail(info && count > 0, 0);
549 h = mmf_attrs_new(count);
553 mmf_attrs_init(h, info, count);
554 attrs = (mmf_attrs_t *) h;
557 attrs->name = strdup(name);
558 attrs->commit_func = commit_func;
559 attrs->commit_param = commit_param;
563 void mmf_attrs_free(MMHandleType h)
566 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
574 for (i = 0; i < attrs->count; i++) {
575 mmf_attribute_clear(&attrs->items[i]);
584 int mmf_attrs_init(MMHandleType h, mmf_attrs_construct_info_t *info, int count)
586 return_val_if_fail(h && info && count > 0, -1);
587 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
588 mmf_attribute_t *item = NULL;
592 for (i = 0; i < count; i++) {
593 item = &attrs->items[i];
595 pthread_mutex_init(&item->write_lock, NULL);
597 mmf_attribute_init(item,
602 switch (info[i].value_type) {
603 case MMF_VALUE_TYPE_INT:
604 assert(item->value.value.i_val == 0);
605 mmf_value_set_int(&item->value,
606 (intptr_t)info[i].default_value);
608 case MMF_VALUE_TYPE_DOUBLE:
610 int i_val = (intptr_t)info[i].default_value;
611 double d_val = (double) i_val;
612 assert(item->value.value.d_val == 0);
613 mmf_value_set_double(&item->value, d_val);
616 case MMF_VALUE_TYPE_STRING:
617 assert(item->value.value.s_val == NULL);
618 if (info[i].default_value) {
619 size = strlen(info[i].default_value)+1;
621 mmf_value_set_string(&item->value,
622 (const char *)info[i].default_value,size);
624 case MMF_VALUE_TYPE_DATA:
625 assert(item->value.value.p_val == NULL);
626 if (info[i].default_value) {
627 size = sizeof(info[i].default_value)+1;
629 mmf_value_set_data(&item->value, info[i].default_value,size);
632 //mmf_debug(MMF_DEBUG_LOG, "ERROR: Invalid MMF_VALUE_TYPE\n");
641 int mmf_attrs_commit(MMHandleType h)
643 return_val_if_fail(h, -1);
645 mmf_attrs_t *attrs = (mmf_attrs_t * )h;
646 mmf_attribute_t *item = NULL;
650 for (i = 0; i < attrs->count; ++i) {
651 item = &attrs->items[i];
653 MM_ATTR_ITEM_WRITE_LOCK(item);
655 if (mmf_attribute_is_modified(item)) {
656 if (attrs->commit_func) {
657 if (attrs->commit_func(i, item->name,
659 attrs->commit_param)) {
660 mmf_attribute_commit(item);
662 /* without this, there is no way to solve modify when commit_func failed. */
663 if (item->flags & MM_ATTRS_FLAG_MODIFIED)
664 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
668 mmf_attribute_commit(item);
672 MM_ATTR_ITEM_WRITE_UNLOCK(item);
678 int mmf_attrs_commit_err(MMHandleType h, char **err_attr_name)
680 mmf_attrs_t *attrs = (mmf_attrs_t * )h;
681 mmf_attribute_t *item = NULL;
685 return_val_if_fail(h, -1);
687 for (i = 0; i < attrs->count; ++i) {
688 item = &attrs->items[i];
690 MM_ATTR_ITEM_WRITE_LOCK(item);
692 if (mmf_attribute_is_modified(item)) {
693 if (attrs->commit_func) {
694 if (attrs->commit_func(i, item->name,
696 attrs->commit_param)) {
697 mmf_attribute_commit(item);
699 /* without this, there is no way to solve modify when commit_func failed. */
700 if (item->flags & MM_ATTRS_FLAG_MODIFIED)
701 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
704 /* Set Error information */
706 *err_attr_name = strdup(item->name);
708 MM_ATTR_ITEM_WRITE_UNLOCK(item);
712 mmf_attribute_commit(item);
716 MM_ATTR_ITEM_WRITE_UNLOCK(item);
722 int mmf_attrs_set_valid_type(MMHandleType h, int idx, int v_type)
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 return mmf_value_spec_init(&attrs->items[idx].value_spec, v_type);
730 int mmf_attrs_set_valid_range(MMHandleType h, int idx, int min, int max, int dval)
732 return_val_if_fail(h, -1);
733 return_val_if_fail(idx>=0, -1);
734 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
735 mmf_value_spec_clear(&attrs->items[idx].value_spec);
736 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_RANGE);
737 return mmf_value_spec_set_int_range(&attrs->items[idx].value_spec, min, max, dval);
740 int mmf_attrs_set_valid_array(MMHandleType h, int idx, const int *array, int count, int dval)
742 return_val_if_fail(h, -1);
743 return_val_if_fail(idx>=0, -1);
744 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
745 mmf_value_spec_clear(&attrs->items[idx].value_spec);
746 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_ARRAY);
747 return mmf_value_spec_set_int_array(&attrs->items[idx].value_spec, array, count, dval);
750 int mmf_attrs_set_valid_double_range(MMHandleType h, int idx, double min, double max, double dval)
752 return_val_if_fail(h, -1);
753 return_val_if_fail(idx>=0, -1);
754 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
755 mmf_value_spec_clear(&attrs->items[idx].value_spec);
756 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_RANGE);
757 return mmf_value_spec_set_double_range(&attrs->items[idx].value_spec, min, max, dval);
760 int mmf_attrs_set_valid_double_array(MMHandleType h, int idx, const double *array, int count, double dval)
762 return_val_if_fail(h, -1);
763 return_val_if_fail(idx>=0, -1);
764 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
765 mmf_value_spec_clear(&attrs->items[idx].value_spec);
766 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_ARRAY);
767 return mmf_value_spec_set_double_array(&attrs->items[idx].value_spec, array, count, dval);