From 825a3d837a33f226c879cd02ad15c3fba57e8b2c Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 23 Jan 2012 23:30:42 +1000 Subject: Update the EFL to what I'm actually using, coz I'm using some stuff not yet released. --- libraries/eina/src/include/Eina.h | 9 +- libraries/eina/src/include/Makefile.am | 6 +- libraries/eina/src/include/Makefile.in | 52 +- libraries/eina/src/include/eina_array.h | 17 +- libraries/eina/src/include/eina_benchmark.h | 8 +- libraries/eina/src/include/eina_binbuf.h | 18 + libraries/eina/src/include/eina_clist.h | 160 +- libraries/eina/src/include/eina_config.h | 10 + libraries/eina/src/include/eina_config.h.in | 10 + libraries/eina/src/include/eina_file.h | 40 + libraries/eina/src/include/eina_hash.h | 4 +- libraries/eina/src/include/eina_inarray.h | 572 ++++ libraries/eina/src/include/eina_inline_array.x | 20 + libraries/eina/src/include/eina_inline_clist.x | 135 + libraries/eina/src/include/eina_inline_hash.x | 2 +- .../eina/src/include/eina_inline_lock_posix.x | 51 +- libraries/eina/src/include/eina_inline_lock_void.x | 62 +- .../eina/src/include/eina_inline_lock_win32.x | 46 + .../eina/src/include/eina_inline_lock_wince.x | 34 + libraries/eina/src/include/eina_inline_log.x | 4 +- libraries/eina/src/include/eina_inline_mempool.x | 49 +- libraries/eina/src/include/eina_inline_value.x | 1705 +++++++++++ libraries/eina/src/include/eina_inlist.h | 101 +- libraries/eina/src/include/eina_iterator.h | 8 +- libraries/eina/src/include/eina_list.h | 26 +- libraries/eina/src/include/eina_lock.h | 4 + libraries/eina/src/include/eina_log.h | 51 +- libraries/eina/src/include/eina_magic.h | 8 + libraries/eina/src/include/eina_main.h | 5 +- libraries/eina/src/include/eina_module.h | 47 +- .../eina/src/include/eina_simple_xml_parser.h | 62 +- libraries/eina/src/include/eina_str.h | 16 +- libraries/eina/src/include/eina_strbuf.h | 18 + libraries/eina/src/include/eina_stringshare.h | 1 + libraries/eina/src/include/eina_types.h | 4 + libraries/eina/src/include/eina_unicode.h | 23 +- libraries/eina/src/include/eina_ustrbuf.h | 20 +- libraries/eina/src/include/eina_value.h | 3114 ++++++++++++++++++++ libraries/eina/src/include/eina_xattr.h | 53 +- 39 files changed, 6222 insertions(+), 353 deletions(-) create mode 100644 libraries/eina/src/include/eina_inarray.h create mode 100644 libraries/eina/src/include/eina_inline_clist.x create mode 100644 libraries/eina/src/include/eina_inline_value.x create mode 100644 libraries/eina/src/include/eina_value.h (limited to 'libraries/eina/src/include') diff --git a/libraries/eina/src/include/Eina.h b/libraries/eina/src/include/Eina.h index 68c41f5..721a991 100644 --- a/libraries/eina/src/include/Eina.h +++ b/libraries/eina/src/include/Eina.h @@ -47,7 +47,7 @@ * * @version 1.1 * @date 2008-2011 - * + * * @section eina_intro_sec Introduction * * The Eina library is a library that implements an API for data types @@ -59,10 +59,11 @@ * Linux, BSD, Opensolaris and Windows (XP and CE). * * The data types that are available are (see @ref Eina_Data_Types_Group): + * @li @ref Eina_Inline_Array_Group standard array of inlined members. * @li @ref Eina_Array_Group standard array of @c void* data. * @li @ref Eina_Hash_Group standard hash of @c void* data. * @li @ref Eina_Inline_List_Group list with nodes inlined into user type. - * @li @ref Eina_CList_Group compact inlined list. + * @li @ref Eina_CList_Group Compact List. * @li @ref Eina_List_Group standard list of @c void* data. * @li @ref Eina_Iterator_Group Iterator functions. * @li @ref Eina_Matrixsparse_Group sparse matrix of @c void* data. @@ -89,7 +90,7 @@ * * Please see the @ref authors page for contact details. * - * @defgroup Eina_Data_Types_Group Data types + * @defgroup Eina_Data_Types_Group Data Types * * Eina provide easy to use and optimized data types and structures. * @@ -158,6 +159,7 @@ extern "C" { #include "eina_mempool.h" #include "eina_error.h" #include "eina_log.h" +#include "eina_inarray.h" #include "eina_array.h" #include "eina_binshare.h" #include "eina_stringshare.h" @@ -186,6 +188,7 @@ extern "C" { #include "eina_refcount.h" #include "eina_mmap.h" #include "eina_xattr.h" +#include "eina_value.h" #ifdef __cplusplus } diff --git a/libraries/eina/src/include/Makefile.am b/libraries/eina/src/include/Makefile.am index 41a37cb..a818d5f 100644 --- a/libraries/eina/src/include/Makefile.am +++ b/libraries/eina/src/include/Makefile.am @@ -14,6 +14,8 @@ eina_hash.h \ eina_inline_hash.x \ eina_lalloc.h \ eina_clist.h \ +eina_inline_clist.x \ +eina_inarray.h \ eina_inlist.h \ eina_list.h \ eina_file.h \ @@ -60,7 +62,9 @@ eina_lock.h \ 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 diff --git a/libraries/eina/src/include/Makefile.in b/libraries/eina/src/include/Makefile.in index f6e0074..ea922e5 100644 --- a/libraries/eina/src/include/Makefile.in +++ b/libraries/eina/src/include/Makefile.in @@ -78,23 +78,24 @@ am__dist_installed_headers_DATA_DIST = eina_safety_checks.h \ eina_error.h eina_log.h eina_inline_log.x eina_fp.h \ eina_inline_f32p32.x eina_inline_f16p16.x eina_inline_f8p24.x \ eina_inline_fp.x eina_hash.h eina_inline_hash.x eina_lalloc.h \ - eina_clist.h eina_inlist.h eina_list.h eina_file.h \ - eina_mempool.h eina_module.h eina_rectangle.h eina_types.h \ - eina_array.h eina_counter.h eina_inline_array.x eina_magic.h \ - eina_stringshare.h eina_binshare.h eina_binbuf.h \ - eina_ustringshare.h eina_inline_stringshare.x \ - eina_inline_ustringshare.x eina_inline_list.x eina_accessor.h \ - eina_convert.h eina_rbtree.h eina_benchmark.h \ - eina_inline_rbtree.x eina_inline_mempool.x \ - eina_inline_rectangle.x eina_inline_trash.x eina_trash.h \ - eina_iterator.h eina_main.h eina_cpu.h eina_sched.h \ - eina_tiler.h eina_hamster.h eina_matrixsparse.h \ - eina_inline_tiler.x eina_str.h eina_inline_str.x eina_strbuf.h \ - eina_ustrbuf.h eina_unicode.h eina_quadtree.h \ - eina_simple_xml_parser.h eina_lock.h eina_prefix.h \ - eina_refcount.h eina_mmap.h eina_xattr.h \ - eina_inline_lock_wince.x eina_inline_lock_win32.x \ - eina_inline_lock_posix.x eina_inline_lock_void.x + eina_clist.h eina_inline_clist.x eina_inarray.h eina_inlist.h \ + eina_list.h eina_file.h eina_mempool.h eina_module.h \ + eina_rectangle.h eina_types.h eina_array.h eina_counter.h \ + eina_inline_array.x eina_magic.h eina_stringshare.h \ + eina_binshare.h eina_binbuf.h eina_ustringshare.h \ + eina_inline_stringshare.x eina_inline_ustringshare.x \ + eina_inline_list.x eina_accessor.h eina_convert.h \ + eina_rbtree.h eina_benchmark.h eina_inline_rbtree.x \ + eina_inline_mempool.x eina_inline_rectangle.x \ + eina_inline_trash.x eina_trash.h eina_iterator.h eina_main.h \ + eina_cpu.h eina_sched.h eina_tiler.h eina_hamster.h \ + eina_matrixsparse.h eina_inline_tiler.x eina_str.h \ + eina_inline_str.x eina_strbuf.h eina_ustrbuf.h eina_unicode.h \ + eina_quadtree.h eina_simple_xml_parser.h eina_lock.h \ + eina_prefix.h eina_refcount.h eina_mmap.h eina_xattr.h \ + eina_value.h eina_inline_value.x eina_inline_lock_wince.x \ + eina_inline_lock_win32.x eina_inline_lock_posix.x \ + eina_inline_lock_void.x am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -163,7 +164,9 @@ EFL_SIMD_FLAGS = @EFL_SIMD_FLAGS@ EGREP = @EGREP@ EINA_CFLAGS = @EINA_CFLAGS@ EINA_CONFIGURE_DEFAULT_MEMPOOL = @EINA_CONFIGURE_DEFAULT_MEMPOOL@ +EINA_CONFIGURE_ENABLE_LOG = @EINA_CONFIGURE_ENABLE_LOG@ EINA_CONFIGURE_HAVE_DEBUG_THREADS = @EINA_CONFIGURE_HAVE_DEBUG_THREADS@ +EINA_CONFIGURE_HAVE_DIRENT_H = @EINA_CONFIGURE_HAVE_DIRENT_H@ EINA_CONFIGURE_HAVE_INTTYPES_H = @EINA_CONFIGURE_HAVE_INTTYPES_H@ EINA_CONFIGURE_HAVE_ON_OFF_THREADS = @EINA_CONFIGURE_HAVE_ON_OFF_THREADS@ EINA_CONFIGURE_HAVE_STDINT_H = @EINA_CONFIGURE_HAVE_STDINT_H@ @@ -215,8 +218,6 @@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -295,10 +296,10 @@ EINAHEADERS = eina_safety_checks.h eina_error.h eina_log.h \ eina_inline_log.x eina_fp.h eina_inline_f32p32.x \ eina_inline_f16p16.x eina_inline_f8p24.x eina_inline_fp.x \ eina_hash.h eina_inline_hash.x eina_lalloc.h eina_clist.h \ - eina_inlist.h eina_list.h eina_file.h eina_mempool.h \ - eina_module.h eina_rectangle.h eina_types.h eina_array.h \ - eina_counter.h eina_inline_array.x eina_magic.h \ - eina_stringshare.h eina_binshare.h eina_binbuf.h \ + eina_inline_clist.x eina_inarray.h eina_inlist.h eina_list.h \ + eina_file.h eina_mempool.h eina_module.h eina_rectangle.h \ + eina_types.h eina_array.h eina_counter.h eina_inline_array.x \ + eina_magic.h eina_stringshare.h eina_binshare.h eina_binbuf.h \ eina_ustringshare.h eina_inline_stringshare.x \ eina_inline_ustringshare.x eina_inline_list.x eina_accessor.h \ eina_convert.h eina_rbtree.h eina_benchmark.h \ @@ -309,8 +310,9 @@ EINAHEADERS = eina_safety_checks.h eina_error.h eina_log.h \ eina_inline_tiler.x eina_str.h eina_inline_str.x eina_strbuf.h \ eina_ustrbuf.h eina_unicode.h eina_quadtree.h \ eina_simple_xml_parser.h eina_lock.h eina_prefix.h \ - eina_refcount.h eina_mmap.h eina_xattr.h $(am__append_1) \ - $(am__append_2) $(am__append_3) $(am__append_4) + eina_refcount.h eina_mmap.h eina_xattr.h eina_value.h \ + eina_inline_value.x $(am__append_1) $(am__append_2) \ + $(am__append_3) $(am__append_4) installed_mainheaderdir = $(includedir)/eina-@VMAJ@ dist_installed_mainheader_DATA = Eina.h eina_config.h installed_headersdir = $(includedir)/eina-@VMAJ@/eina diff --git a/libraries/eina/src/include/eina_array.h b/libraries/eina/src/include/eina_array.h index d33f5e9..53183b4 100644 --- a/libraries/eina/src/include/eina_array.h +++ b/libraries/eina/src/include/eina_array.h @@ -31,7 +31,7 @@ /** - * @page array_01_example_page Basic array usage + * @page eina_array_01_example_page Basic array usage * @dontinclude eina_array_01.c * * For this example we add stdlib.h, stdio.h and string.h for some @@ -94,7 +94,7 @@ */ /** - * @page array_02_example_page Removing array elements + * @page eina_array_02_example_page Removing array elements * @dontinclude eina_array_02.c * * Just the usual includes: @@ -169,7 +169,7 @@ * element, use eina_array_push() and to remove the last element, use * eina_array_pop(). To retrieve the element at a given position, use * eina_array_data_get(). The number of elements can be retrieved with - * eina_array_count_get(). + * eina_array_count(). * * Eina_Array is different from a conventional C array in a number of ways, most * importantly they grow and shrink dynamically, this means that if you add an @@ -191,8 +191,8 @@ * of void pointers. * * See here some examples: - * @li @ref array_01_example_page - * @li @ref array_02_example_page + * @li @ref eina_array_01_example_page + * @li @ref eina_array_02_example_page */ /** @@ -351,7 +351,8 @@ static inline void *eina_array_data_get(const Eina_Array *array, static inline void eina_array_data_set(const Eina_Array *array, unsigned int idx, const void *data) EINA_ARG_NONNULL(1); -static inline unsigned int eina_array_count_get(const Eina_Array *array) EINA_ARG_NONNULL(1); +static inline unsigned int eina_array_count_get(const Eina_Array *array) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT EINA_DEPRECATED; +static inline unsigned int eina_array_count(const Eina_Array *array) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; /** * @brief Returned a new iterator associated to an array. @@ -394,7 +395,7 @@ EAPI Eina_Accessor *eina_array_accessor_new(const Eina_Array *array) EINA */ static inline Eina_Bool eina_array_foreach(Eina_Array *array, Eina_Each_Cb cb, - void *data); + void *fdata); /** * @def EINA_ARRAY_ITER_NEXT * @brief Macro to iterate over an array easily. @@ -429,7 +430,7 @@ static inline Eina_Bool eina_array_foreach(Eina_Array *array, */ #define EINA_ARRAY_ITER_NEXT(array, index, item, iterator) \ for (index = 0, iterator = (array)->data; \ - (index < eina_array_count_get(array)) && ((item = *((iterator)++))); \ + (index < eina_array_count(array)) && ((item = *((iterator)++))); \ ++(index)) #include "eina_inline_array.x" diff --git a/libraries/eina/src/include/eina_benchmark.h b/libraries/eina/src/include/eina_benchmark.h index 721e1c0..9e96d64 100644 --- a/libraries/eina/src/include/eina_benchmark.h +++ b/libraries/eina/src/include/eina_benchmark.h @@ -398,9 +398,9 @@ EAPI void eina_benchmark_free(Eina_Benchmark *bench); * * This function adds the test named @p name to @p benchmark. @p * bench_cb is the function called when the test is executed. That - * test can be executed a certain amount of time. @p start, @p end and - * @p step define a loop with a step increment. The integer that is - * increasing by @p step from @p start to @p end is passed to @p + * test can be executed a certain amount of time. @p count_start, @p count_end and + * @p count_step define a loop with a step increment. The integer that is + * increasing by @p count_step from @p count_start to @p count_end is passed to @p * bench_cb when eina_benchmark_run() is called. * * If @p bench is @c NULL, this function returns imediatly. If the @@ -413,7 +413,7 @@ EAPI Eina_Bool eina_benchmark_register(Eina_Benchmark *bench, Eina_Benchmark_Specimens bench_cb, int count_start, int count_end, - int count_set); + int count_step); /** * @brief Run the benchmark tests that have been registered. diff --git a/libraries/eina/src/include/eina_binbuf.h b/libraries/eina/src/include/eina_binbuf.h index 92f788e..7c3524b 100644 --- a/libraries/eina/src/include/eina_binbuf.h +++ b/libraries/eina/src/include/eina_binbuf.h @@ -49,6 +49,24 @@ typedef struct _Eina_Strbuf Eina_Binbuf; EAPI Eina_Binbuf *eina_binbuf_new(void) EINA_MALLOC EINA_WARN_UNUSED_RESULT; /** + * @brief Create a new string buffer using the passed string. The passed + * string is used directly as the buffer, it's somehow the opposite function of + * @ref eina_binbuf_string_steal . The passed string must be malloced. + * + * @param str the string to manage + * @param length the length of the string. + * @return Newly allocated string buffer instance. + * + * This function creates a new string buffer. On error, @c NULL is + * returned and Eina error is set to #EINA_ERROR_OUT_OF_MEMORY. To + * free the resources, use eina_binbuf_free(). + * + * @see eina_binbuf_manage_new() + * @since 1.2.0 + */ +EAPI Eina_Binbuf *eina_binbuf_manage_new_length(unsigned char *str, size_t length) EINA_MALLOC EINA_WARN_UNUSED_RESULT; + +/** * @brief Free a string buffer. * * @param buf The string buffer to free. diff --git a/libraries/eina/src/include/eina_clist.h b/libraries/eina/src/include/eina_clist.h index 68f15df..096a4b7 100644 --- a/libraries/eina/src/include/eina_clist.h +++ b/libraries/eina/src/include/eina_clist.h @@ -23,7 +23,22 @@ #define __EINA_CLIST_H__ /** - * @addtogroup Eina_CList_Group Compact inline list + * @addtogroup Eina_Data_Types_Group Data Types + * + * @{ + */ + +/** + * @addtogroup Eina_Containers_Group Containers + * + * @{ + */ + +/** + * @defgroup Eina_CList_Group Compact List + * + * @{ + * * @brief Eina_Clist is a compact (inline) list implementation * * Elements of this list are members of the structs stored in the list @@ -42,9 +57,8 @@ * @note There's no NULL at the end of the list, the last item points to the head. * * @note List heads must be initialized with EINA_CLIST_INIT or by calling eina_clist_element_init - */ - -/* Define a list like so: + * + * Define a list like so: * * @code * struct gadget @@ -88,24 +102,6 @@ */ /** - * @addtogroup Eina_Data_Types_Group Data Types - * - * @{ - */ - -/** - * @addtogroup Eina_Containers_Group Containers - * - * @{ - */ - -/** - * @defgroup Eina_CList_Group Compact list - * - * @{ - */ - -/** * @typedef Eina_Clist * This is the list head and the list entry. * @since 1.1.0 @@ -135,13 +131,7 @@ struct _Eina_Clist * @note There's no need to initialize an element before adding it to the list. * @since 1.1.0 */ -static inline void eina_clist_add_after(Eina_Clist *elem, Eina_Clist *to_add) -{ - to_add->next = elem->next; - to_add->prev = elem; - elem->next->prev = to_add; - elem->next = to_add; -} +static inline void eina_clist_add_after(Eina_Clist *elem, Eina_Clist *to_add); /** * Add an element before the specified one. @@ -154,13 +144,7 @@ static inline void eina_clist_add_after(Eina_Clist *elem, Eina_Clist *to_add) * @note There's no need to initialize an element before adding it to the list. * @since 1.1.0 */ -static inline void eina_clist_add_before(Eina_Clist *elem, Eina_Clist *to_add) -{ - to_add->next = elem; - to_add->prev = elem->prev; - elem->prev->next = to_add; - elem->prev = to_add; -} +static inline void eina_clist_add_before(Eina_Clist *elem, Eina_Clist *to_add); /** * Add element at the head of the list. @@ -173,10 +157,7 @@ static inline void eina_clist_add_before(Eina_Clist *elem, Eina_Clist *to_add) * @note There's no need to initialize an element before adding it to the list. * @since 1.1.0 */ -static inline void eina_clist_add_head(Eina_Clist *list, Eina_Clist *elem) -{ - eina_clist_add_after(list, elem); -} +static inline void eina_clist_add_head(Eina_Clist *list, Eina_Clist *elem); /** * Add element at the tail of the list. @@ -189,10 +170,7 @@ static inline void eina_clist_add_head(Eina_Clist *list, Eina_Clist *elem) * @note There's no need to initialize an element before adding it to the list. * @since 1.1.0 */ -static inline void eina_clist_add_tail(Eina_Clist *list, Eina_Clist *elem) -{ - eina_clist_add_before(list, elem); -} +static inline void eina_clist_add_tail(Eina_Clist *list, Eina_Clist *elem); /** * Init an (unlinked) element. @@ -207,11 +185,7 @@ static inline void eina_clist_add_tail(Eina_Clist *list, Eina_Clist *elem) * @note It is not necessary to call this before adding an element to this list. * @since 1.1.0 */ -static inline void eina_clist_element_init(Eina_Clist *elem) -{ - elem->next = NULL; - elem->prev = NULL; -} +static inline void eina_clist_element_init(Eina_Clist *elem); /** * Check if an element is in a list or not. @@ -222,10 +196,7 @@ static inline void eina_clist_element_init(Eina_Clist *elem) * it has been added to a list or remove from a list. * @since 1.1.0 */ -static inline int eina_clist_element_is_linked(Eina_Clist *elem) -{ - return (elem->next != NULL && elem->prev != NULL); -} +static inline int eina_clist_element_is_linked(Eina_Clist *elem); /** * Remove an element from its list. @@ -235,12 +206,7 @@ static inline int eina_clist_element_is_linked(Eina_Clist *elem) * @post The element is marked as not being in any list * @since 1.1.0 */ -static inline void eina_clist_remove(Eina_Clist *elem) -{ - elem->next->prev = elem->prev; - elem->prev->next = elem->next; - eina_clist_element_init(elem); -} +static inline void eina_clist_remove(Eina_Clist *elem); /** * Get the next element. @@ -248,15 +214,10 @@ static inline void eina_clist_remove(Eina_Clist *elem) * @param list The list * @param elem An element * @pre @a elem is in @a list - * @return The element after @elem in @list or NULL if @a elem is last in @a list + * @return The element after @a elem in @a list or @c NULL if @a elem is last in @a list * @since 1.1.0 */ -static inline Eina_Clist *eina_clist_next(const Eina_Clist *list, const Eina_Clist *elem) -{ - Eina_Clist *ret = elem->next; - if (elem->next == list) ret = NULL; - return ret; -} +static inline Eina_Clist *eina_clist_next(const Eina_Clist *list, const Eina_Clist *elem); /** * Get the previous element. @@ -267,12 +228,7 @@ static inline Eina_Clist *eina_clist_next(const Eina_Clist *list, const Eina_Cli * @return The element before @a elem or NULL if @a elem is the first in the list * @since 1.1.0 */ -static inline Eina_Clist *eina_clist_prev(const Eina_Clist *list, const Eina_Clist *elem) -{ - Eina_Clist *ret = elem->prev; - if (elem->prev == list) ret = NULL; - return ret; -} +static inline Eina_Clist *eina_clist_prev(const Eina_Clist *list, const Eina_Clist *elem); /** * Get the first element. @@ -281,22 +237,16 @@ static inline Eina_Clist *eina_clist_prev(const Eina_Clist *list, const Eina_Cli * @returns The first element in @a list or NULL if @a list is empty * @since 1.1.0 */ -static inline Eina_Clist *eina_clist_head(const Eina_Clist *list) -{ - return eina_clist_next(list, list); -} +static inline Eina_Clist *eina_clist_head(const Eina_Clist *list); /** * Get the last element. * * @param list The list - * @returns The last element in @a list or NULL if @list is empty + * @returns The last element in @a list or NULL if @a list is empty * @since 1.1.0 */ -static inline Eina_Clist *eina_clist_tail(const Eina_Clist *list) -{ - return eina_clist_prev(list, list); -} +static inline Eina_Clist *eina_clist_tail(const Eina_Clist *list); /** * Check if a list is empty. @@ -305,10 +255,7 @@ static inline Eina_Clist *eina_clist_tail(const Eina_Clist *list) * @returns non-zero if @a list is empty, zero if it is not * @since 1.1.0 */ -static inline int eina_clist_empty(const Eina_Clist *list) -{ - return list->next == list; -} +static inline int eina_clist_empty(const Eina_Clist *list); /** * Initialize a list @@ -322,10 +269,7 @@ static inline int eina_clist_empty(const Eina_Clist *list) * initialize the list by zero'ing out the list head. * @since 1.1.0 */ -static inline void eina_clist_init(Eina_Clist *list) -{ - list->next = list->prev = list; -} +static inline void eina_clist_init(Eina_Clist *list); /** * Count the elements of a list @@ -334,13 +278,7 @@ static inline void eina_clist_init(Eina_Clist *list) * @returns The number of items in the list * @since 1.1.0 */ -static inline unsigned int eina_clist_count(const Eina_Clist *list) -{ - unsigned count = 0; - const Eina_Clist *ptr; - for (ptr = list->next; ptr != list; ptr = ptr->next) count++; - return count; -} +static inline unsigned int eina_clist_count(const Eina_Clist *list); /** * Move all elements from src to the tail of dst @@ -351,16 +289,7 @@ static inline unsigned int eina_clist_count(const Eina_Clist *list) * @post @a src is initialized but empty after this operation * @since 1.1.0 */ -static inline void eina_clist_move_tail(Eina_Clist *dst, Eina_Clist *src) -{ - if (eina_clist_empty(src)) return; - - dst->prev->next = src->next; - src->next->prev = dst->prev; - dst->prev = src->prev; - src->prev->next = dst; - eina_clist_init(src); -} +static inline void eina_clist_move_tail(Eina_Clist *dst, Eina_Clist *src); /** * move all elements from src to the head of dst @@ -371,16 +300,7 @@ static inline void eina_clist_move_tail(Eina_Clist *dst, Eina_Clist *src) * @post @a src is initialized but empty after this operation * @since 1.1.0 */ -static inline void eina_clist_move_head(Eina_Clist *dst, Eina_Clist *src) -{ - if (eina_clist_empty(src)) return; - - dst->next->prev = src->prev; - src->prev->next = dst->next; - dst->next = src->next; - src->next->prev = dst; - eina_clist_init(src); -} +static inline void eina_clist_move_head(Eina_Clist *dst, Eina_Clist *src); /** * iterate through the list @@ -441,15 +361,17 @@ static inline void eina_clist_move_head(Eina_Clist *dst, Eina_Clist *src) #define EINA_CLIST_ENTRY(elem, type, field) \ ((type *)((char *)(elem) - (unsigned long)(&((type *)0)->field))) -/* +#include "eina_inline_clist.x" + +/** * @} */ -/* +/** * @} */ -/* +/** * @} */ diff --git a/libraries/eina/src/include/eina_config.h b/libraries/eina/src/include/eina_config.h index 3341731..474edaa 100644 --- a/libraries/eina/src/include/eina_config.h +++ b/libraries/eina/src/include/eina_config.h @@ -64,4 +64,14 @@ #endif +#ifdef EINA_CONFIGURE_HAVE_DIRENT_H +# undef EINA_CONFIGURE_HAVE_DIRENT_H +#endif +#define EINA_HAVE_DIRENT_H + +#ifdef EINA_CONFIGURE_ENABLE_LOG +# undef EINA_CONFIGURE_ENABLE_LOG +#endif +#define EINA_ENABLE_LOG + #endif /* EINA_CONFIG_H_ */ diff --git a/libraries/eina/src/include/eina_config.h.in b/libraries/eina/src/include/eina_config.h.in index be328cd..2459ace 100644 --- a/libraries/eina/src/include/eina_config.h.in +++ b/libraries/eina/src/include/eina_config.h.in @@ -64,4 +64,14 @@ #endif @EINA_CONFIGURE_HAVE_ON_OFF_THREADS@ +#ifdef EINA_CONFIGURE_HAVE_DIRENT_H +# undef EINA_CONFIGURE_HAVE_DIRENT_H +#endif +@EINA_CONFIGURE_HAVE_DIRENT_H@ + +#ifdef EINA_CONFIGURE_ENABLE_LOG +# undef EINA_CONFIGURE_ENABLE_LOG +#endif +@EINA_CONFIGURE_ENABLE_LOG@ + #endif /* EINA_CONFIG_H_ */ diff --git a/libraries/eina/src/include/eina_file.h b/libraries/eina/src/include/eina_file.h index 01ef8f5..422fb65 100644 --- a/libraries/eina/src/include/eina_file.h +++ b/libraries/eina/src/include/eina_file.h @@ -94,6 +94,9 @@ typedef struct _Eina_File_Direct_Info Eina_File_Direct_Info; * @typedef Eina_File_Dir_List_Cb * Type for a callback to be called when iterating over the files of a * directory. + * @param The file name EXCLUDING the path + * @param path The path passed to eina_file_dir_list() + * @param data The data passed to eina_file_dir_list() */ typedef void (*Eina_File_Dir_List_Cb)(const char *name, const char *path, void *data); @@ -345,6 +348,33 @@ EAPI time_t eina_file_mtime_get(Eina_File *file); EAPI const char *eina_file_filename_get(Eina_File *file); /** + * @brief Get the eXtended attribute of an open file. + * + * @param file The file handler to request the eXtended attribute from. + * @return an iterator. + * + * The iterator will list all eXtended attribute name without allocating + * them, so you need to copy them yourself if needed. + * + * @since 1.2 + */ +EAPI Eina_Iterator *eina_file_xattr_get(Eina_File *file); + +/** + * @brief Get the eXtended attribute of an open file. + * + * @param file The file handler to request the eXtended attribute from. + * @return an iterator. + * + * The iterator will list all eXtended attribute without allocating + * them, so you need to copy them yourself if needed. It is returning + * Eina_Xattr structure. + * + * @since 1.2 + */ +EAPI Eina_Iterator *eina_file_xattr_value_get(Eina_File *file); + +/** * @brief Map all the file to a buffer. * * @param file The file handler to map in memory @@ -382,6 +412,16 @@ EAPI void *eina_file_map_new(Eina_File *file, Eina_File_Populate rule, EAPI void eina_file_map_free(Eina_File *file, void *map); /** + * @brief Tell if their was an IO error during the life of a mmaped file + * + * @param file The file handler to the mmaped file. + * @param map Memory map to check if an error occured on it. + * + * @since 1.2 + */ +EAPI Eina_Bool eina_file_map_faulted(Eina_File *file, void *map); + +/** * @} */ diff --git a/libraries/eina/src/include/eina_hash.h b/libraries/eina/src/include/eina_hash.h index c8eb048..57316b2 100644 --- a/libraries/eina/src/include/eina_hash.h +++ b/libraries/eina/src/include/eina_hash.h @@ -578,7 +578,7 @@ EAPI Eina_Bool eina_hash_del(Eina_Hash *hash, * otherwise. */ EAPI void *eina_hash_find(const Eina_Hash *hash, - const void *key) EINA_ARG_NONNULL(1, 2); + const void *key) EINA_ARG_NONNULL(2); /** * @brief Modify the entry pointer at the specified key and return the old @@ -1005,7 +1005,7 @@ EAPI Eina_Iterator *eina_hash_iterator_tuple_new(const Eina_Hash *hash) EINA_MAL * @endcode */ EAPI void eina_hash_foreach(const Eina_Hash *hash, - Eina_Hash_Foreach cb, + Eina_Hash_Foreach func, const void *fdata) EINA_ARG_NONNULL(1, 2); /* Paul Hsieh (http://www.azillionmonkeys.com/qed/hash.html) hash function used by WebCore (http://webkit.org/blog/8/hashtables-part-2/) */ EAPI int eina_hash_superfast(const char *key, diff --git a/libraries/eina/src/include/eina_inarray.h b/libraries/eina/src/include/eina_inarray.h new file mode 100644 index 0000000..d37c76b --- /dev/null +++ b/libraries/eina/src/include/eina_inarray.h @@ -0,0 +1,572 @@ +/* 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 . + */ + +#ifndef EINA_INARRAY_H_ +#define EINA_INARRAY_H_ + +#include "eina_types.h" +#include "eina_iterator.h" +#include "eina_accessor.h" + +/** + * @addtogroup Eina_Data_Types_Group Data Types + * + * @since 1.2 + * + * @{ + */ + +/** + * @addtogroup Eina_Containers_Group Containers + * + * @{ + */ + +/** + * @defgroup Eina_Inline_Array_Group Inline Array + * + * @{ + */ + + +/** + * @typedef Eina_Inarray + * Inlined array type. + * + * @since 1.2 + */ +typedef struct _Eina_Inarray Eina_Inarray; + +/** + * Inline array structure, use #Eina_Inarray typedef instead. + * + * Do not modify these fields directly, use eina_inarray_setup() or + * eina_inarray_new() instead. + * + * @since 1.2 + */ +struct _Eina_Inarray +{ + unsigned int member_size; /**< byte size of each entry in members */ + unsigned int len; /**< number of elements used in members */ + unsigned int max; /**< number of elements allocated in members */ + unsigned int step; /**< amount to grow number of members allocated */ + void *members; /**< actual array of elements */ + EINA_MAGIC +}; + +/** + * @brief Create new inline array. + * + * @param member_size size of each member in the array. + * @param step when resizing the array, do this using the following + * extra amount. + * @return The new inline array table or @c NULL on failure. + * + * Create a new array where members are inlined in a sequence. Each + * member has @a member_size bytes. + * + * If the @a step is 0, then a safe default is chosen. + * + * On failure, @c NULL is returned and #EINA_ERROR_OUT_OF_MEMORY is + * set. If @a member_size is zero, then @c NULL is returned. + * + * @see eina_inarray_free() + * + * @since 1.2 + */ +EAPI Eina_Inarray *eina_inarray_new(unsigned int member_size, + unsigned int step) EINA_MALLOC EINA_WARN_UNUSED_RESULT; + +/** + * @brief Free array and its members. + * @param array array object + * + * @see eina_inarray_flush() + * + * @since 1.2 + */ +EAPI void eina_inarray_free(Eina_Inarray *array) EINA_ARG_NONNULL(1); + +/** + * @brief Initialize inline array. + * @param array array object to initialize. + * @param member_size size of each member in the array. + * @param step when resizing the array, do this using the following + * extra amount. + * + * Initialize array. If the @a step is 0, then a safe default is + * chosen. + * + * This is useful for arrays inlined into other structures or + * allocated at stack. + * + * @see eina_inarray_flush() + * + * @since 1.2 + */ +EAPI void eina_inarray_setup(Eina_Inarray *array, + unsigned int member_size, + unsigned int step) EINA_ARG_NONNULL(1); + +/** + * @brief Remove every member from array. + * @param array array object + * + * @since 1.2 + */ +EAPI void eina_inarray_flush(Eina_Inarray *array) EINA_ARG_NONNULL(1); + +/** + * @brief Copy the data as the last member of the array. + * @param array array object + * @param data data to be copied at the end + * @return the index of the new member or -1 on errors. + * + * Copies the given pointer contents at the end of the array. The + * pointer is not referenced, instead it's contents is copied to the + * members array using the previously defined @c member_size. + * + * @see eina_inarray_insert_at(). + * + * @since 1.2 + */ +EAPI int eina_inarray_append(Eina_Inarray *array, + const void *data) EINA_ARG_NONNULL(1, 2); + +/** + * @brief Copy the data to array at position found by comparison function + * @param array array object + * @param data data to be copied + * @param compare compare function + * @return the index of the new member or -1 on errors. + * + * Copies the given pointer contents at the array position defined by + * given @a compare function. The pointer is not referenced, instead + * it's contents is copied to the members array using the previously + * defined @c member_size. + * + * The data given to @a compare function are the pointer to member + * memory itself, do no change it. + * + * @see eina_inarray_insert_sorted() + * @see eina_inarray_insert_at() + * @see eina_inarray_append() + * + * @since 1.2 + */ +EAPI int eina_inarray_insert(Eina_Inarray *array, + const void *data, + Eina_Compare_Cb compare) EINA_ARG_NONNULL(1, 2, 3); + +/** + * @brief Copy the data to array at position found by comparison function + * @param array array object + * @param data data to be copied + * @param compare compare function + * @return the index of the new member or -1 on errors. + * + * Copies the given pointer contents at the array position defined by + * given @a compare function. The pointer is not referenced, instead + * it's contents is copied to the members array using the previously + * defined @c member_size. + * + * The data given to @a compare function are the pointer to member + * memory itself, do no change it. + * + * This variation will optimize insertion position assuming the array + * is already sorted by doing binary search. + * + * @see eina_inarray_sort() + * + * @since 1.2 + */ +EAPI int eina_inarray_insert_sorted(Eina_Inarray *array, + const void *data, + Eina_Compare_Cb compare) EINA_ARG_NONNULL(1, 2, 3); + +/** + * @brief Find data and remove matching member + * @param array array object + * @param data data to be found and removed + * @return the index of the removed member or -1 on errors. + * + * Find data in the array and remove it. Data may be an existing + * member of array (then optimized) or the contents will be matched + * using memcmp(). + * + * @see eina_inarray_pop() + * @see eina_inarray_remove_at() + * + * @since 1.2 + */ +EAPI int eina_inarray_remove(Eina_Inarray *array, + const void *data) EINA_ARG_NONNULL(1, 2); + +/** + * @brief Removes the last member of the array + * @param array array object + * @return the index of the removed member or -1 on errors. + * + * @since 1.2 + */ +EAPI int eina_inarray_pop(Eina_Inarray *array) EINA_ARG_NONNULL(1); + +/** + * @brief Get the member at given position + * @param array array object + * @param position member position + * @return pointer to current member memory. + * + * Gets the member given its position in the array. It is a pointer to + * its current memory, then it can be invalidated with functions that + * changes the array such as eina_inarray_append(), + * eina_inarray_insert_at() or eina_inarray_remove_at() or variants. + * + * See also eina_inarray_lookup() and eina_inarray_lookup_sorted(). + * + * @since 1.2 + */ +EAPI void *eina_inarray_nth(const Eina_Inarray *array, + unsigned int position) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; + +/** + * @brief Copy the data at given position in the array + * @param array array object + * @param position where to insert 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. + * + * All the members from @a position to the end of the array are + * shifted to the end. + * + * If @a position is equal to the end of the array (equals to + * eina_inarray_count()), then the member is appended. + * + * If @a position is bigger than the array length, it will fail. + * + * @since 1.2 + */ +EAPI Eina_Bool eina_inarray_insert_at(Eina_Inarray *array, + unsigned int position, + const void *data) EINA_ARG_NONNULL(1, 3); + +/** + * @brief Opens a space at given position, returning its pointer. + * @param array array object + * @param position where to insert first member (open/allocate space) + * @param member_count how many times member_size bytes will be allocated. + * @return pointer to first member memory allocated or @c NULL on errors. + * + * This is similar to eina_inarray_insert_at(), but useful if the + * members contents are still unknown or unallocated. It will make + * room for the required number of items and return the pointer to the + * first item, similar to malloc(member_count * member_size), with the + * guarantee all memory is within members array. + * + * The new member memory is undefined, it's not automatically zeroed. + * + * All the members from @a position to the end of the array are + * shifted to the end. + * + * If @a position is equal to the end of the array (equals to + * eina_inarray_count()), then the member is appended. + * + * If @a position is bigger than the array length, it will fail. + * + * @since 1.2 + */ +EAPI void *eina_inarray_alloc_at(Eina_Inarray *array, + unsigned int position, + unsigned int member_count) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; + +/** + * @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 + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * The member is removed from array and any members after it are moved + * towards the array head. + * + * See also eina_inarray_pop() and eina_inarray_remove(). + * + * @since 1.2 + */ +EAPI Eina_Bool eina_inarray_remove_at(Eina_Inarray *array, + unsigned int position) EINA_ARG_NONNULL(1); + +/** + * @brief Reverse members in the array. + * @param array array object + * + * If you do not want to change the array, just walk its elements + * backwards, then use EINA_INARRAY_REVERSE_FOREACH() macro. + * + * @see EINA_INARRAY_REVERSE_FOREACH() + * + * @since 1.2 + */ +EAPI void eina_inarray_reverse(Eina_Inarray *array) EINA_ARG_NONNULL(1); + +/** + * @brief Applies quick sort to array + * @param array array object + * @param compare compare function + * + * Applies quick sort to the @a array. + * + * The data given to @a compare function are the pointer to member + * memory itself, do no change it. + * + * @see eina_inarray_insert_sorted() + * + * @since 1.2 + */ +EAPI void eina_inarray_sort(Eina_Inarray *array, + Eina_Compare_Cb compare) EINA_ARG_NONNULL(1, 2); + +/** + * @brief Search member (linear walk) + * @param array array object + * @param data member to search using @a compare function. + * @param compare compare function + * @return the member index or -1 if not found. + * + * Walks array linearly looking for given data as compared by + * @a compare function. + * + * The data given to @a compare function are the pointer to member + * memory itself, do no change it. + * + * See also eina_inarray_lookup_sorted(). + * + * @since 1.2 + */ +EAPI int eina_inarray_search(const Eina_Inarray *array, + const void *data, + Eina_Compare_Cb compare) EINA_ARG_NONNULL(1, 2, 3); + +/** + * @brief Search member (binary search walk) + * @param array array object + * @param data member to search using @a compare function. + * @param compare compare function + * @return the member index or -1 if not found. + * + * Uses binary search for given data as compared by @a compare function. + * + * The data given to @a compare function are the pointer to member + * memory itself, do no change it. + * + * @since 1.2 + */ +EAPI int eina_inarray_search_sorted(const Eina_Inarray *array, + const void *data, + Eina_Compare_Cb compare) EINA_ARG_NONNULL(1, 2, 3); + +/** + * @brief Call function for each array member + * @param array array object + * @param function callback function + * @param user_data user data given to callback @a function + * @return #EINA_TRUE if it successfully iterate all items of the array. + * + * Call @a function for every given data in @a array. + * + * Safe way to iterate over an array. @p function should return + * #EINA_TRUE as long as you want the function to continue iterating, + * by returning #EINA_FALSE it will stop and return #EINA_FALSE as a + * result. + * + * The data given to @a function are the pointer to member memory + * itself. + * + * @see EINA_INARRAY_FOREACH() + * + * @since 1.2 + */ +EAPI Eina_Bool eina_inarray_foreach(const Eina_Inarray *array, + Eina_Each_Cb function, + const void *user_data) EINA_ARG_NONNULL(1, 2); + +/** + * @brief Remove all members that matched. + * @param array array object + * @param match match function + * @param user_data user data given to callback @a match. + * @return number of removed entries or -1 on error. + * + * Remove all entries in the @a array where @a match function + * returns #EINA_TRUE. + * + * @since 1.2 + */ +EAPI int eina_inarray_foreach_remove(Eina_Inarray *array, + Eina_Each_Cb match, + const void *user_data) EINA_ARG_NONNULL(1, 2); + +/** + * @brief number of members in array. + * @param array array object + * @return number of members in array. + * + * @since 1.2 + */ +EAPI unsigned int eina_inarray_count(const Eina_Inarray *array) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; + +/** + * @brief Returned a new iterator associated to an array. + * @param array array object + * @return A new iterator. + * + * This function returns a newly allocated iterator associated to + * @p array. + * + * If the memory can not be allocated, NULL is returned and + * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is + * returned. + * + * @warning if the array structure changes then the iterator becomes + * invalid! That is, if you add or remove members this + * iterator behavior is undefined and your program may crash! + * + * @since 1.2 + */ +EAPI Eina_Iterator *eina_inarray_iterator_new(const Eina_Inarray *array) EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); + +/** + * @brief Returned a new reversed iterator associated to an array. + * @param array array object + * @return A new iterator. + * + * This function returns a newly allocated iterator associated to + * @p array. + * + * Unlike eina_inarray_iterator_new(), this will walk the array backwards. + * + * If the memory can not be allocated, NULL is returned and + * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is + * returned. + * + * @warning if the array structure changes then the iterator becomes + * invalid! That is, if you add or remove nodes this iterator + * behavior is undefined and your program may crash! + * + * @since 1.2 + */ +EAPI Eina_Iterator *eina_inarray_iterator_reversed_new(const Eina_Inarray *array) EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); + +/** + * @brief Returned a new accessor associated to an array. + * @param array array object + * @return A new accessor. + * + * This function returns a newly allocated accessor associated to + * @p array. + * + * If the memory can not be allocated, NULL is returned and + * #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid accessor is + * returned. + * + * @since 1.2 + */ +EAPI Eina_Accessor *eina_inarray_accessor_new(const Eina_Inarray *array) EINA_MALLOC EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); + +/** + * @def EINA_INARRAY_FOREACH + * @brief walks array linearly from head to tail + * @param array array object + * @param itr the iterator pointer + * + * @a itr must be a pointer with sizeof(itr*) == array->member_size. + * + * @warning This is fast as it does direct pointer access, but it will + * not check for @c NULL pointers or invalid array object! + * See eina_inarray_foreach() to do that. + * + * @warning Do not modify array as you walk it! If that is desired, + * then use eina_inarray_foreach_remove() + * + * @since 1.2 + */ +#define EINA_INARRAY_FOREACH(array, itr) \ + for ((itr) = array->members; \ + (itr) < (((typeof(*itr)*)array->members) + array->len); \ + (itr)++) + +/** + * @def EINA_INARRAY_REVERSE_FOREACH + * @brief walks array linearly from tail to head + * @param array array object + * @param itr the iterator pointer + * + * @a itr must be a pointer with sizeof(itr*) == array->member_size. + * + * @warning This is fast as it does direct pointer access, but it will + * not check for @c NULL pointers or invalid array object! + * + * @warning Do not modify array as you walk it! If that is desired, + * then use eina_inarray_foreach_remove() + * + * @since 1.2 + */ +#define EINA_INARRAY_REVERSE_FOREACH(array, itr) \ + for ((itr) = ((((typeof(*(itr))*)array->members) + array->len) - 1); \ + (((itr) >= (typeof(*(itr))*)array->members) \ + && (array->members != NULL)); \ + (itr)--) + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /*EINA_INARRAY_H_*/ diff --git a/libraries/eina/src/include/eina_inline_array.x b/libraries/eina/src/include/eina_inline_array.x index f9f6026..a635ee2 100644 --- a/libraries/eina/src/include/eina_inline_array.x +++ b/libraries/eina/src/include/eina_inline_array.x @@ -19,6 +19,8 @@ #ifndef EINA_INLINE_ARRAY_X_ #define EINA_INLINE_ARRAY_X_ +#include + #include /** @@ -126,6 +128,8 @@ eina_array_data_set(const Eina_Array *array, unsigned int idx, const void *data) * This function returns the number of elements in @p array. For * performance reasons, there is no check of @p array. If it is * @c NULL or invalid, the program may crash. + * + * @deprecated use eina_array_count() */ static inline unsigned int eina_array_count_get(const Eina_Array *array) @@ -133,6 +137,22 @@ eina_array_count_get(const Eina_Array *array) return array->count; } +/** + * @brief Return the number of elements in an array. + * + * @param array The array. + * @return The number of elements. + * + * This function returns the number of elements in @p array. For + * performance reasons, there is no check of @p array. If it is + * @c NULL or invalid, the program may crash. + */ +static inline unsigned int +eina_array_count(const Eina_Array *array) +{ + return array->count; +} + static inline Eina_Bool eina_array_foreach(Eina_Array *array, Eina_Each_Cb cb, void *fdata) { diff --git a/libraries/eina/src/include/eina_inline_clist.x b/libraries/eina/src/include/eina_inline_clist.x new file mode 100644 index 0000000..66223fe --- /dev/null +++ b/libraries/eina/src/include/eina_inline_clist.x @@ -0,0 +1,135 @@ +/* + * Linked lists support + * + * Copyright (C) 2002 Alexandre Julliard + * Copyright (C) 2011 Mike McCormack (adapted for Eina) + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __EINA_CLIST_INLINE_H__ +#define __EINA_CLIST_INLINE_H__ + +#include + +static inline void eina_clist_add_after(Eina_Clist *elem, Eina_Clist *to_add) +{ + to_add->next = elem->next; + to_add->prev = elem; + elem->next->prev = to_add; + elem->next = to_add; +} + +static inline void eina_clist_add_before(Eina_Clist *elem, Eina_Clist *to_add) +{ + to_add->next = elem; + to_add->prev = elem->prev; + elem->prev->next = to_add; + elem->prev = to_add; +} + +static inline void eina_clist_add_head(Eina_Clist *list, Eina_Clist *elem) +{ + eina_clist_add_after(list, elem); +} + +static inline void eina_clist_add_tail(Eina_Clist *list, Eina_Clist *elem) +{ + eina_clist_add_before(list, elem); +} + +static inline void eina_clist_element_init(Eina_Clist *elem) +{ + elem->next = NULL; + elem->prev = NULL; +} + +static inline int eina_clist_element_is_linked(Eina_Clist *elem) +{ + return (elem->next != NULL && elem->prev != NULL); +} + +static inline void eina_clist_remove(Eina_Clist *elem) +{ + elem->next->prev = elem->prev; + elem->prev->next = elem->next; + eina_clist_element_init(elem); +} + +static inline Eina_Clist *eina_clist_next(const Eina_Clist *list, const Eina_Clist *elem) +{ + Eina_Clist *ret = elem->next; + if (elem->next == list) ret = NULL; + return ret; +} + +static inline Eina_Clist *eina_clist_prev(const Eina_Clist *list, const Eina_Clist *elem) +{ + Eina_Clist *ret = elem->prev; + if (elem->prev == list) ret = NULL; + return ret; +} + +static inline Eina_Clist *eina_clist_head(const Eina_Clist *list) +{ + return eina_clist_next(list, list); +} + +static inline Eina_Clist *eina_clist_tail(const Eina_Clist *list) +{ + return eina_clist_prev(list, list); +} + +static inline int eina_clist_empty(const Eina_Clist *list) +{ + return list->next == list; +} + +static inline void eina_clist_init(Eina_Clist *list) +{ + list->next = list->prev = list; +} + +static inline unsigned int eina_clist_count(const Eina_Clist *list) +{ + unsigned count = 0; + const Eina_Clist *ptr; + for (ptr = list->next; ptr != list; ptr = ptr->next) count++; + return count; +} + +static inline void eina_clist_move_tail(Eina_Clist *dst, Eina_Clist *src) +{ + if (eina_clist_empty(src)) return; + + dst->prev->next = src->next; + src->next->prev = dst->prev; + dst->prev = src->prev; + src->prev->next = dst; + eina_clist_init(src); +} + +static inline void eina_clist_move_head(Eina_Clist *dst, Eina_Clist *src) +{ + if (eina_clist_empty(src)) return; + + dst->next->prev = src->prev; + src->prev->next = dst->next; + dst->next = src->next; + src->next->prev = dst; + eina_clist_init(src); +} + +#endif diff --git a/libraries/eina/src/include/eina_inline_hash.x b/libraries/eina/src/include/eina_inline_hash.x index f27060f..be20e8f 100644 --- a/libraries/eina/src/include/eina_inline_hash.x +++ b/libraries/eina/src/include/eina_inline_hash.x @@ -101,7 +101,7 @@ static inline unsigned int _fmix32(unsigned int h) return h; } -int +static inline int eina_hash_murmur3(const char *key, int len) { const unsigned char * data = (const unsigned char*)key; diff --git a/libraries/eina/src/include/eina_inline_lock_posix.x b/libraries/eina/src/include/eina_inline_lock_posix.x index 77f5b8b..64e049a 100644 --- a/libraries/eina/src/include/eina_inline_lock_posix.x +++ b/libraries/eina/src/include/eina_inline_lock_posix.x @@ -19,6 +19,15 @@ #ifndef EINA_INLINE_LOCK_POSIX_X_ #define EINA_INLINE_LOCK_POSIX_X_ +#ifdef EINA_UNUSED +# undef EINA_UNUSED +#endif +#ifdef __GNUC__ +# define EINA_UNUSED __attribute__((unused)) +#else +# define EINA_UNUSED +#endif + #include #ifndef __USE_UNIX98 # define __USE_UNIX98 @@ -28,7 +37,10 @@ # include #endif +#include + #include +#include #ifdef EINA_HAVE_DEBUG_THREADS #include @@ -45,6 +57,7 @@ typedef struct _Eina_Lock Eina_Lock; typedef struct _Eina_RWLock Eina_RWLock; typedef struct _Eina_Condition Eina_Condition; typedef pthread_key_t Eina_TLS; +typedef sem_t Eina_Semaphore; struct _Eina_Lock { @@ -77,8 +90,6 @@ struct _Eina_RWLock EAPI extern Eina_Bool _eina_threads_activated; #ifdef EINA_HAVE_DEBUG_THREADS -# include - EAPI extern int _eina_threads_debug; EAPI extern pthread_t _eina_main_loop; EAPI extern pthread_mutex_t _eina_tracking_lock; @@ -506,4 +517,40 @@ eina_tls_set(Eina_TLS key, const void *data) return EINA_TRUE; } +static inline Eina_Bool +eina_semaphore_new(Eina_Semaphore *sem, int count_init) +{ + if (!sem || (count_init <= 0)) + return EINA_FALSE; + + return (sem_init(sem, count_init, 1) == 0) ? EINA_TRUE : EINA_FALSE; +} + +static inline Eina_Bool +eina_semaphore_free(Eina_Semaphore *sem) +{ + if (!sem) + return EINA_FALSE; + + return (sem_destroy(sem) == 0) ? EINA_TRUE : EINA_FALSE; +} + +static inline Eina_Bool +eina_semaphore_lock(Eina_Semaphore *sem) +{ + if (!sem) + return EINA_FALSE; + + return (sem_wait(sem) == 0) ? EINA_TRUE : EINA_FALSE; +} + +static inline Eina_Bool +eina_semaphore_release(Eina_Semaphore *sem, int count_release EINA_UNUSED) +{ + if (!sem) + return EINA_FALSE; + + return (sem_post(sem) == 0) ? EINA_TRUE : EINA_FALSE; +} + #endif diff --git a/libraries/eina/src/include/eina_inline_lock_void.x b/libraries/eina/src/include/eina_inline_lock_void.x index 8cb9a49..2f5209f 100644 --- a/libraries/eina/src/include/eina_inline_lock_void.x +++ b/libraries/eina/src/include/eina_inline_lock_void.x @@ -47,6 +47,7 @@ typedef void *Eina_Lock; typedef void *Eina_RWLock; typedef void *Eina_Condition; typedef void *Eina_TLS; +typedef void *Eina_Semaphore; /** * @brief Create a new #Eina_Lock. @@ -63,7 +64,7 @@ typedef void *Eina_TLS; static inline Eina_Bool eina_lock_new(Eina_Lock *mutex EINA_UNUSED) { - return EINA_FALSE; + return EINA_TRUE; } /** @@ -94,7 +95,7 @@ eina_lock_free(Eina_Lock *mutex EINA_UNUSED) static inline Eina_Lock_Result eina_lock_take(Eina_Lock *mutex EINA_UNUSED) { - return EINA_LOCK_FAIL; + return EINA_LOCK_SUCCEED; } /** @@ -115,7 +116,7 @@ eina_lock_take(Eina_Lock *mutex EINA_UNUSED) static inline Eina_Lock_Result eina_lock_take_try(Eina_Lock *mutex EINA_UNUSED) { - return EINA_LOCK_FAIL; + return EINA_LOCK_SUCCEED; } /** @@ -132,7 +133,7 @@ eina_lock_take_try(Eina_Lock *mutex EINA_UNUSED) static inline Eina_Lock_Result eina_lock_release(Eina_Lock *mutex EINA_UNUSED) { - return EINA_LOCK_FAIL; + return EINA_LOCK_SUCCEED; } static inline void @@ -143,7 +144,7 @@ eina_lock_debug(const Eina_Lock *mutex EINA_UNUSED) static inline Eina_Bool eina_condition_new(Eina_Condition *cond EINA_UNUSED, Eina_Lock *mutex EINA_UNUSED) { - return EINA_FALSE; + return EINA_TRUE; } static inline void @@ -154,72 +155,72 @@ eina_condition_free(Eina_Condition *cond EINA_UNUSED) static inline Eina_Bool eina_condition_wait(Eina_Condition *cond EINA_UNUSED) { - return EINA_FALSE; + return EINA_TRUE; } static inline Eina_Bool eina_condition_timedwait(Eina_Condition *cond EINA_UNUSED, double val EINA_UNUSED) { - return EINA_FALSE; + return EINA_TRUE; } static inline Eina_Bool eina_condition_broadcast(Eina_Condition *cond EINA_UNUSED) { - return EINA_FALSE; + return EINA_TRUE; } static inline Eina_Bool eina_condition_signal(Eina_Condition *cond EINA_UNUSED) { - return EINA_FALSE; + return EINA_TRUE; } static inline Eina_Bool eina_rwlock_new(Eina_RWLock *mutex EINA_UNUSED) { - return EINA_FALSE; + return EINA_TRUE; } static inline void - eina_rwlock_free(Eina_RWLock *mutex EINA_UNUSED) +eina_rwlock_free(Eina_RWLock *mutex EINA_UNUSED) { } static inline Eina_Lock_Result eina_rwlock_read_take(Eina_RWLock *mutex EINA_UNUSED) { - return EINA_LOCK_FAIL; + return EINA_LOCK_SUCCEED; } static inline Eina_Lock_Result eina_rwlock_write_take(Eina_RWLock *mutex EINA_UNUSED) { - return EINA_LOCK_FAIL; + return EINA_LOCK_SUCCEED; } static inline Eina_Lock_Result eina_rwlock_release(Eina_RWLock *mutex EINA_UNUSED) { - return EINA_LOCK_FAIL; + return EINA_LOCK_SUCCEED; } static inline Eina_Lock_Result eina_rwlock_take_read(Eina_RWLock *mutex EINA_UNUSED) { - return EINA_LOCK_FAIL; + return EINA_LOCK_SUCCEED; } static inline Eina_Lock_Result eina_rwlock_take_write(Eina_RWLock *mutex EINA_UNUSED) { - return EINA_LOCK_FAIL; + return EINA_LOCK_SUCCEED; } static inline Eina_Bool eina_tls_new(Eina_TLS *key EINA_UNUSED) { - return EINA_FALSE; + return EINA_TRUE; } static inline void @@ -236,9 +237,34 @@ eina_tls_get(Eina_TLS key EINA_UNUSED) static inline Eina_Bool eina_tls_set(Eina_TLS key EINA_UNUSED, const void *data EINA_UNUSED) { - return EINA_FALSE; + return EINA_TRUE; } +static inline Eina_Bool +eina_semaphore_new(Eina_Semaphore *sem EINA_UNUSED, + int count_init EINA_UNUSED) +{ + return EINA_TRUE; +} + +static inline Eina_Bool +eina_semaphore_free(Eina_Semaphore *sem EINA_UNUSED) +{ + return EINA_TRUE; +} + +static inline Eina_Bool +eina_semaphore_lock(Eina_Semaphore *sem EINA_UNUSED) +{ + return EINA_TRUE; +} + +static inline Eina_Bool +eina_semaphore_release(Eina_Semaphore *sem EINA_UNUSED, + int count_release EINA_UNUSED) +{ + return EINA_TRUE; +} /** * @} diff --git a/libraries/eina/src/include/eina_inline_lock_win32.x b/libraries/eina/src/include/eina_inline_lock_win32.x index 072095c..e8363d5 100644 --- a/libraries/eina/src/include/eina_inline_lock_win32.x +++ b/libraries/eina/src/include/eina_inline_lock_win32.x @@ -58,6 +58,8 @@ struct _Eina_Win32_RWLock typedef DWORD Eina_TLS; +typedef HANDLE Eina_Semaphore; + EAPI extern Eina_Bool _eina_threads_activated; static inline Eina_Bool @@ -463,4 +465,48 @@ eina_tls_set(Eina_TLS key, const void *data) return EINA_TRUE; } +static inline Eina_Bool +eina_semaphore_new(Eina_Semaphore *sem, int count_init) +{ + if (!sem || (count_init <= 0)) + return EINA_FALSE; + + *sem = CreateSemaphore(NULL, count_init, 32767, NULL); + if (!*sem) + return EINA_FALSE; +} + +static inline Eina_Bool +eina_semaphore_free(Eina_Semaphore *sem) +{ + if (!sem) + return EINA_FALSE; + + CloseHandle(*sem); +} + +static inline Eina_Bool +eina_semaphore_lock(Eina_Semaphore *sem) +{ + DWORD res; + + if (!sem) + return EINA_FALSE; + + res = WaitForSingleObject(*sem, 0L); + if (res == WAIT_OBJECT_0) + return EINA_TRUE; + + return EINA_FALSE; +} + +static inline Eina_Bool +eina_semaphore_release(Eina_Semaphore *sem, int count_release) +{ + if (!sem) + return EINA_FALSE; + + return ReleaseSemaphore(*sem, count_release, NULL) ? EINA_TRUE : EINA_FALSE; +} + #endif diff --git a/libraries/eina/src/include/eina_inline_lock_wince.x b/libraries/eina/src/include/eina_inline_lock_wince.x index 965d475..1af1aac 100644 --- a/libraries/eina/src/include/eina_inline_lock_wince.x +++ b/libraries/eina/src/include/eina_inline_lock_wince.x @@ -19,6 +19,15 @@ #ifndef EINA_INLINE_LOCK_WIN32_X_ #define EINA_INLINE_LOCK_WIN32_X_ +#ifdef EINA_UNUSED +# undef EINA_UNUSED +#endif +#ifdef __GNUC__ +# define EINA_UNUSED __attribute__((unused)) +#else +# define EINA_UNUSED +#endif + #include EAPI extern Eina_Bool _threads_activated; @@ -26,6 +35,7 @@ EAPI extern Eina_Bool _threads_activated; typedef HANDLE Eina_Lock; typedef Eina_Lock Eina_RWLock; typedef DWORD Eina_TLS; +typedef void * Eina_Semaphore; static inline Eina_Bool eina_lock_new(Eina_Lock *mutex) @@ -173,6 +183,30 @@ eina_tls_set(Eina_TLS key, const void *data) return EINA_TRUE; } +static inline Eina_Bool +eina_semaphore_new(Eina_Semaphore *sem EINA_UNUSED, + int count_init EINA_UNUSED) +{ + return EINA_FALSE; +} +static inline Eina_Bool +eina_semaphore_free(Eina_Semaphore *sem EINA_UNUSED) +{ + return EINA_FALSE; +} + +static inline Eina_Bool +eina_semaphore_lock(Eina_Semaphore *sem EINA_UNUSED) +{ + return EINA_FALSE; +} + +static inline Eina_Bool +eina_semaphore_release(Eina_Semaphore *sem EINA_UNUSED, + int count_release EINA_UNUSED) +{ + return EINA_FALSE; +} #endif diff --git a/libraries/eina/src/include/eina_inline_log.x b/libraries/eina/src/include/eina_inline_log.x index 4cdd7d8..53d8afb 100644 --- a/libraries/eina/src/include/eina_inline_log.x +++ b/libraries/eina/src/include/eina_inline_log.x @@ -49,7 +49,7 @@ static inline Eina_Bool eina_log_level_check(int level) { - return eina_log_level_get() <= level; + return eina_log_level_get() >= level; } /** @@ -81,7 +81,7 @@ eina_log_domain_level_check(int domain, int level) int dom_level = eina_log_domain_registered_level_get(domain); if (EINA_UNLIKELY(dom_level == EINA_LOG_LEVEL_UNKNOWN)) return EINA_FALSE; - return dom_level <= level; + return dom_level >= level; } /** diff --git a/libraries/eina/src/include/eina_inline_mempool.x b/libraries/eina/src/include/eina_inline_mempool.x index a67ec3d..729a669 100644 --- a/libraries/eina/src/include/eina_inline_mempool.x +++ b/libraries/eina/src/include/eina_inline_mempool.x @@ -19,6 +19,8 @@ #ifndef EINA_INLINE_MEMPOOL_X_ #define EINA_INLINE_MEMPOOL_X_ +#include + /** * @addtogroup Eina_Memory_Pool_Group Memory Pool * @@ -67,17 +69,16 @@ struct _Eina_Mempool }; /** - * @brief Re-allocate a amount memory by the given mempool. + * @brief Re-allocate an amount memory by the given mempool. * * @param mp The mempool. * @param element The element to re-allocate. * @param size The size in bytes to re-allocate. * @return The newly re-allocated data. * - * This function re-allocates @p element with @p size bytes, using the - * mempool @p mp and returns the allocated data. If not used anymore, - * the data must be freed with eina_mempool_free(). No check is done - * on @p mp, so it must be a valid mempool. + * This function re-allocates and returns @p element with @p size bytes using the + * mempool @p mp. If not used anymore, the data must be freed with eina_mempool_free(). + * @warning No checks are done for @p mp. */ static inline void * eina_mempool_realloc(Eina_Mempool *mp, void *element, unsigned int size) @@ -86,16 +87,15 @@ eina_mempool_realloc(Eina_Mempool *mp, void *element, unsigned int size) } /** - * @brief Allocate a amount memory by the given mempool. + * @brief Allocate memory using the given mempool. * * @param mp The mempool. * @param size The size in bytes to allocate. * @return The newly allocated data. * - * This function allocates @p size bytes, using the mempool @p mp and - * returns the allocated data. If not used anymore, the data must be - * freed with eina_mempool_free(). No check is done on @p mp, so it - * must be a valid mempool. + * This function allocates and returns @p size bytes using the mempool @p mp. + * If not used anymore, the data must be freed with eina_mempool_free(). + * @warning No checks are done for @p mp. */ static inline void * eina_mempool_malloc(Eina_Mempool *mp, unsigned int size) @@ -104,15 +104,36 @@ eina_mempool_malloc(Eina_Mempool *mp, unsigned int size) } /** - * @brief Free the allocated ressources by the given mempool. + * @brief Allocate and zero memory using the given mempool. + * + * @param mp The mempool. + * @param size The size in bytes to allocate. + * @return The newly allocated data. + * + * This function allocates, zeroes, and returns @p size bytes using the mempool @p mp. + * If not used anymore, the data must be freed with eina_mempool_free(). + * @warning No checks are done for @p mp. + * @since 1.2 + */ +static inline void * +eina_mempool_calloc(Eina_Mempool *mp, unsigned int size) +{ + void *r = mp->backend.alloc(mp->backend_data, size); + if (!r) return NULL; + memset(r, 0, size); + return r; +} + +/** + * @brief Free resources previously allocated by the given mempool. * * @param mp The mempool. * @param element The data to free. * * This function frees @p element allocated by @p mp. @p element must - * have been obtained by eina_mempool_malloc() or - * eina_mempool_realloc(). No check is done on @p mp, so it must be a - * valid mempool. + * have been obtained from eina_mempool_malloc(), eina_mempool_calloc(), or + * eina_mempool_realloc(). + * @warning No checks are done for @p mp. */ static inline void eina_mempool_free(Eina_Mempool *mp, void *element) diff --git a/libraries/eina/src/include/eina_inline_value.x b/libraries/eina/src/include/eina_inline_value.x new file mode 100644 index 0000000..59ec315 --- /dev/null +++ b/libraries/eina/src/include/eina_inline_value.x @@ -0,0 +1,1705 @@ +/* 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 . + */ + +#ifndef EINA_INLINE_VALUE_X_ +#define EINA_INLINE_VALUE_X_ + +#include +#include + +#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 + +/** + * @var _EINA_VALUE_TYPE_BASICS_START + * pointer to the first basic type. + * @since 1.2 + * @private + */ +EAPI extern const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_START; + +/** + * @var _EINA_VALUE_TYPE_BASICS_END + * pointer to the last (inclusive) basic type. + * @since 1.2 + * @private + */ +EAPI extern const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_END; +#define EINA_VALUE_TYPE_DEFAULT(type) \ + ((_EINA_VALUE_TYPE_BASICS_START <= type) && \ + (type <= _EINA_VALUE_TYPE_BASICS_END)) +#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) + +/** + * @brief Get memory for given value (inline or allocated buffer). + * @since 1.2 + * @private + */ +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; +} + +/** + * @brief Allocate memory for internal value types. + * @since 1.2 + * @private + */ +EAPI void *eina_value_inner_alloc(size_t size); +/** + * @brief Releases memory for internal value types. + * @since 1.2 + * @private + */ +EAPI void eina_value_inner_free(size_t size, void *mem); + +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; + else + { + mem = value->value.ptr = eina_value_inner_alloc(type->value_size); + EINA_SAFETY_ON_NULL_RETURN_VAL(mem, EINA_FALSE); + } + + memset(mem, 0, type->value_size); + + 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((const char*) value->value.ptr); + } + else if (type == EINA_VALUE_TYPE_STRING) + { + if (value->value.ptr) free(value->value.ptr); + } + else if (type->value_size > 8) + eina_value_inner_free(type->value_size, mem); + eina_error_set(0); + return; + } + + EINA_VALUE_TYPE_DISPATCH(type, flush, EINA_ERROR_VALUE_FAILED, mem); + if (type->value_size > 8) + eina_value_inner_free(type->value_size, 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 = (unsigned char *) pa, *tb = (unsigned char *) pb; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; + } + else if (type == EINA_VALUE_TYPE_USHORT) + { + unsigned short *ta = (unsigned short *) pa, *tb = (unsigned short *) pb; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; + } + else if (type == EINA_VALUE_TYPE_UINT) + { + unsigned int *ta = (unsigned int *) pa, *tb = (unsigned int *) pb; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; + } + else if (type == EINA_VALUE_TYPE_ULONG) + { + unsigned long *ta = (unsigned long *) pa, *tb = (unsigned long *) pb; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; + } + else if (type == EINA_VALUE_TYPE_UINT64) + { + uint64_t *ta = (uint64_t *) pa, *tb = (uint64_t *) pb; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; + } + else if (type == EINA_VALUE_TYPE_CHAR) + { + char *ta = (char *) pa, *tb = (char *) pb; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; + } + else if (type == EINA_VALUE_TYPE_SHORT) + { + short *ta = (short *) pa, *tb = (short *) pb; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; + } + else if (type == EINA_VALUE_TYPE_INT) + { + int *ta = (int *) pa, *tb = (int *) pb; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; + } + else if (type == EINA_VALUE_TYPE_LONG) + { + long *ta = (long *) pa, *tb = (long *) pb; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; + } + else if (type == EINA_VALUE_TYPE_INT64) + { + int64_t *ta = (int64_t *) pa, *tb = (int64_t *) pb; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; + } + else if (type == EINA_VALUE_TYPE_FLOAT) + { + float *ta = (float *) pa, *tb = (float *) pb; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; + } + else if (type == EINA_VALUE_TYPE_DOUBLE) + { + double *ta = (double *) pa, *tb = (double *) 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 = (unsigned char *) mem; + *tmem = va_arg(args, unsigned int); /* promoted by va_arg */ + return EINA_TRUE; + } + else if (type == EINA_VALUE_TYPE_USHORT) + { + unsigned short *tmem = (unsigned short *) mem; + *tmem = va_arg(args, unsigned int); /* promoted by va_arg */ + return EINA_TRUE; + } + else if (type == EINA_VALUE_TYPE_UINT) + { + unsigned int *tmem = (unsigned int *) mem; + *tmem = va_arg(args, unsigned int); + return EINA_TRUE; + } + else if (type == EINA_VALUE_TYPE_ULONG) + { + unsigned long *tmem = (unsigned long *) mem; + *tmem = va_arg(args, unsigned long); + return EINA_TRUE; + } + else if (type == EINA_VALUE_TYPE_UINT64) + { + uint64_t *tmem = (uint64_t *) mem; + *tmem = va_arg(args, uint64_t); + return EINA_TRUE; + } + else if (type == EINA_VALUE_TYPE_CHAR) + { + char *tmem = (char *) mem; + *tmem = va_arg(args, int); /* promoted by va_arg */ + return EINA_TRUE; + } + else if (type == EINA_VALUE_TYPE_SHORT) + { + short *tmem = (short *) mem; + *tmem = va_arg(args, int); /* promoted by va_arg */ + return EINA_TRUE; + } + else if (type == EINA_VALUE_TYPE_INT) + { + int *tmem = (int *) mem; + *tmem = va_arg(args, int); + return EINA_TRUE; + } + else if (type == EINA_VALUE_TYPE_LONG) + { + long *tmem = (long *) mem; + *tmem = va_arg(args, long); + return EINA_TRUE; + } + else if (type == EINA_VALUE_TYPE_INT64) + { + int64_t *tmem = (int64_t *) mem; + *tmem = va_arg(args, int64_t); + return EINA_TRUE; + } + else if (type == EINA_VALUE_TYPE_FLOAT) + { + float *tmem = (float *) mem; + *tmem = va_arg(args, double); /* promoted by va_arg */ + return EINA_TRUE; + } + else if (type == EINA_VALUE_TYPE_DOUBLE) + { + double *tmem = (double *) mem; + *tmem = va_arg(args, double); + return EINA_TRUE; + } + else if (type == EINA_VALUE_TYPE_STRINGSHARE) + { + const char *str = (const char *) 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 = (const char *) 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 *pstr = (const char * const *) ptr; + const char *str = *pstr; + + return eina_stringshare_replace((const char **)&value->value.ptr, + str); + } + else if (type == EINA_VALUE_TYPE_STRING) + { + const char * const * pstr = (const char * const *) ptr; + const char *str = *pstr; + + 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; + + EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0); + if (!eina_value_pget(value, &desc)) + return EINA_FALSE; + + mem = eina_inarray_alloc_at(desc.array, position, 1); + 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; + int position; + + EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0); + if (!eina_value_pget(value, &desc)) + return EINA_FALSE; + + position = eina_inarray_count(desc.array); + mem = eina_inarray_alloc_at(desc.array, position, 1); + 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; + + EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0); + if (!eina_value_pget(value, &desc)) + return EINA_FALSE; + + mem = eina_inarray_alloc_at(desc.array, position, 1); + 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; + int position; + + EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0); + if (!eina_value_pget(value, &desc)) + return EINA_FALSE; + + position = eina_inarray_count(desc.array); + mem = eina_inarray_alloc_at(desc.array, position, 1); + 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 + +#define EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, retval) \ + EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \ + EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_LIST, retval) + +static inline void * +eina_value_list_node_memory_get(const Eina_Value_Type *type, const Eina_List *node) +{ + if (node == NULL) return NULL; + if (type->value_size <= sizeof(void*)) + return (void *)&(node->data); + return node->data; +} + +static inline void * +eina_value_list_node_memory_setup(const Eina_Value_Type *type, Eina_List *node) +{ + if (type->value_size <= sizeof(void*)) + return (void *)&(node->data); + node->data = malloc(type->value_size); + return node->data; +} + +static inline void +eina_value_list_node_memory_flush(const Eina_Value_Type *type, Eina_List *node) +{ + if (type->value_size <= sizeof(void*)) + return; + free(node->data); +} + +static inline Eina_Bool +eina_value_list_setup(Eina_Value *value, const Eina_Value_Type *subtype) +{ + Eina_Value_List desc = { subtype, NULL }; + if (!eina_value_setup(value, EINA_VALUE_TYPE_LIST)) + 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_list_count(const Eina_Value *value) +{ + Eina_Value_List *desc; + EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0); + desc = (Eina_Value_List *)eina_value_memory_get(value); + if (!desc) + return 0; + return eina_list_count(desc->list); +} + +static inline Eina_Bool +eina_value_list_remove(Eina_Value *value, unsigned int position) +{ + Eina_Value_List *desc; + Eina_List *node; + void *mem; + + EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0); + desc = (Eina_Value_List *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + node = eina_list_nth_list(desc->list, position); + mem = eina_value_list_node_memory_get(desc->subtype, node); + if (!mem) + return EINA_FALSE; + + eina_value_type_flush(desc->subtype, mem); + eina_value_list_node_memory_flush(desc->subtype, node); + desc->list = eina_list_remove_list(desc->list, node); + return EINA_TRUE; +} + +static inline Eina_Bool +eina_value_list_vset(Eina_Value *value, unsigned int position, va_list args) +{ + Eina_Value_List *desc; + Eina_List *node; + void *mem; + + EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0); + desc = (Eina_Value_List *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + node = eina_list_nth_list(desc->list, position); + mem = eina_value_list_node_memory_get(desc->subtype, node); + 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_list_vget(const Eina_Value *value, unsigned int position, va_list args) +{ + const Eina_Value_List *desc; + const Eina_List *node; + const void *mem; + void *ptr; + Eina_Bool ret; + + EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0); + desc = (const Eina_Value_List *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + node = eina_list_nth_list(desc->list, position); + mem = eina_value_list_node_memory_get(desc->subtype, node); + 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_list_vinsert(Eina_Value *value, unsigned int position, va_list args) +{ + Eina_Value_List *desc; + Eina_List *node; + void *mem; + + EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0); + desc = (Eina_Value_List *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + if (!desc->list) + node = desc->list = eina_list_append(NULL, (void*)1L); + else if (position == 0) + node = desc->list = eina_list_prepend(desc->list, (void*)1L); + else + { + Eina_List *rel = eina_list_nth_list(desc->list, position - 1); + desc->list = eina_list_append_relative_list(desc->list, (void*)1L, rel); + node = rel->next; + } + EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE); + + mem = eina_value_list_node_memory_setup(desc->subtype, node); + if (!mem) + { + desc->list = eina_list_remove_list(desc->list, node); + 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_value_list_node_memory_flush(desc->subtype, node); + desc->list = eina_list_remove_list(desc->list, node); + return EINA_FALSE; +} + +static inline Eina_Bool +eina_value_list_vappend(Eina_Value *value, va_list args) +{ + Eina_Value_List *desc; + Eina_List *node; + void *mem; + + EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0); + desc = (Eina_Value_List *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + desc->list = eina_list_append(desc->list, (void*)1L); + node = eina_list_last(desc->list); + EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE); + + mem = eina_value_list_node_memory_setup(desc->subtype, node); + if (!mem) + { + desc->list = eina_list_remove_list(desc->list, node); + 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_value_list_node_memory_flush(desc->subtype, node); + desc->list = eina_list_remove_list(desc->list, node); + return EINA_FALSE; +} + +static inline Eina_Bool +eina_value_list_set(Eina_Value *value, unsigned int position, ...) +{ + va_list args; + Eina_Bool ret; + va_start(args, position); + ret = eina_value_list_vset(value, position, args); + va_end(args); + return ret; +} + +static inline Eina_Bool +eina_value_list_get(const Eina_Value *value, unsigned int position, ...) +{ + va_list args; + Eina_Bool ret; + va_start(args, position); + ret = eina_value_list_vget(value, position, args); + va_end(args); + return ret; +} + +static inline Eina_Bool +eina_value_list_insert(Eina_Value *value, unsigned int position, ...) +{ + va_list args; + Eina_Bool ret; + va_start(args, position); + ret = eina_value_list_vinsert(value, position, args); + va_end(args); + return ret; +} + +static inline Eina_Bool eina_value_list_append(Eina_Value *value, ...) +{ + va_list args; + Eina_Bool ret; + va_start(args, value); + ret = eina_value_list_vappend(value, args); + va_end(args); + return ret; +} + +static inline Eina_Bool +eina_value_list_pset(Eina_Value *value, unsigned int position, const void *ptr) +{ + Eina_Value_List *desc; + Eina_List *node; + void *mem; + + EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0); + desc = (Eina_Value_List *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + node = eina_list_nth_list(desc->list, position); + mem = eina_value_list_node_memory_get(desc->subtype, node); + 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_list_pget(const Eina_Value *value, unsigned int position, void *ptr) +{ + const Eina_Value_List *desc; + const Eina_List *node; + const void *mem; + Eina_Bool ret; + + EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0); + desc = (const Eina_Value_List *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + node = eina_list_nth_list(desc->list, position); + mem = eina_value_list_node_memory_get(desc->subtype, node); + if (!mem) + return EINA_FALSE; + + ret = eina_value_type_pget(desc->subtype, mem, ptr); + return ret; +} + +static inline Eina_Bool +eina_value_list_pinsert(Eina_Value *value, unsigned int position, const void *ptr) +{ + Eina_Value_List *desc; + Eina_List *node; + void *mem; + + EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0); + desc = (Eina_Value_List *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + if (!desc->list) + node = desc->list = eina_list_append(NULL, (void*)1L); + else if (position == 0) + node = desc->list = eina_list_prepend(desc->list, (void*)1L); + else + { + Eina_List *rel = eina_list_nth_list(desc->list, position - 1); + desc->list = eina_list_append_relative_list(desc->list, (void*)1L, rel); + node = rel->next; + } + EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE); + + mem = eina_value_list_node_memory_setup(desc->subtype, node); + if (!mem) + { + desc->list = eina_list_remove_list(desc->list, node); + 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_value_list_node_memory_flush(desc->subtype, node); + desc->list = eina_list_remove_list(desc->list, node); + return EINA_FALSE; +} + +static inline Eina_Bool +eina_value_list_pappend(Eina_Value *value, const void *ptr) +{ + Eina_Value_List *desc; + Eina_List *node; + void *mem; + + EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0); + desc = (Eina_Value_List *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + desc->list = eina_list_append(desc->list, (void*)1L); + node = eina_list_last(desc->list); + EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE); + + mem = eina_value_list_node_memory_setup(desc->subtype, node); + if (!mem) + { + desc->list = eina_list_remove_list(desc->list, node); + 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_value_list_node_memory_flush(desc->subtype, node); + desc->list = eina_list_remove_list(desc->list, node); + return EINA_FALSE; +} +#undef EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL + +#define EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, retval) \ + EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \ + EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_HASH, retval) + +static inline Eina_Bool +eina_value_hash_setup(Eina_Value *value, const Eina_Value_Type *subtype, unsigned int buckets_power_size) +{ + Eina_Value_Hash desc = { subtype, buckets_power_size, NULL }; + if (!eina_value_setup(value, EINA_VALUE_TYPE_HASH)) + 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_hash_population(const Eina_Value *value) +{ + Eina_Value_Hash *desc; + EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0); + desc = (Eina_Value_Hash *)eina_value_memory_get(value); + if (!desc) + return 0; + return eina_hash_population(desc->hash); +} + +static inline Eina_Bool +eina_value_hash_del(Eina_Value *value, const char *key) +{ + Eina_Value_Hash *desc; + void *mem; + + EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); + desc = (Eina_Value_Hash *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + mem = eina_hash_find(desc->hash, key); + if (!mem) + return EINA_FALSE; + + eina_value_type_flush(desc->subtype, mem); + free(mem); + eina_hash_del_by_key(desc->hash, key); + return EINA_TRUE; +} + +static inline Eina_Bool +eina_value_hash_vset(Eina_Value *value, const char *key, va_list args) +{ + Eina_Value_Hash *desc; + void *mem; + + EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); + desc = (Eina_Value_Hash *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + mem = eina_hash_find(desc->hash, key); + if (mem) + eina_value_type_flush(desc->subtype, mem); + else + { + mem = malloc(desc->subtype->value_size); + if (!mem) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + if (!eina_hash_add(desc->hash, key, mem)) + { + free(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_hash_del_by_key(desc->hash, key); + free(mem); + return EINA_FALSE; +} + +static inline Eina_Bool +eina_value_hash_vget(const Eina_Value *value, const char *key, va_list args) +{ + const Eina_Value_Hash *desc; + const void *mem; + void *ptr; + Eina_Bool ret; + + EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); + desc = (const Eina_Value_Hash *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + mem = eina_hash_find(desc->hash, key); + 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_hash_set(Eina_Value *value, const char *key, ...) +{ + va_list args; + Eina_Bool ret; + va_start(args, key); + ret = eina_value_hash_vset(value, key, args); + va_end(args); + return ret; +} + +static inline Eina_Bool +eina_value_hash_get(const Eina_Value *value, const char *key, ...) +{ + va_list args; + Eina_Bool ret; + va_start(args, key); + ret = eina_value_hash_vget(value, key, args); + va_end(args); + return ret; +} + +static inline Eina_Bool +eina_value_hash_pset(Eina_Value *value, const char *key, const void *ptr) +{ + Eina_Value_Hash *desc; + void *mem; + + EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); + desc = (Eina_Value_Hash *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + mem = eina_hash_find(desc->hash, key); + if (mem) + eina_value_type_flush(desc->subtype, mem); + else + { + mem = malloc(desc->subtype->value_size); + if (!mem) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + if (!eina_hash_add(desc->hash, key, mem)) + { + free(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_hash_del_by_key(desc->hash, key); + free(mem); + return EINA_FALSE; +} + +static inline Eina_Bool +eina_value_hash_pget(const Eina_Value *value, const char *key, void *ptr) +{ + const Eina_Value_Hash *desc; + const void *mem; + Eina_Bool ret; + + EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE); + desc = (const Eina_Value_Hash *)eina_value_memory_get(value); + if (!desc) + return EINA_FALSE; + + mem = eina_hash_find(desc->hash, key); + if (!mem) + return EINA_FALSE; + + ret = eina_value_type_pget(desc->subtype, mem, ptr); + return ret; +} +#undef EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL + +#define EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, retval) \ + EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \ + EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_STRUCT, retval) + +/** + * @brief Find member of struct + * @since 1.2 + * @internal + */ +EAPI const Eina_Value_Struct_Member *eina_value_struct_member_find(const Eina_Value_Struct *st, const char *name) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT; + +static inline Eina_Bool +eina_value_struct_setup(Eina_Value *value, const Eina_Value_Struct_Desc *sdesc) +{ + Eina_Value_Struct desc = {sdesc, NULL}; + if (!eina_value_setup(value, EINA_VALUE_TYPE_STRUCT)) + return EINA_FALSE; + if (!eina_value_pset(value, &desc)) + { + eina_value_flush(value); + return EINA_FALSE; + } + return EINA_TRUE; +} + +static inline void * +eina_value_struct_member_memory_get(const Eina_Value_Struct *st, const Eina_Value_Struct_Member *member) +{ + unsigned char *base = (unsigned char *)st->memory; + if (!base) return NULL; + return base + member->offset; +} + +static inline Eina_Bool +eina_value_struct_vset(Eina_Value *value, const char *name, va_list args) +{ + const Eina_Value_Struct_Member *member; + Eina_Value_Struct *st; + void *mem; + + EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); + st = (Eina_Value_Struct *)eina_value_memory_get(value); + if (!st) + return EINA_FALSE; + member = eina_value_struct_member_find(st, name); + if (!member) + return EINA_FALSE; + mem = eina_value_struct_member_memory_get(st, member); + if (!mem) + return EINA_FALSE; + + eina_value_type_flush(member->type, mem); + if (!eina_value_type_setup(member->type, mem)) goto error_setup; + if (!eina_value_type_vset(member->type, mem, args)) goto error_set; + return EINA_TRUE; + + error_set: + eina_value_type_flush(member->type, mem); + error_setup: + return EINA_FALSE; +} + +static inline Eina_Bool +eina_value_struct_vget(const Eina_Value *value, const char *name, va_list args) +{ + const Eina_Value_Struct_Member *member; + const Eina_Value_Struct *st; + const void *mem; + void *ptr; + Eina_Bool ret; + + EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); + st = (const Eina_Value_Struct *)eina_value_memory_get(value); + if (!st) + return EINA_FALSE; + member = eina_value_struct_member_find(st, name); + if (!member) + return EINA_FALSE; + mem = eina_value_struct_member_memory_get(st, member); + if (!mem) + return EINA_FALSE; + + ptr = va_arg(args, void *); + ret = eina_value_type_pget(member->type, mem, ptr); + return ret; +} + +static inline Eina_Bool +eina_value_struct_set(Eina_Value *value, const char *name, ...) +{ + va_list args; + Eina_Bool ret; + va_start(args, name); + ret = eina_value_struct_vset(value, name, args); + va_end(args); + return ret; +} + +static inline Eina_Bool +eina_value_struct_get(const Eina_Value *value, const char *name, ...) +{ + va_list args; + Eina_Bool ret; + va_start(args, name); + ret = eina_value_struct_vget(value, name, args); + va_end(args); + return ret; +} + +static inline Eina_Bool +eina_value_struct_pset(Eina_Value *value, const char *name, const void *ptr) +{ + const Eina_Value_Struct_Member *member; + Eina_Value_Struct *st; + void *mem; + + EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); + st = (Eina_Value_Struct *)eina_value_memory_get(value); + if (!st) + return EINA_FALSE; + member = eina_value_struct_member_find(st, name); + if (!member) + return EINA_FALSE; + mem = eina_value_struct_member_memory_get(st, member); + if (!mem) + return EINA_FALSE; + + eina_value_type_flush(member->type, mem); + if (!eina_value_type_setup(member->type, mem)) goto error_setup; + if (!eina_value_type_pset(member->type, mem, ptr)) goto error_set; + return EINA_TRUE; + + error_set: + eina_value_type_flush(member->type, mem); + error_setup: + return EINA_FALSE; +} + +static inline Eina_Bool +eina_value_struct_pget(const Eina_Value *value, const char *name, void *ptr) +{ + const Eina_Value_Struct_Member *member; + const Eina_Value_Struct *st; + const void *mem; + Eina_Bool ret; + + EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE); + st = (const Eina_Value_Struct *)eina_value_memory_get(value); + if (!st) + return EINA_FALSE; + member = eina_value_struct_member_find(st, name); + if (!member) + return EINA_FALSE; + mem = eina_value_struct_member_memory_get(st, member); + if (!mem) + return EINA_FALSE; + + ret = eina_value_type_pget(member->type, mem, ptr); + return ret; +} +#undef EINA_VALUE_TYPE_STRUCT_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, const 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 diff --git a/libraries/eina/src/include/eina_inlist.h b/libraries/eina/src/include/eina_inlist.h index 1b3ab27..cfb3159 100644 --- a/libraries/eina/src/include/eina_inlist.h +++ b/libraries/eina/src/include/eina_inlist.h @@ -25,7 +25,7 @@ #include /** - * @page inlist_01_example_page Eina_Inlist basic usage + * @page eina_inlist_01_example_page Eina_Inlist basic usage * @dontinclude eina_inlist_01.c * * To see the full source for this example, click here: @ref @@ -111,7 +111,7 @@ */ /** - * @page inlist_02_example_page Eina_Inlist advanced usage - lists and inlists + * @page eina_inlist_02_example_page Eina_Inlist advanced usage - lists and inlists * @dontinclude eina_inlist_02.c * * This example describes the usage of @ref Eina_Inlist mixed with @ref @@ -120,7 +120,7 @@ * from this normal list. * * The struct that is going to be used is the same used in @ref - * inlist_01_example_page , since we still need the @ref EINA_INLIST macro to + * eina_inlist_01_example_page , since we still need the @ref EINA_INLIST macro to * declare the inlist node info: * * @skip struct @@ -184,7 +184,7 @@ */ /** - * @page inlist_03_example_page Eina_Inlist advanced usage - multi-inlists + * @page eina_inlist_03_example_page Eina_Inlist advanced usage - multi-inlists * @dontinclude eina_inlist_03.c * * This example describes the usage of multiple inlists storing the same data. @@ -315,7 +315,7 @@ * exactly what type this list is. * * A simple example demonstrating the basic usage of an inlist can be found - * here: @ref inlist_01_example_page + * here: @ref eina_inlist_01_example_page * * @section inlist_algo Algorithm * @@ -368,9 +368,9 @@ * @ref inlist_03_example_page * * List of examples: - * @li @ref inlist_01_example_page - * @li @ref inlist_02_example_page - * @li @ref inlist_03_example_page + * @li @ref eina_inlist_01_example_page + * @li @ref eina_inlist_02_example_page + * @li @ref eina_inlist_03_example_page */ /** @@ -428,17 +428,17 @@ struct _Eina_Inlist * Add a new node to end of a list. * * @note this code is meant to be fast: appends are O(1) and do not - * walk @a list. + * walk @a in_list. * - * @note @a new_l is considered to be in no list. If it was in another + * @note @a in_item is considered to be in no list. If it was in another * list before, eina_inlist_remove() it before adding. No * check of @a new_l prev and next pointers is done, so it's safe * to have them uninitialized. * - * @param list existing list head or NULL to create a new list. - * @param new_l new list node, must not be NULL. + * @param in_list existing list head or NULL to create a new list. + * @param in_item new list node, must not be NULL. * - * @return the new list head. Use it and not @a list anymore. + * @return the new list head. Use it and not @a in_list anymore. */ EAPI Eina_Inlist *eina_inlist_append(Eina_Inlist *in_list, Eina_Inlist *in_item) EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; @@ -447,17 +447,17 @@ EAPI Eina_Inlist *eina_inlist_append(Eina_Inlist *in_list, * Add a new node to beginning of list. * * @note this code is meant to be fast: appends are O(1) and do not - * walk @a list. + * walk @a in_list. * * @note @a new_l is considered to be in no list. If it was in another * list before, eina_inlist_remove() it before adding. No * check of @a new_l prev and next pointers is done, so it's safe * to have them uninitialized. * - * @param list existing list head or NULL to create a new list. - * @param new_l new list node, must not be NULL. + * @param in_list existing list head or NULL to create a new list. + * @param in_item new list node, must not be NULL. * - * @return the new list head. Use it and not @a list anymore. + * @return the new list head. Use it and not @a in_list anymore. */ EAPI Eina_Inlist *eina_inlist_prepend(Eina_Inlist *in_list, Eina_Inlist *in_item) EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; @@ -466,21 +466,21 @@ EAPI Eina_Inlist *eina_inlist_prepend(Eina_Inlist *in_list, * Add a new node after the given relative item in list. * * @note this code is meant to be fast: appends are O(1) and do not - * walk @a list. + * walk @a in_list. * - * @note @a new_l is considered to be in no list. If it was in another + * @note @a in_item_l is considered to be in no list. If it was in another * list before, eina_inlist_remove() it before adding. No - * check of @a new_l prev and next pointers is done, so it's safe + * check of @a in_item prev and next pointers is done, so it's safe * to have them uninitialized. * - * @note @a relative is considered to be inside @a list, no checks are + * @note @a in_relative is considered to be inside @a in_list, no checks are * done to confirm that and giving nodes from different lists - * will lead to problems. Giving NULL @a relative is the same as + * will lead to problems. Giving NULL @a in_relative is the same as * eina_list_append(). * - * @param list existing list head or NULL to create a new list. - * @param new_l new list node, must not be NULL. - * @param relative reference node, @a new_l will be added after it. + * @param in_list existing list head or NULL to create a new list. + * @param in_item new list node, must not be NULL. + * @param in_relative reference node, @a in_item will be added after it. * * @return the new list head. Use it and not @a list anymore. */ @@ -492,23 +492,23 @@ EAPI Eina_Inlist *eina_inlist_append_relative(Eina_Inlist *in_list, * Add a new node before the given relative item in list. * * @note this code is meant to be fast: appends are O(1) and do not - * walk @a list. + * walk @a in_list. * - * @note @a new_l is considered to be in no list. If it was in another + * @note @a in_item is considered to be in no list. If it was in another * list before, eina_inlist_remove() it before adding. No - * check of @a new_l prev and next pointers is done, so it's safe + * check of @a in_item prev and next pointers is done, so it's safe * to have them uninitialized. * - * @note @a relative is considered to be inside @a list, no checks are + * @note @a in_relative is considered to be inside @a in_list, no checks are * done to confirm that and giving nodes from different lists - * will lead to problems. Giving NULL @a relative is the same as + * will lead to problems. Giving NULL @a in_relative is the same as * eina_list_prepend(). * - * @param list existing list head or NULL to create a new list. - * @param new_l new list node, must not be NULL. - * @param relative reference node, @a new_l will be added before it. + * @param in_list existing list head or NULL to create a new list. + * @param in_item new list node, must not be NULL. + * @param in_relative reference node, @a in_item will be added before it. * - * @return the new list head. Use it and not @a list anymore. + * @return the new list head. Use it and not @a in_list anymore. */ EAPI Eina_Inlist *eina_inlist_prepend_relative(Eina_Inlist *in_list, Eina_Inlist *in_item, @@ -520,14 +520,14 @@ EAPI Eina_Inlist *eina_inlist_prepend_relative(Eina_Inlist *in_list, * @note this code is meant to be fast: appends are O(1) and do not * walk @a list. * - * @note @a item is considered to be inside @a list, no checks are + * @note @a in_item is considered to be inside @a in_list, no checks are * done to confirm that and giving nodes from different lists - * will lead to problems, especially if @a item is the head since + * will lead to problems, especially if @a in_item is the head since * it will be different from @a list and the wrong new head will * be returned. * - * @param list existing list head, must not be NULL. - * @param item existing list node, must not be NULL. + * @param in_list existing list head, must not be NULL. + * @param in_item existing list node, must not be NULL. * * @return the new list head. Use it and not @a list anymore. */ @@ -540,10 +540,10 @@ EAPI Eina_Inlist *eina_inlist_remove(Eina_Inlist *in_list, * @warning this is an expensive call and has O(n) cost, possibly * walking the whole list. * - * @param list existing list to search @a item in, must not be NULL. - * @param item what to search for, must not be NULL. + * @param in_list existing list to search @a in_item in, must not be NULL. + * @param in_item what to search for, must not be NULL. * - * @return @a item if found, NULL if not. + * @return @a in_item if found, NULL if not. */ EAPI Eina_Inlist *eina_inlist_find(Eina_Inlist *in_list, Eina_Inlist *in_item) EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT; @@ -603,11 +603,11 @@ EAPI unsigned int eina_inlist_count(const Eina_Inlist *list) EINA_WARN_UNUSED_ /** * @brief Returns a new iterator associated to @a list. * - * @param list The list. + * @param in_list The list. * @return A new iterator. * * This function returns a newly allocated iterator associated to @p - * list. If @p list is @c NULL or the count member of @p list is less + * in_list. If @p in_list is @c NULL or the count member of @p in_list is less * or equal than 0, this function still returns a valid iterator that * will always return false on eina_iterator_next(), thus keeping API * sane. @@ -625,13 +625,13 @@ EAPI Eina_Iterator *eina_inlist_iterator_new(const Eina_Inlist *in_list) EINA_MA /** * @brief Returns a new accessor associated to a list. * - * @param list The list. + * @param in_list The list. * @return A new accessor. * * This function returns a newly allocated accessor associated to - * @p list. If @p list is @c NULL or the count member of @p list is - * less or equal than 0, this function returns NULL. If the memory can - * not be allocated, NULL is returned and #EINA_ERROR_OUT_OF_MEMORY is + * @p in_list. If @p in_list is @c NULL or the count member of @p in_list is + * less or equal than 0, this function returns @c NULL. If the memory can + * not be allocated, @c NULL is returned and #EINA_ERROR_OUT_OF_MEMORY is * set. Otherwise, a valid accessor is returned. */ EAPI Eina_Accessor *eina_inlist_accessor_new(const Eina_Inlist *in_list) EINA_MALLOC EINA_WARN_UNUSED_RESULT; @@ -728,13 +728,13 @@ EAPI Eina_Inlist *eina_inlist_sorted_state_insert(Eina_Inlist *list, /** * @brief Sort a list according to the ordering func will return. * - * @param list The list handle to sort. + * @param head The list handle to sort. * @param func A function pointer that can handle comparing the list data * nodes. * @return the new head of list. * - * This function sorts all the elements of @p list. @p func is used to - * compare two elements of @p list. If @p list or @p func are @c NULL, + * This function sorts all the elements of @p head. @p func is used to + * compare two elements of @p head. If @p head or @p func are @c NULL, * this function returns @c NULL. * * @note @b in-place: this will change the given list, so you should @@ -787,6 +787,7 @@ EAPI Eina_Inlist *eina_inlist_sort(Eina_Inlist *head, Eina_Compare_Cb func); _EINA_INLIST_OFFSET(ref)) #endif +/** Macro to iterate over an inlist */ #define EINA_INLIST_FOREACH(list, l) \ for (l = NULL, l = (list ? _EINA_INLIST_CONTAINER(l, list) : NULL); l; \ l = (EINA_INLIST_GET(l)->next ? _EINA_INLIST_CONTAINER(l, EINA_INLIST_GET(l)->next) : NULL)) diff --git a/libraries/eina/src/include/eina_iterator.h b/libraries/eina/src/include/eina_iterator.h index 1c8e6ce..10a9ece 100644 --- a/libraries/eina/src/include/eina_iterator.h +++ b/libraries/eina/src/include/eina_iterator.h @@ -25,7 +25,7 @@ #include "eina_magic.h" /** - * @page eina_iterator_example Eina_Iterator usage + * @page eina_iterator_example_page Eina_Iterator usage * @dontinclude eina_iterator_01.c * * As always when using eina we need to include it: @@ -48,7 +48,7 @@ * @until eina_init * * Next we populate both an array and a list with our strings, for more details - * see @ref eina_list_01_example and @ref eina_array_01_example: + * see @ref eina_list_01_example_page and @ref eina_array_01_example_page : * @until } * * And now we create an array and because the first element of the container @@ -63,7 +63,7 @@ * iterator itself: * @until eina_iterator_free * - * But so far you're not impressed in @ref eina_array_01_example an array is + * But so far you're not impressed in @ref eina_array_01_example_page an array is * also printed, so now we go to the cool stuff and use an iterator to do same * stuff to a list: * @until eina_iterator_free @@ -99,7 +99,7 @@ * eina_iterator_next(). To call a function on all the elements of a * container, use eina_iterator_foreach(). * - * Here an @ref eina_iterator_example "example" + * Here an @ref eina_iterator_example_page "example" */ /** diff --git a/libraries/eina/src/include/eina_list.h b/libraries/eina/src/include/eina_list.h index 8a8f25e..db65e17 100644 --- a/libraries/eina/src/include/eina_list.h +++ b/libraries/eina/src/include/eina_list.h @@ -29,7 +29,7 @@ #include "eina_magic.h" /** - * @page list_01_example_page Adding elements to Eina_List + * @page eina_list_01_example_page Adding elements to Eina_List * @dontinclude eina_list_01.c * * Creating an @ref Eina_List and adding elements to it is very easy and can be @@ -99,11 +99,11 @@ */ /** - * @page list_02_example_page Sorting Eina_List elements + * @page eina_list_02_example_page Sorting Eina_List elements * @dontinclude eina_list_02.c * * If you don't know how to create lists see - * @ref list_01_example_page. + * @ref eina_list_01_example_page. * * @skip #include * @until boomer @@ -151,11 +151,11 @@ */ /** - * @page list_03_example_page Reordering Eina_List elments + * @page eina_list_03_example_page Reordering Eina_List elments * @dontinclude eina_list_03.c * * If you don't know how to create lists see - * @ref list_01_example_page. + * @ref eina_list_01_example_page. * * We start out with code that should be familiar by now: * @skip #include @@ -197,12 +197,12 @@ */ /** - * @page list_04_example_page Eina_List and memory allocation + * @page eina_list_04_example_page Eina_List and memory allocation * @dontinclude eina_list_04.c * * If you don't know how to create lists see - * @ref list_01_example_page. In this example we also use - * @ref eina_stringshare, however it should be possible to understand the code + * @ref eina_list_01_example_page. In this example we also use + * @ref Eina_Stringshare_Group, however it should be possible to understand the code * regardless of previous knowledge about it. * * Here we have the usual list creation code with a twist, now we are using as @@ -276,10 +276,10 @@ * list as the list! * * Here are some examples of @ref Eina_List usage: - * @li @ref list_01_example_page - * @li @ref list_02_example_page - * @li @ref list_03_example_page - * @li @ref list_04_example_page + * @li @ref eina_list_01_example_page + * @li @ref eina_list_02_example_page + * @li @ref eina_list_03_example_page + * @li @ref eina_list_04_example_page */ /** @@ -582,7 +582,7 @@ EAPI Eina_List *eina_list_remove(Eina_List *list, const void *data) E /** - * @brief Remove the specified data. + * @brief Remove the specified list node. * * @param list The given linked list. * @param remove_list The list node which is to be removed. diff --git a/libraries/eina/src/include/eina_lock.h b/libraries/eina/src/include/eina_lock.h index 7c26dc0..16f4314 100644 --- a/libraries/eina/src/include/eina_lock.h +++ b/libraries/eina/src/include/eina_lock.h @@ -81,6 +81,10 @@ static inline void eina_tls_free(Eina_TLS key); static inline void *eina_tls_get(Eina_TLS key); static inline Eina_Bool eina_tls_set(Eina_TLS key, const void *data); +static inline Eina_Bool eina_semaphore_new(Eina_Semaphore *sem, int count_init); +static inline Eina_Bool eina_semaphore_free(Eina_Semaphore *sem); +static inline Eina_Bool eina_semaphore_lock(Eina_Semaphore *sem); +static inline Eina_Bool eina_semaphore_release(Eina_Semaphore *sem, int count_release); #ifdef EINA_HAVE_DEBUG_THREADS # define EINA_MAIN_LOOP_CHECK_RETURN_VAL(val) \ diff --git a/libraries/eina/src/include/eina_log.h b/libraries/eina/src/include/eina_log.h index 5cd7c59..186397d 100644 --- a/libraries/eina/src/include/eina_log.h +++ b/libraries/eina/src/include/eina_log.h @@ -21,6 +21,7 @@ #include #include +#include #include "eina_types.h" @@ -297,22 +298,27 @@ EAPI extern int EINA_LOG_DOMAIN_GLOBAL; * paths. Never define @c EINA_LOG_LEVEL_MAXIMUM on public * header files. */ -#ifdef EINA_LOG_LEVEL_MAXIMUM -#define EINA_LOG(DOM, LEVEL, fmt, ...) \ - do { \ - if (LEVEL <= EINA_LOG_LEVEL_MAXIMUM) { \ - eina_log_print(DOM, LEVEL, __FILE__, __FUNCTION__, __LINE__, \ - fmt, ## __VA_ARGS__); } \ - } while (0) -#else -#define EINA_LOG(DOM, LEVEL, fmt, ...) \ - eina_log_print(DOM, \ - LEVEL, \ - __FILE__, \ - __FUNCTION__, \ - __LINE__, \ - fmt, \ +#ifdef EINA_ENABLE_LOG +# ifdef EINA_LOG_LEVEL_MAXIMUM +# define EINA_LOG(DOM, LEVEL, fmt, ...) \ + do { \ + if (LEVEL <= EINA_LOG_LEVEL_MAXIMUM) { \ + eina_log_print(DOM, LEVEL, __FILE__, __FUNCTION__, __LINE__, \ + fmt, ## __VA_ARGS__); } \ + } while (0) +# else +# define EINA_LOG(DOM, LEVEL, fmt, ...) \ + eina_log_print(DOM, \ + LEVEL, \ + __FILE__, \ + __FUNCTION__, \ + __LINE__, \ + fmt, \ ## __VA_ARGS__) +# endif +#else +#define EINA_LOG(DOM, LEVEL, fmt, ...) \ + do { (void) DOM; (void) LEVEL; (void) fmt; } while (0) #endif /** @@ -726,7 +732,7 @@ EAPI void eina_log_domain_unregister(int domain); * specified value (eina_log_level_set() or environment * variables EINA_LOG_LEVEL, EINA_LOG_LEVELS) will be ignored. * @param file filename that originated the call, must @b not be @c NULL. - * @param fnc function that originated the call, must @b not be @c NULL. + * @param function function that originated the call, must @b not be @c NULL. * @param line originating line in @a file. * @param fmt printf-like format to use. Should not provide trailing * '\n' as it is automatically included. @@ -780,7 +786,7 @@ EAPI void eina_log_vprint(int domain, */ /** - * Alternative logging method, this will output to standard output stream. + * @brief Alternative logging method, this will output to standard output stream. * * @param d The domain. * @param level The level. @@ -815,7 +821,16 @@ EAPI void eina_log_print_cb_stdout(const Eina_Log_Domain *d, va_list args); /** - * Default logging method, this will output to standard error stream. + * @brief Default logging method, this will output to standard error stream. + * + * @param d The domain. + * @param level The level. + * @param file The file which is logged. + * @param fnc The function which is logged. + * @param line The line which is logged. + * @param fmt The ouptut format to use. + * @param data Not used. + * @param args The arguments needed by the format. * * This method will colorize output based on domain provided color and * message logging level. diff --git a/libraries/eina/src/include/eina_magic.h b/libraries/eina/src/include/eina_magic.h index 44cd4e9..d4909d8 100644 --- a/libraries/eina/src/include/eina_magic.h +++ b/libraries/eina/src/include/eina_magic.h @@ -21,6 +21,7 @@ #include "eina_config.h" #include "eina_types.h" +#include "eina_error.h" /** * @page eina_magic_example_01_page @@ -200,6 +201,13 @@ EAPI Eina_Bool eina_magic_string_static_set(Eina_Magic magic, */ #define EINA_MAGIC_NONE 0x1234fedc +/** + * @var EINA_ERROR_MAGIC_FAILED + * Error identifier corresponding to magic check failure. + */ +EAPI extern Eina_Error EINA_ERROR_MAGIC_FAILED; + + #ifdef EINA_MAGIC_DEBUG /** diff --git a/libraries/eina/src/include/eina_main.h b/libraries/eina/src/include/eina_main.h index fa34d59..4baf40e 100644 --- a/libraries/eina/src/include/eina_main.h +++ b/libraries/eina/src/include/eina_main.h @@ -50,7 +50,7 @@ * @def EINA_VERSION_MINOR * @brief Minor version of Eina */ -#define EINA_VERSION_MINOR 0 +#define EINA_VERSION_MINOR 2 /** * @typedef Eina_Version @@ -134,6 +134,9 @@ EAPI int eina_threads_shutdown(void); /** * @brief Check if you are calling this function from the same thread Eina was initialized or not + * + * @return #EINA_TRUE is the calling function is the same thread, #EINA_FALSE otherwise. + * * @since 1.1.0 * * Most EFL function are not thread safe and all the call need to happen in diff --git a/libraries/eina/src/include/eina_module.h b/libraries/eina/src/include/eina_module.h index 58e38f9..178fa9a 100644 --- a/libraries/eina/src/include/eina_module.h +++ b/libraries/eina/src/include/eina_module.h @@ -67,6 +67,10 @@ */ typedef struct _Eina_Module Eina_Module; +/** + * @typedef Eina_Module_Cb + * Dynamic module loader callback. + */ typedef Eina_Bool (*Eina_Module_Cb)(Eina_Module *m, void *data); /** @@ -135,21 +139,21 @@ EAPI Eina_Module * /** * @brief Delete a module. * - * @param m The module to delete. + * @param module The module to delete. * @return EINA_TRUE on success, EINA_FALSE otherwise. * - * This function calls eina_module_unload() if @p m has been previously + * This function calls eina_module_unload() if @p module has been previously * loaded and frees the allocated memory. On success this function - * returns EINA_TRUE and EINA_FALSE otherwise. If @p m is @c NULL, the + * returns EINA_TRUE and EINA_FALSE otherwise. If @p module is @c NULL, the * function returns immediately. */ EAPI Eina_Bool - eina_module_free(Eina_Module *m) EINA_ARG_NONNULL(1); + eina_module_free(Eina_Module *module) EINA_ARG_NONNULL(1); /** * @brief Load a module. * - * @param m The module to load. + * @param module The module to load. * @return EINA_TRUE on success, EINA_FALSE otherwise. * * This function load the shared file object passed in @@ -160,7 +164,7 @@ EAPI Eina_Bool * module can not be initialized, the error * #EINA_ERROR_MODULE_INIT_FAILED is set and #EINA_FALSE is * returned. If the module has already been loaded, it's refeence - * counter is increased by one and #EINA_TRUE is returned. If @p m is + * counter is increased by one and #EINA_TRUE is returned. If @p module is * @c NULL, the function returns immediately #EINA_FALSE. * * When the symbols of the shared file objetcts are not needed @@ -172,29 +176,29 @@ EAPI Eina_Bool /** * @brief Unload a module. * - * @param m The module to load. + * @param module The module to load. * @return EINA_TRUE on success, EINA_FALSE otherwise. * - * This function unload the module @p m that has been previously - * loaded by eina_module_load(). If the reference counter of @p m is + * This function unload the module @p module that has been previously + * loaded by eina_module_load(). If the reference counter of @p module is * strictly greater than @c 1, #EINA_FALSE is returned. Otherwise, the * shared object file is closed and if it is a internal Eina module, it * is shutted down just before. In that case, #EINA_TRUE is - * returned. In all case, the reference counter is decreased. If @p m + * returned. In all case, the reference counter is decreased. If @p module * is @c NULL, the function returns immediately #EINA_FALSE. */ EAPI Eina_Bool - eina_module_unload(Eina_Module *m) EINA_ARG_NONNULL(1); + eina_module_unload(Eina_Module *module) EINA_ARG_NONNULL(1); /** * @brief Retrive the data associated to a symbol. * - * @param m The module. + * @param module The module. * @param symbol The symbol. * @return The data associated to the symbol, or @c NULL on failure. * - * This function returns the data associated to @p symbol of @p m. @p - * m must have been loaded before with eina_module_load(). If @p m + * This function returns the data associated to @p symbol of @p module. @p + * module must have been loaded before with eina_module_load(). If @p module * is @c NULL, or if it has not been correctly loaded before, the * function returns immediately @c NULL. */ @@ -204,15 +208,15 @@ EAPI void * /** * @brief Return the file name associated to the module. * - * @param m The module. + * @param module The module. * @return The file name. * * This function returns the file name passed in eina_module_new(). If - * @p m is @c NULL, the function returns immediately @c NULL. The + * @p module is @c NULL, the function returns immediately @c NULL. The * returned value must no be freed. */ EAPI const char * - eina_module_file_get(const Eina_Module *m) EINA_PURE EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); + eina_module_file_get(const Eina_Module *module) EINA_PURE EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); /** @@ -256,6 +260,7 @@ EAPI char * * @param array The array that stores the list of the modules. * @param path The directory's path to search for modules. * @param arch The architecture string. + * @return The array of modules found in @p path matching @p arch. * * This function adds to @p array the module names found in @p path * which match the cpu architecture @p arch. If @p path or @p arch is @@ -273,6 +278,7 @@ EAPI Eina_Array * * @param recursive Iterate recursively on the path. * @param cb Callback function to call on each module. * @param data Data passed to the callback function. + * @return The array of modules found in @p path. * * This function adds to @p array the list of modules found in * @p path. If @p recursive is #EINA_TRUE, then recursive search is @@ -295,7 +301,7 @@ EAPI Eina_Array * * @p array. If @p array is @c NULL, this function does nothing. */ EAPI void - eina_module_list_load(Eina_Array *list) EINA_ARG_NONNULL(1); + eina_module_list_load(Eina_Array *array) EINA_ARG_NONNULL(1); /** * @brief Unload every module on the list of modules. @@ -306,7 +312,7 @@ EAPI void * @p array. If @p array is @c NULL, this function does nothing. */ EAPI void - eina_module_list_unload(Eina_Array *list) EINA_ARG_NONNULL(1); + eina_module_list_unload(Eina_Array *array) EINA_ARG_NONNULL(1); /** * @p Free every module on the list of modules. @@ -317,13 +323,14 @@ EAPI void * @p array. If @p array is @c NULL, this function does nothing. */ EAPI void - eina_module_list_free(Eina_Array *list) EINA_ARG_NONNULL(1); + eina_module_list_free(Eina_Array *array) EINA_ARG_NONNULL(1); /** * @brief Find an module in array. * * @param array The array to find the module. * @param module The name of module to be searched. + * @return The module to find on success, @c NULL otherwise. * * This function finds an @p module in @p array. * If the element is found the function returns the module, else diff --git a/libraries/eina/src/include/eina_simple_xml_parser.h b/libraries/eina/src/include/eina_simple_xml_parser.h index db9a4e1..78660ef 100644 --- a/libraries/eina/src/include/eina_simple_xml_parser.h +++ b/libraries/eina/src/include/eina_simple_xml_parser.h @@ -119,16 +119,16 @@ struct _Eina_Simple_XML_Node_Data typedef enum _Eina_Simple_XML_Type { - EINA_SIMPLE_XML_OPEN = 0, /* */ - EINA_SIMPLE_XML_OPEN_EMPTY, /* */ - EINA_SIMPLE_XML_CLOSE, /* */ - EINA_SIMPLE_XML_DATA, /* tag text data */ - EINA_SIMPLE_XML_CDATA, /* */ - EINA_SIMPLE_XML_ERROR, /* error contents */ - EINA_SIMPLE_XML_PROCESSING, /* */ - EINA_SIMPLE_XML_DOCTYPE, /* */ - EINA_SIMPLE_XML_IGNORED /* whatever is ignored by parser, like whitespace */ + EINA_SIMPLE_XML_OPEN = 0, /*!< */ + EINA_SIMPLE_XML_OPEN_EMPTY, /*!< */ + EINA_SIMPLE_XML_CLOSE, /*!< */ + EINA_SIMPLE_XML_DATA, /*!< tag text data */ + EINA_SIMPLE_XML_CDATA, /*!< */ + EINA_SIMPLE_XML_ERROR, /*!< error contents */ + EINA_SIMPLE_XML_PROCESSING, /*!< */ + EINA_SIMPLE_XML_DOCTYPE, /*!< */ + EINA_SIMPLE_XML_IGNORED /*!< whatever is ignored by parser, like whitespace */ } Eina_Simple_XML_Type; typedef Eina_Bool (*Eina_Simple_XML_Cb)(void *data, Eina_Simple_XML_Type type, const char *content, unsigned offset, unsigned length); @@ -137,7 +137,7 @@ typedef Eina_Bool (*Eina_Simple_XML_Attribute_Cb)(void *data, const char *key, c /** * Parse a section of XML string text - * + * * @param buf the input string. May not contain \0 terminator. * @param buflen the input string size. * @param strip whenever this parser should strip leading and trailing @@ -164,12 +164,15 @@ EAPI Eina_Bool eina_simple_xml_parse(const char *buf, unsigned buflen, /** * Given the contents of a tag, find where the attributes start. * - * The tag contents is returned by eina_simple_xml_parse() when - * type is #EINA_SIMPLE_XML_OPEN or #EINA_SIMPLE_XML_OPEN_EMPTY. - * + * @param buf the input string. May not contain \0 terminator. + * @param buflen the input string size. * @return pointer to the start of attributes, it can be used * to feed eina_simple_xml_attributes_parse(). NULL is returned * if no attributes were found. + * + * The tag contents is returned by eina_simple_xml_parse() when + * type is #EINA_SIMPLE_XML_OPEN or #EINA_SIMPLE_XML_OPEN_EMPTY. + * */ EAPI const char * eina_simple_xml_tag_attributes_find(const char *buf, unsigned buflen); @@ -183,6 +186,7 @@ EAPI const char * eina_simple_xml_tag_attributes_find(const char *buf, unsigned * key (null-terminated) and the last is the value (null * terminated). These strings should not be modified and * reference is just valid until the function return. + * @param data data to pass to the callback function. * * @return EINA_TRUE on success or EINA_FALSE if it was aborted by user or * parsing error. @@ -238,8 +242,8 @@ EAPI void eina_simple_xml_node_tag_free(Eina_Simple_XML_Node_Tag *tag); * * @param parent if provided, will be set in the resulting structure * as well as the data will be appended to children list. - * @param content string to be used. Must not be NULL. - * @param length size in bytes of @a content. + * @param contents string to be used. Must not be NULL. + * @param length size in bytes of @a contents. * * @return newly allocated memory or NULL on error. This memory should be * released with eina_simple_xml_node_data_free() or indirectly @@ -250,7 +254,7 @@ EAPI Eina_Simple_XML_Node_Data * eina_simple_xml_node_data_new(Eina_Simple_XML_N /** * Remove data from parent and delete it. * - * @param data to release memory. + * @param node to release memory. */ EAPI void eina_simple_xml_node_data_free(Eina_Simple_XML_Node_Data *node); @@ -260,7 +264,7 @@ EAPI void eina_simple_xml_node_data_free(Eina_Simple_XML_Node_Data *node); * * @param parent if provided, will be set in the resulting structure * as well as the cdata will be appended to children list. - * @param content string to be used. Must not be NULL. + * @param contents string to be used. Must not be NULL. * @param length size in bytes of @a content. * * @return newly allocated memory or NULL on error. This memory should be @@ -272,7 +276,7 @@ EAPI Eina_Simple_XML_Node_CData * eina_simple_xml_node_cdata_new(Eina_Simple_XML /** * Remove cdata from parent and delete it. * - * @param cdata to release memory. + * @param node to release memory. */ EAPI void eina_simple_xml_node_cdata_free(Eina_Simple_XML_Node_Data *node); @@ -282,8 +286,8 @@ EAPI void eina_simple_xml_node_cdata_free(Eina_Simple_XML_Node_Data *node); * * @param parent if provided, will be set in the resulting structure * as well as the processing will be appended to children list. - * @param content string to be used. Must not be NULL. - * @param length size in bytes of @a content. + * @param contents string to be used. Must not be NULL. + * @param length size in bytes of @a contents. * * @return newly allocated memory or NULL on error. This memory should be * released with eina_simple_xml_node_processing_free() or indirectly @@ -294,7 +298,7 @@ EAPI Eina_Simple_XML_Node_Processing * eina_simple_xml_node_processing_new(Eina_ /** * Remove processing from parent and delete it. * - * @param processing to release memory. + * @param node processing to release memory. */ EAPI void eina_simple_xml_node_processing_free(Eina_Simple_XML_Node_Data *node); @@ -304,8 +308,8 @@ EAPI void eina_simple_xml_node_processing_free(Eina_Simple_XML_Node_Data *node); * * @param parent if provided, will be set in the resulting structure * as well as the doctype will be appended to children list. - * @param content string to be used. Must not be NULL. - * @param length size in bytes of @a content. + * @param contents string to be used. Must not be NULL. + * @param length size in bytes of @a contents. * * @return newly allocated memory or NULL on error. This memory should be * released with eina_simple_xml_node_doctype_free() or indirectly @@ -316,7 +320,7 @@ EAPI Eina_Simple_XML_Node_Doctype * eina_simple_xml_node_doctype_new(Eina_Simple /** * Remove doctype from parent and delete it. * - * @param doctype to release memory. + * @param node doctype to release memory. */ EAPI void eina_simple_xml_node_doctype_free(Eina_Simple_XML_Node_Data *node); @@ -326,8 +330,8 @@ EAPI void eina_simple_xml_node_doctype_free(Eina_Simple_XML_Node_Data *node); * * @param parent if provided, will be set in the resulting structure * as well as the comment will be appended to children list. - * @param content string to be used. Must not be NULL. - * @param length size in bytes of @a content. + * @param contents string to be used. Must not be NULL. + * @param length size in bytes of @a contents. * * @return newly allocated memory or NULL on error. This memory should be * released with eina_simple_xml_node_comment_free() or indirectly @@ -338,7 +342,7 @@ EAPI Eina_Simple_XML_Node_Comment * eina_simple_xml_node_comment_new(Eina_Simple /** * Remove comment from parent and delete it. * - * @param comment to release memory. + * @param node comment to release memory. */ EAPI void eina_simple_xml_node_comment_free(Eina_Simple_XML_Node_Data *node); @@ -370,7 +374,7 @@ EAPI void eina_simple_xml_node_root_free(Eina_Simple_XML_Node_Root *root); * @param node the base node to convert. * @param indent indentation string, or NULL to disable it. * - * @param NULL on errors or a newly allocated string on success. + * @return NULL on errors or a newly allocated string on success. */ EAPI char * eina_simple_xml_node_dump(Eina_Simple_XML_Node *node, const char *indent); diff --git a/libraries/eina/src/include/eina_str.h b/libraries/eina/src/include/eina_str.h index 8b52ab2..2913fbf 100644 --- a/libraries/eina/src/include/eina_str.h +++ b/libraries/eina/src/include/eina_str.h @@ -161,14 +161,14 @@ EAPI Eina_Bool eina_str_has_extension(const char *str, const char *ext) EI /** * @brief Split a string using a delimiter. * - * @param str The string to split. - * @param delim The string which specifies the places at which to split the string. + * @param string The string to split. + * @param delimiter The string which specifies the places at which to split the string. * @param max_tokens The maximum number of strings to split string into. * @return A newly-allocated NULL-terminated array of strings or NULL if it * fails to allocate the array. * - * This functin splits @p str into a maximum of @p max_tokens pieces, - * using the given delimiter @p delim. @p delim is not included in any + * This functin splits @p string into a maximum of @p max_tokens pieces, + * using the given delimiter @p delimiter. @p delimiter is not included in any * of the resulting strings, unless @p max_tokens is reached. If * @p max_tokens is less than @c 1, the string is splitted completely. If * @p max_tokens is reached, the last string in the returned string @@ -185,16 +185,16 @@ EAPI char **eina_str_split(const char *string, const char *delimiter, i /** * @brief Split a string using a delimiter and returns number of elements. * - * @param str The string to split. - * @param delim The string which specifies the places at which to split the string. + * @param string The string to split. + * @param delimiter The string which specifies the places at which to split the string. * @param max_tokens The maximum number of strings to split string into. * @param elements Where to return the number of elements in returned * array (not counting the terminating @c NULL). May be @c NULL. * @return A newly-allocated NULL-terminated array of strings or NULL if it * fails to allocate the array. * - * This functin splits @p str into a maximum of @p max_tokens pieces, - * using the given delimiter @p delim. @p delim is not included in any + * This function splits @p string into a maximum of @p max_tokens pieces, + * using the given delimiter @p delimiter. @p delimiter is not included in any * of the resulting strings, unless @p max_tokens is reached. If * @p max_tokens is less than @c 1, the string is splitted completely. If * @p max_tokens is reached, the last string in the returned string diff --git a/libraries/eina/src/include/eina_strbuf.h b/libraries/eina/src/include/eina_strbuf.h index 7043575..34c200f 100644 --- a/libraries/eina/src/include/eina_strbuf.h +++ b/libraries/eina/src/include/eina_strbuf.h @@ -99,6 +99,24 @@ EAPI Eina_Strbuf *eina_strbuf_new(void) EINA_MALLOC EINA_WARN_UNUSED_RESULT; EAPI Eina_Strbuf *eina_strbuf_manage_new(char *str) EINA_MALLOC EINA_WARN_UNUSED_RESULT; /** + * @brief Create a new string buffer using the passed string. The passed + * string is used directly as the buffer, it's somehow the opposite function of + * @ref eina_strbuf_string_steal . The passed string must be malloced. + * + * @param str the string to manage + * @param length the length of the string. + * @return Newly allocated string buffer instance. + * + * This function creates a new string buffer. On error, @c NULL is + * returned and Eina error is set to #EINA_ERROR_OUT_OF_MEMORY. To + * free the resources, use eina_strbuf_free(). + * + * @see eina_strbuf_manage_new() + * @since 1.2.0 + */ +EAPI Eina_Strbuf *eina_strbuf_manage_new_length(char *str, size_t length) EINA_MALLOC EINA_WARN_UNUSED_RESULT; + +/** * @brief Free a string buffer. * * @param buf The string buffer to free. diff --git a/libraries/eina/src/include/eina_stringshare.h b/libraries/eina/src/include/eina_stringshare.h index af58add..862b2b2 100644 --- a/libraries/eina/src/include/eina_stringshare.h +++ b/libraries/eina/src/include/eina_stringshare.h @@ -289,6 +289,7 @@ EAPI void eina_stringshare_del(const char *str); * * @param str the shared string to know the length. It is safe to * give NULL, in that case -1 is returned. + * @return The length of a shared string. * * This function is a cheap way to known the length of a shared * string. Note that if the given pointer is not shared, bad diff --git a/libraries/eina/src/include/eina_types.h b/libraries/eina/src/include/eina_types.h index 8c77cdf..1653949 100644 --- a/libraries/eina/src/include/eina_types.h +++ b/libraries/eina/src/include/eina_types.h @@ -251,6 +251,10 @@ typedef int (*Eina_Compare_Cb)(const void *data1, const void *data2); */ #define EINA_COMPARE_CB(function) ((Eina_Compare_Cb)function) +/** + * @typedef Eina_Each_Cb + * A callback type used when iterating over a container. + */ typedef Eina_Bool (*Eina_Each_Cb)(const void *container, void *data, void *fdata); /** diff --git a/libraries/eina/src/include/eina_unicode.h b/libraries/eina/src/include/eina_unicode.h index aed59af..2bbfe45 100644 --- a/libraries/eina/src/include/eina_unicode.h +++ b/libraries/eina/src/include/eina_unicode.h @@ -68,7 +68,16 @@ EAPI Eina_Unicode *eina_unicode_strdup(const Eina_Unicode *text) EINA_WARN_UNUSE /** - * @brief Same as strdup but cuts on n. Assumes n < len + * @brief Same as strdup but cuts on the given size. Assumes n < len + * + * @param text The text to duplicate. + * @param n The maximum size of the text to duplicate. + * @return The duplicated string. + * + * This function duplicates @p text. The resuting string is cut on @p + * n. @p n is assumed to be lesser (<) than the length of @p + * text. When not needed anymore, the returned string must be freed. + * * @since 1.1.0 */ EAPI Eina_Unicode *eina_unicode_strndup(const Eina_Unicode *text, size_t n) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1) EINA_MALLOC; @@ -107,9 +116,9 @@ EAPI Eina_Unicode *eina_unicode_escape(const Eina_Unicode *str) EINA_ARG_NONNULL /** - * Reads UTF8 bytes from @buf, starting at *@index and returns - * the decoded code point at iindex offset, and advances iindex - * to the next code point after this. iindex is always advanced, + * Reads UTF8 bytes from @p buf, starting at @p iindex and returns + * the decoded code point at @p iindex offset, and advances @p iindex + * to the next code point after this. @p iindex is always advanced, * unless if the advancement is after the NULL. * On error: return a codepoint between DC80 to DCFF where the low 8 bits * are the byte's value. @@ -122,9 +131,9 @@ EAPI Eina_Unicode *eina_unicode_escape(const Eina_Unicode *str) EINA_ARG_NONNULL EAPI Eina_Unicode eina_unicode_utf8_get_next(const char *buf, int *iindex) EINA_ARG_NONNULL(1, 2); /** - * Reads UTF8 bytes from @buf, starting at *@iindex and returns - * the decoded code point at iindex offset, and moves iindex - * to the previous code point. iindex is always moved, as long + * Reads UTF8 bytes from @p buf, starting at @p iindex and returns + * the decoded code point at @p iindex offset, and moves àp iindex + * to the previous code point. @p iindex is always moved, as long * as it's not past the start of the string. * On error: return a codepoint between DC80 to DCFF where the low 8 bits * are the byte's value. diff --git a/libraries/eina/src/include/eina_ustrbuf.h b/libraries/eina/src/include/eina_ustrbuf.h index f68cb7b..9710c42 100644 --- a/libraries/eina/src/include/eina_ustrbuf.h +++ b/libraries/eina/src/include/eina_ustrbuf.h @@ -65,7 +65,25 @@ EAPI Eina_UStrbuf *eina_ustrbuf_new(void) EINA_MALLOC EINA_WARN_UNUSED_RESULT; * @see eina_ustrbuf_string_get() * @since 1.1.0 */ -EAPI Eina_Strbuf *eina_ustrbuf_manage_new(Eina_Unicode *str) EINA_MALLOC EINA_WARN_UNUSED_RESULT; +EAPI Eina_UStrbuf *eina_ustrbuf_manage_new(Eina_Unicode *str) EINA_MALLOC EINA_WARN_UNUSED_RESULT; + +/** + * @brief Create a new string buffer using the passed string. The passed + * string is used directly as the buffer, it's somehow the opposite function of + * @ref eina_ustrbuf_string_steal . The passed string must be malloced. + * + * @param str the string to manage + * @param length the length of the string. + * @return Newly allocated string buffer instance. + * + * This function creates a new string buffer. On error, @c NULL is + * returned and Eina error is set to #EINA_ERROR_OUT_OF_MEMORY. To + * free the resources, use eina_ustrbuf_free(). + * + * @see eina_ustrbuf_manage_new() + * @since 1.2.0 + */ +EAPI Eina_UStrbuf *eina_ustrbuf_manage_new_length(Eina_Unicode *str, size_t length) EINA_MALLOC EINA_WARN_UNUSED_RESULT; /** * @brief Free a string buffer. diff --git a/libraries/eina/src/include/eina_value.h b/libraries/eina/src/include/eina_value.h new file mode 100644 index 0000000..846c4ef --- /dev/null +++ b/libraries/eina/src/include/eina_value.h @@ -0,0 +1,3114 @@ +/* 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 . + */ + +#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 "eina_list.h" +#include "eina_hash.h" +#include + +/** + * @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 the data contained by the value + * + * @since 1.2 + */ +typedef struct _Eina_Value_Type Eina_Value_Type; + +/** + * @typedef Eina_Value_Union + * Union of all known value types. + * + * @since 1.2 + */ +typedef union _Eina_Value_Union Eina_Value_Union; + +/** + * @union _Eina_Value_Union + * All possible value types. + * + * @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 stringshared string 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. Use the value get/set for arrays: + * @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() + * + * eina_value_set() takes an #Eina_Value_Array where just @c subtype + * and @c step are used. If there is an @c array, it will be adopted + * and its contents must be properly configurable as @c subtype + * expects. eina_value_pset() takes a pointer to an #Eina_Value_Array. + * For your convenience, use eina_value_array_setup(). + * + * eina_value_get() and eina_value_pget() takes a pointer to + * #Eina_Value_Array, it's an exact copy of the current structure in + * use by value, no copies are done. + * + * @since 1.2 + */ +EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_ARRAY; + +/** + * @var EINA_VALUE_TYPE_LIST + * + * manages list type. Use the value get/set for lists: + * @li eina_value_list_get() and eina_value_list_set() + * @li eina_value_list_vget() and eina_value_list_vset() + * @li eina_value_list_pget() and eina_value_list_pset() + * + * eina_value_set() takes an #Eina_Value_List where just @c subtype is + * used. If there is an @c list, it will be adopted and its contents + * must be properly configurable as @c subtype + * expects. eina_value_pset() takes a pointer to an #Eina_Value_List. + * For your convenience, use eina_value_list_setup(). + * + * eina_value_get() and eina_value_pget() takes a pointer to + * #Eina_Value_List, it's an exact copy of the current structure in + * use by value, no copies are done. + * + * @since 1.2 + */ +EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_LIST; + +/** + * @var EINA_VALUE_TYPE_HASH + * + * manages hash type. Use the value get/set for hashes: + * @li eina_value_hash_get() and eina_value_hash_set() + * @li eina_value_hash_vget() and eina_value_hash_vset() + * @li eina_value_hash_pget() and eina_value_hash_pset() + * + * eina_value_set() takes an #Eina_Value_Hash where just @c subtype + * and @c buckets_power_size are used. If there is an @c hash, it will + * be adopted and its contents must be properly configurable as @c + * subtype expects. eina_value_pset() takes a pointer to an + * #Eina_Value_Hash. For your convenience, use + * eina_value_hash_setup(). + * + * eina_value_get() and eina_value_pget() takes a pointer to + * #Eina_Value_Hash, it's an exact copy of the current structure in + * use by value, no copies are done. + * + * @note be aware that hash data is always an allocated memory of size + * defined by @c subtype->value_size. If your @c subtype is an + * integer, add as data malloc(sizeof(int)). If your @c subtype + * is an string, add as data malloc(sizeof(char*)) and this data + * value must point to strdup(string)! + * + * @since 1.2 + */ +EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_HASH; + +/** + * @var EINA_VALUE_TYPE_TIMEVAL + * manages 'struct timeval' type + * + * eina_value_set() takes a "struct timeval" from sys/time.h. + * eina_value_pset() takes a pointer to "struct timeval". + * + * eina_value_get() and eina_value_pget() takes a pointer to "struct + * timeval" and it's an exact copy of value. + * + * @since 1.2 + */ +EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_TIMEVAL; + +/** + * @var EINA_VALUE_TYPE_BLOB + * manages blob of bytes type, see @ref Eina_Value_Blob + * + * eina_value_set() takes an #Eina_Value_Blob + * eina_value_pset() takes a pointer to #Eina_Value_Blob. + * + * eina_value_get() and eina_value_pget() takes a pointer to + * #Eina_Value_Blob and it's an exact copy of value, no allocations + * are made. + * + * Memory is untouched unless you provide @c ops (operations) pointer. + * + * @since 1.2 + */ +EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_BLOB; + +/** + * @var EINA_VALUE_TYPE_STRUCT + * + * manages struct type. Use the value get/set for structs: + * @li eina_value_struct_get() and eina_value_struct_set() + * @li eina_value_struct_vget() and eina_value_struct_vset() + * @li eina_value_struct_pget() and eina_value_struct_pset() + * + * eina_value_set() takes an #Eina_Value_Struct where just @c desc is + * used. If there is an @c memory, it will be adopted and its contents + * must be properly configurable as @c desc expects. eina_value_pset() + * takes a pointer to an #Eina_Value_Struct. For your convenience, use + * eina_value_struct_setup(). + * + * eina_value_get() and eina_value_pget() takes a pointer to + * #Eina_Value_Struct, it's an exact copy of the current structure in + * use by value, no copies are done. + * + * @since 1.2 + */ +EAPI extern const Eina_Value_Type *EINA_VALUE_TYPE_STRUCT; + +/** + * @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: + * eg. #EINA_VALUE_TYPE_ARRAY uses eina_value_array_set(), + * eina_value_array_get() and so on. + * + * On failure, @c NULL is returned and either #EINA_ERROR_OUT_OF_MEMORY or + * #EINA_ERROR_VALUE_FAILED is set. + * + * @note this calls creates from mempool and then uses + * eina_value_setup(). Consider using eina_value_flush() and + * eina_value_setup() instead 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 Initialize generic value storage. + * @param value value object + * @param type how to manage this value. + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. + * + * Initializes existing 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 contents are ignored! If the value was previously used, 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 an #Eina_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 overwritten (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 a == b + * + * @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 + * @li EINA_VALUE_TYPE_LIST: Eina_Value_List + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct + * + * @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() + * @note for list member see eina_value_list_set() + * @note for hash member see eina_value_hash_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 freed. + * + * 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* + * @li EINA_VALUE_TYPE_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @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() + * @note for list member see eina_value_list_get() + * @note for hash member see eina_value_hash_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() + * @note for list member see eina_value_list_vset() + * @note for hash member see eina_value_hash_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 freed. + * + * @note for array member see eina_value_array_vget() + * @note for list member see eina_value_list_vget() + * @note for hash member see eina_value_hash_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* + * @li EINA_VALUE_TYPE_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @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() + * @note for list member see eina_value_list_pset() + * @note for hash member see eina_value_hash_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 freed. + * + * 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* + * @li EINA_VALUE_TYPE_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * + * @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() + * @note for list member see eina_value_list_get() + * @note for hash member see eina_value_hash_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 unsuccessful, tries using @c convert_from() + * function in @a convert. + * + * Conversion functions are type defined, and 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 have eina_value_setup() called on them 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 creates from mempool and then uses + * eina_value_array_setup(). @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 Initialize generic value storage of type array. + * @param value value object + * @param subtype how to manage array members. + * @param step how to grow the members array. + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. + * + * Initializes 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 contents are ignored! If the value was previously used, 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 + * @li EINA_VALUE_TYPE_LIST: Eina_Value_List + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct + * + * @code + * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT, 0); + * 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, and 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 freed. + * + * 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* + * @li EINA_VALUE_TYPE_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @code + * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT, 0); + * 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 a 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 + * @li EINA_VALUE_TYPE_LIST: Eina_Value_List + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct + * + * @code + * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT, 0); + * 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 a 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 + * @li EINA_VALUE_TYPE_LIST: Eina_Value_List + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct + * + * @code + * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT, 0); + * 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 a generic value to 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 freed. + * + * @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 a generic value to 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 a generic value to 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 a generic value to an array member from a 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* + * @li EINA_VALUE_TYPE_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @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, 0); + * 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 Retrieve a generic value into a 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 freed. + * + * 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* + * @li EINA_VALUE_TYPE_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @code + * Eina_Value *value = eina_value_array_new(EINA_VALUE_TYPE_INT, 0); + * 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 a generic value to an array member position from a 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* + * @li EINA_VALUE_TYPE_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @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, 0); + * 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 a generic value to an array from a 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* + * @li EINA_VALUE_TYPE_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @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, 0); + * 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_List_Group Generic Value List management + * + * @{ + */ + + +/** + * @typedef Eina_Value_List + * Value type for #EINA_VALUE_TYPE_LIST + * + * @since 1.2 + */ +typedef struct _Eina_Value_List Eina_Value_List; + +/** + * @struct _Eina_Value_List + * Used to store the list and its subtype. + */ +struct _Eina_Value_List +{ + const Eina_Value_Type *subtype; /**< how to allocate and access items */ + Eina_List *list; /**< the list that holds data, members are of subtype->value_size bytes. */ +}; + +/** + * @brief Create generic value storage of type list. + * @param subtype how to manage this list members. + * @return The new value or @c NULL on failure. + * + * Create a new generic value storage of type list. 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 creates from mempool and then uses + * eina_value_list_setup(). + * + * @see eina_value_free() + * @see eina_value_list_setup() + * + * @since 1.2 + */ +EAPI Eina_Value *eina_value_list_new(const Eina_Value_Type *subtype) EINA_ARG_NONNULL(1); + +/** + * @brief Initialize generic value storage of type list. + * @param value value object + * @param subtype how to manage this list members. + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. + * + * Initializes new generic value storage of type list with the given + * @a subtype. + * + * This is the same as calling eina_value_set() with + * #EINA_VALUE_TYPE_LIST followed by eina_value_pset() with the + * #Eina_Value_List description configured. + * + * @note Existing contents are ignored! If the value was previously used, 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_list_setup(Eina_Value *value, + const Eina_Value_Type *subtype) EINA_ARG_NONNULL(1, 2); + +/** + * @brief Query number of elements in value of list type. + * @param value value object. + * @return number of child elements. + * @since 1.2 + */ +static inline unsigned int eina_value_list_count(const Eina_Value *value); + +/** + * @brief Remove element at given position in value of list 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_list_remove(Eina_Value *value, + unsigned int position) EINA_ARG_NONNULL(1); + +/** + * @brief Set the generic value in an list 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_LIST: Eina_Value_List + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct + * + * @code + * Eina_Value *value = eina_value_list_new(EINA_VALUE_TYPE_INT); + * int x; + * + * eina_value_list_append(value, 1234); + * eina_value_list_set(value, 0, 5678); + * eina_value_list_get(value, 0, &x); + * eina_value_free(value); + * @endcode + * + * @see eina_value_list_get() + * @see eina_value_list_vset() + * @see eina_value_list_pset() + * @see eina_value_list_insert() + * @see eina_value_list_vinsert() + * @see eina_value_list_pinsert() + * @see eina_value_list_append() + * @see eina_value_list_vappend() + * @see eina_value_list_pappend() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_list_set(Eina_Value *value, + unsigned int position, + ...) EINA_ARG_NONNULL(1); + +/** + * @brief Get the generic value from an list 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 freed. + * + * 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_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @code + * Eina_Value *value = eina_value_list_new(EINA_VALUE_TYPE_INT); + * int x; + * + * eina_value_list_append(value, 1234); + * eina_value_list_get(value, 0, &x); + * eina_value_free(value); + * @endcode + * + * @see eina_value_list_set() + * @see eina_value_list_vset() + * @see eina_value_list_pset() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_list_get(const Eina_Value *value, + unsigned int position, + ...) EINA_ARG_NONNULL(1); + +/** + * @brief Insert the generic value in an list 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_LIST: Eina_Value_List + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct + * + * @code + * Eina_Value *value = eina_value_list_new(EINA_VALUE_TYPE_INT); + * int x; + * + * eina_value_list_insert(value, 0, 1234); + * eina_value_list_get(value, 0, &x); + * eina_value_free(value); + * @endcode + * + * @see eina_value_list_set() + * @see eina_value_list_get() + * @see eina_value_list_vset() + * @see eina_value_list_pset() + * @see eina_value_list_vinsert() + * @see eina_value_list_pinsert() + * @see eina_value_list_append() + * @see eina_value_list_vappend() + * @see eina_value_list_pappend() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_list_insert(Eina_Value *value, + unsigned int position, + ...) EINA_ARG_NONNULL(1); + + +/** + * @brief Append the generic value in an list. + * @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_LIST: Eina_Value_List + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct + * + * @code + * Eina_Value *value = eina_value_list_new(EINA_VALUE_TYPE_INT); + * int x; + * + * eina_value_list_append(value, 1234); + * eina_value_list_get(value, 0, &x); + * eina_value_free(value); + * @endcode + * + * @see eina_value_list_set() + * @see eina_value_list_get() + * @see eina_value_list_vset() + * @see eina_value_list_pset() + * @see eina_value_list_vinsert() + * @see eina_value_list_pinsert() + * @see eina_value_list_append() + * @see eina_value_list_vappend() + * @see eina_value_list_pappend() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_list_append(Eina_Value *value, + ...) EINA_ARG_NONNULL(1); + +/** + * @brief Set the generic value in an list 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_list_set() + * @see eina_value_list_get() + * @see eina_value_list_pset() + * @see eina_value_list_insert() + * @see eina_value_list_vinsert() + * @see eina_value_list_pinsert() + * @see eina_value_list_append() + * @see eina_value_list_vappend() + * @see eina_value_list_pappend() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_list_vset(Eina_Value *value, + unsigned int position, + va_list args) EINA_ARG_NONNULL(1); + +/** + * @brief Get the generic value from an list 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 freed. + * + * @see eina_value_list_vset() + * @see eina_value_list_get() + * @see eina_value_list_pget() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_list_vget(const Eina_Value *value, + unsigned int position, + va_list args) EINA_ARG_NONNULL(1); +/** + * @brief Insert the generic value in an list 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_list_set() + * @see eina_value_list_get() + * @see eina_value_list_vset() + * @see eina_value_list_pset() + * @see eina_value_list_insert() + * @see eina_value_list_pinsert() + * @see eina_value_list_append() + * @see eina_value_list_vappend() + * @see eina_value_list_pappend() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_list_vinsert(Eina_Value *value, + unsigned int position, + va_list args) EINA_ARG_NONNULL(1); + +/** + * @brief Append the generic value in an list. + * @param value source value object + * @param args variable argument + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. + * @see eina_value_list_set() + * @see eina_value_list_get() + * @see eina_value_list_vget() + * @see eina_value_list_pset() + * @see eina_value_list_insert() + * @see eina_value_list_vinsert() + * @see eina_value_list_pinsert() + * @see eina_value_list_append() + * @see eina_value_list_pappend() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_list_vappend(Eina_Value *value, + va_list args) EINA_ARG_NONNULL(1); + + +/** + * @brief Set the generic value in an list 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_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @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_list_new(EINA_VALUE_TYPE_INT); + * int x = 1234; + * + * eina_value_list_append(value, 1234); + * eina_value_list_pset(value, 0, &x); + * eina_value_list_pget(value, 0, &x); + * eina_value_free(value); + * @endcode + * + * @see eina_value_list_set() + * @see eina_value_list_get() + * @see eina_value_list_vset() + * @see eina_value_list_insert() + * @see eina_value_list_vinsert() + * @see eina_value_list_pinsert() + * @see eina_value_list_append() + * @see eina_value_list_vappend() + * @see eina_value_list_pappend() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_list_pset(Eina_Value *value, + unsigned int position, + const void *ptr) EINA_ARG_NONNULL(1, 3); + +/** + * @brief Get the generic value to pointer from an list 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 freed. + * + * 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_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @code + * Eina_Value *value = eina_value_list_new(EINA_VALUE_TYPE_INT); + * int x; + * + * eina_value_list_append(value, 1234); + * eina_value_list_pget(value, 0, &x); + * eina_value_free(value); + * @endcode + * + * @see eina_value_list_set() + * @see eina_value_list_vset() + * @see eina_value_list_pset() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_list_pget(const Eina_Value *value, + unsigned int position, + void *ptr) EINA_ARG_NONNULL(1, 3); + +/** + * @brief Insert the generic value in an list 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_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @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_list_new(EINA_VALUE_TYPE_INT); + * int x = 1234; + * + * eina_value_list_pinsert(value, 0, &x); + * eina_value_list_pget(value, 0, &x); + * eina_value_free(value); + * @endcode + * + * @see eina_value_list_set() + * @see eina_value_list_get() + * @see eina_value_list_vset() + * @see eina_value_list_insert() + * @see eina_value_list_vinsert() + * @see eina_value_list_pinsert() + * @see eina_value_list_append() + * @see eina_value_list_vappend() + * @see eina_value_list_pappend() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_list_pinsert(Eina_Value *value, + unsigned int position, + const void *ptr) EINA_ARG_NONNULL(1); + +/** + * @brief Append the generic value in an list 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_LIST: Eina_Value_List* + * @li EINA_VALUE_TYPE_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @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_list_new(EINA_VALUE_TYPE_INT); + * int x = 1234; + * + * eina_value_list_pappend(value, &x); + * eina_value_list_pget(value, 0, &x); + * eina_value_free(value); + * @endcode + * + * @see eina_value_list_set() + * @see eina_value_list_get() + * @see eina_value_list_vset() + * @see eina_value_list_insert() + * @see eina_value_list_vinsert() + * @see eina_value_list_pinsert() + * @see eina_value_list_append() + * @see eina_value_list_vappend() + * @see eina_value_list_pappend() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_list_pappend(Eina_Value *value, + const void *ptr) EINA_ARG_NONNULL(1); + +/** + * @} + */ + +/** + * @defgroup Eina_Value_Hash_Group Generic Value Hash management + * + * @{ + */ + +/** + * @typedef Eina_Value_Hash + * Value type for #EINA_VALUE_TYPE_HASH + * + * @since 1.2 + */ +typedef struct _Eina_Value_Hash Eina_Value_Hash; + +/** + * @struct _Eina_Value_Hash + * Used to store the hash and its subtype. + */ +struct _Eina_Value_Hash +{ + const Eina_Value_Type *subtype; /**< how to allocate and access items */ + unsigned int buckets_power_size; /**< how to allocate hash buckets, if zero a sane default is chosen. */ + Eina_Hash *hash; /**< the hash that holds data, members are of subtype->value_size bytes. */ +}; + +/** + * @brief Create generic value storage of type hash. + * @param subtype how to manage this hash members. + * @param buckets_power_size how to allocate hash buckets (2 ^ + * buckets_power_size), if zero then a sane value is chosen. + * @return The new value or @c NULL on failure. + * + * Create a new generic value storage of type hash. 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 creates from mempool and then uses + * eina_value_hash_setup(). + * + * @see eina_value_free() + * @see eina_value_hash_setup() + * + * @since 1.2 + */ +EAPI Eina_Value *eina_value_hash_new(const Eina_Value_Type *subtype, unsigned int buckets_power_size) EINA_ARG_NONNULL(1); + +/** + * @brief Initialize generic value storage of type hash. + * @param value value object + * @param subtype how to manage this hash members. + * @param buckets_power_size how to allocate hash buckets (2 ^ + * buckets_power_size), if zero then a sane value is chosen. + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. + * + * Initializes new generic value storage of type hash with the given + * @a subtype. + * + * This is the same as calling eina_value_set() with + * #EINA_VALUE_TYPE_HASH followed by eina_value_pset() with the + * #Eina_Value_Hash description configured. + * + * @note Existing contents are ignored! If the value was previously used, 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_hash_setup(Eina_Value *value, + const Eina_Value_Type *subtype, + unsigned int buckets_power_size) EINA_ARG_NONNULL(1, 2); + +/** + * @brief Query number of elements in value of hash type. + * @param value value object. + * @return number of child elements. + * @since 1.2 + */ +static inline unsigned int eina_value_hash_population(const Eina_Value *value); + +/** + * @brief Remove element at given position in value of hash type. + * @param value value object. + * @param key key to find the member + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. + * @since 1.2 + */ +static inline Eina_Bool eina_value_hash_del(Eina_Value *value, + const char *key) EINA_ARG_NONNULL(1); + +/** + * @brief Set the generic value in an hash member. + * @param value source value object + * @param key key to find 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_HASH: Eina_Value_Hash + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @code + * Eina_Value *value = eina_value_hash_new(EINA_VALUE_TYPE_INT, 0); + * int x; + * + * eina_value_hash_set(value, "abc", 5678); + * eina_value_hash_get(value, "abc", &x); + * eina_value_free(value); + * @endcode + * + * @see eina_value_hash_get() + * @see eina_value_hash_vset() + * @see eina_value_hash_pset() + * @see eina_value_hash_del() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_hash_set(Eina_Value *value, + const char *key, + ...) EINA_ARG_NONNULL(1); + +/** + * @brief Get the generic value from an hash member. + * @param value source value object + * @param key key to find 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 freed. + * + * 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_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @code + * Eina_Value *value = eina_value_hash_new(EINA_VALUE_TYPE_INT, 0); + * int x; + * + * eina_value_hash_set(value, "abc", 1234); + * eina_value_hash_get(value, "abc", &x); + * eina_value_free(value); + * @endcode + * + * @see eina_value_hash_set() + * @see eina_value_hash_vset() + * @see eina_value_hash_pset() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_hash_get(const Eina_Value *value, + const char *key, + ...) EINA_ARG_NONNULL(1); + +/** + * @brief Set the generic value in an hash member. + * @param value source value object + * @param key key to find the member + * @param args variable argument + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. + * @see eina_value_hash_set() + * @see eina_value_hash_get() + * @see eina_value_hash_pset() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_hash_vset(Eina_Value *value, + const char *key, + va_list args) EINA_ARG_NONNULL(1); + +/** + * @brief Get the generic value from an hash member. + * @param value source value object + * @param key key to find 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 freed. + * + * @see eina_value_hash_vset() + * @see eina_value_hash_get() + * @see eina_value_hash_pget() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_hash_vget(const Eina_Value *value, + const char *key, + va_list args) EINA_ARG_NONNULL(1); + +/** + * @brief Set the generic value in an hash member from pointer. + * @param value source value object + * @param key key to find 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_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @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_hash_new(EINA_VALUE_TYPE_INT, 0); + * int x = 1234; + * + * eina_value_hash_pset(value, "abc", &x); + * eina_value_hash_pget(value, "abc", &x); + * eina_value_free(value); + * @endcode + * + * @see eina_value_hash_set() + * @see eina_value_hash_get() + * @see eina_value_hash_vset() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_hash_pset(Eina_Value *value, + const char *key, + const void *ptr) EINA_ARG_NONNULL(1, 3); + +/** + * @brief Get the generic value to pointer from an hash member. + * @param value source value object + * @param key key to find 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 freed. + * + * 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_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @code + * Eina_Value *value = eina_value_hash_new(EINA_VALUE_TYPE_INT, 0); + * int x; + * + * eina_value_hash_set(value, "abc", 1234); + * eina_value_hash_pget(value, "abc", &x); + * eina_value_free(value); + * @endcode + * + * @see eina_value_hash_set() + * @see eina_value_hash_vset() + * @see eina_value_hash_pset() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_hash_pget(const Eina_Value *value, + const char *key, + void *ptr) EINA_ARG_NONNULL(1, 3); + +/** + * @} + */ + +/** + * @defgroup Eina_Value_Blob_Group Generic Value Blob management + * + * @{ + */ + +/** + * @typedef Eina_Value_Blob_Operations + * How to manage blob. Any @c NULL callback is ignored. + * @since 1.2 + */ +typedef struct _Eina_Value_Blob_Operations Eina_Value_Blob_Operations; + +/** + * @struct _Eina_Value_Blob_Operations + * How to manage blob. Any @c NULL callback is ignored. + * @since 1.2 + */ +struct _Eina_Value_Blob_Operations +{ +#define EINA_VALUE_BLOB_OPERATIONS_VERSION (1) + unsigned int version; /**< must be EINA_VALUE_BLOB_OPERATIONS_VERSION */ + void (*free)(const Eina_Value_Blob_Operations *ops, void *memory, size_t size); + void *(*copy)(const Eina_Value_Blob_Operations *ops, const void *memory, size_t size); + int (*compare)(const Eina_Value_Blob_Operations *ops, const void *data1, size_t size_data1, const void *data2, size_t size_data2); + char *(*to_string)(const Eina_Value_Blob_Operations *ops, const void *memory, size_t size); +}; + +/** + * @var EINA_VALUE_BLOB_OPERATIONS_MALLOC + * + * Assumes @c memory was create with malloc() and applies free() to it + * during flush (Eina_Value_Blob_Operations::free). Copy is done with + * malloc() as well. + * + * No compare or to_string are provided, defaults will be used. + */ +EAPI extern const Eina_Value_Blob_Operations *EINA_VALUE_BLOB_OPERATIONS_MALLOC; + +/** + * @typedef Eina_Value_Blob + * @since 1.2 + */ +typedef struct _Eina_Value_Blob Eina_Value_Blob; + +/** + * @struct _Eina_Value_Blob + * @since 1.2 + */ +struct _Eina_Value_Blob +{ + const Eina_Value_Blob_Operations *ops; /**< if @c NULL, nothing is freed, copy will just copy the memory pointer, not its value. */ + const void *memory; + unsigned int size; +}; + +/** + * @} + */ + +/** + * @defgroup Eina_Value_Struct_Group Generic Value Struct management + * + * @{ + */ + +/** + * @typedef Eina_Value_Struct_Operations + * How to manage struct. Any @c NULL callback is ignored. + * @since 1.2 + */ +typedef struct _Eina_Value_Struct_Operations Eina_Value_Struct_Operations; + +/** + * @typedef Eina_Value_Struct_Member + * Describes a single member of struct. + * @since 1.2 + */ +typedef struct _Eina_Value_Struct_Member Eina_Value_Struct_Member; + +/** + * @typedef Eina_Value_Struct_Desc + * Describes the struct by listing its size, members and operations. + * @since 1.2 + */ +typedef struct _Eina_Value_Struct_Desc Eina_Value_Struct_Desc; + +/** + * @typedef Eina_Value_Struct + * @since 1.2 + */ +typedef struct _Eina_Value_Struct Eina_Value_Struct; + +/** + * @struct _Eina_Value_Struct_Operations + * How to manage struct. Any @c NULL callback is ignored. + * @since 1.2 + */ +struct _Eina_Value_Struct_Operations +{ +#define EINA_VALUE_STRUCT_OPERATIONS_VERSION (1) + unsigned int version; /**< must be EINA_VALUE_STRUCT_OPERATIONS_VERSION */ + void *(*alloc)(const Eina_Value_Struct_Operations *ops, const Eina_Value_Struct_Desc *desc); + void (*free)(const Eina_Value_Struct_Operations *ops, const Eina_Value_Struct_Desc *desc, void *memory); + void *(*copy)(const Eina_Value_Struct_Operations *ops, const Eina_Value_Struct_Desc *desc, const void *memory); + int (*compare)(const Eina_Value_Struct_Operations *ops, const Eina_Value_Struct_Desc *desc, const void *data1, const void *data2); + const Eina_Value_Struct_Member *(*find_member)(const Eina_Value_Struct_Operations *ops, const Eina_Value_Struct_Desc *desc, const char *name); /**< replace the function to find description for member. For huge structures consider using binary search, stringshared, hash or gperf. The default function does linear search using strcmp(). */ +}; + +/** + * @var EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH + * + * Assumes @c members is sorted by name and applies binary search for + * names. + * + * Ideally the @c member_count field is set to speed it up. + * + * No other methods are set (alloc, free, copy, compare), then it uses + * the default operations. + */ +EAPI extern const Eina_Value_Struct_Operations *EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH; + +/** + * @var EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE + * + * Assumes @c members name are stringshared and can be compared for + * equality without using its contents (simple pointer comparison). + * + * Ideally the search @c name will be stringshared as well, but it + * will do a second loop with a forced stringshare if it did not find + * the member. + * + * No other methods are set (alloc, free, copy, compare), then it uses + * the default operations. + */ +EAPI extern const Eina_Value_Struct_Operations *EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE; + +/** + * @struct _Eina_Value_Struct_Member + * @since 1.2 + */ +struct _Eina_Value_Struct_Member +{ + const char *name; + const Eina_Value_Type *type; + unsigned int offset; +}; + +/** + * @struct _Eina_Value_Struct_Desc + * @since 1.2 + */ +struct _Eina_Value_Struct_Desc +{ +#define EINA_VALUE_STRUCT_DESC_VERSION (1) + unsigned int version; /**< must be EINA_VALUE_STRUCT_DESC_VERSION */ + const Eina_Value_Struct_Operations *ops; /**< operations, if @c NULL defaults will be used. You may use operations to optimize member lookup using binary search or gperf hash. */ + const Eina_Value_Struct_Member *members; /**< array of member descriptions, if @c member_count is zero, then it must be @c NULL terminated. */ + unsigned int member_count; /**< if > 0, specifies number of members. If zero then @c members must be NULL terminated. */ + unsigned int size; /**< byte size to allocate, may be bigger than sum of members */ +}; + +/** + * @def EINA_VALUE_STRUCT_MEMBER + * + * Helper to define Eina_Value_Struct_Member fields, uses offsetof() + * with type and member. + * + * @since 1.2 + */ +#define EINA_VALUE_STRUCT_MEMBER(eina_value_type, type, member) \ + {#member, eina_value_type, offsetof(type, member)} + +/** + * @def EINA_VALUE_STRUCT_MEMBER_SENTINEL + * + * Helper to define Eina_Value_Struct_Member fields for sentinel (last + * item), useful if you did not define @c member_count. + * + * @since 1.2 + */ +#define EINA_VALUE_STRUCT_MEMBER_SENTINEL {NULL, NULL, 0} + + +/** + * @struct _Eina_Value_Struct + * @since 1.2 + */ +struct _Eina_Value_Struct +{ + const Eina_Value_Struct_Desc *desc; + void *memory; +}; + +/** + * @brief Create generic value storage of type struct. + * @param desc how to manage this struct members. + * @return The new value or @c NULL on failure. + * + * Create a new generic value storage of type struct. The members are + * managed using the description specified by @a desc. + * + * On failure, @c NULL is returned and #EINA_ERROR_OUT_OF_MEMORY or + * #EINA_ERROR_VALUE_FAILED is set. + * + * @note this creates from mempool and then uses + * eina_value_struct_setup(). + * + * @see eina_value_free() + * @see eina_value_struct_setup() + * + * @since 1.2 + */ +EAPI Eina_Value *eina_value_struct_new(const Eina_Value_Struct_Desc *desc) EINA_ARG_NONNULL(1); + +/** + * @brief Initialize generic value storage of type struct. + * @param value value object + * @param desc how to manage this struct members. + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. + * + * Initializes new generic value storage of type struct with the given + * @a desc. + * + * This is the same as calling eina_value_set() with + * #EINA_VALUE_TYPE_STRUCT followed by eina_value_pset() with the + * #Eina_Value_Struct description configured. + * + * @note Existing contents are ignored! If the value was previously used, 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_struct_setup(Eina_Value *value, + const Eina_Value_Struct_Desc *desc) EINA_ARG_NONNULL(1, 2); + +/** + * @brief Set the generic value in an struct member. + * @param value source value object + * @param name name to find the member + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. + * + * The variable argument is dependent on chosen member 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_HASH: Eina_Value_Hash + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @code + * struct myst { + * int i; + * char c; + * }; + * const Eina_Value_Struct_Member myst_members[] = { + * {"i", EINA_VALUE_TYPE_INT, 0}, + * {"c", EINA_VALUE_TYPE_CHAR, 4}, + * {NULL, NULL, 0} + * }; + * const Eina_Value_Struct_Desc myst_desc = { + * EINA_VALUE_STRUCT_DESC_VERSION, + * NULL, myst_members, 2, sizeof(struct myst) + * }; + * Eina_Value *value = eina_value_struct_new(&my_desc); + * int x; + * char y; + * + * eina_value_struct_set(value, "i", 5678); + * eina_value_struct_get(value, "i", &x); + * eina_value_struct_set(value, "c", 0xf); + * eina_value_struct_get(value, "c", &y); + * eina_value_free(value); + * @endcode + * + * @see eina_value_struct_get() + * @see eina_value_struct_vset() + * @see eina_value_struct_pset() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_struct_set(Eina_Value *value, + const char *name, + ...) EINA_ARG_NONNULL(1); + +/** + * @brief Get the generic value from an struct member. + * @param value source value object + * @param name name to find 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 freed. + * + * The variable argument is dependent on chosen member 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_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @code + * struct myst { + * int i; + * char c; + * }; + * const Eina_Value_Struct_Member myst_members[] = { + * {"i", EINA_VALUE_TYPE_INT, 0}, + * {"c", EINA_VALUE_TYPE_CHAR, 4}, + * {NULL, NULL, 0} + * }; + * const Eina_Value_Struct_Desc myst_desc = { + * EINA_VALUE_STRUCT_DESC_VERSION, + * NULL, myst_members, 2, sizeof(struct myst) + * }; + * Eina_Value *value = eina_value_struct_new(&my_desc); + * int x; + * char y; + * + * eina_value_struct_set(value, "i", 5678); + * eina_value_struct_get(value, "i", &x); + * eina_value_struct_set(value, "c", 0xf); + * eina_value_struct_get(value, "c", &y); + * eina_value_free(value); + * @endcode + * + * @see eina_value_struct_set() + * @see eina_value_struct_vset() + * @see eina_value_struct_pset() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_struct_get(const Eina_Value *value, + const char *name, + ...) EINA_ARG_NONNULL(1); + +/** + * @brief Set the generic value in an struct member. + * @param value source value object + * @param name name to find the member + * @param args variable argument + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. + * @see eina_value_struct_set() + * @see eina_value_struct_get() + * @see eina_value_struct_pset() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_struct_vset(Eina_Value *value, + const char *name, + va_list args) EINA_ARG_NONNULL(1); + +/** + * @brief Get the generic value from an struct member. + * @param value source value object + * @param name name to find 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 freed. + * + * @see eina_value_struct_vset() + * @see eina_value_struct_get() + * @see eina_value_struct_pget() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_struct_vget(const Eina_Value *value, + const char *name, + va_list args) EINA_ARG_NONNULL(1); + +/** + * @brief Set the generic value in an struct member from pointer. + * @param value source value object + * @param name name to find 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_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @note the pointer contents are written using the size defined by + * type. It can be larger than void* or uint64_t. + * + * @code + * struct myst { + * int i; + * char c; + * }; + * const Eina_Value_Struct_Member myst_members[] = { + * {"i", EINA_VALUE_TYPE_INT, 0}, + * {"c", EINA_VALUE_TYPE_CHAR, 4}, + * {NULL, NULL, 0} + * }; + * const Eina_Value_Struct_Desc myst_desc = { + * EINA_VALUE_STRUCT_DESC_VERSION, + * NULL, myst_members, 2, sizeof(struct myst) + * }; + * Eina_Value *value = eina_value_struct_new(&my_desc); + * int x = 5678; + * char y = 0xf; + * + * eina_value_struct_pset(value, "i", &); + * eina_value_struct_pget(value, "i", &x); + * eina_value_struct_pset(value, "c", &y); + * eina_value_struct_pget(value, "c", &y); + * eina_value_free(value); + * @endcode + * + * @see eina_value_struct_set() + * @see eina_value_struct_get() + * @see eina_value_struct_vset() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_struct_pset(Eina_Value *value, + const char *name, + const void *ptr) EINA_ARG_NONNULL(1, 3); + +/** + * @brief Get the generic value to pointer from an struct member. + * @param value source value object + * @param name name to find 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 freed. + * + * 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_HASH: Eina_Value_Hash* + * @li EINA_VALUE_TYPE_TIMEVAL: struct timeval* + * @li EINA_VALUE_TYPE_BLOB: Eina_Value_Blob* + * @li EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct* + * + * @code + * struct myst { + * int i; + * char c; + * }; + * const Eina_Value_Struct_Member myst_members[] = { + * {"i", EINA_VALUE_TYPE_INT, 0}, + * {"c", EINA_VALUE_TYPE_CHAR, 4}, + * {NULL, NULL, 0} + * }; + * const Eina_Value_Struct_Desc myst_desc = { + * EINA_VALUE_STRUCT_DESC_VERSION, + * NULL, myst_members, 2, sizeof(struct myst) + * }; + * Eina_Value *value = eina_value_struct_new(&my_desc); + * int x = 5678; + * char y = 0xf; + * + * eina_value_struct_pset(value, "i", &); + * eina_value_struct_pget(value, "i", &x); + * eina_value_struct_pset(value, "c", &y); + * eina_value_struct_pget(value, "c", &y); + * eina_value_free(value); + * @endcode + * + * @see eina_value_struct_set() + * @see eina_value_struct_vset() + * @see eina_value_struct_pset() + * + * @since 1.2 + */ +static inline Eina_Bool eina_value_struct_pget(const Eina_Value *value, + const char *name, + void *ptr) EINA_ARG_NONNULL(1, 3); + +/** + * @} + */ + + +/** + * @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 Initialize 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, const 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 diff --git a/libraries/eina/src/include/eina_xattr.h b/libraries/eina/src/include/eina_xattr.h index 8ddb30a..0f89cc3 100644 --- a/libraries/eina/src/include/eina_xattr.h +++ b/libraries/eina/src/include/eina_xattr.h @@ -39,6 +39,14 @@ typedef enum { EINA_XATTR_CREATED /**< This will only succeed if the extended attribute wasn't previously set */ } Eina_Xattr_Flags; +typedef struct _Eina_Xattr Eina_Xattr; +struct _Eina_Xattr +{ + const char *name; /**< The eXtended attribute name @since 1.2 */ + const char *value; /**< The eXtended attribute value @since 1.2 */ + + size_t length; /**< The length of the eXtended attribute value @since 1.2 */ +}; /** * @brief Get an iterator that list all extended attribute of a file. @@ -54,10 +62,49 @@ typedef enum { EAPI Eina_Iterator *eina_xattr_ls(const char *file); /** + * @brief Get an iterator that list all extended attribute value related to a fd. + * + * @param file The filename to retrieve the extended attribute list from. + * @return an iterator. + * + * The iterator will not allocate any data during the iteration step, so you need to copy them yourself + * if you need. The iterator will provide an Eina_Xattr structure. + * + * @since 1.2 + */ +EAPI Eina_Iterator *eina_xattr_value_ls(const char *file); + +/** + * @brief Get an iterator that list all extended attribute related to a fd. + * + * @param fd The file descriptor to retrieve the extended attribute list from. + * @return an iterator. + * + * The iterator will not allocate any data during the iteration step, so you need to copy them yourself + * if you need. + * + * @since 1.2 + */ +EAPI Eina_Iterator *eina_xattr_fd_ls(int fd); + +/** + * @brief Get an iterator that list all extended attribute value related to a fd. + * + * @param fd The file descriptor to retrieve the extended attribute list from. + * @return an iterator. + * + * The iterator will not allocate any data during the iteration step, so you need to copy them yourself + * if you need. The iterator will provide an Eina_Xattr structure. + * + * @since 1.2 + */ +EAPI Eina_Iterator *eina_xattr_value_fd_ls(int fd); + +/** * @brief Retrieve an extended attribute from a file. * * @param file The file to retrieve the extended attribute from. - * @param atttribute The extended attribute name to retrieve. + * @param attribute The extended attribute name to retrieve. * @param size The size of the retrieved extended attribute. * @return the allocated data that hold the extended attribute value. * @@ -112,7 +159,7 @@ EAPI char *eina_xattr_string_get(const char *file, const char *attribute); * * @param file The file to set the double to. * @param attribute The attribute to set. - * @param data The NULL terminated double to set. + * @param value The NULL terminated double to set. * @param flags Define the set policy. * @return EINA_TRUE on success, EINA_FALSE otherwise. * @@ -139,7 +186,7 @@ EAPI Eina_Bool eina_xattr_double_get(const char *file, const char *attribute, do * * @param file The file to set the int to. * @param attribute The attribute to set. - * @param data The NULL terminated int to set. + * @param value The NULL terminated int to set. * @param flags Define the set policy. * @return EINA_TRUE on success, EINA_FALSE otherwise. * -- cgit v1.1