1 /* Eina - EFL data type library
2 * Copyright (C) 2012 ProFUSION embedded systems
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
19 #ifndef EINA_INLINE_VALUE_X_
20 #define EINA_INLINE_VALUE_X_
25 #include "eina_stringshare.h"
27 /* NOTE: most of value is implemented here for performance reasons */
29 //#define EINA_VALUE_NO_OPTIMIZE 1
30 #ifdef EINA_VALUE_NO_OPTIMIZE
31 #define EINA_VALUE_TYPE_DEFAULT(type) (0)
35 * @var _EINA_VALUE_TYPE_BASICS_START
36 * pointer to the first basic type.
40 EAPI extern const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_START;
43 * @var _EINA_VALUE_TYPE_BASICS_END
44 * pointer to the last (inclusive) basic type.
48 EAPI extern const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_END;
49 #define EINA_VALUE_TYPE_DEFAULT(type) \
50 ((_EINA_VALUE_TYPE_BASICS_START <= type) && \
51 (type <= _EINA_VALUE_TYPE_BASICS_END))
54 #define EINA_VALUE_TYPE_CHECK_RETURN(value) \
55 EINA_SAFETY_ON_NULL_RETURN(value); \
56 EINA_SAFETY_ON_FALSE_RETURN(eina_value_type_check(value->type))
58 #define EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, retval) \
59 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
60 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), retval)
62 #define EINA_VALUE_TYPE_DISPATCH(type, method, no_method_err, ...) \
66 type->method(type, ##__VA_ARGS__); \
68 eina_error_set(no_method_err); \
72 #define EINA_VALUE_TYPE_DISPATCH_RETURN(value, method, no_method_err, def_ret, ...) \
76 return type->method(type, ##__VA_ARGS__); \
77 eina_error_set(no_method_err); \
83 * @brief Get memory for given value (inline or allocated buffer).
88 eina_value_memory_get(const Eina_Value *value)
90 if (value->type->value_size <= 8)
91 return (void *)value->value.buf;
92 return value->value.ptr;
96 * @brief Allocate memory for internal value types.
100 EAPI void *eina_value_inner_alloc(size_t size);
102 * @brief Releases memory for internal value types.
106 EAPI void eina_value_inner_free(size_t size, void *mem);
108 static inline Eina_Bool
109 eina_value_setup(Eina_Value *value, const Eina_Value_Type *type)
113 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
114 EINA_SAFETY_ON_FALSE_RETURN_VAL(type->value_size > 0, EINA_FALSE);
118 if (type->value_size <= 8) mem = &value->value;
121 mem = value->value.ptr = eina_value_inner_alloc(type->value_size);
122 EINA_SAFETY_ON_NULL_RETURN_VAL(mem, EINA_FALSE);
125 memset(mem, 0, type->value_size);
127 if (EINA_VALUE_TYPE_DEFAULT(type))
133 EINA_VALUE_TYPE_DISPATCH_RETURN(type, setup,
134 EINA_ERROR_VALUE_FAILED, EINA_FALSE, mem);
138 eina_value_flush(Eina_Value *value)
140 const Eina_Value_Type *type;
143 EINA_VALUE_TYPE_CHECK_RETURN(value);
146 mem = eina_value_memory_get(value);
148 if (EINA_VALUE_TYPE_DEFAULT(type))
150 if (type == EINA_VALUE_TYPE_STRINGSHARE)
152 if (value->value.ptr) eina_stringshare_del((const char*) value->value.ptr);
154 else if (type == EINA_VALUE_TYPE_STRING)
156 if (value->value.ptr) free(value->value.ptr);
158 else if (type->value_size > 8)
159 eina_value_inner_free(type->value_size, mem);
164 EINA_VALUE_TYPE_DISPATCH(type, flush, EINA_ERROR_VALUE_FAILED, mem);
165 if (type->value_size > 8)
166 eina_value_inner_free(type->value_size, mem);
171 eina_value_compare(const Eina_Value *a, const Eina_Value *b)
173 const Eina_Value_Type *type;
176 EINA_VALUE_TYPE_CHECK_RETURN_VAL(a, -1);
177 EINA_SAFETY_ON_NULL_RETURN_VAL(b, -1);
178 EINA_SAFETY_ON_FALSE_RETURN_VAL(a->type == b->type, -1);
182 pa = eina_value_memory_get(a);
183 pb = eina_value_memory_get(b);
185 #ifndef EINA_VALUE_NO_OPTIMIZE
186 if (type == EINA_VALUE_TYPE_UCHAR)
188 unsigned char *ta = (unsigned char *) pa, *tb = (unsigned char *) pb;
195 else if (type == EINA_VALUE_TYPE_USHORT)
197 unsigned short *ta = (unsigned short *) pa, *tb = (unsigned short *) pb;
204 else if (type == EINA_VALUE_TYPE_UINT)
206 unsigned int *ta = (unsigned int *) pa, *tb = (unsigned int *) pb;
213 else if ((type == EINA_VALUE_TYPE_ULONG) || (type == EINA_VALUE_TYPE_TIMESTAMP))
215 unsigned long *ta = (unsigned long *) pa, *tb = (unsigned long *) pb;
222 else if (type == EINA_VALUE_TYPE_UINT64)
224 uint64_t *ta = (uint64_t *) pa, *tb = (uint64_t *) pb;
231 else if (type == EINA_VALUE_TYPE_CHAR)
233 signed char *ta = (signed char *) pa, *tb = (signed char *) pb;
240 else if (type == EINA_VALUE_TYPE_SHORT)
242 short *ta = (short *) pa, *tb = (short *) pb;
249 else if (type == EINA_VALUE_TYPE_INT)
251 int *ta = (int *) pa, *tb = (int *) pb;
258 else if (type == EINA_VALUE_TYPE_LONG)
260 long *ta = (long *) pa, *tb = (long *) pb;
267 else if (type == EINA_VALUE_TYPE_INT64)
269 int64_t *ta = (int64_t *) pa, *tb = (int64_t *) pb;
276 else if (type == EINA_VALUE_TYPE_FLOAT)
278 float *ta = (float *) pa, *tb = (float *) pb;
285 else if (type == EINA_VALUE_TYPE_DOUBLE)
287 double *ta = (double *) pa, *tb = (double *) pb;
294 else if (type == EINA_VALUE_TYPE_STRINGSHARE ||
295 type == EINA_VALUE_TYPE_STRING)
297 const char *sa = *(const char **)pa;
298 const char *sb = *(const char **)pb;
305 return strcmp(sa, sb);
309 EINA_VALUE_TYPE_DISPATCH_RETURN(type, compare, EINA_ERROR_VALUE_FAILED,
313 static inline Eina_Bool
314 eina_value_set(Eina_Value *value, ...)
318 va_start(args, value);
319 ret = eina_value_vset(value, args);
324 static inline Eina_Bool
325 eina_value_get(const Eina_Value *value, ...)
329 va_start(args, value);
330 ret = eina_value_vget(value, args);
335 static inline Eina_Bool
336 eina_value_vset(Eina_Value *value, va_list args)
338 const Eina_Value_Type *type;
341 EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
344 mem = eina_value_memory_get(value);
346 #ifndef EINA_VALUE_NO_OPTIMIZE
347 if (type == EINA_VALUE_TYPE_UCHAR)
349 unsigned char *tmem = (unsigned char *) mem;
350 *tmem = va_arg(args, unsigned int); /* promoted by va_arg */
353 else if (type == EINA_VALUE_TYPE_USHORT)
355 unsigned short *tmem = (unsigned short *) mem;
356 *tmem = va_arg(args, unsigned int); /* promoted by va_arg */
359 else if (type == EINA_VALUE_TYPE_UINT)
361 unsigned int *tmem = (unsigned int *) mem;
362 *tmem = va_arg(args, unsigned int);
365 else if ((type == EINA_VALUE_TYPE_ULONG) || (type == EINA_VALUE_TYPE_TIMESTAMP))
367 unsigned long *tmem = (unsigned long *) mem;
368 *tmem = va_arg(args, unsigned long);
371 else if (type == EINA_VALUE_TYPE_UINT64)
373 uint64_t *tmem = (uint64_t *) mem;
374 *tmem = va_arg(args, uint64_t);
377 else if (type == EINA_VALUE_TYPE_CHAR)
379 signed char *tmem = (signed char *) mem;
380 *tmem = va_arg(args, int); /* promoted by va_arg */
383 else if (type == EINA_VALUE_TYPE_SHORT)
385 short *tmem = (short *) mem;
386 *tmem = va_arg(args, int); /* promoted by va_arg */
389 else if (type == EINA_VALUE_TYPE_INT)
391 int *tmem = (int *) mem;
392 *tmem = va_arg(args, int);
395 else if (type == EINA_VALUE_TYPE_LONG)
397 long *tmem = (long *) mem;
398 *tmem = va_arg(args, long);
401 else if (type == EINA_VALUE_TYPE_INT64)
403 int64_t *tmem = (int64_t *) mem;
404 *tmem = va_arg(args, int64_t);
407 else if (type == EINA_VALUE_TYPE_FLOAT)
409 float *tmem = (float *) mem;
410 *tmem = va_arg(args, double); /* promoted by va_arg */
413 else if (type == EINA_VALUE_TYPE_DOUBLE)
415 double *tmem = (double *) mem;
416 *tmem = va_arg(args, double);
419 else if (type == EINA_VALUE_TYPE_STRINGSHARE)
421 const char *str = (const char *) va_arg(args, const char *);
422 return eina_stringshare_replace((const char **)&value->value.ptr, str);
424 else if (type == EINA_VALUE_TYPE_STRING)
426 const char *str = (const char *) va_arg(args, const char *);
427 if (value->value.ptr == str) return EINA_TRUE;
430 free(value->value.ptr);
431 value->value.ptr = NULL;
435 char *tmp = strdup(str);
438 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
441 free(value->value.ptr);
442 value->value.ptr = tmp;
448 EINA_VALUE_TYPE_DISPATCH_RETURN(value, vset, EINA_ERROR_VALUE_FAILED,
449 EINA_FALSE, mem, args);
452 static inline Eina_Bool
453 eina_value_vget(const Eina_Value *value, va_list args)
455 const Eina_Value_Type *type;
459 EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
462 mem = eina_value_memory_get(value);
463 ptr = va_arg(args, void *);
465 if (EINA_VALUE_TYPE_DEFAULT(type))
467 memcpy(ptr, mem, type->value_size);
471 EINA_VALUE_TYPE_DISPATCH_RETURN(value, pget, EINA_ERROR_VALUE_FAILED,
472 EINA_FALSE, mem, ptr);
475 static inline Eina_Bool
476 eina_value_pset(Eina_Value *value, const void *ptr)
478 const Eina_Value_Type *type;
481 EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
482 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
485 mem = eina_value_memory_get(value);
488 if (EINA_VALUE_TYPE_DEFAULT(type))
490 if (type == EINA_VALUE_TYPE_STRINGSHARE)
492 const char *str = *((const char * const *) ptr);
494 return eina_stringshare_replace((const char **)&value->value.ptr,
497 else if (type == EINA_VALUE_TYPE_STRING)
499 const char *str = *((const char * const *) ptr);
500 if (value->value.ptr == str) return EINA_TRUE;
503 free(value->value.ptr);
504 value->value.ptr = NULL;
508 char *tmp = strdup(str);
511 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
514 free(value->value.ptr);
515 value->value.ptr = tmp;
520 memcpy(mem, ptr, type->value_size);
524 EINA_VALUE_TYPE_DISPATCH_RETURN(value, pset, EINA_ERROR_VALUE_FAILED,
525 EINA_FALSE, mem, ptr);
528 static inline Eina_Bool
529 eina_value_pget(const Eina_Value *value, void *ptr)
531 const Eina_Value_Type *type;
534 EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
535 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
538 mem = eina_value_memory_get(value);
540 if (EINA_VALUE_TYPE_DEFAULT(type))
542 memcpy(ptr, mem, type->value_size);
546 EINA_VALUE_TYPE_DISPATCH_RETURN(value, pget, EINA_ERROR_VALUE_FAILED,
547 EINA_FALSE, mem, ptr);
550 static inline const Eina_Value_Type *
551 eina_value_type_get(const Eina_Value *value)
553 EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, NULL);
557 #define EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, retval) \
558 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
559 EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_ARRAY, retval)
561 static inline Eina_Bool
562 eina_value_array_setup(Eina_Value *value, const Eina_Value_Type *subtype, unsigned int step)
564 Eina_Value_Array desc = { subtype, step, NULL };
565 if (!eina_value_setup(value, EINA_VALUE_TYPE_ARRAY))
567 if (!eina_value_pset(value, &desc))
569 eina_value_flush(value);
575 static inline unsigned int
576 eina_value_array_count(const Eina_Value *value)
578 Eina_Value_Array desc;
579 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
580 if (!eina_value_pget(value, &desc))
582 return eina_inarray_count(desc.array);
585 static inline Eina_Bool
586 eina_value_array_remove(Eina_Value *value, unsigned int position)
588 Eina_Value_Array desc;
591 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
592 if (!eina_value_pget(value, &desc))
595 mem = eina_inarray_nth(desc.array, position);
599 eina_value_type_flush(desc.subtype, mem);
600 return eina_inarray_remove_at(desc.array, position);
603 static inline Eina_Bool
604 eina_value_array_vset(Eina_Value *value, unsigned int position, va_list args)
606 Eina_Value_Array desc;
609 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
610 if (!eina_value_pget(value, &desc))
613 mem = eina_inarray_nth(desc.array, position);
617 return eina_value_type_vset(desc.subtype, mem, args);
620 static inline Eina_Bool
621 eina_value_array_vget(const Eina_Value *value, unsigned int position, va_list args)
623 Eina_Value_Array desc;
628 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
629 if (!eina_value_pget(value, &desc))
632 mem = eina_inarray_nth(desc.array, position);
636 ptr = va_arg(args, void *);
637 ret = eina_value_type_pget(desc.subtype, mem, ptr);
641 static inline Eina_Bool
642 eina_value_array_vinsert(Eina_Value *value, unsigned int position, va_list args)
644 Eina_Value_Array desc;
647 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
648 if (!eina_value_pget(value, &desc))
651 mem = eina_inarray_alloc_at(desc.array, position, 1);
655 if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
656 if (!eina_value_type_vset(desc.subtype, mem, args)) goto error_set;
660 eina_value_type_flush(desc.subtype, mem);
662 eina_inarray_remove_at(desc.array, position);
666 static inline Eina_Bool
667 eina_value_array_vappend(Eina_Value *value, va_list args)
669 Eina_Value_Array desc;
673 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
674 if (!eina_value_pget(value, &desc))
677 position = eina_inarray_count(desc.array);
678 mem = eina_inarray_alloc_at(desc.array, position, 1);
682 if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
683 if (!eina_value_type_vset(desc.subtype, mem, args)) goto error_set;
687 eina_value_type_flush(desc.subtype, mem);
689 eina_inarray_remove_at(desc.array, position);
693 static inline Eina_Bool
694 eina_value_array_set(Eina_Value *value, unsigned int position, ...)
698 va_start(args, position);
699 ret = eina_value_array_vset(value, position, args);
704 static inline Eina_Bool
705 eina_value_array_get(const Eina_Value *value, unsigned int position, ...)
709 va_start(args, position);
710 ret = eina_value_array_vget(value, position, args);
715 static inline Eina_Bool
716 eina_value_array_insert(Eina_Value *value, unsigned int position, ...)
720 va_start(args, position);
721 ret = eina_value_array_vinsert(value, position, args);
726 static inline Eina_Bool eina_value_array_append(Eina_Value *value, ...)
730 va_start(args, value);
731 ret = eina_value_array_vappend(value, args);
736 static inline Eina_Bool
737 eina_value_array_pset(Eina_Value *value, unsigned int position, const void *ptr)
739 Eina_Value_Array desc;
742 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
743 if (!eina_value_pget(value, &desc))
746 mem = eina_inarray_nth(desc.array, position);
750 return eina_value_type_pset(desc.subtype, mem, ptr);
753 static inline Eina_Bool
754 eina_value_array_pget(const Eina_Value *value, unsigned int position, void *ptr)
756 Eina_Value_Array desc;
760 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
761 if (!eina_value_pget(value, &desc))
764 mem = eina_inarray_nth(desc.array, position);
768 ret = eina_value_type_pget(desc.subtype, mem, ptr);
772 static inline Eina_Bool
773 eina_value_array_pinsert(Eina_Value *value, unsigned int position, const void *ptr)
775 Eina_Value_Array desc;
778 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
779 if (!eina_value_pget(value, &desc))
782 mem = eina_inarray_alloc_at(desc.array, position, 1);
786 if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
787 if (!eina_value_type_pset(desc.subtype, mem, ptr)) goto error_set;
791 eina_value_type_flush(desc.subtype, mem);
793 eina_inarray_remove_at(desc.array, position);
797 static inline Eina_Bool
798 eina_value_array_pappend(Eina_Value *value, const void *ptr)
800 Eina_Value_Array desc;
804 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
805 if (!eina_value_pget(value, &desc))
808 position = eina_inarray_count(desc.array);
809 mem = eina_inarray_alloc_at(desc.array, position, 1);
813 if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
814 if (!eina_value_type_pset(desc.subtype, mem, ptr)) goto error_set;
818 eina_value_type_flush(desc.subtype, mem);
820 eina_inarray_remove_at(desc.array, position);
824 static inline Eina_Bool
825 eina_value_array_value_get(const Eina_Value *src, unsigned int position, Eina_Value *dst)
827 Eina_Value_Array desc;
829 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(src, EINA_FALSE);
830 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
832 if (!eina_value_pget(src, &desc))
834 if (position >= eina_inarray_count(desc.array))
836 if (!eina_value_setup(dst, desc.subtype))
838 if (!eina_value_pset(dst, eina_inarray_nth(desc.array, position)))
840 eina_value_flush(dst);
847 #undef EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL
849 #define EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, retval) \
850 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
851 EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_LIST, retval)
854 eina_value_list_node_memory_get(const Eina_Value_Type *type, const Eina_List *node)
856 if (node == NULL) return NULL;
857 if (type->value_size <= sizeof(void*))
858 return (void *)&(node->data);
863 eina_value_list_node_memory_setup(const Eina_Value_Type *type, Eina_List *node)
865 if (type->value_size <= sizeof(void*))
866 return (void *)&(node->data);
867 node->data = malloc(type->value_size);
872 eina_value_list_node_memory_flush(const Eina_Value_Type *type, Eina_List *node)
874 if (type->value_size <= sizeof(void*))
879 static inline Eina_Bool
880 eina_value_list_setup(Eina_Value *value, const Eina_Value_Type *subtype)
882 Eina_Value_List desc = { subtype, NULL };
883 if (!eina_value_setup(value, EINA_VALUE_TYPE_LIST))
885 if (!eina_value_pset(value, &desc))
887 eina_value_flush(value);
893 static inline unsigned int
894 eina_value_list_count(const Eina_Value *value)
896 Eina_Value_List *desc;
897 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
898 desc = (Eina_Value_List *)eina_value_memory_get(value);
901 return eina_list_count(desc->list);
904 static inline Eina_Bool
905 eina_value_list_remove(Eina_Value *value, unsigned int position)
907 Eina_Value_List *desc;
911 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
912 desc = (Eina_Value_List *)eina_value_memory_get(value);
916 node = eina_list_nth_list(desc->list, position);
917 mem = eina_value_list_node_memory_get(desc->subtype, node);
921 eina_value_type_flush(desc->subtype, mem);
922 eina_value_list_node_memory_flush(desc->subtype, node);
923 desc->list = eina_list_remove_list(desc->list, node);
927 static inline Eina_Bool
928 eina_value_list_vset(Eina_Value *value, unsigned int position, va_list args)
930 Eina_Value_List *desc;
934 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
935 desc = (Eina_Value_List *)eina_value_memory_get(value);
939 node = eina_list_nth_list(desc->list, position);
940 mem = eina_value_list_node_memory_get(desc->subtype, node);
944 return eina_value_type_vset(desc->subtype, mem, args);
947 static inline Eina_Bool
948 eina_value_list_vget(const Eina_Value *value, unsigned int position, va_list args)
950 const Eina_Value_List *desc;
951 const Eina_List *node;
956 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
957 desc = (const Eina_Value_List *)eina_value_memory_get(value);
961 node = eina_list_nth_list(desc->list, position);
962 mem = eina_value_list_node_memory_get(desc->subtype, node);
966 ptr = va_arg(args, void *);
967 ret = eina_value_type_pget(desc->subtype, mem, ptr);
971 static inline Eina_Bool
972 eina_value_list_vinsert(Eina_Value *value, unsigned int position, va_list args)
974 Eina_Value_List *desc;
978 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
979 desc = (Eina_Value_List *)eina_value_memory_get(value);
984 node = desc->list = eina_list_append(NULL, (void*)1L);
985 else if (position == 0)
986 node = desc->list = eina_list_prepend(desc->list, (void*)1L);
989 Eina_List *rel = eina_list_nth_list(desc->list, position - 1);
990 desc->list = eina_list_append_relative_list(desc->list, (void*)1L, rel);
993 EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
994 EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
996 mem = eina_value_list_node_memory_setup(desc->subtype, node);
999 desc->list = eina_list_remove_list(desc->list, node);
1003 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1004 if (!eina_value_type_vset(desc->subtype, mem, args)) goto error_set;
1008 eina_value_type_flush(desc->subtype, mem);
1010 eina_value_list_node_memory_flush(desc->subtype, node);
1011 desc->list = eina_list_remove_list(desc->list, node);
1015 static inline Eina_Bool
1016 eina_value_list_vappend(Eina_Value *value, va_list args)
1018 Eina_Value_List *desc;
1022 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1023 desc = (Eina_Value_List *)eina_value_memory_get(value);
1027 desc->list = eina_list_append(desc->list, (void*)1L);
1028 node = eina_list_last(desc->list);
1029 EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
1030 EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
1032 mem = eina_value_list_node_memory_setup(desc->subtype, node);
1035 desc->list = eina_list_remove_list(desc->list, node);
1039 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1040 if (!eina_value_type_vset(desc->subtype, mem, args)) goto error_set;
1044 eina_value_type_flush(desc->subtype, mem);
1046 eina_value_list_node_memory_flush(desc->subtype, node);
1047 desc->list = eina_list_remove_list(desc->list, node);
1051 static inline Eina_Bool
1052 eina_value_list_set(Eina_Value *value, unsigned int position, ...)
1056 va_start(args, position);
1057 ret = eina_value_list_vset(value, position, args);
1062 static inline Eina_Bool
1063 eina_value_list_get(const Eina_Value *value, unsigned int position, ...)
1067 va_start(args, position);
1068 ret = eina_value_list_vget(value, position, args);
1073 static inline Eina_Bool
1074 eina_value_list_insert(Eina_Value *value, unsigned int position, ...)
1078 va_start(args, position);
1079 ret = eina_value_list_vinsert(value, position, args);
1084 static inline Eina_Bool eina_value_list_append(Eina_Value *value, ...)
1088 va_start(args, value);
1089 ret = eina_value_list_vappend(value, args);
1094 static inline Eina_Bool
1095 eina_value_list_pset(Eina_Value *value, unsigned int position, const void *ptr)
1097 Eina_Value_List *desc;
1101 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1102 desc = (Eina_Value_List *)eina_value_memory_get(value);
1106 node = eina_list_nth_list(desc->list, position);
1107 mem = eina_value_list_node_memory_get(desc->subtype, node);
1111 return eina_value_type_pset(desc->subtype, mem, ptr);
1114 static inline Eina_Bool
1115 eina_value_list_pget(const Eina_Value *value, unsigned int position, void *ptr)
1117 const Eina_Value_List *desc;
1118 const Eina_List *node;
1122 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1123 desc = (const Eina_Value_List *)eina_value_memory_get(value);
1127 node = eina_list_nth_list(desc->list, position);
1128 mem = eina_value_list_node_memory_get(desc->subtype, node);
1132 ret = eina_value_type_pget(desc->subtype, mem, ptr);
1136 static inline Eina_Bool
1137 eina_value_list_pinsert(Eina_Value *value, unsigned int position, const void *ptr)
1139 Eina_Value_List *desc;
1143 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1144 desc = (Eina_Value_List *)eina_value_memory_get(value);
1149 node = desc->list = eina_list_append(NULL, (void*)1L);
1150 else if (position == 0)
1151 node = desc->list = eina_list_prepend(desc->list, (void*)1L);
1154 Eina_List *rel = eina_list_nth_list(desc->list, position - 1);
1155 desc->list = eina_list_append_relative_list(desc->list, (void*)1L, rel);
1158 EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
1159 EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
1161 mem = eina_value_list_node_memory_setup(desc->subtype, node);
1164 desc->list = eina_list_remove_list(desc->list, node);
1168 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1169 if (!eina_value_type_pset(desc->subtype, mem, ptr)) goto error_set;
1173 eina_value_type_flush(desc->subtype, mem);
1175 eina_value_list_node_memory_flush(desc->subtype, node);
1176 desc->list = eina_list_remove_list(desc->list, node);
1180 static inline Eina_Bool
1181 eina_value_list_pappend(Eina_Value *value, const void *ptr)
1183 Eina_Value_List *desc;
1187 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1188 desc = (Eina_Value_List *)eina_value_memory_get(value);
1192 desc->list = eina_list_append(desc->list, (void*)1L);
1193 node = eina_list_last(desc->list);
1194 EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
1195 EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
1197 mem = eina_value_list_node_memory_setup(desc->subtype, node);
1200 desc->list = eina_list_remove_list(desc->list, node);
1204 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1205 if (!eina_value_type_pset(desc->subtype, mem, ptr)) goto error_set;
1209 eina_value_type_flush(desc->subtype, mem);
1211 eina_value_list_node_memory_flush(desc->subtype, node);
1212 desc->list = eina_list_remove_list(desc->list, node);
1215 #undef EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL
1217 #define EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, retval) \
1218 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
1219 EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_HASH, retval)
1221 static inline Eina_Bool
1222 eina_value_hash_setup(Eina_Value *value, const Eina_Value_Type *subtype, unsigned int buckets_power_size)
1224 Eina_Value_Hash desc = { subtype, buckets_power_size, NULL };
1225 if (!eina_value_setup(value, EINA_VALUE_TYPE_HASH))
1227 if (!eina_value_pset(value, &desc))
1229 eina_value_flush(value);
1235 static inline unsigned int
1236 eina_value_hash_population(const Eina_Value *value)
1238 Eina_Value_Hash *desc;
1239 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0);
1240 desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1243 return eina_hash_population(desc->hash);
1246 static inline Eina_Bool
1247 eina_value_hash_del(Eina_Value *value, const char *key)
1249 Eina_Value_Hash *desc;
1252 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE);
1253 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1254 desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1258 mem = eina_hash_find(desc->hash, key);
1262 eina_value_type_flush(desc->subtype, mem);
1264 eina_hash_del_by_key(desc->hash, key);
1268 static inline Eina_Bool
1269 eina_value_hash_vset(Eina_Value *value, const char *key, va_list args)
1271 Eina_Value_Hash *desc;
1274 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE);
1275 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1276 desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1280 mem = eina_hash_find(desc->hash, key);
1283 mem = malloc(desc->subtype->value_size);
1286 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
1289 if (!eina_hash_add(desc->hash, key, mem))
1294 if (!eina_value_type_setup(desc->subtype, mem))
1296 eina_value_type_flush(desc->subtype, mem);
1297 eina_hash_del_by_key(desc->hash, key);
1302 return eina_value_type_vset(desc->subtype, mem, args);
1305 static inline Eina_Bool
1306 eina_value_hash_vget(const Eina_Value *value, const char *key, va_list args)
1308 const Eina_Value_Hash *desc;
1313 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE);
1314 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1315 desc = (const Eina_Value_Hash *)eina_value_memory_get(value);
1319 mem = eina_hash_find(desc->hash, key);
1323 ptr = va_arg(args, void *);
1324 ret = eina_value_type_pget(desc->subtype, mem, ptr);
1328 static inline Eina_Bool
1329 eina_value_hash_set(Eina_Value *value, const char *key, ...)
1333 va_start(args, key);
1334 ret = eina_value_hash_vset(value, key, args);
1339 static inline Eina_Bool
1340 eina_value_hash_get(const Eina_Value *value, const char *key, ...)
1344 va_start(args, key);
1345 ret = eina_value_hash_vget(value, key, args);
1350 static inline Eina_Bool
1351 eina_value_hash_pset(Eina_Value *value, const char *key, const void *ptr)
1353 Eina_Value_Hash *desc;
1356 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0);
1357 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1358 desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1362 mem = eina_hash_find(desc->hash, key);
1365 mem = malloc(desc->subtype->value_size);
1368 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
1371 if (!eina_hash_add(desc->hash, key, mem))
1376 if (!eina_value_type_setup(desc->subtype, mem))
1378 eina_value_type_flush(desc->subtype, mem);
1379 eina_hash_del_by_key(desc->hash, key);
1384 return eina_value_type_pset(desc->subtype, mem, ptr);
1387 static inline Eina_Bool
1388 eina_value_hash_pget(const Eina_Value *value, const char *key, void *ptr)
1390 const Eina_Value_Hash *desc;
1394 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0);
1395 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1396 desc = (const Eina_Value_Hash *)eina_value_memory_get(value);
1400 mem = eina_hash_find(desc->hash, key);
1404 ret = eina_value_type_pget(desc->subtype, mem, ptr);
1407 #undef EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL
1409 #define EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, retval) \
1410 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
1411 EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_STRUCT, retval)
1414 * @brief Find member of struct
1418 EAPI const Eina_Value_Struct_Member *eina_value_struct_member_find(const Eina_Value_Struct *st, const char *name) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
1420 static inline Eina_Bool
1421 eina_value_struct_setup(Eina_Value *value, const Eina_Value_Struct_Desc *sdesc)
1423 Eina_Value_Struct desc = {sdesc, NULL};
1424 if (!eina_value_setup(value, EINA_VALUE_TYPE_STRUCT))
1426 if (!eina_value_pset(value, &desc))
1428 eina_value_flush(value);
1434 static inline void *
1435 eina_value_struct_member_memory_get(const Eina_Value_Struct *st, const Eina_Value_Struct_Member *member)
1437 unsigned char *base = (unsigned char *)st->memory;
1438 if (!base) return NULL;
1439 return base + member->offset;
1442 static inline Eina_Bool
1443 eina_value_struct_vset(Eina_Value *value, const char *name, va_list args)
1445 const Eina_Value_Struct_Member *member;
1446 Eina_Value_Struct *st;
1449 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1450 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1451 st = (Eina_Value_Struct *)eina_value_memory_get(value);
1454 member = eina_value_struct_member_find(st, name);
1457 mem = eina_value_struct_member_memory_get(st, member);
1461 return eina_value_type_vset(member->type, mem, args);
1464 static inline Eina_Bool
1465 eina_value_struct_vget(const Eina_Value *value, const char *name, va_list args)
1467 const Eina_Value_Struct_Member *member;
1468 const Eina_Value_Struct *st;
1473 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1474 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1475 st = (const Eina_Value_Struct *)eina_value_memory_get(value);
1478 member = eina_value_struct_member_find(st, name);
1481 mem = eina_value_struct_member_memory_get(st, member);
1485 ptr = va_arg(args, void *);
1486 ret = eina_value_type_pget(member->type, mem, ptr);
1490 static inline Eina_Bool
1491 eina_value_struct_set(Eina_Value *value, const char *name, ...)
1495 va_start(args, name);
1496 ret = eina_value_struct_vset(value, name, args);
1501 static inline Eina_Bool
1502 eina_value_struct_get(const Eina_Value *value, const char *name, ...)
1506 va_start(args, name);
1507 ret = eina_value_struct_vget(value, name, args);
1512 static inline Eina_Bool
1513 eina_value_struct_pset(Eina_Value *value, const char *name, const void *ptr)
1515 const Eina_Value_Struct_Member *member;
1516 Eina_Value_Struct *st;
1519 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1520 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1521 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
1522 st = (Eina_Value_Struct *)eina_value_memory_get(value);
1525 member = eina_value_struct_member_find(st, name);
1528 mem = eina_value_struct_member_memory_get(st, member);
1532 return eina_value_type_pset(member->type, mem, ptr);
1535 static inline Eina_Bool
1536 eina_value_struct_pget(const Eina_Value *value, const char *name, void *ptr)
1538 const Eina_Value_Struct_Member *member;
1539 const Eina_Value_Struct *st;
1543 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1544 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1545 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
1546 st = (const Eina_Value_Struct *)eina_value_memory_get(value);
1549 member = eina_value_struct_member_find(st, name);
1552 mem = eina_value_struct_member_memory_get(st, member);
1556 ret = eina_value_type_pget(member->type, mem, ptr);
1560 static inline Eina_Bool
1561 eina_value_struct_value_get(const Eina_Value *src, const char *name, Eina_Value *dst)
1563 const Eina_Value_Struct_Member *member;
1564 const Eina_Value_Struct *st;
1567 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(src, EINA_FALSE);
1568 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1569 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
1570 st = (const Eina_Value_Struct *)eina_value_memory_get(src);
1573 member = eina_value_struct_member_find(st, name);
1576 mem = eina_value_struct_member_memory_get(st, member);
1579 if (!eina_value_setup(dst, member->type))
1581 if (!eina_value_pset(dst, mem))
1583 eina_value_flush(dst);
1589 static inline Eina_Bool
1590 eina_value_struct_value_set(Eina_Value *dst, const char *name, const Eina_Value *src)
1592 const Eina_Value_Struct_Member *member;
1593 Eina_Value_Struct *st;
1597 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(dst, EINA_FALSE);
1598 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1599 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
1601 st = (Eina_Value_Struct *)eina_value_memory_get(dst);
1604 member = eina_value_struct_member_find(st, name);
1607 EINA_SAFETY_ON_FALSE_RETURN_VAL(src->type == member->type, EINA_FALSE);
1609 mem = eina_value_struct_member_memory_get(st, member);
1613 ptr = eina_value_memory_get(src);
1617 return eina_value_type_pset(member->type, mem, ptr);
1620 static inline Eina_Bool
1621 eina_value_struct_member_value_get(const Eina_Value *src, const Eina_Value_Struct_Member *member, Eina_Value *dst)
1623 const Eina_Value_Struct *st;
1626 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(src, EINA_FALSE);
1627 EINA_SAFETY_ON_NULL_RETURN_VAL(member, EINA_FALSE);
1628 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
1629 st = (const Eina_Value_Struct *)eina_value_memory_get(src);
1632 mem = eina_value_struct_member_memory_get(st, member);
1635 if (!eina_value_setup(dst, member->type))
1637 if (!eina_value_pset(dst, mem))
1639 eina_value_flush(dst);
1645 static inline Eina_Bool
1646 eina_value_struct_member_value_set(Eina_Value *dst, const Eina_Value_Struct_Member *member, const Eina_Value *src)
1648 Eina_Value_Struct *st;
1652 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(dst, EINA_FALSE);
1653 EINA_SAFETY_ON_NULL_RETURN_VAL(member, EINA_FALSE);
1654 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
1656 st = (Eina_Value_Struct *)eina_value_memory_get(dst);
1659 EINA_SAFETY_ON_FALSE_RETURN_VAL(src->type == member->type, EINA_FALSE);
1661 mem = eina_value_struct_member_memory_get(st, member);
1665 ptr = eina_value_memory_get(src);
1669 return eina_value_type_pset(member->type, mem, ptr);
1672 #undef EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL
1675 static inline Eina_Bool
1676 eina_value_type_setup(const Eina_Value_Type *type, void *mem)
1678 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1681 eina_error_set(EINA_ERROR_VALUE_FAILED);
1684 return type->setup(type, mem);
1687 static inline Eina_Bool
1688 eina_value_type_flush(const Eina_Value_Type *type, void *mem)
1690 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1693 eina_error_set(EINA_ERROR_VALUE_FAILED);
1696 return type->flush(type, mem);
1699 static inline Eina_Bool
1700 eina_value_type_copy(const Eina_Value_Type *type, const void *src, void *dst)
1702 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1705 eina_error_set(EINA_ERROR_VALUE_FAILED);
1708 return type->copy(type, src, dst);
1712 eina_value_type_compare(const Eina_Value_Type *type, const void *a, const void *b)
1714 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1717 eina_error_set(EINA_ERROR_VALUE_FAILED);
1720 return type->compare(type, a, b);
1723 static inline Eina_Bool
1724 eina_value_type_convert_to(const Eina_Value_Type *type, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
1726 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1727 if (!type->convert_to)
1729 eina_error_set(EINA_ERROR_VALUE_FAILED);
1732 return type->convert_to(type, convert, type_mem, convert_mem);
1735 static inline Eina_Bool
1736 eina_value_type_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem)
1738 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1739 if (!type->convert_from)
1741 eina_error_set(EINA_ERROR_VALUE_FAILED);
1744 return type->convert_from(type, convert, type_mem, convert_mem);
1747 static inline Eina_Bool
1748 eina_value_type_vset(const Eina_Value_Type *type, void *mem, va_list args)
1750 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1753 eina_error_set(EINA_ERROR_VALUE_FAILED);
1756 return type->vset(type, mem, args);
1759 static inline Eina_Bool
1760 eina_value_type_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
1762 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1765 eina_error_set(EINA_ERROR_VALUE_FAILED);
1768 return type->pset(type, mem, ptr);
1771 static inline Eina_Bool
1772 eina_value_type_pget(const Eina_Value_Type *type, const void *mem, void *ptr)
1774 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1777 eina_error_set(EINA_ERROR_VALUE_FAILED);
1780 return type->pget(type, mem, ptr);
1783 #undef EINA_VALUE_TYPE_DEFAULT
1784 #undef EINA_VALUE_TYPE_CHECK_RETURN
1785 #undef EINA_VALUE_TYPE_CHECK_RETURN_VAL
1786 #undef EINA_VALUE_TYPE_DISPATCH
1787 #undef EINA_VALUE_TYPE_DISPATCH_RETURN