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 const 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 //mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of range\n", item->name);
353 case MMF_VALUE_SPEC_INT_ARRAY:
355 for (i = 0; i < item->value_spec.spec.int_spec.array.count; i++) {
356 if (val == item->value_spec.spec.int_spec.array.array[i]) {
362 //mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of array\n", item->name);
372 bool mmf_attribute_validate_double(mmf_attribute_t *item, double val)
374 return_val_if_fail(item, false);
375 return_val_if_fail(item->value.type == MMF_VALUE_TYPE_DOUBLE, false);
380 switch (item->value_spec.type) {
381 case MMF_VALUE_SPEC_DOUBLE_RANGE:
382 if (val < item->value_spec.spec.double_spec.range.min ||
383 val > item->value_spec.spec.double_spec.range.max) {
385 //mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of range\n", item->name);
388 case MMF_VALUE_SPEC_DOUBLE_ARRAY:
390 for (i = 0; i < item->value_spec.spec.double_spec.array.count; i++) {
391 if (val == item->value_spec.spec.double_spec.array.array[i]) {
397 //mmf_debug(MMF_DEBUG_LOG, "[mmf_attribute:%s] out of array\n", item->name);
407 void mmf_attribute_clear(mmf_attribute_t *item)
415 mmf_value_clear(&item->tmpval);
416 mmf_value_clear(&item->value);
417 mmf_value_spec_clear(&item->value_spec);
420 bool mmf_attribute_is_modified(mmf_attribute_t *item)
422 return_val_if_fail(item, false);
423 return (item->flags & MM_ATTRS_FLAG_MODIFIED);
426 void mmf_attribute_set_modified(mmf_attribute_t *item)
428 return_if_fail(item);
429 if (!(item->flags & MM_ATTRS_FLAG_MODIFIED)) {
430 mmf_value_copy(&item->tmpval, &item->value);
431 item->flags |= MM_ATTRS_FLAG_MODIFIED;
435 void mmf_attribute_set_readonly(mmf_attribute_t *item)
437 return_if_fail(item);
438 if (item->flags & MM_ATTRS_FLAG_WRITABLE)
439 item->flags -= MM_ATTRS_FLAG_WRITABLE;
442 void mmf_attribute_set_disabled(mmf_attribute_t *item)
444 return_if_fail(item);
445 if (item->flags & MM_ATTRS_FLAG_WRITABLE)
446 item->flags -= MM_ATTRS_FLAG_WRITABLE;
447 if (item->flags & MM_ATTRS_FLAG_READABLE)
448 item->flags -= MM_ATTRS_FLAG_READABLE;
449 if (item->flags & MM_ATTRS_FLAG_MODIFIED)
450 item->flags -= MM_ATTRS_FLAG_MODIFIED;
453 void mmf_attribute_commit(mmf_attribute_t *item)
455 return_if_fail(item);
456 if (item->flags & MM_ATTRS_FLAG_MODIFIED) {
457 mmf_value_copy(&item->value, &item->tmpval);
458 mmf_value_clear(&item->tmpval);
459 item->flags ^= MM_ATTRS_FLAG_MODIFIED;
463 int mmf_attribute_set_int(mmf_attribute_t *item, int val)
465 return_val_if_fail(item, -1);
466 if (mmf_value_set_int(&item->tmpval, val) == 0) {
467 item->flags |= MM_ATTRS_FLAG_MODIFIED;
473 int mmf_attribute_set_double(mmf_attribute_t *item, double val)
475 return_val_if_fail(item, -1);
476 if (mmf_value_set_double(&item->tmpval, val) == 0) {
477 item->flags |= MM_ATTRS_FLAG_MODIFIED;
483 int mmf_attribute_set_string(mmf_attribute_t *item, const char *string, int size)
485 return_val_if_fail(item, -1);
487 if (mmf_value_set_string(&item->tmpval, string,size) == 0) {
489 item->flags |= MM_ATTRS_FLAG_MODIFIED;
496 int mmf_attribute_set_data(mmf_attribute_t *item, void *data, int size)
498 return_val_if_fail(item, -1);
500 if (mmf_value_set_data(&item->tmpval, data,size) == 0) {
501 item->flags |= MM_ATTRS_FLAG_MODIFIED;
507 MMHandleType mmf_attrs_new(int count)
509 return_val_if_fail(count > 0, 0);
511 attrs = (mmf_attrs_t *) malloc (sizeof(mmf_attrs_t));
514 debug_error("malloc failed");
518 attrs->count = count;
519 attrs->items = (mmf_attribute_t *) malloc (sizeof(mmf_attribute_t) * count);
520 return_val_if_fail(attrs->items, 0);
521 memset(attrs->items, 0, sizeof(mmf_attribute_t) * count);
523 if (pthread_mutex_init(&attrs->write_lock, NULL) != 0) {
524 //mmf_debug(MMF_DEBUG_ERROR, "mutex init failed");
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]);
580 pthread_mutex_destroy(&attrs->write_lock);
585 int mmf_attrs_init(MMHandleType h, mmf_attrs_construct_info_t *info, int count)
587 return_val_if_fail(h && info && count > 0, -1);
588 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
592 for (i = 0; i < count; i++) {
593 mmf_attribute_init(&attrs->items[i],
598 switch (info[i].value_type) {
599 case MMF_VALUE_TYPE_INT:
600 assert(attrs->items[i].value.value.i_val == 0);
601 mmf_value_set_int(&attrs->items[i].value,
602 (int)info[i].default_value);
604 case MMF_VALUE_TYPE_DOUBLE:
606 int i_val = (int)info[i].default_value;
607 double d_val = (double) i_val;
608 assert(attrs->items[i].value.value.d_val == 0);
609 mmf_value_set_double(&attrs->items[i].value, d_val);
612 case MMF_VALUE_TYPE_STRING:
613 assert(attrs->items[i].value.value.s_val == NULL);
614 if (info[i].default_value) {
615 size = strlen(info[i].default_value)+1;
617 mmf_value_set_string(&attrs->items[i].value,
618 (const char *)info[i].default_value,size);
620 case MMF_VALUE_TYPE_DATA:
621 assert(attrs->items[i].value.value.p_val == NULL);
622 if (info[i].default_value) {
623 size = sizeof(info[i].default_value)+1;
625 mmf_value_set_data(&attrs->items[i].value, info[i].default_value,size);
628 //mmf_debug(MMF_DEBUG_LOG, "ERROR: Invalid MMF_VALUE_TYPE\n");
637 int mmf_attrs_commit(MMHandleType h)
639 return_val_if_fail(h, -1);
641 mmf_attrs_t *attrs = (mmf_attrs_t * )h;
645 MM_ATTRS_WRITE_LOCK(attrs);
647 for (i = 0; i < attrs->count; ++i) {
648 if (mmf_attribute_is_modified(&attrs->items[i])) {
649 if (attrs->commit_func) {
650 if (attrs->commit_func(i, attrs->items[i].name,
651 &attrs->items[i].tmpval,
652 attrs->commit_param)) {
653 mmf_attribute_commit(&attrs->items[i]);
655 /* without this, there is no way to solve modify when commit_func failed. */
656 if (attrs->items[i].flags & MM_ATTRS_FLAG_MODIFIED)
657 attrs->items[i].flags ^= MM_ATTRS_FLAG_MODIFIED;
661 mmf_attribute_commit(&attrs->items[i]);
666 MM_ATTRS_WRITE_UNLOCK(attrs);
671 int mmf_attrs_commit_err(MMHandleType h, char **err_attr_name)
673 mmf_attrs_t *attrs = (mmf_attrs_t * )h;
677 return_val_if_fail(h, -1);
679 MM_ATTRS_WRITE_LOCK(attrs);
681 for (i = 0; i < attrs->count; ++i) {
682 if (mmf_attribute_is_modified(&attrs->items[i])) {
683 if (attrs->commit_func) {
684 if (attrs->commit_func(i, attrs->items[i].name,
685 &attrs->items[i].tmpval,
686 attrs->commit_param)) {
687 mmf_attribute_commit(&attrs->items[i]);
689 /* without this, there is no way to solve modify when commit_func failed. */
690 if (attrs->items[i].flags & MM_ATTRS_FLAG_MODIFIED)
691 attrs->items[i].flags ^= MM_ATTRS_FLAG_MODIFIED;
694 /* Set Error information */
696 *err_attr_name = strdup(attrs->items[i].name);
701 mmf_attribute_commit(&attrs->items[i]);
706 MM_ATTRS_WRITE_UNLOCK(attrs);
711 int mmf_attrs_set_valid_type(MMHandleType h, int idx, int v_type)
713 return_val_if_fail(h, -1);
714 return_val_if_fail(idx>=0, -1);
715 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
716 return mmf_value_spec_init(&attrs->items[idx].value_spec, v_type);
719 int mmf_attrs_set_valid_range(MMHandleType h, int idx, int min, int max, int dval)
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 mmf_value_spec_clear(&attrs->items[idx].value_spec);
725 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_RANGE);
726 return mmf_value_spec_set_int_range(&attrs->items[idx].value_spec, min, max, dval);
729 int mmf_attrs_set_valid_array(MMHandleType h, int idx, const int *array, int count, int dval)
731 return_val_if_fail(h, -1);
732 return_val_if_fail(idx>=0, -1);
733 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
734 mmf_value_spec_clear(&attrs->items[idx].value_spec);
735 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_ARRAY);
736 return mmf_value_spec_set_int_array(&attrs->items[idx].value_spec, array, count, dval);
739 int mmf_attrs_set_valid_double_range(MMHandleType h, int idx, double min, double max, double dval)
741 return_val_if_fail(h, -1);
742 return_val_if_fail(idx>=0, -1);
743 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
744 mmf_value_spec_clear(&attrs->items[idx].value_spec);
745 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_RANGE);
746 return mmf_value_spec_set_double_range(&attrs->items[idx].value_spec, min, max, dval);
749 int mmf_attrs_set_valid_double_array(MMHandleType h, int idx, const double *array, int count, double dval)
751 return_val_if_fail(h, -1);
752 return_val_if_fail(idx>=0, -1);
753 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
754 mmf_value_spec_clear(&attrs->items[idx].value_spec);
755 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_ARRAY);
756 return mmf_value_spec_set_double_array(&attrs->items[idx].value_spec, array, count, dval);