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 memset(attrs->items, 0, sizeof(mmf_attribute_t) * count);
522 if (pthread_mutex_init(&attrs->write_lock, NULL) != 0) {
523 //mmf_debug(MMF_DEBUG_ERROR, "mutex init failed");
535 return (MMHandleType) attrs;
538 MMHandleType mmf_attrs_new_from_data(const char *name,
539 mmf_attrs_construct_info_t *info,
541 mmf_attrs_commit_func_t commit_func,
544 return_val_if_fail(info && count > 0, 0);
548 h = mmf_attrs_new(count);
552 mmf_attrs_init(h, info, count);
553 attrs = (mmf_attrs_t *) h;
556 attrs->name = strdup(name);
557 attrs->commit_func = commit_func;
558 attrs->commit_param = commit_param;
562 void mmf_attrs_free(MMHandleType h)
565 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
573 for (i = 0; i < attrs->count; i++) {
574 mmf_attribute_clear(&attrs->items[i]);
579 pthread_mutex_destroy(&attrs->write_lock);
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;
591 for (i = 0; i < count; i++) {
592 mmf_attribute_init(&attrs->items[i],
597 switch (info[i].value_type) {
598 case MMF_VALUE_TYPE_INT:
599 assert(attrs->items[i].value.value.i_val == 0);
600 mmf_value_set_int(&attrs->items[i].value,
601 (int)info[i].default_value);
603 case MMF_VALUE_TYPE_DOUBLE:
605 int i_val = (int)info[i].default_value;
606 double d_val = (double) i_val;
607 assert(attrs->items[i].value.value.d_val == 0);
608 mmf_value_set_double(&attrs->items[i].value, d_val);
611 case MMF_VALUE_TYPE_STRING:
612 assert(attrs->items[i].value.value.s_val == NULL);
613 if (info[i].default_value) {
614 size = strlen(info[i].default_value)+1;
616 mmf_value_set_string(&attrs->items[i].value,
617 (const char *)info[i].default_value,size);
619 case MMF_VALUE_TYPE_DATA:
620 assert(attrs->items[i].value.value.p_val == NULL);
621 if (info[i].default_value) {
622 size = sizeof(info[i].default_value)+1;
624 mmf_value_set_data(&attrs->items[i].value, info[i].default_value,size);
627 //mmf_debug(MMF_DEBUG_LOG, "ERROR: Invalid MMF_VALUE_TYPE\n");
636 int mmf_attrs_commit(MMHandleType h)
638 return_val_if_fail(h, -1);
640 mmf_attrs_t *attrs = (mmf_attrs_t * )h;
644 MM_ATTRS_WRITE_LOCK(attrs);
646 for (i = 0; i < attrs->count; ++i) {
647 if (mmf_attribute_is_modified(&attrs->items[i])) {
648 if (attrs->commit_func) {
649 if (attrs->commit_func(i, attrs->items[i].name,
650 &attrs->items[i].tmpval,
651 attrs->commit_param)) {
652 mmf_attribute_commit(&attrs->items[i]);
654 /* without this, there is no way to solve modify when commit_func failed. */
655 if (attrs->items[i].flags & MM_ATTRS_FLAG_MODIFIED)
656 attrs->items[i].flags ^= MM_ATTRS_FLAG_MODIFIED;
660 mmf_attribute_commit(&attrs->items[i]);
665 MM_ATTRS_WRITE_UNLOCK(attrs);
670 int mmf_attrs_commit_err(MMHandleType h, char **err_attr_name)
672 mmf_attrs_t *attrs = (mmf_attrs_t * )h;
676 return_val_if_fail(h, -1);
678 MM_ATTRS_WRITE_LOCK(attrs);
680 for (i = 0; i < attrs->count; ++i) {
681 if (mmf_attribute_is_modified(&attrs->items[i])) {
682 if (attrs->commit_func) {
683 if (attrs->commit_func(i, attrs->items[i].name,
684 &attrs->items[i].tmpval,
685 attrs->commit_param)) {
686 mmf_attribute_commit(&attrs->items[i]);
688 /* without this, there is no way to solve modify when commit_func failed. */
689 if (attrs->items[i].flags & MM_ATTRS_FLAG_MODIFIED)
690 attrs->items[i].flags ^= MM_ATTRS_FLAG_MODIFIED;
693 /* Set Error information */
695 *err_attr_name = strdup(attrs->items[i].name);
700 mmf_attribute_commit(&attrs->items[i]);
705 MM_ATTRS_WRITE_UNLOCK(attrs);
710 int mmf_attrs_set_valid_type(MMHandleType h, int idx, int v_type)
712 return_val_if_fail(h, -1);
713 return_val_if_fail(idx>=0, -1);
714 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
715 return mmf_value_spec_init(&attrs->items[idx].value_spec, v_type);
718 int mmf_attrs_set_valid_range(MMHandleType h, int idx, int min, int max, int dval)
720 return_val_if_fail(h, -1);
721 return_val_if_fail(idx>=0, -1);
722 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
723 mmf_value_spec_clear(&attrs->items[idx].value_spec);
724 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_RANGE);
725 return mmf_value_spec_set_int_range(&attrs->items[idx].value_spec, min, max, dval);
728 int mmf_attrs_set_valid_array(MMHandleType h, int idx, const int *array, int count, int dval)
730 return_val_if_fail(h, -1);
731 return_val_if_fail(idx>=0, -1);
732 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
733 mmf_value_spec_clear(&attrs->items[idx].value_spec);
734 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_ARRAY);
735 return mmf_value_spec_set_int_array(&attrs->items[idx].value_spec, array, count, dval);
738 int mmf_attrs_set_valid_double_range(MMHandleType h, int idx, double min, double max, double dval)
740 return_val_if_fail(h, -1);
741 return_val_if_fail(idx>=0, -1);
742 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
743 mmf_value_spec_clear(&attrs->items[idx].value_spec);
744 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_RANGE);
745 return mmf_value_spec_set_double_range(&attrs->items[idx].value_spec, min, max, dval);
748 int mmf_attrs_set_valid_double_array(MMHandleType h, int idx, const double *array, int count, double dval)
750 return_val_if_fail(h, -1);
751 return_val_if_fail(idx>=0, -1);
752 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
753 mmf_value_spec_clear(&attrs->items[idx].value_spec);
754 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_ARRAY);
755 return mmf_value_spec_set_double_array(&attrs->items[idx].value_spec, array, count, dval);