2012-01-09 Gustavo Barbieri
* Add eina_inarray data type.
+ * Add eina_value data type (generic value storage).
* eina_file_map_faulted API
* Xattr iterator for Eina_File : eina_file_xattr_get and eina_file_xattr_value_get API
* Added eina_inarray data type
+ * Added eina_value data type (generic value storage)
Eina 1.1.0
#include "eina_refcount.h"
#include "eina_mmap.h"
#include "eina_xattr.h"
+#include "eina_value.h"
#ifdef __cplusplus
}
eina_prefix.h \
eina_refcount.h \
eina_mmap.h \
-eina_xattr.h
+eina_xattr.h \
+eina_value.h \
+eina_inline_value.x
# Will be back for developper after 1.1.
# eina_object.h
const void *data) EINA_ARG_NONNULL(1, 3);
/**
+ * @brief Copy the data over the given position.
+ * @param array array object
+ * @param position where to replace the member
+ * @param data data to be copied at position
+ * @return #EINA_TRUE on success, #EINA_FALSE on failure.
+ *
+ * Copies the given pointer contents at the given @a position in the
+ * array. The pointer is not referenced, instead it's contents is
+ * copied to the members array using the previously defined
+ * @c member_size.
+ *
+ * If @a position does not exist, it will fail.
+ *
+ * @since 1.2
+ */
+EAPI Eina_Bool eina_inarray_replace_at(Eina_Inarray *array,
+ unsigned int position,
+ const void *data) EINA_ARG_NONNULL(1, 3);
+
+/**
* @brief Remove member at given position
* @param array array object
* @param position position to be removed
--- /dev/null
+/* EINA - EFL data type library
+ * Copyright (C) 2012 ProFUSION embedded systems
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef EINA_INLINE_VALUE_X_
+#define EINA_INLINE_VALUE_X_
+
+#include <string.h>
+#include "eina_stringshare.h"
+
+/* NOTE: most of value is implemented here for performance reasons */
+
+//#define EINA_VALUE_NO_OPTIMIZE 1
+#ifdef EINA_VALUE_NO_OPTIMIZE
+#define EINA_VALUE_TYPE_DEFAULT(type) (0)
+#else
+#define EINA_VALUE_TYPE_DEFAULT(type) \
+ ((type == EINA_VALUE_TYPE_UCHAR) || \
+ (type == EINA_VALUE_TYPE_USHORT) || \
+ (type == EINA_VALUE_TYPE_UINT) || \
+ (type == EINA_VALUE_TYPE_ULONG) || \
+ (type == EINA_VALUE_TYPE_UINT64) || \
+ (type == EINA_VALUE_TYPE_CHAR) || \
+ (type == EINA_VALUE_TYPE_SHORT) || \
+ (type == EINA_VALUE_TYPE_INT) || \
+ (type == EINA_VALUE_TYPE_LONG) || \
+ (type == EINA_VALUE_TYPE_INT64) || \
+ (type == EINA_VALUE_TYPE_FLOAT) || \
+ (type == EINA_VALUE_TYPE_DOUBLE) || \
+ (type == EINA_VALUE_TYPE_STRINGSHARE) || \
+ (type == EINA_VALUE_TYPE_STRING))
+#endif
+
+#define EINA_VALUE_TYPE_CHECK_RETURN(value) \
+ EINA_SAFETY_ON_NULL_RETURN(value); \
+ EINA_SAFETY_ON_FALSE_RETURN(eina_value_type_check(value->type))
+
+#define EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, retval) \
+ EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), retval)
+
+#define EINA_VALUE_TYPE_DISPATCH(type, method, no_method_err, ...) \
+ do \
+ { \
+ if (type->method) \
+ type->method(type, ##__VA_ARGS__); \
+ else \
+ eina_error_set(no_method_err); \
+ } \
+ while (0)
+
+#define EINA_VALUE_TYPE_DISPATCH_RETURN(value, method, no_method_err, def_ret, ...) \
+ do \
+ { \
+ if (type->method) \
+ return type->method(type, ##__VA_ARGS__); \
+ eina_error_set(no_method_err); \
+ return def_ret; \
+ } \
+ while (0)
+
+static inline void *
+eina_value_memory_get(const Eina_Value *value)
+{
+ if (value->type->value_size <= 8)
+ return (void *)value->value.buf;
+ return value->value.ptr;
+}
+
+static inline Eina_Bool
+eina_value_setup(Eina_Value *value, const Eina_Value_Type *type)
+{
+ void *mem;
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(type->value_size > 0, EINA_FALSE);
+
+ value->type = type;
+
+ if (type->value_size <= 8)
+ {
+ mem = &value->value;
+ memset(mem, 0, type->value_size);
+ }
+ else
+ {
+ mem = value->value.ptr = calloc(1, type->value_size);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(mem, EINA_FALSE);
+ }
+
+ if (EINA_VALUE_TYPE_DEFAULT(type))
+ {
+ eina_error_set(0);
+ return EINA_TRUE;
+ }
+
+ EINA_VALUE_TYPE_DISPATCH_RETURN(type, setup,
+ EINA_ERROR_VALUE_FAILED, EINA_FALSE, mem);
+}
+
+static inline void
+eina_value_flush(Eina_Value *value)
+{
+ const Eina_Value_Type *type;
+ void *mem;
+
+ EINA_VALUE_TYPE_CHECK_RETURN(value);
+
+ type = value->type;
+ mem = eina_value_memory_get(value);
+
+ if (EINA_VALUE_TYPE_DEFAULT(type))
+ {
+ if (type == EINA_VALUE_TYPE_STRINGSHARE)
+ {
+ if (value->value.ptr) eina_stringshare_del(value->value.ptr);
+ }
+ else if (type == EINA_VALUE_TYPE_STRING)
+ {
+ if (value->value.ptr) free(value->value.ptr);
+ }
+ else if (type->value_size > 8) free(mem);
+ eina_error_set(0);
+ return;
+ }
+
+ EINA_VALUE_TYPE_DISPATCH(type, flush, EINA_ERROR_VALUE_FAILED, mem);
+ if (type->value_size > 8) free(mem);
+ value->type = NULL;
+}
+
+static inline int
+eina_value_compare(const Eina_Value *a, const Eina_Value *b)
+{
+ const Eina_Value_Type *type;
+ void *pa, *pb;
+
+ EINA_VALUE_TYPE_CHECK_RETURN_VAL(a, -1);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(b, -1);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(a->type == b->type, -1);
+
+ eina_error_set(0);
+ type = a->type;
+ pa = eina_value_memory_get(a);
+ pb = eina_value_memory_get(b);
+
+#ifndef EINA_VALUE_NO_OPTIMIZE
+ if (type == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char *ta = pa, *tb = pb;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+ }
+ else if (type == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short *ta = pa, *tb = pb;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+ }
+ else if (type == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int *ta = pa, *tb = pb;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+ }
+ else if (type == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long *ta = pa, *tb = pb;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+ }
+ else if (type == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t *ta = pa, *tb = pb;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+ }
+ else if (type == EINA_VALUE_TYPE_CHAR)
+ {
+ char *ta = pa, *tb = pb;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+ }
+ else if (type == EINA_VALUE_TYPE_SHORT)
+ {
+ short *ta = pa, *tb = pb;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+ }
+ else if (type == EINA_VALUE_TYPE_INT)
+ {
+ int *ta = pa, *tb = pb;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+ }
+ else if (type == EINA_VALUE_TYPE_LONG)
+ {
+ long *ta = pa, *tb = pb;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+ }
+ else if (type == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t *ta = pa, *tb = pb;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+ }
+ else if (type == EINA_VALUE_TYPE_FLOAT)
+ {
+ float *ta = pa, *tb = pb;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+ }
+ else if (type == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double *ta = pa, *tb = pb;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+ }
+ else if (type == EINA_VALUE_TYPE_STRINGSHARE ||
+ type == EINA_VALUE_TYPE_STRING)
+ {
+ const char *sa = *(const char **)pa;
+ const char *sb = *(const char **)pb;
+ if (sa == sb)
+ return 0;
+ if (sa == NULL)
+ return -1;
+ if (sb == NULL)
+ return 1;
+ return strcmp(sa, sb);
+ }
+#endif
+
+ EINA_VALUE_TYPE_DISPATCH_RETURN(type, compare, EINA_ERROR_VALUE_FAILED,
+ EINA_FALSE, pa, pb);
+}
+
+static inline Eina_Bool
+eina_value_set(Eina_Value *value, ...)
+{
+ va_list args;
+ Eina_Bool ret;
+ va_start(args, value);
+ ret = eina_value_vset(value, args);
+ va_end(args);
+ return ret;
+}
+
+static inline Eina_Bool
+eina_value_get(const Eina_Value *value, ...)
+{
+ va_list args;
+ Eina_Bool ret;
+ va_start(args, value);
+ ret = eina_value_vget(value, args);
+ va_end(args);
+ return ret;
+}
+
+static inline Eina_Bool
+eina_value_vset(Eina_Value *value, va_list args)
+{
+ const Eina_Value_Type *type;
+ void *mem;
+
+ EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
+
+ type = value->type;
+ mem = eina_value_memory_get(value);
+ eina_error_set(0);
+#ifndef EINA_VALUE_NO_OPTIMIZE
+ if (type == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char *tmem = mem;
+ *tmem = va_arg(args, unsigned int); /* promoted by va_arg */
+ return EINA_TRUE;
+ }
+ else if (type == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short *tmem = mem;
+ *tmem = va_arg(args, unsigned int); /* promoted by va_arg */
+ return EINA_TRUE;
+ }
+ else if (type == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int *tmem = mem;
+ *tmem = va_arg(args, unsigned int);
+ return EINA_TRUE;
+ }
+ else if (type == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long *tmem = mem;
+ *tmem = va_arg(args, unsigned long);
+ return EINA_TRUE;
+ }
+ else if (type == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t *tmem = mem;
+ *tmem = va_arg(args, uint64_t);
+ return EINA_TRUE;
+ }
+ else if (type == EINA_VALUE_TYPE_CHAR)
+ {
+ char *tmem = mem;
+ *tmem = va_arg(args, int); /* promoted by va_arg */
+ return EINA_TRUE;
+ }
+ else if (type == EINA_VALUE_TYPE_SHORT)
+ {
+ short *tmem = mem;
+ *tmem = va_arg(args, int); /* promoted by va_arg */
+ return EINA_TRUE;
+ }
+ else if (type == EINA_VALUE_TYPE_INT)
+ {
+ int *tmem = mem;
+ *tmem = va_arg(args, int);
+ return EINA_TRUE;
+ }
+ else if (type == EINA_VALUE_TYPE_LONG)
+ {
+ long *tmem = mem;
+ *tmem = va_arg(args, long);
+ return EINA_TRUE;
+ }
+ else if (type == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t *tmem = mem;
+ *tmem = va_arg(args, int64_t);
+ return EINA_TRUE;
+ }
+ else if (type == EINA_VALUE_TYPE_FLOAT)
+ {
+ float *tmem = mem;
+ *tmem = va_arg(args, double); /* promoted by va_arg */
+ return EINA_TRUE;
+ }
+ else if (type == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double *tmem = mem;
+ *tmem = va_arg(args, double);
+ return EINA_TRUE;
+ }
+ else if (type == EINA_VALUE_TYPE_STRINGSHARE)
+ {
+ const char *str = va_arg(args, const char *);
+ return eina_stringshare_replace((const char **)&value->value.ptr, str);
+ }
+ else if (type == EINA_VALUE_TYPE_STRING)
+ {
+ const char *str = va_arg(args, const char *);
+ free(value->value.ptr);
+ if (!str)
+ value->value.ptr = NULL;
+ else
+ {
+ value->value.ptr = strdup(str);
+ if (!value->value.ptr)
+ {
+ eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
+ return EINA_FALSE;
+ }
+ }
+ return EINA_TRUE;
+ }
+#endif
+
+ EINA_VALUE_TYPE_DISPATCH_RETURN(value, vset, EINA_ERROR_VALUE_FAILED,
+ EINA_FALSE, mem, args);
+}
+
+static inline Eina_Bool
+eina_value_vget(const Eina_Value *value, va_list args)
+{
+ const Eina_Value_Type *type;
+ const void *mem;
+ void *ptr;
+
+ EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
+
+ type = value->type;
+ mem = eina_value_memory_get(value);
+ ptr = va_arg(args, void *);
+ eina_error_set(0);
+ if (EINA_VALUE_TYPE_DEFAULT(type))
+ {
+ memcpy(ptr, mem, type->value_size);
+ return EINA_TRUE;
+ }
+
+ EINA_VALUE_TYPE_DISPATCH_RETURN(value, pget, EINA_ERROR_VALUE_FAILED,
+ EINA_FALSE, mem, ptr);
+}
+
+static inline Eina_Bool
+eina_value_pset(Eina_Value *value, const void *ptr)
+{
+ const Eina_Value_Type *type;
+ void *mem;
+
+ EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
+
+ type = value->type;
+ mem = eina_value_memory_get(value);
+ eina_error_set(0);
+
+ if (EINA_VALUE_TYPE_DEFAULT(type))
+ {
+ if (type == EINA_VALUE_TYPE_STRINGSHARE)
+ {
+ const char * const *str = ptr;
+ return eina_stringshare_replace((const char **)&value->value.ptr,
+ *str);
+ }
+ else if (type == EINA_VALUE_TYPE_STRING)
+ {
+ const char * const *str = ptr;
+ free(value->value.ptr);
+ if (!*str)
+ value->value.ptr = NULL;
+ else
+ {
+ value->value.ptr = strdup(*str);
+ if (!value->value.ptr)
+ {
+ eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
+ return EINA_FALSE;
+ }
+ }
+ return EINA_TRUE;
+ }
+ else
+ memcpy(mem, ptr, type->value_size);
+ return EINA_TRUE;
+ }
+
+ EINA_VALUE_TYPE_DISPATCH_RETURN(value, pset, EINA_ERROR_VALUE_FAILED,
+ EINA_FALSE, mem, ptr);
+}
+
+static inline Eina_Bool
+eina_value_pget(const Eina_Value *value, void *ptr)
+{
+ const Eina_Value_Type *type;
+ const void *mem;
+
+ EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
+
+ type = value->type;
+ mem = eina_value_memory_get(value);
+ eina_error_set(0);
+ if (EINA_VALUE_TYPE_DEFAULT(type))
+ {
+ memcpy(ptr, mem, type->value_size);
+ return EINA_TRUE;
+ }
+
+ EINA_VALUE_TYPE_DISPATCH_RETURN(value, pget, EINA_ERROR_VALUE_FAILED,
+ EINA_FALSE, mem, ptr);
+}
+
+static inline const Eina_Value_Type *
+eina_value_type_get(const Eina_Value *value)
+{
+ EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, NULL);
+ return value->type;
+}
+
+#define EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, retval) \
+ EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_ARRAY, retval)
+
+static inline Eina_Bool
+eina_value_array_setup(Eina_Value *value, const Eina_Value_Type *subtype, unsigned int step)
+{
+ Eina_Value_Array desc = {subtype, step, NULL};
+ if (!eina_value_setup(value, EINA_VALUE_TYPE_ARRAY))
+ return EINA_FALSE;
+ if (!eina_value_pset(value, &desc))
+ {
+ eina_value_flush(value);
+ return EINA_FALSE;
+ }
+ return EINA_TRUE;
+}
+
+static inline unsigned int
+eina_value_array_count(const Eina_Value *value)
+{
+ Eina_Value_Array desc;
+ EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
+ if (!eina_value_pget(value, &desc))
+ return 0;
+ return eina_inarray_count(desc.array);
+}
+
+static inline Eina_Bool
+eina_value_array_remove(Eina_Value *value, unsigned int position)
+{
+ Eina_Value_Array desc;
+ void *mem;
+
+ EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
+ if (!eina_value_pget(value, &desc))
+ return EINA_FALSE;
+
+ mem = eina_inarray_nth(desc.array, position);
+ if (!mem)
+ return EINA_FALSE;
+
+ eina_value_type_flush(desc.subtype, mem);
+ return eina_inarray_remove_at(desc.array, position);
+}
+
+static inline Eina_Bool
+eina_value_array_vset(Eina_Value *value, unsigned int position, va_list args)
+{
+ Eina_Value_Array desc;
+ void *mem;
+
+ EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
+ if (!eina_value_pget(value, &desc))
+ return EINA_FALSE;
+
+ mem = eina_inarray_nth(desc.array, position);
+ if (!mem)
+ return EINA_FALSE;
+
+ eina_value_type_flush(desc.subtype, mem);
+
+ if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
+ if (!eina_value_type_vset(desc.subtype, mem, args)) goto error_set;
+ return EINA_TRUE;
+
+ error_set:
+ eina_value_type_flush(desc.subtype, mem);
+ error_setup:
+ return EINA_FALSE;
+}
+
+static inline Eina_Bool
+eina_value_array_vget(const Eina_Value *value, unsigned int position, va_list args)
+{
+ Eina_Value_Array desc;
+ const void *mem;
+ void *ptr;
+ Eina_Bool ret;
+
+ EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
+ if (!eina_value_pget(value, &desc))
+ return EINA_FALSE;
+
+ mem = eina_inarray_nth(desc.array, position);
+ if (!mem)
+ return EINA_FALSE;
+
+ ptr = va_arg(args, void *);
+ ret = eina_value_type_pget(desc.subtype, mem, ptr);
+ return ret;
+}
+
+static inline Eina_Bool
+eina_value_array_vinsert(Eina_Value *value, unsigned int position, va_list args)
+{
+ Eina_Value_Array desc;
+ void *mem, *placeholder;
+
+ EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
+ if (!eina_value_pget(value, &desc))
+ return EINA_FALSE;
+
+ placeholder = alloca(desc.subtype->value_size);
+ memset(placeholder, 0, desc.subtype->value_size);
+ if (!eina_inarray_insert_at(desc.array, position, placeholder))
+ return EINA_FALSE;
+
+ mem = eina_inarray_nth(desc.array, position);
+ if (!mem)
+ return EINA_FALSE;
+
+ if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
+ if (!eina_value_type_vset(desc.subtype, mem, args)) goto error_set;
+ return EINA_TRUE;
+
+ error_set:
+ eina_value_type_flush(desc.subtype, mem);
+ error_setup:
+ eina_inarray_remove_at(desc.array, position);
+ return EINA_FALSE;
+}
+
+static inline Eina_Bool
+eina_value_array_vappend(Eina_Value *value, va_list args)
+{
+ Eina_Value_Array desc;
+ void *mem, *placeholder;
+ int position;
+
+ EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
+ if (!eina_value_pget(value, &desc))
+ return EINA_FALSE;
+
+ placeholder = alloca(desc.subtype->value_size);
+ memset(placeholder, 0, desc.subtype->value_size);
+ position = eina_inarray_append(desc.array, placeholder);
+ if (position < 0)
+ return EINA_FALSE;
+
+ mem = eina_inarray_nth(desc.array, position);
+ if (!mem)
+ return EINA_FALSE;
+
+ if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
+ if (!eina_value_type_vset(desc.subtype, mem, args)) goto error_set;
+ return EINA_TRUE;
+
+ error_set:
+ eina_value_type_flush(desc.subtype, mem);
+ error_setup:
+ eina_inarray_remove_at(desc.array, position);
+ return EINA_FALSE;
+}
+
+static inline Eina_Bool
+eina_value_array_set(Eina_Value *value, unsigned int position, ...)
+{
+ va_list args;
+ Eina_Bool ret;
+ va_start(args, position);
+ ret = eina_value_array_vset(value, position, args);
+ va_end(args);
+ return ret;
+}
+
+static inline Eina_Bool
+eina_value_array_get(const Eina_Value *value, unsigned int position, ...)
+{
+ va_list args;
+ Eina_Bool ret;
+ va_start(args, position);
+ ret = eina_value_array_vget(value, position, args);
+ va_end(args);
+ return ret;
+}
+
+static inline Eina_Bool
+eina_value_array_insert(Eina_Value *value, unsigned int position, ...)
+{
+ va_list args;
+ Eina_Bool ret;
+ va_start(args, position);
+ ret = eina_value_array_vinsert(value, position, args);
+ va_end(args);
+ return ret;
+}
+
+static inline Eina_Bool eina_value_array_append(Eina_Value *value, ...)
+{
+ va_list args;
+ Eina_Bool ret;
+ va_start(args, value);
+ ret = eina_value_array_vappend(value, args);
+ va_end(args);
+ return ret;
+}
+
+static inline Eina_Bool
+eina_value_array_pset(Eina_Value *value, unsigned int position, const void *ptr)
+{
+ Eina_Value_Array desc;
+ void *mem;
+
+ EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
+ if (!eina_value_pget(value, &desc))
+ return EINA_FALSE;
+
+ mem = eina_inarray_nth(desc.array, position);
+ if (!mem)
+ return EINA_FALSE;
+
+ eina_value_type_flush(desc.subtype, mem);
+
+ if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
+ if (!eina_value_type_pset(desc.subtype, mem, ptr)) goto error_set;
+ return EINA_TRUE;
+
+ error_set:
+ eina_value_type_flush(desc.subtype, mem);
+ error_setup:
+ return EINA_FALSE;
+}
+
+static inline Eina_Bool
+eina_value_array_pget(const Eina_Value *value, unsigned int position, void *ptr)
+{
+ Eina_Value_Array desc;
+ const void *mem;
+ Eina_Bool ret;
+
+ EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
+ if (!eina_value_pget(value, &desc))
+ return EINA_FALSE;
+
+ mem = eina_inarray_nth(desc.array, position);
+ if (!mem)
+ return EINA_FALSE;
+
+ ret = eina_value_type_pget(desc.subtype, mem, ptr);
+ return ret;
+}
+
+static inline Eina_Bool
+eina_value_array_pinsert(Eina_Value *value, unsigned int position, const void *ptr)
+{
+ Eina_Value_Array desc;
+ void *mem, *placeholder;
+
+ EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
+ if (!eina_value_pget(value, &desc))
+ return EINA_FALSE;
+
+ placeholder = alloca(desc.subtype->value_size);
+ memset(placeholder, 0, desc.subtype->value_size);
+ if (!eina_inarray_insert_at(desc.array, position, placeholder))
+ return EINA_FALSE;
+
+ mem = eina_inarray_nth(desc.array, position);
+ if (!mem)
+ return EINA_FALSE;
+
+ if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
+ if (!eina_value_type_pset(desc.subtype, mem, ptr)) goto error_set;
+ return EINA_TRUE;
+
+ error_set:
+ eina_value_type_flush(desc.subtype, mem);
+ error_setup:
+ eina_inarray_remove_at(desc.array, position);
+ return EINA_FALSE;
+}
+
+static inline Eina_Bool
+eina_value_array_pappend(Eina_Value *value, const void *ptr)
+{
+ Eina_Value_Array desc;
+ void *mem, *placeholder;
+ int position;
+
+ EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
+ if (!eina_value_pget(value, &desc))
+ return EINA_FALSE;
+
+ placeholder = alloca(desc.subtype->value_size);
+ memset(placeholder, 0, desc.subtype->value_size);
+ position = eina_inarray_append(desc.array, placeholder);
+ if (position < 0)
+ return EINA_FALSE;
+
+ mem = eina_inarray_nth(desc.array, position);
+ if (!mem)
+ return EINA_FALSE;
+
+ if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
+ if (!eina_value_type_pset(desc.subtype, mem, ptr)) goto error_set;
+ return EINA_TRUE;
+
+ error_set:
+ eina_value_type_flush(desc.subtype, mem);
+ error_setup:
+ eina_inarray_remove_at(desc.array, position);
+ return EINA_FALSE;
+}
+
+#undef EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL
+
+
+static inline Eina_Bool
+eina_value_type_setup(const Eina_Value_Type *type, void *mem)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
+ if (!type->setup)
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+ return type->setup(type, mem);
+}
+
+static inline Eina_Bool
+eina_value_type_flush(const Eina_Value_Type *type, void *mem)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
+ if (!type->flush)
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+ return type->flush(type, mem);
+}
+
+static inline Eina_Bool
+eina_value_type_copy(const Eina_Value_Type *type, const void *src, void *dst)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
+ if (!type->copy)
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+ return type->copy(type, src, dst);
+}
+
+static inline int
+eina_value_type_compare(const Eina_Value_Type *type, const void *a, void *b)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
+ if (!type->compare)
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+ return type->compare(type, a, b);
+}
+
+static inline Eina_Bool
+eina_value_type_convert_to(const Eina_Value_Type *type, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
+ if (!type->convert_to)
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+ return type->convert_to(type, convert, type_mem, convert_mem);
+}
+
+static inline Eina_Bool
+eina_value_type_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
+ if (!type->convert_from)
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+ return type->convert_from(type, convert, type_mem, convert_mem);
+}
+
+static inline Eina_Bool
+eina_value_type_vset(const Eina_Value_Type *type, void *mem, va_list args)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
+ if (!type->vset)
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+ return type->vset(type, mem, args);
+}
+
+static inline Eina_Bool
+eina_value_type_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
+ if (!type->pset)
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+ return type->pset(type, mem, ptr);
+}
+
+static inline Eina_Bool
+eina_value_type_pget(const Eina_Value_Type *type, const void *mem, void *ptr)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
+ if (!type->pget)
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+ return type->pget(type, mem, ptr);
+}
+
+#undef EINA_VALUE_TYPE_DEFAULT
+#undef EINA_VALUE_TYPE_CHECK_RETURN
+#undef EINA_VALUE_TYPE_CHECK_RETURN_VAL
+#undef EINA_VALUE_TYPE_DISPATCH
+#undef EINA_VALUE_TYPE_DISPATCH_RETURN
+#endif
--- /dev/null
+/* EINA - EFL data type library
+ * Copyright (C) 2012 ProFUSION embedded systems
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef EINA_VALUE_H_
+#define EINA_VALUE_H_
+
+#include "eina_types.h"
+#include "eina_fp.h" /* defines int64_t and uint64_t */
+#include "eina_inarray.h"
+#include <stdarg.h>
+
+/**
+ * @addtogroup Eina_Data_Types_Group Data Types
+ *
+ * @since 1.2
+ *
+ * @{
+ */
+
+/**
+ * @addtogroup Eina_Containers_Group Containers
+ *
+ * @{
+ */
+
+/**
+ * @defgroup Eina_Value_Group Generic Value Storage
+ *
+ * @{
+ */
+
+
+/**
+ * @typedef Eina_Value
+ * Store generic values.
+ *
+ * @since 1.2
+ */
+typedef struct _Eina_Value Eina_Value;
+
+/**
+ * @typedef Eina_Value_Type
+ * Describes access to the value
+ *
+ * @since 1.2
+ */
+typedef struct _Eina_Value_Type Eina_Value_Type;
+
+/**
+ * @typedef Eina_Value_Union
+ * Union with all known values to be hold.
+ *
+ * @since 1.2
+ */
+typedef union _Eina_Value_Union Eina_Value_Union;
+
+/**
+ * @union _Eina_Value_Union
+ * All possible values to be hold.
+ *
+ * @since 1.2
+ */
+union _Eina_Value_Union
+{
+ unsigned char buf[8]; /**< just hold 8-bytes, more goes into ptr */
+ void *ptr; /**< used as generic pointer */
+ uint64_t _guarantee; /**< guarantees 8-byte alignment */
+};
+
+/**
+ * @var EINA_VALUE_TYPE_UCHAR
+ * manages unsigned char type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_UCHAR;
+
+/**
+ * @var EINA_VALUE_TYPE_USHORT
+ * manages unsigned short type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_USHORT;
+
+/**
+ * @var EINA_VALUE_TYPE_UINT
+ * manages unsigned int type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_UINT;
+
+/**
+ * @var EINA_VALUE_TYPE_ULONG
+ * manages unsigned long type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_ULONG;
+
+/**
+ * @var EINA_VALUE_TYPE_UINT64
+ * manages unsigned integer of 64 bits type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_UINT64;
+
+/**
+ * @var EINA_VALUE_TYPE_CHAR
+ * manages char type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_CHAR;
+
+/**
+ * @var EINA_VALUE_TYPE_SHORT
+ * manages short type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_SHORT;
+
+/**
+ * @var EINA_VALUE_TYPE_INT
+ * manages int type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_INT;
+
+/**
+ * @var EINA_VALUE_TYPE_LONG
+ * manages long type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_LONG;
+
+/**
+ * @var EINA_VALUE_TYPE_INT64
+ * manages integer of 64 bits type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_INT64;
+
+/**
+ * @var EINA_VALUE_TYPE_FLOAT
+ * manages float type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_FLOAT;
+
+/**
+ * @var EINA_VALUE_TYPE_DOUBLE
+ * manages double type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_DOUBLE;
+
+/**
+ * @var EINA_VALUE_TYPE_STRINGSHARE
+ * manages stringshare type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_STRINGSHARE;
+
+/**
+ * @var EINA_VALUE_TYPE_STRING
+ * manages string type.
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_STRING;
+
+
+/**
+ * @var EINA_VALUE_TYPE_ARRAY
+ *
+ * manages array type. The value get/set are the type of elements in
+ * the array, use the alternaties:
+ * @li eina_value_array_get() and eina_value_array_set()
+ * @li eina_value_array_vget() and eina_value_array_vset()
+ * @li eina_value_array_pget() and eina_value_array_pset()
+ *
+ * @since 1.2
+ */
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_ARRAY;
+
+
+/**
+ * @var EINA_ERROR_VALUE_FAILED
+ * Error identifier corresponding to value check failure.
+ *
+ * @since 1.2
+ */
+EAPI extern int EINA_ERROR_VALUE_FAILED;
+
+/**
+ * @defgroup Eina_Value_Value_Group Generic Value management
+ *
+ * @{
+ */
+
+/**
+ * @struct _Eina_Value
+ * defines the contents of a value
+ *
+ * @since 1.2
+ */
+struct _Eina_Value
+{
+ const Eina_Value_Type *type; /**< how to access values */
+ Eina_Value_Union value; /**< to be accessed with type descriptor */
+};
+
+/**
+ * @brief Create generic value storage.
+ * @param type how to manage this value.
+ * @return The new value or @c NULL on failure.
+ *
+ * Create a new generic value storage. The members are managed using
+ * the description specified by @a type.
+ *
+ * Some types may specify more operations, as an example
+ * #EINA_VALUE_TYPE_ARRAY uses eina_value_array_set(),
+ * eina_value_array_get() and so on.
+ *
+ * On failure, @c NULL is returned and #EINA_ERROR_OUT_OF_MEMORY or
+ * #EINA_ERROR_VALUE_FAILED is set.
+ *
+ * @note this is a helper around eina_value_setup() doing malloc for
+ * you. Consider using eina_value_flush() and eina_value_setup()
+ * to avoid memory allocations.
+ *
+ * @see eina_value_free()
+ *
+ * @since 1.2
+ */
+EAPI Eina_Value *eina_value_new(const Eina_Value_Type *type) EINA_ARG_NONNULL(1) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
+
+/**
+ * @brief Free value and its data.
+ * @param value value object
+ *
+ * @see eina_value_flush()
+ *
+ * @since 1.2
+ */
+EAPI void eina_value_free(Eina_Value *value) EINA_ARG_NONNULL(1);
+
+
+/**
+ * @brief Setup generic value storage.
+ * @param value value object
+ * @param type how to manage this value.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * Setups new generic value storage. The members are managed using the
+ * description specified by @a type.
+ *
+ * Some types may specify more operations, as an example
+ * #EINA_VALUE_TYPE_ARRAY uses eina_value_array_set(),
+ * eina_value_array_get() and so on.
+ *
+ * @note Existing memory is ignored! If it was previously set, then
+ * use eina_value_flush() first.
+ *
+ * On failure, #EINA_FALSE is returned and #EINA_ERROR_OUT_OF_MEMORY
+ * or #EINA_ERROR_VALUE_FAILED is set.
+ *
+ * @see eina_value_flush()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_setup(Eina_Value *value,
+ const Eina_Value_Type *type) EINA_ARG_NONNULL(1, 2);
+
+/**
+ * @brief Create generic value storage.
+ * @param value value object
+ *
+ * Releases all the resources associated with a generic value. The
+ * value must be already set with eina_value_setup() or
+ * eina_value_new().
+ *
+ * After this call returns, the contents of the value are undefined,
+ * but the value can be reused by calling eina_value_setup() again.
+ *
+ * @see eina_value_setup()
+ * @see eina_value_free()
+ *
+ * @since 1.2
+ */
+static inline void eina_value_flush(Eina_Value *value) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Copy generic value storage.
+ * @param value source value object
+ * @param copy destination value object
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The @a copy object is considered internalized and its existing
+ * contents are ignored (just as if eina_value_flush() was called on
+ * it).
+ *
+ * The copy happens by calling eina_value_setup() on @a copy, followed
+ * by getting the contents of @a value and setting it to @a copy.
+ *
+ * @since 1.2
+ */
+EAPI Eina_Bool eina_value_copy(const Eina_Value *value,
+ Eina_Value *copy) EINA_ARG_NONNULL(1, 2);
+
+/**
+ * @brief Compare generic value storage.
+ * @param a left side of comparison
+ * @param b right side of comparison
+ * @return less than zero if a < b, greater than zero if a > b, zero
+ * if equals
+ *
+ * @since 1.2
+ */
+static inline int eina_value_compare(const Eina_Value *a,
+ const Eina_Value *b) EINA_ARG_NONNULL(1, 2);
+
+/**
+ * @brief Set the generic value.
+ * @param value source value object
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The variable argument is dependent on chosen type. The list for
+ * basic types:
+ *
+ * @li EINA_VALUE_TYPE_UCHAR: unsigned char
+ * @li EINA_VALUE_TYPE_USHORT: unsigned short
+ * @li EINA_VALUE_TYPE_UINT: unsigned int
+ * @li EINA_VALUE_TYPE_ULONG: unsigned long
+ * @li EINA_VALUE_TYPE_UINT64: uint64_t
+ * @li EINA_VALUE_TYPE_CHAR: char
+ * @li EINA_VALUE_TYPE_SHORT: short
+ * @li EINA_VALUE_TYPE_INT: int
+ * @li EINA_VALUE_TYPE_LONG: long
+ * @li EINA_VALUE_TYPE_INT64: int64_t
+ * @li EINA_VALUE_TYPE_FLOAT: float
+ * @li EINA_VALUE_TYPE_DOUBLE: double
+ * @li EINA_VALUE_TYPE_STRINGSHARE: const char *
+ * @li EINA_VALUE_TYPE_STRING: const char *
+ * @li EINA_VALUE_TYPE_ARRAY: Eina_Value_Array
+ *
+ * @code
+ * Eina_Value *value = eina_value_new(EINA_VALUE_TYPE_INT);
+ * int x = 567;
+ * eina_value_set(value, 1234);
+ * eina_value_set(value, x);
+ *
+ * eina_value_flush(value);
+ *
+ * eina_value_setup(value, EINA_VALUE_TYPE_STRING);
+ * eina_value_set(value, "hello world!");
+ *
+ * eina_value_free(value);
+ * @endcode
+ *
+ * @note for array member see eina_value_array_set()
+ *
+ * @see eina_value_get()
+ * @see eina_value_vset()
+ * @see eina_value_pset()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_set(Eina_Value *value,
+ ...) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Get the generic value.
+ * @param value source value object
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The value is returned in the variable argument parameter, the
+ * actual value is type-dependent, but usually it will be what is
+ * stored inside the object. There shouldn't be any memory allocation,
+ * thus the contents should @b not be free'd.
+ *
+ * The variable argument is dependent on chosen type. The list for
+ * basic types:
+ *
+ * @li EINA_VALUE_TYPE_UCHAR: unsigned char*
+ * @li EINA_VALUE_TYPE_USHORT: unsigned short*
+ * @li EINA_VALUE_TYPE_UINT: unsigned int*
+ * @li EINA_VALUE_TYPE_ULONG: unsigned long*
+ * @li EINA_VALUE_TYPE_UINT64: uint64_t*
+ * @li EINA_VALUE_TYPE_CHAR: char*
+ * @li EINA_VALUE_TYPE_SHORT: short*
+ * @li EINA_VALUE_TYPE_INT: int*
+ * @li EINA_VALUE_TYPE_LONG: long*
+ * @li EINA_VALUE_TYPE_INT64: int64_t*
+ * @li EINA_VALUE_TYPE_FLOAT: float*
+ * @li EINA_VALUE_TYPE_DOUBLE: double*
+ * @li EINA_VALUE_TYPE_STRINGSHARE: const char **
+ * @li EINA_VALUE_TYPE_STRING: const char **
+ * @li EINA_VALUE_TYPE_ARRAY: Eina_Value_Array*
+ *
+ * @code
+ * Eina_Value *value = eina_value_new(EINA_VALUE_TYPE_INT);
+ * int x;
+ * const char *s;
+ *
+ * eina_value_set(value, 1234);
+ * eina_value_get(value, &x);
+ *
+ * eina_value_flush(value);
+ *
+ * eina_value_setup(value, EINA_VALUE_TYPE_STRING);
+ * eina_value_set(value, "hello world!");
+ * eina_value_get(value, &s);
+ *
+ * eina_value_free(value);
+ * @endcode
+ *
+ * @note for array member see eina_value_array_get()
+ *
+ * @see eina_value_set()
+ * @see eina_value_vset()
+ * @see eina_value_pset()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_get(const Eina_Value *value,
+ ...) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Set the generic value.
+ * @param value source value object
+ * @param args variable argument
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * @note for array member see eina_value_array_vset()
+ *
+ * @see eina_value_vget()
+ * @see eina_value_set()
+ * @see eina_value_pset()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_vset(Eina_Value *value,
+ va_list args) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Get the generic value.
+ * @param value source value object
+ * @param args variable argument
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The value is returned in the variable argument parameter, the
+ * actual value is type-dependent, but usually it will be what is
+ * stored inside the object. There shouldn't be any memory allocation,
+ * thus the contents should @b not be free'd.
+ *
+ * @note for array member see eina_value_array_vget()
+ *
+ * @see eina_value_vset()
+ * @see eina_value_get()
+ * @see eina_value_pget()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_vget(const Eina_Value *value,
+ va_list args) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Set the generic value from pointer.
+ * @param value source value object
+ * @param ptr pointer to specify the contents.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The pointer type is dependent on chosen value type. The list for
+ * basic types:
+ *
+ * @li EINA_VALUE_TYPE_UCHAR: unsigned char*
+ * @li EINA_VALUE_TYPE_USHORT: unsigned short*
+ * @li EINA_VALUE_TYPE_UINT: unsigned int*
+ * @li EINA_VALUE_TYPE_ULONG: unsigned long*
+ * @li EINA_VALUE_TYPE_UINT64: uint64_t*
+ * @li EINA_VALUE_TYPE_CHAR: char*
+ * @li EINA_VALUE_TYPE_SHORT: short*
+ * @li EINA_VALUE_TYPE_INT: int*
+ * @li EINA_VALUE_TYPE_LONG: long*
+ * @li EINA_VALUE_TYPE_INT64: int64_t*
+ * @li EINA_VALUE_TYPE_FLOAT: float*
+ * @li EINA_VALUE_TYPE_DOUBLE: double*
+ * @li EINA_VALUE_TYPE_STRINGSHARE: const char **
+ * @li EINA_VALUE_TYPE_STRING: const char **
+ * @li EINA_VALUE_TYPE_ARRAY: Eina_Value_Array*
+ *
+ * @note the pointer contents are written using the size defined by
+ * type. It can be larger than void* or uint64_t.
+ *
+ * @code
+ * Eina_Value *value = eina_value_new(EINA_VALUE_TYPE_INT);
+ * int x = 567;
+ * const char *s = "hello world!";
+ *
+ * eina_value_pset(value, &x);
+ *
+ * eina_value_flush(value);
+ *
+ * eina_value_setup(value, EINA_VALUE_TYPE_STRING);
+ * eina_value_pset(value, &s);
+ *
+ * eina_value_free(value);
+ * @endcode
+ *
+ * @note for array member see eina_value_array_pset()
+ *
+ * @see eina_value_pget()
+ * @see eina_value_set()
+ * @see eina_value_vset()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_pset(Eina_Value *value,
+ const void *ptr) EINA_ARG_NONNULL(1, 2);
+
+/**
+ * @brief Get the generic value to pointer.
+ * @param value source value object
+ * @param ptr pointer to receive the contents.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The value is returned in pointer contents, the actual value is
+ * type-dependent, but usually it will be what is stored inside the
+ * object. There shouldn't be any memory allocation, thus the contents
+ * should @b not be free'd.
+ *
+ * The pointer type is dependent on chosen value type. The list for
+ * basic types:
+ *
+ * @li EINA_VALUE_TYPE_UCHAR: unsigned char*
+ * @li EINA_VALUE_TYPE_USHORT: unsigned short*
+ * @li EINA_VALUE_TYPE_UINT: unsigned int*
+ * @li EINA_VALUE_TYPE_ULONG: unsigned long*
+ * @li EINA_VALUE_TYPE_UINT64: uint64_t*
+ * @li EINA_VALUE_TYPE_CHAR: char*
+ * @li EINA_VALUE_TYPE_SHORT: short*
+ * @li EINA_VALUE_TYPE_INT: int*
+ * @li EINA_VALUE_TYPE_LONG: long*
+ * @li EINA_VALUE_TYPE_INT64: int64_t*
+ * @li EINA_VALUE_TYPE_FLOAT: float*
+ * @li EINA_VALUE_TYPE_DOUBLE: double*
+ * @li EINA_VALUE_TYPE_STRINGSHARE: const char **
+ * @li EINA_VALUE_TYPE_STRING: const char **
+ * @li EINA_VALUE_TYPE_ARRAY: Eina_Value_Array*
+ *
+ * @code
+ * Eina_Value *value = eina_value_new(EINA_VALUE_TYPE_INT);
+ * int x;
+ * const char *s;
+ *
+ * eina_value_set(value, 1234);
+ * eina_value_pget(value, &x);
+ *
+ * eina_value_flush(value);
+ *
+ * eina_value_setup(value, EINA_VALUE_TYPE_STRING);
+ * eina_value_set(value, "hello world!");
+ * eina_value_pget(value, &s);
+ *
+ * eina_value_free(value);
+ * @endcode
+ *
+ * @note for array member see eina_value_array_get()
+ *
+ * @see eina_value_set()
+ * @see eina_value_vset()
+ * @see eina_value_pset()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_pget(const Eina_Value *value,
+ void *ptr) EINA_ARG_NONNULL(1, 2);
+
+/**
+ * @brief Convert one value to another type.
+ * @param value source value object.
+ * @param convert destination value object.
+ * @return #EINA_TRUE if converted, #EINA_FALSE otherwise.
+ *
+ * Converts one value to another trying first @a value type
+ * @c convert_to() function, if it did not work, try @a convert
+ * type @c convert_from() function.
+ *
+ * Conversion functions are type defined, the basic types can convert
+ * between themselves, but conversion is strict! That is, if
+ * converting from negative value to unsigned type, it will fail. It
+ * also fails on value overflow.
+ *
+ * It is recommended that all types implement at least convert to
+ * string, used by eina_value_to_string().
+ *
+ * @note Both objects must be setup beforehand!
+ *
+ * @since 1.2
+ */
+EAPI Eina_Bool eina_value_convert(const Eina_Value *value,
+ Eina_Value *convert) EINA_ARG_NONNULL(1, 2);
+
+
+/**
+ * @brief Convert value to string.
+ * @param value value object.
+ * @return newly allocated memory or @c NULL on failure.
+ *
+ * @see eina_value_convert()
+ * @since 1.2
+ */
+EAPI char *eina_value_to_string(const Eina_Value *value) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Query value type.
+ * @param value value object.
+ * @return type instance or @c NULL if type is invalid.
+ *
+ * Check if value type is valid and returns it. A type is invalid if
+ * it does not exist or if it is using a different version field.
+ *
+ * @see eina_value_type_check()
+ *
+ * @since 1.2
+ */
+static inline const Eina_Value_Type *eina_value_type_get(const Eina_Value *value) EINA_PURE EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup Eina_Value_Array_Group Generic Value Array management
+ *
+ * @{
+ */
+
+
+/**
+ * @typedef Eina_Value_Array
+ * Value type for #EINA_VALUE_TYPE_ARRAY
+ *
+ * @since 1.2
+ */
+typedef struct _Eina_Value_Array Eina_Value_Array;
+
+/**
+ * @struct _Eina_Value_Array
+ * Used to store the array and its subtype.
+ */
+struct _Eina_Value_Array
+{
+ const Eina_Value_Type *subtype; /**< how to allocate and access items */
+ unsigned int step; /**< how to grow the members array */
+ Eina_Inarray *array; /**< the array that holds data, members are of subtype->value_size bytes. */
+ };
+
+/**
+ * @brief Create generic value storage of type array.
+ * @param subtype how to manage this array members.
+ * @param step how to grow the members array.
+ * @return The new value or @c NULL on failure.
+ *
+ * Create a new generic value storage of type array. The members are
+ * managed using the description specified by @a subtype.
+ *
+ * On failure, @c NULL is returned and #EINA_ERROR_OUT_OF_MEMORY or
+ * #EINA_ERROR_VALUE_FAILED is set.
+ *
+ * @note this is a helper around eina_value_array_setup() doing malloc
+ * for you.
+ *
+ * @see eina_value_free()
+ * @see eina_value_array_setup()
+ *
+ * @since 1.2
+ */
+EAPI Eina_Value *eina_value_array_new(const Eina_Value_Type *subtype,
+ unsigned int step) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Setup generic value storage of type array.
+ * @param value value object
+ * @param subtype how to manage this array members.
+ * @param step how to grow the members array.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * Setups new generic value storage of type array with the given
+ * @a subtype.
+ *
+ * This is the same as calling eina_value_set() with
+ * #EINA_VALUE_TYPE_ARRAY followed by eina_value_pset() with the
+ * #Eina_Value_Array description configured.
+ *
+ * @note Existing memory is ignored! If it was previously set, then
+ * use eina_value_flush() first.
+ *
+ * On failure, #EINA_FALSE is returned and #EINA_ERROR_OUT_OF_MEMORY
+ * or #EINA_ERROR_VALUE_FAILED is set.
+ *
+ * @see eina_value_flush()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_setup(Eina_Value *value,
+ const Eina_Value_Type *subtype,
+ unsigned int step) EINA_ARG_NONNULL(1, 2);
+
+/**
+ * @brief Query number of elements in value of array type.
+ * @param value value object.
+ * @return number of child elements.
+ * @since 1.2
+ */
+static inline unsigned int eina_value_array_count(const Eina_Value *value);
+
+/**
+ * @brief Remove element at given position in value of array type.
+ * @param value value object.
+ * @param position index of the member
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_remove(Eina_Value *value,
+ unsigned int position) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Set the generic value in an array member.
+ * @param value source value object
+ * @param position index of the member
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The variable argument is dependent on chosen subtype. The list for
+ * basic types:
+ *
+ * @li EINA_VALUE_TYPE_UCHAR: unsigned char
+ * @li EINA_VALUE_TYPE_USHORT: unsigned short
+ * @li EINA_VALUE_TYPE_UINT: unsigned int
+ * @li EINA_VALUE_TYPE_ULONG: unsigned long
+ * @li EINA_VALUE_TYPE_UINT64: uint64_t
+ * @li EINA_VALUE_TYPE_CHAR: char
+ * @li EINA_VALUE_TYPE_SHORT: short
+ * @li EINA_VALUE_TYPE_INT: int
+ * @li EINA_VALUE_TYPE_LONG: long
+ * @li EINA_VALUE_TYPE_INT64: int64_t
+ * @li EINA_VALUE_TYPE_FLOAT: float
+ * @li EINA_VALUE_TYPE_DOUBLE: double
+ * @li EINA_VALUE_TYPE_STRINGSHARE: const char *
+ * @li EINA_VALUE_TYPE_STRING: const char *
+ * @li EINA_VALUE_TYPE_ARRAY: Eina_Value_Array
+ *
+ * @code
+ * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT);
+ * int x;
+ *
+ * eina_value_array_append(value, 1234);
+ * eina_value_array_set(value, 0, 5678);
+ * eina_value_array_get(value, 0, &x);
+ * eina_value_free(value);
+ * @endcode
+ *
+ * @see eina_value_array_get()
+ * @see eina_value_array_vset()
+ * @see eina_value_array_pset()
+ * @see eina_value_array_insert()
+ * @see eina_value_array_vinsert()
+ * @see eina_value_array_pinsert()
+ * @see eina_value_array_append()
+ * @see eina_value_array_vappend()
+ * @see eina_value_array_pappend()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_set(Eina_Value *value,
+ unsigned int position,
+ ...) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Get the generic value from an array member.
+ * @param value source value object
+ * @param position index of the member
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The value is returned in the variable argument parameter, the
+ * actual value is type-dependent, but usually it will be what is
+ * stored inside the object. There shouldn't be any memory allocation,
+ * thus the contents should @b not be free'd.
+ *
+ * The variable argument is dependent on chosen subtype. The list for
+ * basic types:
+ *
+ * @li EINA_VALUE_TYPE_UCHAR: unsigned char*
+ * @li EINA_VALUE_TYPE_USHORT: unsigned short*
+ * @li EINA_VALUE_TYPE_UINT: unsigned int*
+ * @li EINA_VALUE_TYPE_ULONG: unsigned long*
+ * @li EINA_VALUE_TYPE_UINT64: uint64_t*
+ * @li EINA_VALUE_TYPE_CHAR: char*
+ * @li EINA_VALUE_TYPE_SHORT: short*
+ * @li EINA_VALUE_TYPE_INT: int*
+ * @li EINA_VALUE_TYPE_LONG: long*
+ * @li EINA_VALUE_TYPE_INT64: int64_t*
+ * @li EINA_VALUE_TYPE_FLOAT: float*
+ * @li EINA_VALUE_TYPE_DOUBLE: double*
+ * @li EINA_VALUE_TYPE_STRINGSHARE: const char **
+ * @li EINA_VALUE_TYPE_STRING: const char **
+ * @li EINA_VALUE_TYPE_ARRAY: Eina_Value_Array*
+ *
+ * @code
+ * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT);
+ * int x;
+ *
+ * eina_value_array_append(value, 1234);
+ * eina_value_array_get(value, 0, &x);
+ * eina_value_free(value);
+ * @endcode
+ *
+ * @see eina_value_array_set()
+ * @see eina_value_array_vset()
+ * @see eina_value_array_pset()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_get(const Eina_Value *value,
+ unsigned int position,
+ ...) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Insert the generic value in an array member position.
+ * @param value source value object
+ * @param position index of the member
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The variable argument is dependent on chosen subtype. The list for
+ * basic types:
+ *
+ * @li EINA_VALUE_TYPE_UCHAR: unsigned char
+ * @li EINA_VALUE_TYPE_USHORT: unsigned short
+ * @li EINA_VALUE_TYPE_UINT: unsigned int
+ * @li EINA_VALUE_TYPE_ULONG: unsigned long
+ * @li EINA_VALUE_TYPE_UINT64: uint64_t
+ * @li EINA_VALUE_TYPE_CHAR: char
+ * @li EINA_VALUE_TYPE_SHORT: short
+ * @li EINA_VALUE_TYPE_INT: int
+ * @li EINA_VALUE_TYPE_LONG: long
+ * @li EINA_VALUE_TYPE_INT64: int64_t
+ * @li EINA_VALUE_TYPE_FLOAT: float
+ * @li EINA_VALUE_TYPE_DOUBLE: double
+ * @li EINA_VALUE_TYPE_STRINGSHARE: const char *
+ * @li EINA_VALUE_TYPE_STRING: const char *
+ * @li EINA_VALUE_TYPE_ARRAY: Eina_Value_Array
+ *
+ * @code
+ * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT);
+ * int x;
+ *
+ * eina_value_array_insert(value, 0, 1234);
+ * eina_value_array_get(value, 0, &x);
+ * eina_value_free(value);
+ * @endcode
+ *
+ * @see eina_value_array_set()
+ * @see eina_value_array_get()
+ * @see eina_value_array_vset()
+ * @see eina_value_array_pset()
+ * @see eina_value_array_vinsert()
+ * @see eina_value_array_pinsert()
+ * @see eina_value_array_append()
+ * @see eina_value_array_vappend()
+ * @see eina_value_array_pappend()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_insert(Eina_Value *value,
+ unsigned int position,
+ ...) EINA_ARG_NONNULL(1);
+
+
+/**
+ * @brief Append the generic value in an array.
+ * @param value source value object
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The variable argument is dependent on chosen subtype. The list for
+ * basic types:
+ *
+ * @li EINA_VALUE_TYPE_UCHAR: unsigned char
+ * @li EINA_VALUE_TYPE_USHORT: unsigned short
+ * @li EINA_VALUE_TYPE_UINT: unsigned int
+ * @li EINA_VALUE_TYPE_ULONG: unsigned long
+ * @li EINA_VALUE_TYPE_UINT64: uint64_t
+ * @li EINA_VALUE_TYPE_CHAR: char
+ * @li EINA_VALUE_TYPE_SHORT: short
+ * @li EINA_VALUE_TYPE_INT: int
+ * @li EINA_VALUE_TYPE_LONG: long
+ * @li EINA_VALUE_TYPE_INT64: int64_t
+ * @li EINA_VALUE_TYPE_FLOAT: float
+ * @li EINA_VALUE_TYPE_DOUBLE: double
+ * @li EINA_VALUE_TYPE_STRINGSHARE: const char *
+ * @li EINA_VALUE_TYPE_STRING: const char *
+ * @li EINA_VALUE_TYPE_ARRAY: Eina_Value_Array
+ *
+ * @code
+ * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT);
+ * int x;
+ *
+ * eina_value_array_append(value, 1234);
+ * eina_value_array_get(value, 0, &x);
+ * eina_value_free(value);
+ * @endcode
+ *
+ * @see eina_value_array_set()
+ * @see eina_value_array_get()
+ * @see eina_value_array_vset()
+ * @see eina_value_array_pset()
+ * @see eina_value_array_vinsert()
+ * @see eina_value_array_pinsert()
+ * @see eina_value_array_append()
+ * @see eina_value_array_vappend()
+ * @see eina_value_array_pappend()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_append(Eina_Value *value,
+ ...) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Set the generic value in an array member.
+ * @param value source value object
+ * @param position index of the member
+ * @param args variable argument
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ * @see eina_value_array_set()
+ * @see eina_value_array_get()
+ * @see eina_value_array_pset()
+ * @see eina_value_array_insert()
+ * @see eina_value_array_vinsert()
+ * @see eina_value_array_pinsert()
+ * @see eina_value_array_append()
+ * @see eina_value_array_vappend()
+ * @see eina_value_array_pappend()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_vset(Eina_Value *value,
+ unsigned int position,
+ va_list args) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Get the generic value from an array member.
+ * @param value source value object
+ * @param position index of the member
+ * @param args variable argument
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The value is returned in the variable argument parameter, the
+ * actual value is type-dependent, but usually it will be what is
+ * stored inside the object. There shouldn't be any memory allocation,
+ * thus the contents should @b not be free'd.
+ *
+ * @see eina_value_array_vset()
+ * @see eina_value_array_get()
+ * @see eina_value_array_pget()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_vget(const Eina_Value *value,
+ unsigned int position,
+ va_list args) EINA_ARG_NONNULL(1);
+/**
+ * @brief Insert the generic value in an array member position.
+ * @param value source value object
+ * @param position index of the member
+ * @param args variable argument
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ * @see eina_value_array_set()
+ * @see eina_value_array_get()
+ * @see eina_value_array_vset()
+ * @see eina_value_array_pset()
+ * @see eina_value_array_insert()
+ * @see eina_value_array_pinsert()
+ * @see eina_value_array_append()
+ * @see eina_value_array_vappend()
+ * @see eina_value_array_pappend()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_vinsert(Eina_Value *value,
+ unsigned int position,
+ va_list args) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Append the generic value in an array.
+ * @param value source value object
+ * @param args variable argument
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ * @see eina_value_array_set()
+ * @see eina_value_array_get()
+ * @see eina_value_array_vget()
+ * @see eina_value_array_pset()
+ * @see eina_value_array_insert()
+ * @see eina_value_array_vinsert()
+ * @see eina_value_array_pinsert()
+ * @see eina_value_array_append()
+ * @see eina_value_array_pappend()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_vappend(Eina_Value *value,
+ va_list args) EINA_ARG_NONNULL(1);
+
+
+/**
+ * @brief Set the generic value in an array member from pointer.
+ * @param value source value object
+ * @param position index of the member
+ * @param ptr pointer to specify the contents.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The pointer type is dependent on chosen value type. The list for
+ * basic types:
+ *
+ * @li EINA_VALUE_TYPE_UCHAR: unsigned char*
+ * @li EINA_VALUE_TYPE_USHORT: unsigned short*
+ * @li EINA_VALUE_TYPE_UINT: unsigned int*
+ * @li EINA_VALUE_TYPE_ULONG: unsigned long*
+ * @li EINA_VALUE_TYPE_UINT64: uint64_t*
+ * @li EINA_VALUE_TYPE_CHAR: char*
+ * @li EINA_VALUE_TYPE_SHORT: short*
+ * @li EINA_VALUE_TYPE_INT: int*
+ * @li EINA_VALUE_TYPE_LONG: long*
+ * @li EINA_VALUE_TYPE_INT64: int64_t*
+ * @li EINA_VALUE_TYPE_FLOAT: float*
+ * @li EINA_VALUE_TYPE_DOUBLE: double*
+ * @li EINA_VALUE_TYPE_STRINGSHARE: const char **
+ * @li EINA_VALUE_TYPE_STRING: const char **
+ * @li EINA_VALUE_TYPE_ARRAY: Eina_Value_Array*
+ *
+ * @note the pointer contents are written using the size defined by
+ * type. It can be larger than void* or uint64_t.
+ *
+ * @code
+ * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT);
+ * int x = 1234;
+ *
+ * eina_value_array_append(value, 1234);
+ * eina_value_array_pset(value, 0, &x);
+ * eina_value_array_pget(value, 0, &x);
+ * eina_value_free(value);
+ * @endcode
+ *
+ * @see eina_value_array_set()
+ * @see eina_value_array_get()
+ * @see eina_value_array_vset()
+ * @see eina_value_array_insert()
+ * @see eina_value_array_vinsert()
+ * @see eina_value_array_pinsert()
+ * @see eina_value_array_append()
+ * @see eina_value_array_vappend()
+ * @see eina_value_array_pappend()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_pset(Eina_Value *value,
+ unsigned int position,
+ const void *ptr) EINA_ARG_NONNULL(1, 3);
+
+/**
+ * @brief Get the generic value to pointer from an array member.
+ * @param value source value object
+ * @param position index of the member
+ * @param ptr pointer to receive the contents.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The value is returned in pointer contents, the actual value is
+ * type-dependent, but usually it will be what is stored inside the
+ * object. There shouldn't be any memory allocation, thus the contents
+ * should @b not be free'd.
+ *
+ * The pointer type is dependent on chosen value type. The list for
+ * basic types:
+ *
+ * @li EINA_VALUE_TYPE_UCHAR: unsigned char*
+ * @li EINA_VALUE_TYPE_USHORT: unsigned short*
+ * @li EINA_VALUE_TYPE_UINT: unsigned int*
+ * @li EINA_VALUE_TYPE_ULONG: unsigned long*
+ * @li EINA_VALUE_TYPE_UINT64: uint64_t*
+ * @li EINA_VALUE_TYPE_CHAR: char*
+ * @li EINA_VALUE_TYPE_SHORT: short*
+ * @li EINA_VALUE_TYPE_INT: int*
+ * @li EINA_VALUE_TYPE_LONG: long*
+ * @li EINA_VALUE_TYPE_INT64: int64_t*
+ * @li EINA_VALUE_TYPE_FLOAT: float*
+ * @li EINA_VALUE_TYPE_DOUBLE: double*
+ * @li EINA_VALUE_TYPE_STRINGSHARE: const char **
+ * @li EINA_VALUE_TYPE_STRING: const char **
+ * @li EINA_VALUE_TYPE_ARRAY: Eina_Value_Array*
+ *
+ * @code
+ * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT);
+ * int x;
+ *
+ * eina_value_array_append(value, 1234);
+ * eina_value_array_pget(value, 0, &x);
+ * eina_value_free(value);
+ * @endcode
+ *
+ * @see eina_value_array_set()
+ * @see eina_value_array_vset()
+ * @see eina_value_array_pset()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_pget(const Eina_Value *value,
+ unsigned int position,
+ void *ptr) EINA_ARG_NONNULL(1, 3);
+
+/**
+ * @brief Insert the generic value in an array member position from pointer.
+ * @param value source value object
+ * @param position index of the member
+ * @param ptr pointer to specify the contents.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The pointer type is dependent on chosen value type. The list for
+ * basic types:
+ *
+ * @li EINA_VALUE_TYPE_UCHAR: unsigned char*
+ * @li EINA_VALUE_TYPE_USHORT: unsigned short*
+ * @li EINA_VALUE_TYPE_UINT: unsigned int*
+ * @li EINA_VALUE_TYPE_ULONG: unsigned long*
+ * @li EINA_VALUE_TYPE_UINT64: uint64_t*
+ * @li EINA_VALUE_TYPE_CHAR: char*
+ * @li EINA_VALUE_TYPE_SHORT: short*
+ * @li EINA_VALUE_TYPE_INT: int*
+ * @li EINA_VALUE_TYPE_LONG: long*
+ * @li EINA_VALUE_TYPE_INT64: int64_t*
+ * @li EINA_VALUE_TYPE_FLOAT: float*
+ * @li EINA_VALUE_TYPE_DOUBLE: double*
+ * @li EINA_VALUE_TYPE_STRINGSHARE: const char **
+ * @li EINA_VALUE_TYPE_STRING: const char **
+ * @li EINA_VALUE_TYPE_ARRAY: Eina_Value_Array*
+ *
+ * @note the pointer contents are written using the size defined by
+ * type. It can be larger than void* or uint64_t.
+ *
+ * @code
+ * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT);
+ * int x = 1234;
+ *
+ * eina_value_array_pinsert(value, 0, &x);
+ * eina_value_array_pget(value, 0, &x);
+ * eina_value_free(value);
+ * @endcode
+ *
+ * @see eina_value_array_set()
+ * @see eina_value_array_get()
+ * @see eina_value_array_vset()
+ * @see eina_value_array_insert()
+ * @see eina_value_array_vinsert()
+ * @see eina_value_array_pinsert()
+ * @see eina_value_array_append()
+ * @see eina_value_array_vappend()
+ * @see eina_value_array_pappend()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_pinsert(Eina_Value *value,
+ unsigned int position,
+ const void *ptr) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Append the generic value in an array from pointer.
+ * @param value source value object
+ * @param ptr pointer to specify the contents.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ *
+ * The pointer type is dependent on chosen value type. The list for
+ * basic types:
+ *
+ * @li EINA_VALUE_TYPE_UCHAR: unsigned char*
+ * @li EINA_VALUE_TYPE_USHORT: unsigned short*
+ * @li EINA_VALUE_TYPE_UINT: unsigned int*
+ * @li EINA_VALUE_TYPE_ULONG: unsigned long*
+ * @li EINA_VALUE_TYPE_UINT64: uint64_t*
+ * @li EINA_VALUE_TYPE_CHAR: char*
+ * @li EINA_VALUE_TYPE_SHORT: short*
+ * @li EINA_VALUE_TYPE_INT: int*
+ * @li EINA_VALUE_TYPE_LONG: long*
+ * @li EINA_VALUE_TYPE_INT64: int64_t*
+ * @li EINA_VALUE_TYPE_FLOAT: float*
+ * @li EINA_VALUE_TYPE_DOUBLE: double*
+ * @li EINA_VALUE_TYPE_STRINGSHARE: const char **
+ * @li EINA_VALUE_TYPE_STRING: const char **
+ * @li EINA_VALUE_TYPE_ARRAY: Eina_Value_Array*
+ *
+ * @note the pointer contents are written using the size defined by
+ * type. It can be larger than void* or uint64_t.
+ *
+ * @code
+ * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT);
+ * int x = 1234;
+ *
+ * eina_value_array_pappend(value, &x);
+ * eina_value_array_pget(value, 0, &x);
+ * eina_value_free(value);
+ * @endcode
+ *
+ * @see eina_value_array_set()
+ * @see eina_value_array_get()
+ * @see eina_value_array_vset()
+ * @see eina_value_array_insert()
+ * @see eina_value_array_vinsert()
+ * @see eina_value_array_pinsert()
+ * @see eina_value_array_append()
+ * @see eina_value_array_vappend()
+ * @see eina_value_array_pappend()
+ *
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_array_pappend(Eina_Value *value,
+ const void *ptr) EINA_ARG_NONNULL(1);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Eina_Value_Type_Group Generic Value Type management
+ *
+ * @{
+ */
+
+/**
+ * @struct _Eina_Value_Type
+ * API to access values.
+ *
+ * @since 1.2
+ */
+struct _Eina_Value_Type
+{
+ /**
+ * @def EINA_VALUE_TYPE_VERSION
+ * Current API version, used to validate type.
+ */
+#define EINA_VALUE_TYPE_VERSION (1)
+ unsigned int version; /**< must be #EINA_VALUE_TYPE_VERSION */
+ unsigned int value_size; /**< byte size of value */
+ const char *name; /**< name for debug and introspection */
+ Eina_Bool (*setup)(const Eina_Value_Type *type, void *mem); /**< mem will be malloc(value_size) and should be configured */
+ Eina_Bool (*flush)(const Eina_Value_Type *type, void *mem); /**< clear any values from mem */
+ Eina_Bool (*copy)(const Eina_Value_Type *type, const void *src, void *dst); /**< how to copy values, both memory are @c value_size */
+ int (*compare)(const Eina_Value_Type *type, const void *a, const void *b); /**< how to compare values, both memory are @c value_size */
+ Eina_Bool (*convert_to)(const Eina_Value_Type *type, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem); /**< how to convert values, both memory are @c value_size */
+ Eina_Bool (*convert_from)(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem); /**< how to convert values, both memory are @c value_size */
+ Eina_Bool (*vset)(const Eina_Value_Type *type, void *mem, va_list args); /**< how to set memory from variable argument */
+ Eina_Bool (*pset)(const Eina_Value_Type *type, void *mem, const void *ptr); /**< how to set memory from pointer */
+ Eina_Bool (*pget)(const Eina_Value_Type *type, const void *mem, void *ptr); /**< how to read memory */
+};
+
+/**
+ * @brief Query type name.
+ * @param type type reference.
+ * @return string or @c NULL if type is invalid.
+ * @since 1.2
+ */
+EAPI const char *eina_value_type_name_get(const Eina_Value_Type *type) EINA_PURE EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+/**
+ * @brief Check if type is valid.
+ * @param type type reference.
+ * @return #EINA_TRUE if valid, #EINA_FALSE otherwise.
+ *
+ * A type is invalid if it's NULL or if version field is not the same
+ * as runtime #EINA_VALUE_TYPE_VERSION.
+ *
+ * @since 1.2
+ */
+EAPI Eina_Bool eina_value_type_check(const Eina_Value_Type *type) EINA_PURE EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+/**
+ * @brief Setup memory using type descriptor.
+ * @param type type reference.
+ * @param mem memory to operate, must be of size @c type->value_size.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_type_setup(const Eina_Value_Type *type, void *mem);
+
+/**
+ * @brief Flush (clear) memory using type descriptor.
+ * @param type type reference.
+ * @param mem memory to operate, must be of size @c type->value_size.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_type_flush(const Eina_Value_Type *type, void *mem);
+
+/**
+ * @brief Copy memory using type descriptor.
+ * @param type type reference.
+ * @param src memory to operate, must be of size @c type->value_size.
+ * @param dst memory to operate, must be of size @c type->value_size.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_type_copy(const Eina_Value_Type *type, const void *src, void *dst);
+
+/**
+ * @brief Compare memory using type descriptor.
+ * @param type type reference.
+ * @param a memory to operate, must be of size @c type->value_size.
+ * @param b memory to operate, must be of size @c type->value_size.
+ * @return less than zero if a < b, greater than zero if a > b, zero if equal.
+ * @since 1.2
+ */
+static inline int eina_value_type_compare(const Eina_Value_Type *type, const void *a, void *b);
+
+/**
+ * @brief Convert memory using type descriptor.
+ * @param type type reference of the source.
+ * @param convert type reference of the destination.
+ * @param type_mem memory to operate, must be of size @c type->value_size.
+ * @param convert_mem memory to operate, must be of size @c convert->value_size.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_type_convert_to(const Eina_Value_Type *type, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem);
+
+/**
+ * @brief Convert memory using type descriptor.
+ * @param type type reference of the destination.
+ * @param convert type reference of the source.
+ * @param type_mem memory to operate, must be of size @c type->value_size.
+ * @param convert_mem memory to operate, must be of size @c convert->value_size.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_type_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem);
+
+/**
+ * @brief Set memory using type descriptor and variable argument.
+ * @param type type reference of the source.
+ * @param mem memory to operate, must be of size @c type->value_size.
+ * @param args input value.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_type_vset(const Eina_Value_Type *type, void *mem, va_list args);
+
+/**
+ * @brief Set memory using type descriptor and pointer.
+ * @param type type reference of the source.
+ * @param mem memory to operate, must be of size @c type->value_size.
+ * @param ptr pointer to input value.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_type_pset(const Eina_Value_Type *type, void *mem, const void *ptr);
+
+/**
+ * @brief Get memory using type descriptor.
+ * @param type type reference of the source.
+ * @param mem memory to operate, must be of size @c type->value_size.
+ * @param ptr pointer to output.
+ * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
+ * @since 1.2
+ */
+static inline Eina_Bool eina_value_type_pget(const Eina_Value_Type *type, const void *mem, void *ptr);
+
+/**
+ * @}
+ */
+
+#include "eina_inline_value.x"
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+#endif
}
EAPI Eina_Bool
+eina_inarray_replace_at(Eina_Inarray *array, unsigned int position, const void *data)
+{
+ unsigned char *p;
+
+ EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE);
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(position >= array->len, EINA_FALSE);
+
+ p = _eina_inarray_get(array, position);
+ memcpy(p, data, array->member_size);
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
eina_inarray_remove_at(Eina_Inarray *array, unsigned int position)
{
EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE);
#include "eina_safety_checks.h"
#include "eina_inlist.h"
#include "eina_inarray.h"
+#include "eina_value.h"
/*============================================================================*
* Local *
S(simple_xml);
S(file);
S(prefix);
+ S(value);
#undef S
struct eina_desc_setup
S(quadtree),
S(simple_xml),
S(file),
- S(prefix)
+ S(prefix),
+ S(value)
#undef S
};
static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) /
# include "config.h"
#endif
+/* _GNU_SOURCE: asprintf() */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
#include "eina_config.h"
#include "eina_private.h"
+#include "eina_error.h"
+#include "eina_log.h"
+#include "eina_strbuf.h"
+
+/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
+#include "eina_safety_checks.h"
+#include "eina_value.h"
+
+#include <stdio.h> /* asprintf() */
+#include <inttypes.h> /* PRId64 and PRIu64 */
+
+/*============================================================================*
+* Local *
+*============================================================================*/
+
+/**
+ * @cond LOCAL
+ */
+
+static int _eina_value_log_dom = -1;
+
+#ifdef ERR
+#undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_eina_value_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+#undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_eina_value_log_dom, __VA_ARGS__)
+
+static const unsigned char eina_value_uchar_max = 255U;
+static const char eina_value_char_max = 127;
+static const char eina_value_char_min = -127 - 1;
+
+static const unsigned short eina_value_ushort_max = 65535U;
+static const short eina_value_short_max = 32767;
+static const short eina_value_short_min = -32767 - 1;
+
+static const unsigned int eina_value_uint_max = 4294967295U;
+static const int eina_value_int_max = 2147483647;
+static const int eina_value_int_min = -2147483647 - 1;
+
+static const uint64_t eina_value_uint64_max = 18446744073709551615ULL;
+static const int64_t eina_value_int64_max = 9223372036854775807LL;
+static const int64_t eina_value_int64_min = -9223372036854775807LL - 1LL;
+
+#if __WORDSIZE == 64
+static const unsigned long eina_value_ulong_max = 18446744073709551615ULL;
+static const long eina_value_long_max = 9223372036854775807LL;
+static const long eina_value_long_min = -9223372036854775807LL - 1LL;
+#else
+static const unsigned long eina_value_ulong_max = 4294967295U;
+static const long eina_value_long_max = 2147483647;
+static const long eina_value_long_min = -2147483647 - 1;
+#endif
+
+
+static Eina_Bool
+_eina_value_type_uchar_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ unsigned char *tmem = mem;
+ *tmem = 0;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uchar_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
+{
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uchar_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const unsigned char *s = src;
+ unsigned char *d = dst;
+ *d = *s;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_uchar_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const unsigned char *ta = a, *tb = b;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+}
+
+static Eina_Bool
+_eina_value_type_uchar_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const unsigned char v = *(const unsigned char *)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ const char *other_mem;
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%hhu", v);
+ other_mem = buf; /* required due &buf == buf */
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uchar_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ unsigned char *tmem = mem;
+ *tmem = va_arg(args, unsigned int); /* char is promoted to int for va_arg */
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uchar_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ unsigned char *tmem = mem;
+ const unsigned char *p = ptr;
+ *tmem = *p;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uchar_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ const unsigned char *tmem = mem;
+ unsigned char *p = ptr;
+ *p = *tmem;
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_UCHAR = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(unsigned char),
+ "unsigned char",
+ _eina_value_type_uchar_setup,
+ _eina_value_type_uchar_flush,
+ _eina_value_type_uchar_copy,
+ _eina_value_type_uchar_compare,
+ _eina_value_type_uchar_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_uchar_vset,
+ _eina_value_type_uchar_pset,
+ _eina_value_type_uchar_pget
+};
+
+static Eina_Bool
+_eina_value_type_ushort_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ unsigned short *tmem = mem;
+ *tmem = 0;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_ushort_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
+{
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_ushort_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const unsigned short *s = src;
+ unsigned short *d = dst;
+ *d = *s;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_ushort_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const unsigned short *ta = a, *tb = b;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+}
+
+static Eina_Bool
+_eina_value_type_ushort_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const unsigned short v = *(const unsigned short *)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem = v;
+ if (EINA_UNLIKELY(v > eina_value_uchar_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ const char *other_mem;
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%hu", v);
+ other_mem = buf; /* required due &buf == buf */
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_ushort_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ unsigned short *tmem = mem;
+ *tmem = va_arg(args, unsigned int); /* short is promoted to int for va_arg */
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_ushort_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ unsigned short *tmem = mem;
+ const unsigned short *p = ptr;
+ *tmem = *p;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_ushort_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ const unsigned short *tmem = mem;
+ unsigned short *p = ptr;
+ *p = *tmem;
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_USHORT = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(unsigned short),
+ "unsigned short",
+ _eina_value_type_ushort_setup,
+ _eina_value_type_ushort_flush,
+ _eina_value_type_ushort_copy,
+ _eina_value_type_ushort_compare,
+ _eina_value_type_ushort_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_ushort_vset,
+ _eina_value_type_ushort_pset,
+ _eina_value_type_ushort_pget
+};
+
+static Eina_Bool
+_eina_value_type_uint_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ unsigned int *tmem = mem;
+ *tmem = 0;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uint_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
+{
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uint_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const unsigned int *s = src;
+ unsigned int *d = dst;
+ *d = *s;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_uint_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const unsigned int *ta = a, *tb = b;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+}
+
+static Eina_Bool
+_eina_value_type_uint_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const unsigned int v = *(const unsigned int *)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem = v;
+ if (EINA_UNLIKELY(v > eina_value_uchar_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem = v;
+ if (EINA_UNLIKELY(v > eina_value_ushort_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned int)eina_value_int_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ const char *other_mem;
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%u", v);
+ other_mem = buf; /* required due &buf == buf */
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uint_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ unsigned int *tmem = mem;
+ *tmem = va_arg(args, unsigned int);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uint_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ unsigned int *tmem = mem;
+ const unsigned int *p = ptr;
+ *tmem = *p;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uint_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ const unsigned int *tmem = mem;
+ unsigned int *p = ptr;
+ *p = *tmem;
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_UINT = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(unsigned int),
+ "unsigned int",
+ _eina_value_type_uint_setup,
+ _eina_value_type_uint_flush,
+ _eina_value_type_uint_copy,
+ _eina_value_type_uint_compare,
+ _eina_value_type_uint_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_uint_vset,
+ _eina_value_type_uint_pset,
+ _eina_value_type_uint_pget
+};
+
+static Eina_Bool
+_eina_value_type_ulong_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ unsigned long *tmem = mem;
+ *tmem = 0;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_ulong_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
+{
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_ulong_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const unsigned long *s = src;
+ unsigned long *d = dst;
+ *d = *s;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_ulong_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const unsigned long *ta = a, *tb = b;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+}
+
+static Eina_Bool
+_eina_value_type_ulong_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const unsigned long v = *(const unsigned long *)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem = v;
+ if (EINA_UNLIKELY(v > eina_value_uchar_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem = v;
+ if (EINA_UNLIKELY(v > eina_value_ushort_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem = v;
+ if (EINA_UNLIKELY(v > eina_value_uint_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned int)eina_value_int_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned long)eina_value_long_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ const char *other_mem;
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%lu", v);
+ other_mem = buf; /* required due &buf == buf */
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_ulong_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ unsigned long *tmem = mem;
+ *tmem = va_arg(args, unsigned long);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_ulong_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ unsigned long *tmem = mem;
+ const unsigned long *p = ptr;
+ *tmem = *p;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_ulong_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ const unsigned long *tmem = mem;
+ unsigned long *p = ptr;
+ *p = *tmem;
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_ULONG = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(unsigned long),
+ "unsigned long",
+ _eina_value_type_ulong_setup,
+ _eina_value_type_ulong_flush,
+ _eina_value_type_ulong_copy,
+ _eina_value_type_ulong_compare,
+ _eina_value_type_ulong_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_ulong_vset,
+ _eina_value_type_ulong_pset,
+ _eina_value_type_ulong_pget
+};
+
+
+static Eina_Bool
+_eina_value_type_uint64_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ uint64_t *tmem = mem;
+ *tmem = 0;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uint64_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
+{
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uint64_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const uint64_t *s = src;
+ uint64_t *d = dst;
+ *d = *s;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_uint64_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const uint64_t *ta = a, *tb = b;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+}
+
+static Eina_Bool
+_eina_value_type_uint64_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const uint64_t v = *(const uint64_t *)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem = v;
+ if (EINA_UNLIKELY(v > eina_value_uchar_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem = v;
+ if (EINA_UNLIKELY(v > eina_value_ushort_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem = v;
+ if (EINA_UNLIKELY(v > eina_value_uint_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem = v;
+ if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) &&
+ (v > eina_value_ulong_max)))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned int)eina_value_int_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem = v;
+ if (EINA_UNLIKELY(v > (unsigned long)eina_value_long_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem = v;
+ if (EINA_UNLIKELY(v > (uint64_t)eina_value_int64_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ const char *other_mem;
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%"PRIu64, v);
+ other_mem = buf; /* required due &buf == buf */
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uint64_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ uint64_t *tmem = mem;
+ *tmem = va_arg(args, uint64_t);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uint64_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ uint64_t *tmem = mem;
+ const uint64_t *p = ptr;
+ *tmem = *p;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_uint64_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ const uint64_t *tmem = mem;
+ uint64_t *p = ptr;
+ *p = *tmem;
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_UINT64 = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(uint64_t),
+ "uint64_t",
+ _eina_value_type_uint64_setup,
+ _eina_value_type_uint64_flush,
+ _eina_value_type_uint64_copy,
+ _eina_value_type_uint64_compare,
+ _eina_value_type_uint64_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_uint64_vset,
+ _eina_value_type_uint64_pset,
+ _eina_value_type_uint64_pget
+};
+
+static Eina_Bool
+_eina_value_type_char_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ char *tmem = mem;
+ *tmem = 0;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_char_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
+{
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_char_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const char *s = src;
+ char *d = dst;
+ *d = *s;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_char_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const char *ta = a, *tb = b;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+}
+
+static Eina_Bool
+_eina_value_type_char_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const char v = *(const char *)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ const char *other_mem;
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%hhd", v);
+ other_mem = buf; /* required due &buf == buf */
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_char_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ char *tmem = mem;
+ *tmem = va_arg(args, int); /* char is promoted to int for va_arg */
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_char_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ char *tmem = mem;
+ const char *p = ptr;
+ *tmem = *p;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_char_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ const char *tmem = mem;
+ char *p = ptr;
+ *p = *tmem;
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_CHAR = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(char),
+ "char",
+ _eina_value_type_char_setup,
+ _eina_value_type_char_flush,
+ _eina_value_type_char_copy,
+ _eina_value_type_char_compare,
+ _eina_value_type_char_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_char_vset,
+ _eina_value_type_char_pset,
+ _eina_value_type_char_pget
+};
+
+static Eina_Bool
+_eina_value_type_short_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ short *tmem = mem;
+ *tmem = 0;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_short_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
+{
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_short_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const short *s = src;
+ short *d = dst;
+ *d = *s;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_short_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const short *ta = a, *tb = b;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+}
+
+static Eina_Bool
+_eina_value_type_short_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const short v = *(const short *)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_uchar_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_char_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_char_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ const char *other_mem;
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%hd", v);
+ other_mem = buf; /* required due &buf == buf */
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_short_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ short *tmem = mem;
+ *tmem = va_arg(args, int); /* short int is promoted to int for va_arg */
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_short_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ short *tmem = mem;
+ const short *p = ptr;
+ *tmem = *p;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_short_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ const short *tmem = mem;
+ short *p = ptr;
+ *p = *tmem;
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_SHORT = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(short),
+ "short",
+ _eina_value_type_short_setup,
+ _eina_value_type_short_flush,
+ _eina_value_type_short_copy,
+ _eina_value_type_short_compare,
+ _eina_value_type_short_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_short_vset,
+ _eina_value_type_short_pset,
+ _eina_value_type_short_pget
+};
+
+static Eina_Bool
+_eina_value_type_int_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ int *tmem = mem;
+ *tmem = 0;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_int_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
+{
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_int_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const int *s = src;
+ int *d = dst;
+ *d = *s;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_int_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const int *ta = a, *tb = b;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+}
+
+static Eina_Bool
+_eina_value_type_int_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const int v = *(const int *)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_uchar_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_ushort_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_char_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_char_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_short_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_short_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ const char *other_mem;
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%d", v);
+ other_mem = buf; /* required due &buf == buf */
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_int_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ int *tmem = mem;
+ *tmem = va_arg(args, int);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_int_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ int *tmem = mem;
+ const int *p = ptr;
+ *tmem = *p;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_int_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ const int *tmem = mem;
+ int *p = ptr;
+ *p = *tmem;
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_INT = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(int),
+ "int",
+ _eina_value_type_int_setup,
+ _eina_value_type_int_flush,
+ _eina_value_type_int_copy,
+ _eina_value_type_int_compare,
+ _eina_value_type_int_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_int_vset,
+ _eina_value_type_int_pset,
+ _eina_value_type_int_pget
+};
+
+static Eina_Bool
+_eina_value_type_long_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ long *tmem = mem;
+ *tmem = 0;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_long_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
+{
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_long_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const long *s = src;
+ long *d = dst;
+ *d = *s;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_long_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const long *ta = a, *tb = b;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+}
+
+static Eina_Bool
+_eina_value_type_long_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const long v = *(const long *)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_uchar_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_ushort_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_uint_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_char_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_char_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_short_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_short_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_int_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_int_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ const char *other_mem;
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%ld", v);
+ other_mem = buf; /* required due &buf == buf */
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_long_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ long *tmem = mem;
+ *tmem = va_arg(args, long);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_long_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ long *tmem = mem;
+ const long *p = ptr;
+ *tmem = *p;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_long_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ const long *tmem = mem;
+ long *p = ptr;
+ *p = *tmem;
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_LONG = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(long),
+ "long",
+ _eina_value_type_long_setup,
+ _eina_value_type_long_flush,
+ _eina_value_type_long_copy,
+ _eina_value_type_long_compare,
+ _eina_value_type_long_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_long_vset,
+ _eina_value_type_long_pset,
+ _eina_value_type_long_pget
+};
+
+static Eina_Bool
+_eina_value_type_int64_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ int64_t *tmem = mem;
+ *tmem = 0;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_int64_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
+{
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_int64_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const int64_t *s = src;
+ int64_t *d = dst;
+ *d = *s;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_int64_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const int64_t *ta = a, *tb = b;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+}
+
+static Eina_Bool
+_eina_value_type_int64_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const int64_t v = *(const int64_t *)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_uchar_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_ushort_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_uint_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) &&
+ (v > eina_value_ulong_max)))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_char_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_char_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_short_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_short_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_int_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_int_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_long_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_long_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ const char *other_mem;
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%"PRId64, v);
+ other_mem = buf; /* required due &buf == buf */
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_int64_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ int64_t *tmem = mem;
+ *tmem = va_arg(args, int64_t);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_int64_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ int64_t *tmem = mem;
+ const int64_t *p = ptr;
+ *tmem = *p;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_int64_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ const int64_t *tmem = mem;
+ int64_t *p = ptr;
+ *p = *tmem;
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_INT64 = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(int64_t),
+ "int64_t",
+ _eina_value_type_int64_setup,
+ _eina_value_type_int64_flush,
+ _eina_value_type_int64_copy,
+ _eina_value_type_int64_compare,
+ _eina_value_type_int64_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_int64_vset,
+ _eina_value_type_int64_pset,
+ _eina_value_type_int64_pget
+};
+
+static Eina_Bool
+_eina_value_type_float_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ float *tmem = mem;
+ *tmem = 0;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_float_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
+{
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_float_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const float *s = src;
+ float *d = dst;
+ *d = *s;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_float_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const float *ta = a, *tb = b;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+}
+
+static Eina_Bool
+_eina_value_type_float_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const float v = *(const float *)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_uchar_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_ushort_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_uint_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) &&
+ (v > eina_value_ulong_max)))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_uint64_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_char_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_char_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_short_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_short_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_int_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_int_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_long_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_long_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_int64_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_int64_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ const char *other_mem;
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%f", v);
+ other_mem = buf; /* required due &buf == buf */
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_float_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ float *tmem = mem;
+ *tmem = va_arg(args, double); /* float is promoted to double for va_args */
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_float_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ float *tmem = mem;
+ const float *p = ptr;
+ *tmem = *p;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_float_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ const float *tmem = mem;
+ float *p = ptr;
+ *p = *tmem;
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_FLOAT = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(float),
+ "float",
+ _eina_value_type_float_setup,
+ _eina_value_type_float_flush,
+ _eina_value_type_float_copy,
+ _eina_value_type_float_compare,
+ _eina_value_type_float_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_float_vset,
+ _eina_value_type_float_pset,
+ _eina_value_type_float_pget
+};
+
+static Eina_Bool
+_eina_value_type_double_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ double *tmem = mem;
+ *tmem = 0;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_double_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
+{
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_double_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const double *s = src;
+ double *d = dst;
+ *d = *s;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_double_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const double *ta = a, *tb = b;
+ if (*ta < *tb)
+ return -1;
+ else if (*ta > *tb)
+ return 1;
+ return 0;
+}
+
+static Eina_Bool
+_eina_value_type_double_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const double v = *(const double *)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_uchar_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_ushort_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_uint_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) &&
+ (v > eina_value_ulong_max)))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem = v;
+ if (EINA_UNLIKELY(v < 0))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_char_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_char_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_short_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_short_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_int_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_int_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem = v;
+ if (EINA_UNLIKELY(v < eina_value_long_min))
+ return EINA_FALSE;
+ if (EINA_UNLIKELY(v > eina_value_long_max))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem = v;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ const char *other_mem;
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%g", (double)v);
+ other_mem = buf; /* required due &buf == buf */
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_double_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ double *tmem = mem;
+ *tmem = va_arg(args, double);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_double_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ double *tmem = mem;
+ const double *p = ptr;
+ *tmem = *p;
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_double_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ const double *tmem = mem;
+ double *p = ptr;
+ *p = *tmem;
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_DOUBLE = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(double),
+ "double",
+ _eina_value_type_double_setup,
+ _eina_value_type_double_flush,
+ _eina_value_type_double_copy,
+ _eina_value_type_double_compare,
+ _eina_value_type_double_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_double_vset,
+ _eina_value_type_double_pset,
+ _eina_value_type_double_pget
+};
+
+static Eina_Bool
+_eina_value_type_string_common_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ const char **tmem = mem;
+ *tmem = NULL;
+ return EINA_TRUE;
+}
+
+static int
+_eina_value_type_string_common_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const char *sa = *(const char **)a;
+ const char *sb = *(const char **)b;
+ if (sa == sb)
+ return 0;
+ if (sa == NULL)
+ return -1;
+ if (sb == NULL)
+ return 1;
+ return strcmp(sa, sb);
+}
+
+static Eina_Bool
+_eina_value_type_string_common_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const char *v = *(const char **)type_mem;
+
+ eina_error_set(0);
+
+ if (convert == EINA_VALUE_TYPE_UCHAR)
+ {
+ unsigned char other_mem;
+ if ((sscanf(v, "%hhu", &other_mem) != 1) &&
+ (sscanf(v, "%hhx", &other_mem) != 1) &&
+ (sscanf(v, "%hho", &other_mem) != 1))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_USHORT)
+ {
+ unsigned short other_mem;
+ if ((sscanf(v, "%hu", &other_mem) != 1) &&
+ (sscanf(v, "%hx", &other_mem) != 1) &&
+ (sscanf(v, "%ho", &other_mem) != 1))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT)
+ {
+ unsigned int other_mem;
+ if ((sscanf(v, "%u", &other_mem) != 1) &&
+ (sscanf(v, "%x", &other_mem) != 1) &&
+ (sscanf(v, "%o", &other_mem) != 1))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_ULONG)
+ {
+ unsigned long other_mem;
+ if ((sscanf(v, "%lu", &other_mem) != 1) &&
+ (sscanf(v, "%lx", &other_mem) != 1) &&
+ (sscanf(v, "%lo", &other_mem) != 1))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_UINT64)
+ {
+ uint64_t other_mem;
+ if ((sscanf(v, "%"SCNu64, &other_mem) != 1) &&
+ (sscanf(v, "%"SCNx64, &other_mem) != 1) &&
+ (sscanf(v, "%"SCNo64, &other_mem) != 1))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_CHAR)
+ {
+ char other_mem;
+ if ((sscanf(v, "%hhd", &other_mem) != 1) &&
+ (sscanf(v, "%hhx", &other_mem) != 1) &&
+ (sscanf(v, "%hho", &other_mem) != 1))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_SHORT)
+ {
+ short other_mem;
+ if ((sscanf(v, "%hd", &other_mem) != 1) &&
+ (sscanf(v, "%hx", &other_mem) != 1) &&
+ (sscanf(v, "%ho", &other_mem) != 1))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT)
+ {
+ int other_mem;
+ if ((sscanf(v, "%d", &other_mem) != 1) &&
+ (sscanf(v, "%x", &other_mem) != 1) &&
+ (sscanf(v, "%o", &other_mem) != 1))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_LONG)
+ {
+ long other_mem;
+ if ((sscanf(v, "%ld", &other_mem) != 1) &&
+ (sscanf(v, "%lx", &other_mem) != 1) &&
+ (sscanf(v, "%lo", &other_mem) != 1))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_INT64)
+ {
+ int64_t other_mem;
+ if ((sscanf(v, "%"SCNd64, &other_mem) != 1) &&
+ (sscanf(v, "%"SCNx64, &other_mem) != 1) &&
+ (sscanf(v, "%"SCNo64, &other_mem) != 1))
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_FLOAT)
+ {
+ float other_mem;
+ if (sscanf(v, "%f", &other_mem) != 1)
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_DOUBLE)
+ {
+ double other_mem;
+ if (sscanf(v, "%lf", &other_mem) != 1)
+ return EINA_FALSE;
+ return eina_value_type_pset(convert, convert_mem, &other_mem);
+ }
+ else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
+ convert == EINA_VALUE_TYPE_STRING)
+ {
+ return eina_value_type_pset(convert, convert_mem, &v);
+ }
+ else
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_string_common_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ memcpy(ptr, mem, sizeof(const char *));
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_stringshare_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ const char **tmem = mem;
+ if (*tmem) eina_stringshare_del(*tmem);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_stringshare_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const char * const*s = src;
+ const char **d = dst;
+ *d = *s;
+ eina_stringshare_ref(*d);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_stringshare_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ const char *str = va_arg(args, const char *);
+ return eina_stringshare_replace((const char **)mem, str);
+}
+
+static Eina_Bool
+_eina_value_type_stringshare_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ const char * const *str = ptr;
+ return eina_stringshare_replace((const char **)mem, *str);
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_STRINGSHARE = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(const char *),
+ "stringshare",
+ _eina_value_type_string_common_setup,
+ _eina_value_type_stringshare_flush,
+ _eina_value_type_stringshare_copy,
+ _eina_value_type_string_common_compare,
+ _eina_value_type_string_common_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_stringshare_vset,
+ _eina_value_type_stringshare_pset,
+ _eina_value_type_string_common_pget
+};
+
+static Eina_Bool
+_eina_value_type_string_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ char **tmem = mem;
+ if (*tmem) free(*tmem);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_string_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const char * const *s = src;
+ char **d = dst;
+ if (*s == NULL)
+ *d = NULL;
+ else
+ {
+ *d = strdup(*s);
+ if (*d == NULL)
+ {
+ eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
+ return EINA_FALSE;
+ }
+ }
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_string_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
+{
+ char **tmem = mem;
+ const char *str = va_arg(args, const char *);
+ free(*tmem);
+ if (str == NULL)
+ *tmem = NULL;
+ else
+ {
+ *tmem = strdup(str);
+ if (*tmem == NULL)
+ {
+ eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
+ return EINA_FALSE;
+ }
+ }
+ eina_error_set(0);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_string_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ char **tmem = mem;
+ const char * const *str = ptr;
+ free(*tmem);
+ if (*str == NULL)
+ *tmem = NULL;
+ else
+ {
+ *tmem = strdup(*str);
+ if (*tmem == NULL)
+ {
+ eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
+ return EINA_FALSE;
+ }
+ }
+ eina_error_set(0);
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_STRING = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(char *),
+ "string",
+ _eina_value_type_string_common_setup,
+ _eina_value_type_string_flush,
+ _eina_value_type_string_copy,
+ _eina_value_type_string_common_compare,
+ _eina_value_type_string_common_convert_to,
+ NULL, /* no convert from */
+ _eina_value_type_string_vset,
+ _eina_value_type_string_pset,
+ _eina_value_type_string_common_pget
+};
+
+
+static Eina_Bool
+_eina_value_type_array_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ memset(mem, 0, sizeof(Eina_Value_Array));
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_array_flush_elements(Eina_Value_Array *tmem)
+{
+ const Eina_Value_Type *subtype = tmem->subtype;
+ Eina_Bool ret = EINA_TRUE;
+ unsigned char sz;
+ char *ptr, *ptr_end;
+
+ if (!tmem->array) return EINA_TRUE;
+
+ sz = tmem->array->member_size;
+ ptr = tmem->array->members;
+ ptr_end = ptr + tmem->array->len * sz;
+
+ for (; ptr < ptr_end; ptr += sz)
+ ret &= eina_value_type_flush(subtype, ptr);
+
+ eina_inarray_flush(tmem->array);
+ return ret;
+}
+
+static Eina_Bool
+_eina_value_type_array_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
+{
+ Eina_Value_Array *tmem = mem;
+ Eina_Bool ret =_eina_value_type_array_flush_elements(tmem);
+
+ if (tmem->array) eina_inarray_free(tmem->array);
+ tmem->array = NULL;
+ tmem->subtype = NULL;
+ return ret;
+}
+
+static Eina_Bool
+_eina_value_type_array_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
+{
+ const Eina_Value_Type *subtype;
+ const Eina_Value_Array *s = src;
+ Eina_Value_Array *d = dst;
+ unsigned int count, sz;
+ char *placeholder, *ptr, *ptr_end;
+
+ d->subtype = subtype = s->subtype;
+ d->step = s->step;
+
+ if ((!s->array) || (!s->subtype))
+ {
+ d->array = NULL;
+ return EINA_TRUE;
+ }
+
+ if (!subtype->copy)
+ return EINA_FALSE;
+
+ d->array = eina_inarray_new(subtype->value_size, s->step);
+ if (!d->array)
+ return EINA_FALSE;
+
+ sz = s->array->member_size;
+ placeholder = alloca(sz);
+ memset(placeholder, 0, sz);
+
+ count = eina_inarray_count(s->array);
+ ptr = s->array->members;
+ ptr_end = ptr + (count * sz);
+
+ for (; ptr < ptr_end; ptr += sz)
+ {
+ int i = eina_inarray_append(d->array, placeholder);
+ void *imem = eina_inarray_nth(d->array, i);
+ if ((i < 0) || (!imem)) goto error;
+ if (!subtype->copy(subtype, ptr, imem)) goto error;
+ }
+
+ return EINA_TRUE;
+
+ error:
+ _eina_value_type_array_flush_elements(d);
+ return EINA_FALSE;
+}
+
+static int
+_eina_value_type_array_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
+{
+ const Eina_Value_Type *subtype;
+ const Eina_Value_Array *eva_a = a, *eva_b = b;
+ const char *a_ptr, *a_ptr_end, *b_ptr;
+ unsigned int count_a, count_b, count, sz;
+ int cmp = 0;
+
+ if (eva_a->subtype != eva_b->subtype)
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return -1;
+ }
+
+ subtype = eva_a->subtype;
+ if (!subtype->compare)
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return 0;
+ }
+
+ if ((!eva_a->array) && (!eva_b->array))
+ return 0;
+ else if (!eva_a->array)
+ return -1;
+ else if (!eva_b->array)
+ return 1;
+
+ count_a = eina_inarray_count(eva_a->array);
+ count_b = eina_inarray_count(eva_b->array);
+
+ if (count_a <= count_b)
+ count = count_a;
+ else
+ count = count_b;
+
+ sz = eva_a->array->member_size;
+
+ a_ptr = eva_a->array->members;
+ a_ptr_end = a_ptr + (count * sz);
+ b_ptr = eva_b->array->members;
+
+ for (; (cmp == 0) && (a_ptr < a_ptr_end); a_ptr += sz, b_ptr += sz)
+ cmp = subtype->compare(subtype, a_ptr, b_ptr);
+
+ if (cmp == 0)
+ {
+ if (count_a < count_b)
+ return -1;
+ else if (count_a > count_b)
+ return 1;
+ return 0;
+ }
+
+ return cmp;
+}
+
+static Eina_Bool
+_eina_value_type_array_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
+{
+ const Eina_Value_Array *tmem = type_mem;
+ Eina_Bool ret = EINA_FALSE;
+
+ if ((tmem->array) && (tmem->array->len == 1))
+ {
+ const Eina_Value_Type *subtype = tmem->subtype;
+ void *imem = tmem->array->members;
+
+ if (subtype->convert_to)
+ ret = subtype->convert_to(subtype, convert, imem, convert_mem);
+ if ((!ret) && (convert->convert_from))
+ ret = convert->convert_from(convert, subtype, convert_mem, imem);
+ }
+ else if ((convert == EINA_VALUE_TYPE_STRING) ||
+ (convert == EINA_VALUE_TYPE_STRINGSHARE))
+ {
+ Eina_Strbuf *str = eina_strbuf_new();
+ if (!tmem->array) eina_strbuf_append(str, "[]");
+ else
+ {
+ const Eina_Value_Type *subtype = tmem->subtype;
+ unsigned char sz;
+ const char *ptr, *ptr_end;
+ Eina_Value tmp;
+ Eina_Bool first = EINA_TRUE;
+
+ eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING);
+
+ eina_strbuf_append_char(str, '[');
+
+ sz = tmem->array->member_size;
+ ptr = tmem->array->members;
+ ptr_end = ptr + tmem->array->len * sz;
+ for (; ptr < ptr_end; ptr += sz)
+ {
+ Eina_Bool r = EINA_FALSE;
+ if (subtype->convert_to)
+ {
+ r = subtype->convert_to(subtype, EINA_VALUE_TYPE_STRING,
+ ptr, tmp.value.buf);
+ if (r)
+ {
+ if (first) first = EINA_FALSE;
+ else eina_strbuf_append_length(str, ", ", 2);
+ eina_strbuf_append(str, tmp.value.ptr);
+ free(tmp.value.ptr);
+ tmp.value.ptr = NULL;
+ }
+ }
+
+ if (!r)
+ {
+ if (first)
+ {
+ first = EINA_FALSE;
+ eina_strbuf_append_char(str, '?');
+ }
+ else
+ eina_strbuf_append_length(str, ", ?", 3);
+ }
+ }
+
+ eina_strbuf_append_char(str, ']');
+ ptr = eina_strbuf_string_get(str);
+ ret = eina_value_type_pset(convert, convert_mem, &ptr);
+ eina_strbuf_free(str);
+ }
+ }
+
+ if (!ret)
+ {
+ eina_error_set(EINA_ERROR_VALUE_FAILED);
+ return EINA_FALSE;
+ }
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_array_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem)
+{
+ Eina_Value_Array *tmem = type_mem;
+ Eina_Value_Array desc = {convert, tmem->step, NULL};
+ char *buf, *placeholder;
+ void *imem;
+
+ if (!eina_value_type_pset(type, tmem, &desc))
+ return EINA_FALSE;
+
+ buf = alloca(convert->value_size);
+ if (!eina_value_type_pget(convert, convert_mem, &buf))
+ return EINA_FALSE;
+
+ placeholder = alloca(convert->value_size);
+ memset(placeholder, 0, convert->value_size);
+
+ if (eina_inarray_append(tmem->array, placeholder) != 0)
+ return EINA_FALSE;
+ imem = eina_inarray_nth(tmem->array, 0);
+ if (!imem)
+ return EINA_FALSE;
+
+ if (!eina_value_type_setup(convert, imem)) goto error_setup;
+ if (!eina_value_type_pset(convert, imem, &buf)) goto error_set;
+ return EINA_TRUE;
+
+ error_set:
+ eina_value_type_flush(convert, imem);
+ error_setup:
+ eina_inarray_remove_at(tmem->array, 0);
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+_eina_value_type_array_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
+{
+ Eina_Value_Array *tmem = mem;
+ const Eina_Value_Array *desc = ptr;
+
+ if ((!tmem->subtype) && (!desc->subtype))
+ return EINA_TRUE;
+
+ if (tmem->array)
+ {
+ _eina_value_type_array_flush_elements(tmem);
+ eina_inarray_setup(tmem->array, desc->subtype->value_size, desc->step);
+ }
+ else
+ {
+ tmem->array = eina_inarray_new(desc->subtype->value_size, desc->step);
+ if (!tmem->array)
+ return EINA_FALSE;
+ }
+
+ tmem->subtype = desc->subtype;
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_array_vset(const Eina_Value_Type *type, void *mem, va_list args)
+{
+ const Eina_Value_Array desc = va_arg(args, Eina_Value_Array);
+ _eina_value_type_array_pset(type, mem, &desc);
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_eina_value_type_array_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
+{
+ memcpy(ptr, mem, sizeof(Eina_Value_Array));
+ return EINA_TRUE;
+}
+
+static const Eina_Value_Type _EINA_VALUE_TYPE_ARRAY = {
+ EINA_VALUE_TYPE_VERSION,
+ sizeof(Eina_Value_Array),
+ "Eina_Value_Array",
+ _eina_value_type_array_setup,
+ _eina_value_type_array_flush,
+ _eina_value_type_array_copy,
+ _eina_value_type_array_compare,
+ _eina_value_type_array_convert_to,
+ _eina_value_type_array_convert_from,
+ _eina_value_type_array_vset,
+ _eina_value_type_array_pset,
+ _eina_value_type_array_pget
+};
+
+
+/**
+ * @endcond
+ */
+
+static const char EINA_ERROR_VALUE_FAILED_STR[] = "Value check failed.";
+
+/**
+ * @internal
+ * @brief Initialize the value module.
+ *
+ * @return #EINA_TRUE on success, #EINA_FALSE on failure.
+ *
+ * This function sets up the value module of Eina. It is called
+ * by eina_init().
+ *
+ * @see eina_init()
+ */
+Eina_Bool
+eina_value_init(void)
+{
+ _eina_value_log_dom = eina_log_domain_register("eina_value",
+ EINA_LOG_COLOR_DEFAULT);
+ if (_eina_value_log_dom < 0)
+ {
+ EINA_LOG_ERR("Could not register log domain: eina_value");
+ return EINA_FALSE;
+ }
+
+ EINA_ERROR_VALUE_FAILED = eina_error_msg_static_register(
+ EINA_ERROR_VALUE_FAILED_STR);
+
+ EINA_VALUE_TYPE_UCHAR = &_EINA_VALUE_TYPE_UCHAR;
+ EINA_VALUE_TYPE_USHORT = &_EINA_VALUE_TYPE_USHORT;
+ EINA_VALUE_TYPE_UINT = &_EINA_VALUE_TYPE_UINT;
+ EINA_VALUE_TYPE_ULONG = &_EINA_VALUE_TYPE_ULONG;
+ EINA_VALUE_TYPE_UINT64 = &_EINA_VALUE_TYPE_UINT64;
+ EINA_VALUE_TYPE_CHAR = &_EINA_VALUE_TYPE_CHAR;
+ EINA_VALUE_TYPE_SHORT = &_EINA_VALUE_TYPE_SHORT;
+ EINA_VALUE_TYPE_INT = &_EINA_VALUE_TYPE_INT;
+ EINA_VALUE_TYPE_LONG = &_EINA_VALUE_TYPE_LONG;
+ EINA_VALUE_TYPE_INT64 = &_EINA_VALUE_TYPE_INT64;
+ EINA_VALUE_TYPE_FLOAT = &_EINA_VALUE_TYPE_FLOAT;
+ EINA_VALUE_TYPE_DOUBLE = &_EINA_VALUE_TYPE_DOUBLE;
+ EINA_VALUE_TYPE_STRINGSHARE = &_EINA_VALUE_TYPE_STRINGSHARE;
+ EINA_VALUE_TYPE_STRING = &_EINA_VALUE_TYPE_STRING;
+ EINA_VALUE_TYPE_ARRAY = &_EINA_VALUE_TYPE_ARRAY;
+
+ return EINA_TRUE;
+}
+
+/**
+ * @internal
+ * @brief Shut down the value module.
+ *
+ * @return #EINA_TRUE on success, #EINA_FALSE on failure.
+ *
+ * This function shuts down the value module set up by
+ * eina_value_init(). It is called by eina_shutdown().
+ *
+ * @see eina_shutdown()
+ */
+Eina_Bool
+eina_value_shutdown(void)
+{
+ eina_log_domain_unregister(_eina_value_log_dom);
+ _eina_value_log_dom = -1;
+ return EINA_TRUE;
+}
/*============================================================================*
* Global *
* API *
*============================================================================*/
+EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_UCHAR;
+
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UCHAR = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_USHORT = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ULONG = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT64 = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_CHAR = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_SHORT = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_INT = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_LONG = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_INT64 = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_FLOAT = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_DOUBLE = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRINGSHARE = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRING = NULL;
+EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ARRAY = NULL;
+
+EAPI Eina_Error EINA_ERROR_VALUE_FAILED = 0;
+
EAPI const unsigned int eina_prime_table[] =
{
17, 31, 61, 127, 257, 509, 1021,
2053, 4093, 8191, 16381, 32771, 65537, 131071, 262147, 524287, 1048573,
2097143, 4194301, 8388617, 16777213
};
+
+EAPI Eina_Value *
+eina_value_new(const Eina_Value_Type *type)
+{
+ Eina_Value *value = malloc(sizeof(Eina_Value));
+ if (!value)
+ {
+ eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
+ return NULL;
+ }
+ if (!eina_value_setup(value, type))
+ {
+ free(value);
+ return NULL;
+ }
+ return value;
+}
+
+EAPI void
+eina_value_free(Eina_Value *value)
+{
+ EINA_SAFETY_ON_NULL_RETURN(value);
+ eina_value_flush(value);
+ free(value);
+}
+
+
+EAPI Eina_Bool
+eina_value_copy(const Eina_Value *value, Eina_Value *copy)
+{
+ const Eina_Value_Type *type;
+ const void *src;
+ void *dst;
+ Eina_Bool ret;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type),
+ EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(copy, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(value->type->copy, EINA_FALSE);
+
+ type = value->type;
+ if (!eina_value_setup(copy, type))
+ return EINA_FALSE;
+
+ src = eina_value_memory_get(value);
+ dst = eina_value_memory_get(copy);
+ ret = type->copy(type, src, dst);
+ if (!ret)
+ eina_value_flush(copy);
+
+ return ret;
+}
+
+EAPI Eina_Bool
+eina_value_convert(const Eina_Value *value, Eina_Value *convert)
+{
+ Eina_Bool ret = EINA_FALSE;
+ const Eina_Value_Type *type, *convert_type;
+ const void *type_mem;
+ void *convert_mem;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(convert, EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type),
+ EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(convert->type),
+ EINA_FALSE);
+
+ type = value->type;
+ convert_type = convert->type;
+
+ type_mem = eina_value_memory_get(value);
+ convert_mem = eina_value_memory_get(convert);
+
+ if (type->convert_to)
+ ret = type->convert_to(type, convert_type, type_mem, convert_mem);
+
+ if ((!ret) && (convert_type->convert_from))
+ ret = convert_type->convert_from(convert_type, type, convert_mem,
+ type_mem);
+
+ return ret;
+}
+
+EAPI char *
+eina_value_to_string(const Eina_Value *value)
+{
+ Eina_Value tmp;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(value, NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), NULL);
+
+ if (!eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING))
+ return NULL;
+ if (!eina_value_convert(value, &tmp))
+ return NULL;
+
+ return tmp.value.ptr; /* steal value */
+}
+
+EAPI Eina_Value *
+eina_value_array_new(const Eina_Value_Type *subtype, unsigned int step)
+{
+ Eina_Value *value;
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(subtype), EINA_FALSE);
+
+ value = calloc(1, sizeof(Eina_Value));
+ if (!value)
+ return NULL;
+
+ if (!eina_value_array_setup(value, subtype, step))
+ {
+ free(value);
+ return NULL;
+ }
+
+ return value;
+}
+
+EAPI Eina_Bool
+eina_value_type_check(const Eina_Value_Type *type)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE);
+ return type->version == EINA_VALUE_TYPE_VERSION;
+}
+
+EAPI const char *
+eina_value_type_name_get(const Eina_Value_Type *type)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), NULL);
+ return type->name;
+}
eina_test_strbuf.c \
eina_test_str.c \
eina_test_quadtree.c \
-eina_test_simple_xml_parser.c
+eina_test_simple_xml_parser.c \
+eina_test_value.c
eina_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libeina.la -lm
{ "QuadTree", eina_test_quadtree },
{ "Sched", eina_test_sched },
{ "Simple Xml Parser", eina_test_simple_xml_parser},
+ { "Value", eina_test_value },
{ NULL, NULL }
};
void eina_test_fp(TCase *tc);
void eina_test_sched(TCase *tc);
void eina_test_simple_xml_parser(TCase *tc);
+void eina_test_value(TCase *tc);
#endif /* EINA_SUITE_H_ */
--- /dev/null
+/* EINA - EFL data type library
+ * Copyright (C) 2012 ProFUSION embedded systems
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "eina_suite.h"
+#include "Eina.h"
+
+#define FP_ERR (0.0000001)
+#define CHECK_FP(a, b) ((a - b) < FP_ERR)
+
+START_TEST(eina_value_test_simple)
+{
+ Eina_Value *value;
+ char c;
+ short s;
+ int i;
+ long l;
+ int64_t i64;
+ unsigned char uc;
+ unsigned short us;
+ unsigned int ui;
+ unsigned long ul;
+ uint64_t u64;
+ float f;
+ double d;
+
+ eina_init();
+
+ value = eina_value_new(EINA_VALUE_TYPE_CHAR);
+ fail_unless(value != NULL);
+ fail_unless(eina_value_set(value, 'x'));
+ fail_unless(eina_value_get(value, &c));
+ fail_unless(c == 'x');
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_SHORT));
+ fail_unless(eina_value_set(value, 300));
+ fail_unless(eina_value_get(value, &s));
+ fail_unless(s == 300);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_INT));
+ fail_unless(eina_value_set(value, -12345));
+ fail_unless(eina_value_get(value, &i));
+ fail_unless(i == -12345);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_LONG));
+ fail_unless(eina_value_set(value, 0xb33f));
+ fail_unless(eina_value_get(value, &l));
+ fail_unless(l == 0xb33f);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_INT64));
+ fail_unless(eina_value_set(value, 0x0011223344556677));
+ fail_unless(eina_value_get(value, &i64));
+ fail_unless(i64 == 0x0011223344556677);
+ eina_value_flush(value);
+
+ /* unsigned: */
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UCHAR));
+ fail_unless(eina_value_set(value, 200));
+ fail_unless(eina_value_get(value, &uc));
+ fail_unless(uc == 200);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_USHORT));
+ fail_unless(eina_value_set(value, 65535));
+ fail_unless(eina_value_get(value, &us));
+ fail_unless(us == 65535);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UINT));
+ fail_unless(eina_value_set(value, 4000000000U));
+ fail_unless(eina_value_get(value, &ui));
+ fail_unless(ui == 4000000000U);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_ULONG));
+ fail_unless(eina_value_set(value, 3000000001U));
+ fail_unless(eina_value_get(value, &ul));
+ fail_unless(ul == 3000000001U);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UINT64));
+ fail_unless(eina_value_set(value, 0x1122334455667788));
+ fail_unless(eina_value_get(value, &u64));
+ fail_unless(u64 == 0x1122334455667788);
+ eina_value_flush(value);
+
+ /* floating point */
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_FLOAT));
+ fail_unless(eina_value_set(value, 0.1234));
+ fail_unless(eina_value_get(value, &f));
+ fail_unless(CHECK_FP(0.1234, f));
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_DOUBLE));
+ fail_unless(eina_value_set(value, 34567.8));
+ fail_unless(eina_value_get(value, &d));
+ fail_unless(CHECK_FP(34567.8, d));
+ eina_value_flush(value);
+
+ eina_value_free(value);
+ eina_shutdown();
+}
+END_TEST
+
+START_TEST(eina_value_test_compare)
+{
+ Eina_Value *a, *b;
+
+ eina_init();
+
+ a = eina_value_new(EINA_VALUE_TYPE_CHAR);
+ fail_unless(a != NULL);
+ b = eina_value_new(EINA_VALUE_TYPE_CHAR);
+ fail_unless(b != NULL);
+
+ fail_unless(eina_value_set(a, 123));
+ fail_unless(eina_value_set(b, 123));
+ fail_unless(eina_value_compare(a, b) == 0);
+ fail_unless(eina_value_set(a, -10));
+ fail_unless(eina_value_set(b, 123));
+ fail_unless(eina_value_compare(a, b) < 0);
+ fail_unless(eina_value_set(a, 123));
+ fail_unless(eina_value_set(b, 10));
+ fail_unless(eina_value_compare(a, b) > 0);
+ eina_value_flush(a);
+ eina_value_flush(b);
+
+ fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_SHORT));
+ fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_SHORT));
+ fail_unless(eina_value_set(a, 1230));
+ fail_unless(eina_value_set(b, 1230));
+ fail_unless(eina_value_compare(a, b) == 0);
+ fail_unless(eina_value_set(a, -100));
+ fail_unless(eina_value_set(b, 1230));
+ fail_unless(eina_value_compare(a, b) < 0);
+ fail_unless(eina_value_set(a, 1230));
+ fail_unless(eina_value_set(b, -100));
+ fail_unless(eina_value_compare(a, b) > 0);
+ eina_value_flush(a);
+ eina_value_flush(b);
+
+ fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_INT));
+ fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_INT));
+ fail_unless(eina_value_set(a, 300000));
+ fail_unless(eina_value_set(b, 300000));
+ fail_unless(eina_value_compare(a, b) == 0);
+ fail_unless(eina_value_set(a, -100));
+ fail_unless(eina_value_set(b, 300000));
+ fail_unless(eina_value_compare(a, b) < 0);
+ fail_unless(eina_value_set(a, 300000));
+ fail_unless(eina_value_set(b, -100));
+ fail_unless(eina_value_compare(a, b) > 0);
+ eina_value_flush(a);
+ eina_value_flush(b);
+
+ fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_LONG));
+ fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_LONG));
+ fail_unless(eina_value_set(a, 300000L));
+ fail_unless(eina_value_set(b, 300000L));
+ fail_unless(eina_value_compare(a, b) == 0);
+ fail_unless(eina_value_set(a, -100L));
+ fail_unless(eina_value_set(b, 300000L));
+ fail_unless(eina_value_compare(a, b) < 0);
+ fail_unless(eina_value_set(a, 300000L));
+ fail_unless(eina_value_set(b, -100L));
+ fail_unless(eina_value_compare(a, b) > 0);
+ eina_value_flush(a);
+ eina_value_flush(b);
+
+ fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_INT64));
+ fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_INT64));
+ fail_unless(eina_value_set(a, (int64_t)800000));
+ fail_unless(eina_value_set(b, (int64_t)800000));
+ fail_unless(eina_value_compare(a, b) == 0);
+ fail_unless(eina_value_set(a, (int64_t)-100));
+ fail_unless(eina_value_set(b, (int64_t)8000000));
+ fail_unless(eina_value_compare(a, b) < 0);
+ fail_unless(eina_value_set(a, (int64_t)8000000));
+ fail_unless(eina_value_set(b, (int64_t)-100));
+ fail_unless(eina_value_compare(a, b) > 0);
+ eina_value_flush(a);
+ eina_value_flush(b);
+
+ fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_UCHAR));
+ fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_UCHAR));
+ fail_unless(eina_value_set(a, 123));
+ fail_unless(eina_value_set(b, 123));
+ fail_unless(eina_value_compare(a, b) == 0);
+ fail_unless(eina_value_set(a, 10));
+ fail_unless(eina_value_set(b, 123));
+ fail_unless(eina_value_compare(a, b) < 0);
+ fail_unless(eina_value_set(a, 123));
+ fail_unless(eina_value_set(b, 10));
+ fail_unless(eina_value_compare(a, b) > 0);
+ eina_value_flush(a);
+ eina_value_flush(b);
+
+ fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_USHORT));
+ fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_USHORT));
+ fail_unless(eina_value_set(a, 1230));
+ fail_unless(eina_value_set(b, 1230));
+ fail_unless(eina_value_compare(a, b) == 0);
+ fail_unless(eina_value_set(a, 100));
+ fail_unless(eina_value_set(b, 1230));
+ fail_unless(eina_value_compare(a, b) < 0);
+ fail_unless(eina_value_set(a, 1230));
+ fail_unless(eina_value_set(b, 100));
+ fail_unless(eina_value_compare(a, b) > 0);
+ eina_value_flush(a);
+ eina_value_flush(b);
+
+ fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_UINT));
+ fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_UINT));
+ fail_unless(eina_value_set(a, 300000));
+ fail_unless(eina_value_set(b, 300000));
+ fail_unless(eina_value_compare(a, b) == 0);
+ fail_unless(eina_value_set(a, 100));
+ fail_unless(eina_value_set(b, 300000));
+ fail_unless(eina_value_compare(a, b) < 0);
+ fail_unless(eina_value_set(a, 300000));
+ fail_unless(eina_value_set(b, 100));
+ fail_unless(eina_value_compare(a, b) > 0);
+ eina_value_flush(a);
+ eina_value_flush(b);
+
+ fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_ULONG));
+ fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_ULONG));
+ fail_unless(eina_value_set(a, 300000UL));
+ fail_unless(eina_value_set(b, 300000UL));
+ fail_unless(eina_value_compare(a, b) == 0);
+ fail_unless(eina_value_set(a, 100UL));
+ fail_unless(eina_value_set(b, 300000UL));
+ fail_unless(eina_value_compare(a, b) < 0);
+ fail_unless(eina_value_set(a, 300000UL));
+ fail_unless(eina_value_set(b, 100UL));
+ fail_unless(eina_value_compare(a, b) > 0);
+ eina_value_flush(a);
+ eina_value_flush(b);
+
+ fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_UINT64));
+ fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_UINT64));
+ fail_unless(eina_value_set(a, (uint64_t)8000000));
+ fail_unless(eina_value_set(b, (uint64_t)8000000));
+ fail_unless(eina_value_compare(a, b) == 0);
+ fail_unless(eina_value_set(a, (uint64_t)100));
+ fail_unless(eina_value_set(b, (uint64_t)8000000));
+ fail_unless(eina_value_compare(a, b) < 0);
+ fail_unless(eina_value_set(a, (uint64_t)8000000));
+ fail_unless(eina_value_set(b, (uint64_t)100));
+ fail_unless(eina_value_compare(a, b) > 0);
+ eina_value_flush(a);
+ eina_value_flush(b);
+
+ fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_STRING));
+ fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_STRING));
+ fail_unless(eina_value_set(a, "aaa"));
+ fail_unless(eina_value_set(b, "aaa"));
+ fail_unless(eina_value_compare(a, b) == 0);
+ fail_unless(eina_value_set(a, "abc"));
+ fail_unless(eina_value_set(b, "acd"));
+ fail_unless(eina_value_compare(a, b) < 0);
+ fail_unless(eina_value_set(a, "acd"));
+ fail_unless(eina_value_set(b, "abc"));
+ fail_unless(eina_value_compare(a, b) > 0);
+ eina_value_flush(a);
+ eina_value_flush(b);
+
+ fail_unless(eina_value_array_setup(a, EINA_VALUE_TYPE_CHAR, 0));
+ fail_unless(eina_value_array_setup(b, EINA_VALUE_TYPE_CHAR, 0));
+ fail_unless(eina_value_compare(a, b) == 0);
+
+ fail_unless(eina_value_array_append(a, 1));
+ fail_unless(eina_value_array_append(a, 2));
+ fail_unless(eina_value_array_append(a, 3));
+
+ fail_unless(eina_value_array_append(b, 1));
+ fail_unless(eina_value_array_append(b, 2));
+ fail_unless(eina_value_array_append(b, 3));
+
+ fail_unless(eina_value_compare(a, b) == 0);
+
+ fail_unless(eina_value_array_set(a, 0, 0));
+ fail_unless(eina_value_compare(a, b) < 0);
+
+ fail_unless(eina_value_array_set(a, 0, 10));
+ fail_unless(eina_value_compare(a, b) > 0);
+
+ fail_unless(eina_value_array_set(a, 0, 1));
+
+ fail_unless(eina_value_array_set(b, 0, 0));
+ fail_unless(eina_value_compare(a, b) > 0);
+
+ fail_unless(eina_value_array_set(b, 0, 10));
+ fail_unless(eina_value_compare(a, b) < 0);
+
+ fail_unless(eina_value_array_set(b, 0, 1));
+ fail_unless(eina_value_compare(a, b) == 0);
+
+ /* bigger arrays are greater */
+ fail_unless(eina_value_array_append(b, 0));
+ fail_unless(eina_value_compare(a, b) < 0);
+
+ fail_unless(eina_value_array_append(a, 0));
+ fail_unless(eina_value_array_append(a, 0));
+ fail_unless(eina_value_compare(a, b) > 0);
+
+ /* bigger arrays are greater, unless an element says otherwise */
+ fail_unless(eina_value_array_set(b, 0, 10));
+ fail_unless(eina_value_compare(a, b) < 0);
+
+ eina_value_free(a);
+ eina_value_free(b);
+ eina_shutdown();
+}
+END_TEST
+
+START_TEST(eina_value_test_string)
+{
+ Eina_Value *value;
+ const char *s;
+
+ eina_init();
+
+ value = eina_value_new(EINA_VALUE_TYPE_STRING);
+ fail_unless(value != NULL);
+ fail_unless(eina_value_set(value, "hello world!"));
+ fail_unless(eina_value_get(value, &s));
+ fail_unless(strcmp(s, "hello world!") == 0);
+
+ fail_unless(eina_value_set(value, "eina-value"));
+ fail_unless(eina_value_get(value, &s));
+ fail_unless(strcmp(s, "eina-value") == 0);
+
+ eina_value_flush(value);
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_STRING));
+
+ fail_unless(eina_value_set(value, "profusion"));
+ fail_unless(eina_value_get(value, &s));
+ fail_unless(strcmp(s, "profusion") == 0);
+
+ eina_value_free(value);
+ eina_shutdown();
+}
+END_TEST
+
+START_TEST(eina_value_test_pvariant)
+{
+ Eina_Value *value;
+ char c, in_c;
+ short s, in_s;
+ int i, in_i;
+ long l, in_l;
+ int64_t i64, in_i64;
+ unsigned char uc, in_uc;
+ unsigned short us, in_us;
+ unsigned int ui, in_ui;
+ unsigned long ul, in_ul;
+ uint64_t u64, in_u64;
+ float f, in_f;
+ double d, in_d;
+ const char *str, *in_str;
+
+ eina_init();
+
+ value = eina_value_new(EINA_VALUE_TYPE_CHAR);
+ fail_unless(value != NULL);
+ in_c = 'x';
+ fail_unless(eina_value_pset(value, &in_c));
+ fail_unless(eina_value_pget(value, &c));
+ fail_unless(c == 'x');
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_SHORT));
+ in_s = 300;
+ fail_unless(eina_value_pset(value, &in_s));
+ fail_unless(eina_value_pget(value, &s));
+ fail_unless(s == 300);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_INT));
+ in_i = -12345;
+ fail_unless(eina_value_pset(value, &in_i));
+ fail_unless(eina_value_pget(value, &i));
+ fail_unless(i == -12345);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_LONG));
+ in_l = 0xb33f;
+ fail_unless(eina_value_pset(value, &in_l));
+ fail_unless(eina_value_pget(value, &l));
+ fail_unless(l == 0xb33f);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_INT64));
+ in_i64 = 0x0011223344556677;
+ fail_unless(eina_value_pset(value, &in_i64));
+ fail_unless(eina_value_pget(value, &i64));
+ fail_unless(i64 == 0x0011223344556677);
+ eina_value_flush(value);
+
+ /* unsigned: */
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UCHAR));
+ in_uc = 200;
+ fail_unless(eina_value_pset(value, &in_uc));
+ fail_unless(eina_value_pget(value, &uc));
+ fail_unless(uc == 200);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_USHORT));
+ in_us = 65535;
+ fail_unless(eina_value_pset(value, &in_us));
+ fail_unless(eina_value_pget(value, &us));
+ fail_unless(us == 65535);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UINT));
+ in_ui = 4000000000U;
+ fail_unless(eina_value_pset(value, &in_ui));
+ fail_unless(eina_value_pget(value, &ui));
+ fail_unless(ui == 4000000000U);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_ULONG));
+ in_ul = 3000000001U;
+ fail_unless(eina_value_pset(value, &in_ul));
+ fail_unless(eina_value_pget(value, &ul));
+ fail_unless(ul == 3000000001U);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UINT64));
+ in_u64 = 0x1122334455667788;
+ fail_unless(eina_value_pset(value, &in_u64));
+ fail_unless(eina_value_pget(value, &u64));
+ fail_unless(u64 == 0x1122334455667788);
+ eina_value_flush(value);
+
+ /* floating point */
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_FLOAT));
+ in_f = 0.1234;
+ fail_unless(eina_value_pset(value, &in_f));
+ fail_unless(eina_value_pget(value, &f));
+ fail_unless(CHECK_FP(0.1234, f));
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_DOUBLE));
+ in_d = 34567.8;
+ fail_unless(eina_value_pset(value, &in_d));
+ fail_unless(eina_value_pget(value, &d));
+ fail_unless(CHECK_FP(34567.8, d));
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_STRING));
+ in_str = "hello world!";
+ fail_unless(eina_value_pset(value, &in_str));
+ fail_unless(eina_value_pget(value, &str));
+ fail_unless(strcmp(str, "hello world!") == 0);
+
+ in_str = "eina-value";
+ fail_unless(eina_value_pset(value, &in_str));
+ fail_unless(eina_value_pget(value, &str));
+ fail_unless(strcmp(str, "eina-value") == 0);
+
+ eina_value_flush(value);
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_STRING));
+
+ in_str = "profusion";
+ fail_unless(eina_value_pset(value, &in_str));
+ fail_unless(eina_value_pget(value, &str));
+ fail_unless(strcmp(str, "profusion") == 0);
+
+ eina_value_free(value);
+ eina_shutdown();
+}
+END_TEST
+
+START_TEST(eina_value_test_to_string)
+{
+ Eina_Value *value;
+ char c, in_c;
+ short s, in_s;
+ int i, in_i;
+ long l, in_l;
+ int64_t i64, in_i64;
+ unsigned char uc, in_uc;
+ unsigned short us, in_us;
+ unsigned int ui, in_ui;
+ unsigned long ul, in_ul;
+ uint64_t u64, in_u64;
+ float f, in_f;
+ double d, in_d;
+ const char *str, *in_str;
+ char *out;
+ char buf[256];
+
+ eina_init();
+
+ value = eina_value_new(EINA_VALUE_TYPE_CHAR);
+ fail_unless(value != NULL);
+ in_c = 'x';
+ fail_unless(eina_value_pset(value, &in_c));
+ fail_unless(eina_value_pget(value, &c));
+ fail_unless(c == 'x');
+ snprintf(buf, sizeof(buf), "%hhd", in_c);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(buf, out) == 0);
+ free(out);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_SHORT));
+ in_s = 300;
+ fail_unless(eina_value_pset(value, &in_s));
+ fail_unless(eina_value_pget(value, &s));
+ fail_unless(s == 300);
+ snprintf(buf, sizeof(buf), "%hd", in_s);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(buf, out) == 0);
+ free(out);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_INT));
+ in_i = -12345;
+ fail_unless(eina_value_pset(value, &in_i));
+ fail_unless(eina_value_pget(value, &i));
+ fail_unless(i == -12345);
+ snprintf(buf, sizeof(buf), "%d", in_i);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(buf, out) == 0);
+ free(out);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_LONG));
+ in_l = 0xb33f;
+ fail_unless(eina_value_pset(value, &in_l));
+ fail_unless(eina_value_pget(value, &l));
+ fail_unless(l == 0xb33f);
+ snprintf(buf, sizeof(buf), "%ld", in_l);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(buf, out) == 0);
+ free(out);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_INT64));
+ in_i64 = 0x0011223344556677;
+ fail_unless(eina_value_pset(value, &in_i64));
+ fail_unless(eina_value_pget(value, &i64));
+ fail_unless(i64 == 0x0011223344556677);
+ snprintf(buf, sizeof(buf), "%"PRId64, in_i64);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(buf, out) == 0);
+ free(out);
+ eina_value_flush(value);
+
+ /* unsigned: */
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UCHAR));
+ in_uc = 200;
+ fail_unless(eina_value_pset(value, &in_uc));
+ fail_unless(eina_value_pget(value, &uc));
+ fail_unless(uc == 200);
+ snprintf(buf, sizeof(buf), "%hhu", in_uc);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(buf, out) == 0);
+ free(out);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_USHORT));
+ in_us = 65535;
+ fail_unless(eina_value_pset(value, &in_us));
+ fail_unless(eina_value_pget(value, &us));
+ fail_unless(us == 65535);
+ snprintf(buf, sizeof(buf), "%hu", in_us);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(buf, out) == 0);
+ free(out);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UINT));
+ in_ui = 4000000000U;
+ fail_unless(eina_value_pset(value, &in_ui));
+ fail_unless(eina_value_pget(value, &ui));
+ fail_unless(ui == 4000000000U);
+ snprintf(buf, sizeof(buf), "%u", in_ui);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(buf, out) == 0);
+ free(out);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_ULONG));
+ in_ul = 3000000001U;
+ fail_unless(eina_value_pset(value, &in_ul));
+ fail_unless(eina_value_pget(value, &ul));
+ fail_unless(ul == 3000000001U);
+ snprintf(buf, sizeof(buf), "%lu", in_ul);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(buf, out) == 0);
+ free(out);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UINT64));
+ in_u64 = 0x1122334455667788;
+ fail_unless(eina_value_pset(value, &in_u64));
+ fail_unless(eina_value_pget(value, &u64));
+ fail_unless(u64 == 0x1122334455667788);
+ snprintf(buf, sizeof(buf), "%"PRIu64, in_u64);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(buf, out) == 0);
+ free(out);
+ eina_value_flush(value);
+
+ /* floating point */
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_FLOAT));
+ in_f = 0.1234;
+ fail_unless(eina_value_pset(value, &in_f));
+ fail_unless(eina_value_pget(value, &f));
+ fail_unless(CHECK_FP(0.1234, f));
+ snprintf(buf, sizeof(buf), "%g", in_f);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strncmp(buf, out, 6) == 0); /* stupid float... */
+ free(out);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_DOUBLE));
+ in_d = 34567.8;
+ fail_unless(eina_value_pset(value, &in_d));
+ fail_unless(eina_value_pget(value, &d));
+ fail_unless(CHECK_FP(34567.8, d));
+ snprintf(buf, sizeof(buf), "%g", in_d);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strncmp(buf, out, 7) == 0); /* stupid double... */
+ free(out);
+ eina_value_flush(value);
+
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_STRING));
+ in_str = "hello world!";
+ fail_unless(eina_value_pset(value, &in_str));
+ fail_unless(eina_value_pget(value, &str));
+ fail_unless(strcmp(str, "hello world!") == 0);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(in_str, out) == 0);
+ free(out);
+
+ in_str = "eina-value";
+ fail_unless(eina_value_pset(value, &in_str));
+ fail_unless(eina_value_pget(value, &str));
+ fail_unless(strcmp(str, "eina-value") == 0);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(in_str, out) == 0);
+ free(out);
+
+ eina_value_flush(value);
+ fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_STRING));
+
+ in_str = "profusion";
+ fail_unless(eina_value_pset(value, &in_str));
+ fail_unless(eina_value_pget(value, &str));
+ fail_unless(strcmp(str, "profusion") == 0);
+ out = eina_value_to_string(value);
+ fail_unless(out != NULL);
+ fail_unless(strcmp(in_str, out) == 0);
+ free(out);
+
+ eina_value_free(value);
+ eina_shutdown();
+}
+END_TEST
+
+START_TEST(eina_value_test_convert_char)
+{
+ Eina_Value *value, conv;
+ char c;
+ short s;
+ int i;
+ long l;
+ int64_t i64;
+ unsigned char uc;
+ unsigned short us;
+ unsigned int ui;
+ unsigned long ul;
+ uint64_t u64;
+ float f;
+ double d;
+ const char *str;
+
+ eina_init();
+
+ value = eina_value_new(EINA_VALUE_TYPE_CHAR);
+ fail_unless(value != NULL);
+
+ fail_unless(eina_value_set(value, 123));
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UCHAR));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &uc));
+ fail_unless(uc == 123);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_USHORT));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &us));
+ fail_unless(us == 123);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UINT));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &ui));
+ fail_unless(ui == 123);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_ULONG));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &ul));
+ fail_unless(ul == 123);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UINT64));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &u64));
+ fail_unless(u64 == 123);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_CHAR));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &c));
+ fail_unless(c == 123);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_SHORT));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &s));
+ fail_unless(s == 123);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_INT));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &i));
+ fail_unless(i == 123);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_LONG));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &l));
+ fail_unless(l == 123);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_INT64));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &i64));
+ fail_unless(i64 == 123);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_FLOAT));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &f));
+ fail_unless(CHECK_FP(f, 123));
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_DOUBLE));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &d));
+ fail_unless(CHECK_FP(d, 123));
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_STRING));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &str));
+ fail_unless(str != NULL);
+ fail_unless(strcmp(str, "123") == 0);
+ eina_value_flush(&conv);
+
+ /* negative tests */
+ fail_unless(eina_value_set(value, -123));
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UCHAR));
+ fail_if(eina_value_convert(value, &conv));
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_USHORT));
+ fail_if(eina_value_convert(value, &conv));
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UINT));
+ fail_if(eina_value_convert(value, &conv));
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_ULONG));
+ fail_if(eina_value_convert(value, &conv));
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UINT64));
+ fail_if(eina_value_convert(value, &conv));
+ eina_value_flush(&conv);
+
+ eina_value_free(value);
+ eina_shutdown();
+}
+END_TEST
+
+START_TEST(eina_value_test_convert_uchar)
+{
+ Eina_Value *value, conv;
+ char c;
+ short s;
+ int i;
+ long l;
+ int64_t i64;
+ unsigned char uc;
+ unsigned short us;
+ unsigned int ui;
+ unsigned long ul;
+ uint64_t u64;
+ float f;
+ double d;
+ const char *str;
+
+ eina_init();
+
+ value = eina_value_new(EINA_VALUE_TYPE_UCHAR);
+ fail_unless(value != NULL);
+
+ fail_unless(eina_value_set(value, 31));
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UCHAR));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &uc));
+ fail_unless(uc == 31);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_USHORT));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &us));
+ fail_unless(us == 31);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UINT));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &ui));
+ fail_unless(ui == 31);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_ULONG));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &ul));
+ fail_unless(ul == 31);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UINT64));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &u64));
+ fail_unless(u64 == 31);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_CHAR));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &c));
+ fail_unless(c == 31);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_SHORT));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &s));
+ fail_unless(s == 31);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_INT));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &i));
+ fail_unless(i == 31);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_LONG));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &l));
+ fail_unless(l == 31);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_INT64));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &i64));
+ fail_unless(i64 == 31);
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_FLOAT));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &f));
+ fail_unless(CHECK_FP(f, 31));
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_DOUBLE));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &d));
+ fail_unless(CHECK_FP(d, 31));
+ eina_value_flush(&conv);
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_STRING));
+ fail_unless(eina_value_convert(value, &conv));
+ fail_unless(eina_value_get(&conv, &str));
+ fail_unless(str != NULL);
+ fail_unless(strcmp(str, "31") == 0);
+ eina_value_flush(&conv);
+
+ /* negative tests */
+ fail_unless(eina_value_set(value, 200));
+
+ fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_CHAR));
+ fail_if(eina_value_convert(value, &conv));
+ eina_value_flush(&conv);
+
+ eina_value_free(value);
+ eina_shutdown();
+}
+END_TEST
+
+
+START_TEST(eina_value_test_array)
+{
+ Eina_Value *value;
+ char c;
+ char buf[1024];
+ char *str;
+
+ eina_init();
+
+ value = eina_value_array_new(EINA_VALUE_TYPE_CHAR, 0);
+ fail_unless(value != NULL);
+
+ fail_unless(eina_value_array_append(value, 'k'));
+ fail_unless(eina_value_array_append(value, '-'));
+ fail_unless(eina_value_array_append(value, 's'));
+
+ fail_unless(eina_value_array_get(value, 0, &c));
+ fail_unless(c == 'k');
+ fail_unless(eina_value_array_get(value, 1, &c));
+ fail_unless(c == '-');
+ fail_unless(eina_value_array_get(value, 2, &c));
+ fail_unless(c == 's');
+
+ fail_unless(eina_value_array_insert(value, 0, '!'));
+ fail_unless(eina_value_array_get(value, 0, &c));
+ fail_unless(c == '!');
+ fail_unless(eina_value_array_get(value, 1, &c));
+ fail_unless(c == 'k');
+ fail_unless(eina_value_array_get(value, 2, &c));
+ fail_unless(c == '-');
+ fail_unless(eina_value_array_get(value, 3, &c));
+ fail_unless(c == 's');
+
+ fail_unless(eina_value_array_set(value, 0, '*'));
+ fail_unless(eina_value_array_get(value, 0, &c));
+ fail_unless(c == '*');
+ fail_unless(eina_value_array_get(value, 1, &c));
+ fail_unless(c == 'k');
+ fail_unless(eina_value_array_get(value, 2, &c));
+ fail_unless(c == '-');
+ fail_unless(eina_value_array_get(value, 3, &c));
+ fail_unless(c == 's');
+
+ snprintf(buf, sizeof(buf), "[%hhd, %hhd, %hhd, %hhd]",
+ '*', 'k', '-', 's');
+
+ str = eina_value_to_string(value);
+ fail_unless(str != NULL);
+ fail_unless(strcmp(str, buf) == 0);
+ free(str);
+
+ eina_value_flush(value);
+ fail_unless(eina_value_array_setup(value, EINA_VALUE_TYPE_STRINGSHARE, 2));
+
+ fail_unless(eina_value_array_append(value, "Enlightenment.org"));
+ fail_unless(eina_value_array_append(value, "X11"));
+ fail_unless(eina_value_array_append(value, "Pants"));
+ fail_unless(eina_value_array_append(value, "on!!!"));
+ fail_unless(eina_value_array_append(value, "k-s"));
+
+ str = eina_value_to_string(value);
+ fail_unless(str != NULL);
+ fail_unless(strcmp(str, "[Enlightenment.org, X11, Pants, on!!!, k-s]") == 0);
+ free(str);
+
+ eina_value_free(value);
+ eina_shutdown();
+}
+END_TEST
+
+void
+eina_test_value(TCase *tc)
+{
+ tcase_add_test(tc, eina_value_test_simple);
+ tcase_add_test(tc, eina_value_test_string);
+ tcase_add_test(tc, eina_value_test_pvariant);
+ tcase_add_test(tc, eina_value_test_compare);
+ tcase_add_test(tc, eina_value_test_to_string);
+ tcase_add_test(tc, eina_value_test_convert_char);
+ tcase_add_test(tc, eina_value_test_convert_uchar);
+ // TODO: other converters...
+ tcase_add_test(tc, eina_value_test_array);
+}