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 //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 if(attrs->items == NULL) {
521 debug_error("Failed to malloc for attrs->items.");
527 memset(attrs->items, 0, sizeof(mmf_attribute_t) * count);
529 if (pthread_mutex_init(&attrs->write_lock, NULL) != 0) {
530 //mmf_debug(MMF_DEBUG_ERROR, "mutex init failed");
542 return (MMHandleType) attrs;
545 MMHandleType mmf_attrs_new_from_data(const char *name,
546 mmf_attrs_construct_info_t *info,
548 mmf_attrs_commit_func_t commit_func,
551 return_val_if_fail(info && count > 0, 0);
555 h = mmf_attrs_new(count);
559 mmf_attrs_init(h, info, count);
560 attrs = (mmf_attrs_t *) h;
563 attrs->name = strdup(name);
564 attrs->commit_func = commit_func;
565 attrs->commit_param = commit_param;
569 void mmf_attrs_free(MMHandleType h)
572 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
580 for (i = 0; i < attrs->count; i++) {
581 mmf_attribute_clear(&attrs->items[i]);
586 pthread_mutex_destroy(&attrs->write_lock);
591 int mmf_attrs_init(MMHandleType h, mmf_attrs_construct_info_t *info, int count)
593 return_val_if_fail(h && info && count > 0, -1);
594 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
598 for (i = 0; i < count; i++) {
599 mmf_attribute_init(&attrs->items[i],
604 switch (info[i].value_type) {
605 case MMF_VALUE_TYPE_INT:
606 assert(attrs->items[i].value.value.i_val == 0);
607 mmf_value_set_int(&attrs->items[i].value,
608 (int)info[i].default_value);
610 case MMF_VALUE_TYPE_DOUBLE:
612 int i_val = (int)info[i].default_value;
613 double d_val = (double) i_val;
614 assert(attrs->items[i].value.value.d_val == 0);
615 mmf_value_set_double(&attrs->items[i].value, d_val);
618 case MMF_VALUE_TYPE_STRING:
619 assert(attrs->items[i].value.value.s_val == NULL);
620 if (info[i].default_value) {
621 size = strlen(info[i].default_value)+1;
623 mmf_value_set_string(&attrs->items[i].value,
624 (const char *)info[i].default_value,size);
626 case MMF_VALUE_TYPE_DATA:
627 assert(attrs->items[i].value.value.p_val == NULL);
628 if (info[i].default_value) {
629 size = sizeof(info[i].default_value)+1;
631 mmf_value_set_data(&attrs->items[i].value, info[i].default_value,size);
634 //mmf_debug(MMF_DEBUG_LOG, "ERROR: Invalid MMF_VALUE_TYPE\n");
643 int mmf_attrs_commit(MMHandleType h)
645 return_val_if_fail(h, -1);
647 mmf_attrs_t *attrs = (mmf_attrs_t * )h;
651 MM_ATTRS_WRITE_LOCK(attrs);
653 for (i = 0; i < attrs->count; ++i) {
654 if (mmf_attribute_is_modified(&attrs->items[i])) {
655 if (attrs->commit_func) {
656 if (attrs->commit_func(i, attrs->items[i].name,
657 &attrs->items[i].tmpval,
658 attrs->commit_param)) {
659 mmf_attribute_commit(&attrs->items[i]);
661 /* without this, there is no way to solve modify when commit_func failed. */
662 if (attrs->items[i].flags & MM_ATTRS_FLAG_MODIFIED)
663 attrs->items[i].flags ^= MM_ATTRS_FLAG_MODIFIED;
667 mmf_attribute_commit(&attrs->items[i]);
672 MM_ATTRS_WRITE_UNLOCK(attrs);
677 int mmf_attrs_commit_err(MMHandleType h, char **err_attr_name)
679 mmf_attrs_t *attrs = (mmf_attrs_t * )h;
683 return_val_if_fail(h, -1);
685 MM_ATTRS_WRITE_LOCK(attrs);
687 for (i = 0; i < attrs->count; ++i) {
688 if (mmf_attribute_is_modified(&attrs->items[i])) {
689 if (attrs->commit_func) {
690 if (attrs->commit_func(i, attrs->items[i].name,
691 &attrs->items[i].tmpval,
692 attrs->commit_param)) {
693 mmf_attribute_commit(&attrs->items[i]);
695 /* without this, there is no way to solve modify when commit_func failed. */
696 if (attrs->items[i].flags & MM_ATTRS_FLAG_MODIFIED)
697 attrs->items[i].flags ^= MM_ATTRS_FLAG_MODIFIED;
700 /* Set Error information */
702 *err_attr_name = strdup(attrs->items[i].name);
707 mmf_attribute_commit(&attrs->items[i]);
712 MM_ATTRS_WRITE_UNLOCK(attrs);
717 int mmf_attrs_set_valid_type(MMHandleType h, int idx, int v_type)
719 return_val_if_fail(h, -1);
720 return_val_if_fail(idx>=0, -1);
721 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
722 return mmf_value_spec_init(&attrs->items[idx].value_spec, v_type);
725 int mmf_attrs_set_valid_range(MMHandleType h, int idx, int min, int max, int dval)
727 return_val_if_fail(h, -1);
728 return_val_if_fail(idx>=0, -1);
729 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
730 mmf_value_spec_clear(&attrs->items[idx].value_spec);
731 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_RANGE);
732 return mmf_value_spec_set_int_range(&attrs->items[idx].value_spec, min, max, dval);
735 int mmf_attrs_set_valid_array(MMHandleType h, int idx, const int *array, int count, int dval)
737 return_val_if_fail(h, -1);
738 return_val_if_fail(idx>=0, -1);
739 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
740 mmf_value_spec_clear(&attrs->items[idx].value_spec);
741 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_INT_ARRAY);
742 return mmf_value_spec_set_int_array(&attrs->items[idx].value_spec, array, count, dval);
745 int mmf_attrs_set_valid_double_range(MMHandleType h, int idx, double min, double max, double dval)
747 return_val_if_fail(h, -1);
748 return_val_if_fail(idx>=0, -1);
749 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
750 mmf_value_spec_clear(&attrs->items[idx].value_spec);
751 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_RANGE);
752 return mmf_value_spec_set_double_range(&attrs->items[idx].value_spec, min, max, dval);
755 int mmf_attrs_set_valid_double_array(MMHandleType h, int idx, const double *array, int count, double dval)
757 return_val_if_fail(h, -1);
758 return_val_if_fail(idx>=0, -1);
759 mmf_attrs_t *attrs = (mmf_attrs_t *) h;
760 mmf_value_spec_clear(&attrs->items[idx].value_spec);
761 assert(attrs->items[idx].value_spec.type == MMF_VALUE_SPEC_DOUBLE_ARRAY);
762 return mmf_value_spec_set_double_array(&attrs->items[idx].value_spec, array, count, dval);