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/Makefile.in | 4 +- libraries/eina/src/examples/Makefile.am | 10 +- libraries/eina/src/examples/Makefile.in | 68 +- libraries/eina/src/examples/eina_array_01.c | 4 +- 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 +- libraries/eina/src/lib/Makefile.am | 10 +- libraries/eina/src/lib/Makefile.in | 68 +- libraries/eina/src/lib/eina_array.c | 4 +- libraries/eina/src/lib/eina_binbuf_template_c.x | 9 + libraries/eina/src/lib/eina_cpu.c | 4 +- libraries/eina/src/lib/eina_file.c | 128 +- libraries/eina/src/lib/eina_hash.c | 6 +- libraries/eina/src/lib/eina_inarray.c | 777 +++ libraries/eina/src/lib/eina_log.c | 145 +- libraries/eina/src/lib/eina_magic.c | 11 +- libraries/eina/src/lib/eina_main.c | 16 +- libraries/eina/src/lib/eina_mmap.c | 5 + libraries/eina/src/lib/eina_module.c | 1 + libraries/eina/src/lib/eina_prefix.c | 37 +- libraries/eina/src/lib/eina_private.h | 6 + libraries/eina/src/lib/eina_rbtree.c | 10 +- libraries/eina/src/lib/eina_simple_xml_parser.c | 19 +- libraries/eina/src/lib/eina_strbuf.c | 6 +- libraries/eina/src/lib/eina_value.c | 4977 ++++++++++++++++++++ libraries/eina/src/lib/eina_xattr.c | 191 + libraries/eina/src/modules/Makefile.in | 4 +- libraries/eina/src/modules/mp/Makefile.in | 4 +- libraries/eina/src/modules/mp/buddy/Makefile.in | 4 +- libraries/eina/src/modules/mp/buddy/eina_buddy.c | 20 +- .../eina/src/modules/mp/chained_pool/Makefile.in | 4 +- .../modules/mp/chained_pool/eina_chained_mempool.c | 31 +- .../eina/src/modules/mp/ememoa_fixed/Makefile.in | 4 +- .../eina/src/modules/mp/ememoa_unknown/Makefile.in | 4 +- .../eina/src/modules/mp/fixed_bitmap/Makefile.in | 4 +- libraries/eina/src/modules/mp/one_big/Makefile.in | 4 +- .../eina/src/modules/mp/pass_through/Makefile.in | 4 +- libraries/eina/src/tests/Makefile.am | 9 +- libraries/eina/src/tests/Makefile.in | 77 +- libraries/eina/src/tests/cxx_compile_test.cxx | 34 + libraries/eina/src/tests/eina_bench.c | 3 +- libraries/eina/src/tests/eina_bench_hash.c | 2 + libraries/eina/src/tests/eina_bench_quad.c | 2 + libraries/eina/src/tests/eina_bench_stringshare.c | 8 + libraries/eina/src/tests/eina_suite.c | 2 + libraries/eina/src/tests/eina_suite.h | 2 + libraries/eina/src/tests/eina_test_array.c | 6 +- libraries/eina/src/tests/eina_test_binbuf.c | 36 +- libraries/eina/src/tests/eina_test_file.c | 4 +- libraries/eina/src/tests/eina_test_inarray.c | 401 ++ libraries/eina/src/tests/eina_test_value.c | 1799 +++++++ libraries/eina/src/tests/evas_list.c | 2 +- libraries/eina/src/tests/evas_mempool.c | 2 +- 90 files changed, 15026 insertions(+), 541 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 create mode 100644 libraries/eina/src/lib/eina_inarray.c create mode 100644 libraries/eina/src/tests/cxx_compile_test.cxx create mode 100644 libraries/eina/src/tests/eina_test_inarray.c create mode 100644 libraries/eina/src/tests/eina_test_value.c (limited to 'libraries/eina/src') diff --git a/libraries/eina/src/Makefile.in b/libraries/eina/src/Makefile.in index c954fc5..eb3a2c0 100644 --- a/libraries/eina/src/Makefile.in +++ b/libraries/eina/src/Makefile.in @@ -147,7 +147,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@ @@ -199,8 +201,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@ diff --git a/libraries/eina/src/examples/Makefile.am b/libraries/eina/src/examples/Makefile.am index ea5ca6a..45b72f0 100644 --- a/libraries/eina/src/examples/Makefile.am +++ b/libraries/eina/src/examples/Makefile.am @@ -1,6 +1,6 @@ MAINTAINERCLEANFILES = Makefile.in -pkglibdir = $(datadir)/$(PACKAGE)/examples +examplesdir = $(datadir)/$(PACKAGE)/examples AM_CPPFLAGS = \ -I. \ @@ -39,7 +39,7 @@ SRCS = \ eina_strbuf_01.c \ eina_tiler_01.c -pkglib_PROGRAMS = +examples_PROGRAMS = if EFL_INSTALL_EXAMPLES filesdir = $(datadir)/$(PACKAGE)/examples @@ -47,9 +47,9 @@ files_DATA = $(SRCS) endif if EFL_BUILD_EXAMPLES -pkglib_PROGRAMS += \ +examples_PROGRAMS += \ eina_accessor_01 \ - eina_array_01 \ + eina_array_01 \ eina_array_02 \ eina_error_01 \ eina_file_01 \ @@ -77,7 +77,7 @@ pkglib_PROGRAMS += \ if BUILD_TILER_EXAMPLE AM_CPPFLAGS += @ECORE_EVAS_CFLAGS@ -pkglib_PROGRAMS += eina_tiler_01 +examples_PROGRAMS += eina_tiler_01 eina_tiler_01_LDADD = $(top_builddir)/src/lib/libeina.la @ECORE_EVAS_LIBS@ endif diff --git a/libraries/eina/src/examples/Makefile.in b/libraries/eina/src/examples/Makefile.in index 3379e55..6e432bb 100644 --- a/libraries/eina/src/examples/Makefile.in +++ b/libraries/eina/src/examples/Makefile.in @@ -19,6 +19,7 @@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 @@ -34,10 +35,10 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -pkglib_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) +examples_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) @EFL_BUILD_EXAMPLES_TRUE@am__append_1 = \ @EFL_BUILD_EXAMPLES_TRUE@ eina_accessor_01 \ -@EFL_BUILD_EXAMPLES_TRUE@ eina_array_01 \ +@EFL_BUILD_EXAMPLES_TRUE@ eina_array_01 \ @EFL_BUILD_EXAMPLES_TRUE@ eina_array_02 \ @EFL_BUILD_EXAMPLES_TRUE@ eina_error_01 \ @EFL_BUILD_EXAMPLES_TRUE@ eina_file_01 \ @@ -115,8 +116,8 @@ CONFIG_CLEAN_VPATH_FILES = @EFL_BUILD_EXAMPLES_TRUE@ eina_str_01$(EXEEXT) \ @EFL_BUILD_EXAMPLES_TRUE@ eina_strbuf_01$(EXEEXT) @BUILD_TILER_EXAMPLE_TRUE@@EFL_BUILD_EXAMPLES_TRUE@am__EXEEXT_2 = eina_tiler_01$(EXEEXT) -am__installdirs = "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(filesdir)" -PROGRAMS = $(pkglib_PROGRAMS) +am__installdirs = "$(DESTDIR)$(examplesdir)" "$(DESTDIR)$(filesdir)" +PROGRAMS = $(examples_PROGRAMS) eina_accessor_01_SOURCES = eina_accessor_01.c eina_accessor_01_OBJECTS = eina_accessor_01.$(OBJEXT) eina_accessor_01_LDADD = $(LDADD) @@ -294,7 +295,6 @@ DATA = $(files_DATA) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -pkglibdir = $(datadir)/$(PACKAGE)/examples ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ @@ -337,7 +337,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@ @@ -389,8 +391,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@ @@ -465,6 +465,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ version_info = @version_info@ MAINTAINERCLEANFILES = Makefile.in +examplesdir = $(datadir)/$(PACKAGE)/examples AM_CPPFLAGS = -I. -I$(top_srcdir)/src/include \ -I$(top_builddir)/src/include $(am__append_2) LDADD = \ @@ -536,10 +537,10 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-pkglibPROGRAMS: $(pkglib_PROGRAMS) +install-examplesPROGRAMS: $(examples_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" - @list='$(pkglib_PROGRAMS)'; test -n "$(pkglibdir)" || list=; \ + test -z "$(examplesdir)" || $(MKDIR_P) "$(DESTDIR)$(examplesdir)" + @list='$(examples_PROGRAMS)'; test -n "$(examplesdir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ @@ -556,23 +557,23 @@ install-pkglibPROGRAMS: $(pkglib_PROGRAMS) while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(pkglibdir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(pkglibdir)$$dir" || exit $$?; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(examplesdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(examplesdir)$$dir" || exit $$?; \ } \ ; done -uninstall-pkglibPROGRAMS: +uninstall-examplesPROGRAMS: @$(NORMAL_UNINSTALL) - @list='$(pkglib_PROGRAMS)'; test -n "$(pkglibdir)" || list=; \ + @list='$(examples_PROGRAMS)'; test -n "$(examplesdir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(pkglibdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(pkglibdir)" && rm -f $$files + echo " ( cd '$(DESTDIR)$(examplesdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(examplesdir)" && rm -f $$files -clean-pkglibPROGRAMS: - @list='$(pkglib_PROGRAMS)'; test -n "$$list" || exit 0; \ +clean-examplesPROGRAMS: + @list='$(examples_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ @@ -831,7 +832,7 @@ check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(DATA) installdirs: - for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(filesdir)"; do \ + for dir in "$(DESTDIR)$(examplesdir)" "$(DESTDIR)$(filesdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -862,7 +863,7 @@ maintainer-clean-generic: -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am -clean-am: clean-generic clean-libtool clean-pkglibPROGRAMS \ +clean-am: clean-examplesPROGRAMS clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am @@ -883,13 +884,13 @@ info: info-am info-am: -install-data-am: install-filesDATA +install-data-am: install-examplesPROGRAMS install-filesDATA install-dvi: install-dvi-am install-dvi-am: -install-exec-am: install-pkglibPROGRAMS +install-exec-am: install-html: install-html-am @@ -929,24 +930,25 @@ ps: ps-am ps-am: -uninstall-am: uninstall-filesDATA uninstall-pkglibPROGRAMS +uninstall-am: uninstall-examplesPROGRAMS uninstall-filesDATA .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-pkglibPROGRAMS ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-filesDATA \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am install-pkglibPROGRAMS \ +.PHONY: CTAGS GTAGS all all-am check check-am clean \ + clean-examplesPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am \ + install-examplesPROGRAMS install-exec install-exec-am \ + install-filesDATA install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-filesDATA \ - uninstall-pkglibPROGRAMS + tags uninstall uninstall-am uninstall-examplesPROGRAMS \ + uninstall-filesDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/libraries/eina/src/examples/eina_array_01.c b/libraries/eina/src/examples/eina_array_01.c index 25e0944..d93eb35 100644 --- a/libraries/eina/src/examples/eina_array_01.c +++ b/libraries/eina/src/examples/eina_array_01.c @@ -35,12 +35,12 @@ main(int argc, char **argv) for (i = 0; i < 20; i++) eina_array_push(array, strdup(strings[i])); - printf("array count: %d\n", eina_array_count_get(array)); + printf("array count: %d\n", eina_array_count(array)); eina_array_foreach(array, _print, NULL); printf("Top gun: %s\n", (char*)eina_array_data_get(array, 2)); - while (eina_array_count_get(array)) + while (eina_array_count(array)) free(eina_array_pop(array)); eina_array_free(array); 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. * diff --git a/libraries/eina/src/lib/Makefile.am b/libraries/eina/src/lib/Makefile.am index 0537a61..d8c9d20 100644 --- a/libraries/eina/src/lib/Makefile.am +++ b/libraries/eina/src/lib/Makefile.am @@ -22,6 +22,7 @@ eina_error.c \ eina_fp.c \ eina_hamster.c \ eina_hash.c \ +eina_inarray.c \ eina_inlist.c \ eina_iterator.c \ eina_lalloc.c \ @@ -130,12 +131,17 @@ eina_amalgamation.c: $(base_sources) Makefile @echo "#include " >> eina_amalgamation.c @echo "#include " >> eina_amalgamation.c @echo "#include " >> eina_amalgamation.c - @echo "#include " >> eina_amalgamation.c + @echo "#ifdef HAVE_DLOPEN" >> eina_amalgamation.c + @echo "# include " >> eina_amalgamation.c + @echo "#endif" >> eina_amalgamation.c @echo "#include " >> eina_amalgamation.c - @echo "#include " >> eina_amalgamation.c + @echo "#ifdef HAVE_DIRENT_H" >> eina_amalgamation.c + @echo "# include " >> eina_amalgamation.c + @echo "#endif" >> eina_amalgamation.c @echo "#include " >> eina_amalgamation.c @echo "#include " >> eina_amalgamation.c @echo "#include " >> eina_amalgamation.c + @echo "#include " >> eina_amalgamation.c @echo "#ifdef HAVE_EVIL" >> eina_amalgamation.c @echo "# include " >> eina_amalgamation.c diff --git a/libraries/eina/src/lib/Makefile.in b/libraries/eina/src/lib/Makefile.in index 359aba0..878bcbe 100644 --- a/libraries/eina/src/lib/Makefile.in +++ b/libraries/eina/src/lib/Makefile.in @@ -96,15 +96,16 @@ libeina_la_DEPENDENCIES = am__libeina_la_SOURCES_DIST = eina_accessor.c eina_array.c \ eina_benchmark.c eina_binbuf.c eina_binshare.c eina_convert.c \ eina_counter.c eina_cpu.c eina_error.c eina_fp.c \ - eina_hamster.c eina_hash.c eina_inlist.c eina_iterator.c \ - eina_lalloc.c eina_list.c eina_log.c eina_magic.c eina_main.c \ - eina_matrixsparse.c eina_mempool.c eina_mmap.c eina_module.c \ - eina_prefix.c eina_quadtree.c eina_rbtree.c eina_rectangle.c \ - eina_safety_checks.c eina_sched.c eina_share_common.c \ - eina_simple_xml_parser.c eina_str.c eina_strbuf.c \ - eina_strbuf_common.c eina_stringshare.c eina_tiler.c \ - eina_unicode.c eina_ustrbuf.c eina_ustringshare.c eina_value.c \ - eina_xattr.c eina_file_win32.c eina_file.c \ + eina_hamster.c eina_hash.c eina_inarray.c eina_inlist.c \ + eina_iterator.c eina_lalloc.c eina_list.c eina_log.c \ + eina_magic.c eina_main.c eina_matrixsparse.c eina_mempool.c \ + eina_mmap.c eina_module.c eina_prefix.c eina_quadtree.c \ + eina_rbtree.c eina_rectangle.c eina_safety_checks.c \ + eina_sched.c eina_share_common.c eina_simple_xml_parser.c \ + eina_str.c eina_strbuf.c eina_strbuf_common.c \ + eina_stringshare.c eina_tiler.c eina_unicode.c eina_ustrbuf.c \ + eina_ustringshare.c eina_value.c eina_xattr.c \ + eina_file_win32.c eina_file.c \ $(top_srcdir)/src/modules/mp/buddy/eina_buddy.c \ $(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c \ $(top_srcdir)/src/modules/mp/ememoa_fixed/eina_ememoa_fixed.c \ @@ -129,15 +130,16 @@ am__objects_10 = libeina_la-eina_accessor.lo libeina_la-eina_array.lo \ libeina_la-eina_counter.lo libeina_la-eina_cpu.lo \ libeina_la-eina_error.lo libeina_la-eina_fp.lo \ libeina_la-eina_hamster.lo libeina_la-eina_hash.lo \ - libeina_la-eina_inlist.lo libeina_la-eina_iterator.lo \ - libeina_la-eina_lalloc.lo libeina_la-eina_list.lo \ - libeina_la-eina_log.lo libeina_la-eina_magic.lo \ - libeina_la-eina_main.lo libeina_la-eina_matrixsparse.lo \ - libeina_la-eina_mempool.lo libeina_la-eina_mmap.lo \ - libeina_la-eina_module.lo libeina_la-eina_prefix.lo \ - libeina_la-eina_quadtree.lo libeina_la-eina_rbtree.lo \ - libeina_la-eina_rectangle.lo libeina_la-eina_safety_checks.lo \ - libeina_la-eina_sched.lo libeina_la-eina_share_common.lo \ + libeina_la-eina_inarray.lo libeina_la-eina_inlist.lo \ + libeina_la-eina_iterator.lo libeina_la-eina_lalloc.lo \ + libeina_la-eina_list.lo libeina_la-eina_log.lo \ + libeina_la-eina_magic.lo libeina_la-eina_main.lo \ + libeina_la-eina_matrixsparse.lo libeina_la-eina_mempool.lo \ + libeina_la-eina_mmap.lo libeina_la-eina_module.lo \ + libeina_la-eina_prefix.lo libeina_la-eina_quadtree.lo \ + libeina_la-eina_rbtree.lo libeina_la-eina_rectangle.lo \ + libeina_la-eina_safety_checks.lo libeina_la-eina_sched.lo \ + libeina_la-eina_share_common.lo \ libeina_la-eina_simple_xml_parser.lo libeina_la-eina_str.lo \ libeina_la-eina_strbuf.lo libeina_la-eina_strbuf_common.lo \ libeina_la-eina_stringshare.lo libeina_la-eina_tiler.lo \ @@ -231,7 +233,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@ @@ -283,8 +287,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@ @@ -371,10 +373,10 @@ AM_CPPFLAGS = \ base_sources = eina_accessor.c eina_array.c eina_benchmark.c \ eina_binbuf.c eina_binshare.c eina_convert.c eina_counter.c \ eina_cpu.c eina_error.c eina_fp.c eina_hamster.c eina_hash.c \ - eina_inlist.c eina_iterator.c eina_lalloc.c eina_list.c \ - eina_log.c eina_magic.c eina_main.c eina_matrixsparse.c \ - eina_mempool.c eina_mmap.c eina_module.c eina_prefix.c \ - eina_quadtree.c eina_rbtree.c eina_rectangle.c \ + eina_inarray.c eina_inlist.c eina_iterator.c eina_lalloc.c \ + eina_list.c eina_log.c eina_magic.c eina_main.c \ + eina_matrixsparse.c eina_mempool.c eina_mmap.c eina_module.c \ + eina_prefix.c eina_quadtree.c eina_rbtree.c eina_rectangle.c \ eina_safety_checks.c eina_sched.c eina_share_common.c \ eina_simple_xml_parser.c eina_str.c eina_strbuf.c \ eina_strbuf_common.c eina_stringshare.c eina_tiler.c \ @@ -489,6 +491,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_fp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_hamster.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_hash.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_inarray.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_inlist.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_iterator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeina_la-eina_lalloc.Plo@am__quote@ @@ -641,6 +644,14 @@ libeina_la-eina_hash.lo: eina_hash.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_hash.lo `test -f 'eina_hash.c' || echo '$(srcdir)/'`eina_hash.c +libeina_la-eina_inarray.lo: eina_inarray.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_inarray.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_inarray.Tpo -c -o libeina_la-eina_inarray.lo `test -f 'eina_inarray.c' || echo '$(srcdir)/'`eina_inarray.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_inarray.Tpo $(DEPDIR)/libeina_la-eina_inarray.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eina_inarray.c' object='libeina_la-eina_inarray.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -c -o libeina_la-eina_inarray.lo `test -f 'eina_inarray.c' || echo '$(srcdir)/'`eina_inarray.c + libeina_la-eina_inlist.lo: eina_inlist.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeina_la_CFLAGS) $(CFLAGS) -MT libeina_la-eina_inlist.lo -MD -MP -MF $(DEPDIR)/libeina_la-eina_inlist.Tpo -c -o libeina_la-eina_inlist.lo `test -f 'eina_inlist.c' || echo '$(srcdir)/'`eina_inlist.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeina_la-eina_inlist.Tpo $(DEPDIR)/libeina_la-eina_inlist.Plo @@ -1189,12 +1200,17 @@ uninstall-am: uninstall-libLTLIBRARIES @EINA_AMALGAMATION_TRUE@ @echo "#include " >> eina_amalgamation.c @EINA_AMALGAMATION_TRUE@ @echo "#include " >> eina_amalgamation.c @EINA_AMALGAMATION_TRUE@ @echo "#include " >> eina_amalgamation.c -@EINA_AMALGAMATION_TRUE@ @echo "#include " >> eina_amalgamation.c +@EINA_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_DLOPEN" >> eina_amalgamation.c +@EINA_AMALGAMATION_TRUE@ @echo "# include " >> eina_amalgamation.c +@EINA_AMALGAMATION_TRUE@ @echo "#endif" >> eina_amalgamation.c @EINA_AMALGAMATION_TRUE@ @echo "#include " >> eina_amalgamation.c -@EINA_AMALGAMATION_TRUE@ @echo "#include " >> eina_amalgamation.c +@EINA_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_DIRENT_H" >> eina_amalgamation.c +@EINA_AMALGAMATION_TRUE@ @echo "# include " >> eina_amalgamation.c +@EINA_AMALGAMATION_TRUE@ @echo "#endif" >> eina_amalgamation.c @EINA_AMALGAMATION_TRUE@ @echo "#include " >> eina_amalgamation.c @EINA_AMALGAMATION_TRUE@ @echo "#include " >> eina_amalgamation.c @EINA_AMALGAMATION_TRUE@ @echo "#include " >> eina_amalgamation.c +@EINA_AMALGAMATION_TRUE@ @echo "#include " >> eina_amalgamation.c @EINA_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_EVIL" >> eina_amalgamation.c @EINA_AMALGAMATION_TRUE@ @echo "# include " >> eina_amalgamation.c diff --git a/libraries/eina/src/lib/eina_array.c b/libraries/eina/src/lib/eina_array.c index 5a850ac..4bcab61 100644 --- a/libraries/eina/src/lib/eina_array.c +++ b/libraries/eina/src/lib/eina_array.c @@ -119,7 +119,7 @@ eina_array_iterator_next(Eina_Iterator_Array *it, void **data) { EINA_MAGIC_CHECK_ARRAY_ITERATOR(it, EINA_FALSE); - if (!(it->index < eina_array_count_get(it->array))) + if (!(it->index < eina_array_count(it->array))) return EINA_FALSE; if (data) @@ -150,7 +150,7 @@ eina_array_accessor_get_at(Eina_Accessor_Array *it, { EINA_MAGIC_CHECK_ARRAY_ACCESSOR(it, EINA_FALSE); - if (!(idx < eina_array_count_get(it->array))) + if (!(idx < eina_array_count(it->array))) return EINA_FALSE; if (data) diff --git a/libraries/eina/src/lib/eina_binbuf_template_c.x b/libraries/eina/src/lib/eina_binbuf_template_c.x index 613a715..7e0c539 100644 --- a/libraries/eina/src/lib/eina_binbuf_template_c.x +++ b/libraries/eina/src/lib/eina_binbuf_template_c.x @@ -65,6 +65,15 @@ _FUNC_EXPAND(new)(void) return buf; } +EAPI _STRBUF_STRUCT_NAME * +_FUNC_EXPAND(manage_new_length)(_STRBUF_DATA_TYPE *str, size_t length) +{ + _STRBUF_STRUCT_NAME *buf = + eina_strbuf_common_manage_new(_STRBUF_CSIZE, (void *) str, length); + EINA_MAGIC_SET(buf, _STRBUF_MAGIC); + return buf; +} + EAPI void _FUNC_EXPAND(free)(_STRBUF_STRUCT_NAME *buf) { diff --git a/libraries/eina/src/lib/eina_cpu.c b/libraries/eina/src/lib/eina_cpu.c index 8af550d..5b190e4 100644 --- a/libraries/eina/src/lib/eina_cpu.c +++ b/libraries/eina/src/lib/eina_cpu.c @@ -24,7 +24,7 @@ # ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # include -# elif defined (__SUNPRO_C) || defined(__GNU__) +# elif defined (__sun) || defined(__GNU__) # include # elif defined (__FreeBSD__) || defined (__OpenBSD__) || \ defined (__NetBSD__) || defined (__DragonFly__) || defined (__MacOSX__) || \ @@ -140,7 +140,7 @@ EAPI int eina_cpu_count(void) GetSystemInfo(&sysinfo); return sysinfo.dwNumberOfProcessors; -# elif defined (__SUNPRO_C) || defined(__GNU__) +# elif defined (__sun) || defined(__GNU__) /* * _SC_NPROCESSORS_ONLN: number of processors that are online, that is available when sysconf is called. The number diff --git a/libraries/eina/src/lib/eina_file.c b/libraries/eina/src/lib/eina_file.c index 84b9e78..0b836b3 100644 --- a/libraries/eina/src/lib/eina_file.c +++ b/libraries/eina/src/lib/eina_file.c @@ -38,13 +38,18 @@ extern "C" void *alloca (size_t); #endif +#include #include #include -#include +#ifdef HAVE_DIRENT_H +# include +#endif #include #include #include -#include +#ifdef HAVE_SYS_MMAN_H +# include +#endif #include #define PATH_DELIM '/' @@ -60,6 +65,8 @@ void *alloca (size_t); #include "eina_list.h" #include "eina_lock.h" #include "eina_mmap.h" +#include "eina_log.h" +#include "eina_xattr.h" #ifdef HAVE_ESCAPE_H # include @@ -95,9 +102,8 @@ void *alloca (size_t); #define EINA_SMALL_PAGE 4096 # define EINA_HUGE_PAGE 16 * 1024 * 1024 +#ifdef HAVE_DIRENT_H typedef struct _Eina_File_Iterator Eina_File_Iterator; -typedef struct _Eina_File_Map Eina_File_Map; - struct _Eina_File_Iterator { Eina_Iterator iterator; @@ -107,6 +113,7 @@ struct _Eina_File_Iterator char dir[1]; }; +#endif struct _Eina_File { @@ -132,8 +139,10 @@ struct _Eina_File Eina_Bool shared : 1; Eina_Bool delete_me : 1; + Eina_Bool global_faulty : 1; }; +typedef struct _Eina_File_Map Eina_File_Map; struct _Eina_File_Map { void *map; @@ -144,6 +153,7 @@ struct _Eina_File_Map int refcount; Eina_Bool hugetlb : 1; + Eina_Bool faulty : 1; }; static Eina_Hash *_eina_file_cache = NULL; @@ -156,6 +166,7 @@ static int _eina_file_log_dom = -1; * The code and description of the issue can be found at : * http://womble.decadent.org.uk/readdir_r-advisory.html */ +#ifdef HAVE_DIRENT_H static long _eina_name_max(DIR *dirp) { @@ -390,6 +401,7 @@ _eina_file_stat_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data) return EINA_TRUE; } +#endif static void _eina_file_real_close(Eina_File *file) @@ -511,8 +523,8 @@ slprintf(char *str, size_t size, const char *format, ...) va_end(ap); } -static char* -_eina_file_escape(const char* path, int* length) +static char * +_eina_file_escape(const char *path, int *length) { char *result = strdup(path ? path : ""); char *p = result; @@ -738,6 +750,7 @@ eina_file_split(char *path) EAPI Eina_Iterator * eina_file_ls(const char *dir) { +#ifdef HAVE_DIRENT_H Eina_File_Iterator *it; size_t length; @@ -773,11 +786,16 @@ eina_file_ls(const char *dir) it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_ls_iterator_free); return &it->iterator; +#else + (void) dir; + return NULL; +#endif } EAPI Eina_Iterator * eina_file_direct_ls(const char *dir) { +#ifdef HAVE_DIRENT_H Eina_File_Direct_Iterator *it; size_t length; @@ -825,11 +843,16 @@ eina_file_direct_ls(const char *dir) it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_direct_ls_iterator_free); return &it->iterator; +#else + (void) dir; + return NULL; +#endif } EAPI Eina_Iterator * eina_file_stat_ls(const char *dir) { +#ifdef HAVE_DIRENT_H Eina_File_Direct_Iterator *it; size_t length; @@ -877,6 +900,10 @@ eina_file_stat_ls(const char *dir) it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_direct_ls_iterator_free); return &it->iterator; +#else + (void) dir; + return NULL; +#endif } EAPI Eina_File * @@ -887,7 +914,9 @@ eina_file_open(const char *path, Eina_Bool shared) char *filename; struct stat file_stat; int fd = -1; +#ifdef HAVE_EXECVP int flags; +#endif EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); @@ -1184,4 +1213,91 @@ eina_file_map_free(Eina_File *file, void *map) eina_lock_release(&file->lock); } +EAPI Eina_Bool +eina_file_map_faulted(Eina_File *file, void *map) +{ + Eina_File_Map *em; + + EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE); + + eina_lock_take(&file->lock); + + if (file->global_map == map) return file->global_faulty; + + em = eina_hash_find(file->rmap, &map); + if (!em) return EINA_FALSE; + + return em->faulty; +} + +EAPI Eina_Iterator * +eina_file_xattr_get(Eina_File *file) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); + + return eina_xattr_fd_ls(file->fd); +} + +EAPI Eina_Iterator * +eina_file_xattr_value_get(Eina_File *file) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); + + return eina_xattr_value_fd_ls(file->fd); +} + +void +eina_file_mmap_faulty(void *addr, long page_size) +{ + Eina_File_Map *m; + Eina_File *f; + Eina_Iterator *itf; + Eina_Iterator *itm; + + /* NOTE: I actually don't know if other thread are running, I will try to take the lock. + It may be possible that if other thread are not running and they were in the middle of + accessing an Eina_File this lock are still taken and we will result as a deadlock. */ + eina_lock_take(&_eina_file_lock_cache); + + itf = eina_hash_iterator_data_new(_eina_file_cache); + EINA_ITERATOR_FOREACH(itf, f) + { + Eina_Bool faulty = EINA_FALSE; + + eina_lock_take(&f->lock); + + if (f->global_map) + { + if ((unsigned char *) addr < (((unsigned char *)f->global_map) + f->length) && + (((unsigned char *) addr) + page_size) >= (unsigned char *) f->global_map) + { + f->global_faulty = EINA_TRUE; + faulty = EINA_TRUE; + } + } + + if (!faulty) + { + itm = eina_hash_iterator_data_new(f->map); + EINA_ITERATOR_FOREACH(itm, m) + { + if ((unsigned char *) addr < (((unsigned char *)m->map) + m->length) && + (((unsigned char *) addr) + page_size) >= (unsigned char *) m->map) + { + m->faulty = EINA_TRUE; + faulty = EINA_TRUE; + break; + } + } + eina_iterator_free(itm); + } + + eina_lock_release(&f->lock); + + if (faulty) break; + } + eina_iterator_free(itf); + + eina_lock_release(&_eina_file_lock_cache); +} diff --git a/libraries/eina/src/lib/eina_hash.c b/libraries/eina/src/lib/eina_hash.c index 5df20aa..5196894 100644 --- a/libraries/eina/src/lib/eina_hash.c +++ b/libraries/eina/src/lib/eina_hash.c @@ -854,8 +854,9 @@ eina_hash_free(Eina_Hash *hash) { int i; + if (!hash) return ; + EINA_MAGIC_CHECK_HASH(hash); - EINA_SAFETY_ON_NULL_RETURN(hash); if (hash->buckets) { @@ -871,8 +872,9 @@ eina_hash_free_buckets(Eina_Hash *hash) { int i; + if (!hash) return ; + EINA_MAGIC_CHECK_HASH(hash); - EINA_SAFETY_ON_NULL_RETURN(hash); if (hash->buckets) { diff --git a/libraries/eina/src/lib/eina_inarray.c b/libraries/eina/src/lib/eina_inarray.c new file mode 100644 index 0000000..dc95bc6 --- /dev/null +++ b/libraries/eina/src/lib/eina_inarray.c @@ -0,0 +1,777 @@ +/* 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 . + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "eina_config.h" +#include "eina_private.h" +#include "eina_error.h" +#include "eina_log.h" + +/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ +#include "eina_safety_checks.h" +#include "eina_inarray.h" + +/*============================================================================* +* Local * +*============================================================================*/ + +/** + * @cond LOCAL + */ + +static const char EINA_MAGIC_INARRAY_STR[] = "Eina Inline Array"; +static const char EINA_MAGIC_INARRAY_ITERATOR_STR[] = "Eina Inline Array Iterator"; +static const char EINA_MAGIC_INARRAY_ACCESSOR_STR[] = "Eina Inline Array Accessor"; + +typedef struct _Eina_Iterator_Inarray Eina_Iterator_Inarray; +typedef struct _Eina_Accessor_Inarray Eina_Accessor_Inarray; + +struct _Eina_Iterator_Inarray +{ + Eina_Iterator iterator; + const Eina_Inarray *array; + unsigned int pos; + EINA_MAGIC +}; + +struct _Eina_Accessor_Inarray +{ + Eina_Accessor accessor; + const Eina_Inarray *array; + EINA_MAGIC +}; + +static int _eina_inarray_log_dom = -1; + +#ifdef ERR +#undef ERR +#endif +#define ERR(...) EINA_LOG_DOM_ERR(_eina_inarray_log_dom, __VA_ARGS__) + +#ifdef DBG +#undef DBG +#endif +#define DBG(...) EINA_LOG_DOM_DBG(_eina_inarray_log_dom, __VA_ARGS__) + +#define EINA_MAGIC_CHECK_INARRAY(d, ...) \ + do \ + { \ + if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_INARRAY)) \ + { \ + EINA_MAGIC_FAIL(d, EINA_MAGIC_INARRAY); \ + return __VA_ARGS__; \ + } \ + eina_error_set(0); \ + } \ + while(0) + +#define EINA_MAGIC_CHECK_INARRAY_ITERATOR(d, ...) \ + do \ + { \ + if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_INARRAY_ITERATOR)) \ + { \ + EINA_MAGIC_FAIL(d, EINA_MAGIC_INARRAY_ITERATOR); \ + return __VA_ARGS__; \ + } \ + eina_error_set(0); \ + } \ + while(0) + +#define EINA_MAGIC_CHECK_INARRAY_ACCESSOR(d, ...) \ + do \ + { \ + if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_INARRAY_ACCESSOR)) \ + { \ + EINA_MAGIC_FAIL(d, EINA_MAGIC_INARRAY_ACCESSOR); \ + return __VA_ARGS__; \ + } \ + eina_error_set(0); \ + } \ + while(0) + +static void +_eina_inarray_setup(Eina_Inarray *array, unsigned int member_size, unsigned int step) +{ + EINA_MAGIC_SET(array, EINA_MAGIC_INARRAY); + array->member_size = member_size; + array->len = 0; + array->max = 0; + array->step = (step > 0) ? step : 32; + array->members = NULL; +} + +static Eina_Bool +_eina_inarray_resize(Eina_Inarray *array, unsigned int new_size) +{ + unsigned int new_max; + void *tmp; + + if (new_size < array->max) + return EINA_TRUE; + + if (new_size % array->step == 0) + new_max = new_size; + else + new_max = ((new_size / array->step) + 1) * array->step; + + tmp = realloc(array->members, new_max * array->member_size); + if ((!tmp) && (new_max > 0)) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + + array->members = tmp; + array->max = new_max; + return EINA_TRUE; +} + +static inline void * +_eina_inarray_get(const Eina_Inarray *array, unsigned int position) +{ + unsigned int offset = position * array->member_size; + return (unsigned char *)array->members + offset; +} + +static int +_eina_inarray_search(const Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) +{ + const unsigned char *start, *found; + start = array->members; + found = bsearch(data, start, array->len, array->member_size, compare); + if (!found) + return -1; + return (found - start) / array->member_size; +} + +static unsigned int +_eina_inarray_search_sorted_near(const Eina_Inarray *array, const void *data, Eina_Compare_Cb compare, int *cmp) +{ + unsigned int start, last, middle; + + if (array->len == 0) + { + *cmp = -1; + return 0; + } + else if (array->len == 1) + { + *cmp = compare(data, array->members); + return 0; + } + + start = 0; + last = array->len - 1; /* inclusive */ + do + { + void *p; + middle = start + (last - start) / 2; /* avoid overflow */ + p = _eina_inarray_get(array, middle); + *cmp = compare(data, p); + if (*cmp == 0) + return middle; + else if (*cmp > 0) + start = middle + 1; + else if (middle > 0) + last = middle - 1; + else + break; + } + while (start <= last); + return middle; +} + + +static Eina_Bool +_eina_inarray_iterator_next(Eina_Iterator_Inarray *it, void **data) +{ + EINA_MAGIC_CHECK_INARRAY_ITERATOR(it, EINA_FALSE); + + if (it->pos >= it->array->len) + return EINA_FALSE; + + *data = _eina_inarray_get(it->array, it->pos); + it->pos++; + + return EINA_TRUE; +} + +static Eina_Bool +_eina_inarray_iterator_prev(Eina_Iterator_Inarray *it, void **data) +{ + EINA_MAGIC_CHECK_INARRAY_ITERATOR(it, EINA_FALSE); + + if (it->pos == 0) + return EINA_FALSE; + + it->pos--; + *data = _eina_inarray_get(it->array, it->pos); + + return EINA_TRUE; +} + +static Eina_Inarray * +_eina_inarray_iterator_get_container(Eina_Iterator_Inarray *it) +{ + EINA_MAGIC_CHECK_INARRAY_ITERATOR(it, NULL); + return (Eina_Inarray *)it->array; +} + +static void +_eina_inarray_iterator_free(Eina_Iterator_Inarray *it) +{ + EINA_MAGIC_CHECK_INARRAY_ITERATOR(it); + MAGIC_FREE(it); +} + +static Eina_Bool +_eina_inarray_accessor_get_at(Eina_Accessor_Inarray *it, unsigned int pos, void **data) +{ + EINA_MAGIC_CHECK_INARRAY_ACCESSOR(it, EINA_FALSE); + + if (pos >= it->array->len) + return EINA_FALSE; + + *data = _eina_inarray_get(it->array, pos); + return EINA_TRUE; +} + +static Eina_Inarray * +_eina_inarray_accessor_get_container(Eina_Accessor_Inarray *it) +{ + EINA_MAGIC_CHECK_INARRAY_ACCESSOR(it, NULL); + return (Eina_Inarray *)it->array; +} + +static void +_eina_inarray_accessor_free(Eina_Accessor_Inarray *it) +{ + EINA_MAGIC_CHECK_INARRAY_ACCESSOR(it); + MAGIC_FREE(it); +} + +/** + * @endcond + */ + + +/*============================================================================* +* Global * +*============================================================================*/ + +/** + * @internal + * @brief Initialize the inline array module. + * + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function sets up the inline array module of Eina. It is called + * by eina_init(). + * + * @see eina_init() + */ +Eina_Bool +eina_inarray_init(void) +{ + _eina_inarray_log_dom = eina_log_domain_register("eina_inarray", + EINA_LOG_COLOR_DEFAULT); + if (_eina_inarray_log_dom < 0) + { + EINA_LOG_ERR("Could not register log domain: eina_inarray"); + return EINA_FALSE; + } + +#define EMS(n) eina_magic_string_static_set(n, n ## _STR) + EMS(EINA_MAGIC_INARRAY); + EMS(EINA_MAGIC_INARRAY_ITERATOR); + EMS(EINA_MAGIC_INARRAY_ACCESSOR); +#undef EMS + + return EINA_TRUE; +} + +/** + * @internal + * @brief Shut down the inline array module. + * + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function shuts down the inline array module set up by + * eina_inarray_init(). It is called by eina_shutdown(). + * + * @see eina_shutdown() + */ +Eina_Bool +eina_inarray_shutdown(void) +{ + eina_log_domain_unregister(_eina_inarray_log_dom); + _eina_inarray_log_dom = -1; + return EINA_TRUE; +} + +/*============================================================================* +* API * +*============================================================================*/ +EAPI Eina_Inarray * +eina_inarray_new(unsigned int member_size, unsigned int step) +{ + Eina_Inarray *ret; + + EINA_SAFETY_ON_TRUE_RETURN_VAL(member_size == 0, NULL); + + ret = malloc(sizeof(*ret)); + if (!ret) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return NULL; + } + eina_error_set(0); + _eina_inarray_setup(ret, member_size, step); + return ret; +} + +EAPI void +eina_inarray_free(Eina_Inarray *array) +{ + EINA_MAGIC_CHECK_INARRAY(array); + free(array->members); + free(array); +} + +EAPI void +eina_inarray_setup(Eina_Inarray *array, unsigned int member_size, unsigned int step) +{ + EINA_SAFETY_ON_NULL_RETURN(array); + EINA_SAFETY_ON_TRUE_RETURN(member_size == 0); + _eina_inarray_setup(array, member_size, step); +} + +EAPI void +eina_inarray_flush(Eina_Inarray *array) +{ + EINA_MAGIC_CHECK_INARRAY(array); + free(array->members); + array->len = 0; + array->max = 0; + array->members = NULL; +} + +EAPI int +eina_inarray_append(Eina_Inarray *array, const void *data) +{ + void *p; + + EINA_MAGIC_CHECK_INARRAY(array, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); + + if (!_eina_inarray_resize(array, array->len + 1)) + return -1; + + p = _eina_inarray_get(array, array->len); + memcpy(p, data, array->member_size); + + array->len++; + return array->len - 1; +} + +EAPI int +eina_inarray_insert(Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) +{ + const unsigned char *itr, *itr_end; + unsigned int sz; + + EINA_MAGIC_CHECK_INARRAY(array, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(compare, -1); + + sz = array->member_size; + itr = array->members; + itr_end = itr + array->len * sz; + for (; itr < itr_end; itr += sz) + { + unsigned int offset, position; + int cmp = compare(itr, data); + if (cmp <= 0) + continue; + + offset = itr - (unsigned char *)array->members; + position = offset / sz; + if (!eina_inarray_insert_at(array, position, data)) + return -1; + return position; + } + return eina_inarray_append(array, data); +} + +EAPI int +eina_inarray_insert_sorted(Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) +{ + unsigned int pos; + int cmp; + + EINA_MAGIC_CHECK_INARRAY(array, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(compare, -1); + + pos = _eina_inarray_search_sorted_near(array, data, compare, &cmp); + if (cmp > 0) + pos++; + + if (!eina_inarray_insert_at(array, pos, data)) + return -1; + return pos; +} + +EAPI int +eina_inarray_remove(Eina_Inarray *array, const void *data) +{ + const unsigned char *itr, *itr_end; + unsigned int position, sz; + + EINA_MAGIC_CHECK_INARRAY(array, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); + + sz = array->member_size; + if ((data >= array->members) && + (data < _eina_inarray_get(array, array->len))) + { + unsigned int offset = ((unsigned char *)data - + (unsigned char *)array->members); + position = offset / sz; + goto found; + } + + itr = array->members; + itr_end = itr + array->len * sz; + for (; itr < itr_end; itr += sz) + { + if (memcmp(data, itr, sz) == 0) + { + unsigned int offset = itr - (unsigned char *)array->members; + position = offset / sz; + goto found; + } + } + return -1; + +found: + if (!eina_inarray_remove_at(array, position)) + return -1; + return position; +} + +EAPI int +eina_inarray_pop(Eina_Inarray *array) +{ + EINA_MAGIC_CHECK_INARRAY(array, -1); + EINA_SAFETY_ON_TRUE_RETURN_VAL(array->len == 0, -1); + if (!_eina_inarray_resize(array, array->len - 1)) + return -1; + array->len--; + return array->len + 1; +} + +EAPI void * +eina_inarray_nth(const Eina_Inarray *array, unsigned int position) +{ + EINA_MAGIC_CHECK_INARRAY(array, NULL); + EINA_SAFETY_ON_TRUE_RETURN_VAL(position >= array->len, NULL); + return _eina_inarray_get(array, position); +} + +EAPI Eina_Bool +eina_inarray_insert_at(Eina_Inarray *array, unsigned int position, const void *data) +{ + unsigned int sz; + unsigned char *p; + + EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); + EINA_SAFETY_ON_TRUE_RETURN_VAL(position > array->len, EINA_FALSE); + + if (!_eina_inarray_resize(array, array->len + 1)) + return EINA_FALSE; + + p = _eina_inarray_get(array, position); + sz = array->member_size; + if (array->len > position) + memmove(p + sz, p, (array->len - position) * sz); + memcpy(p, data, sz); + + array->len++; + return EINA_TRUE; +} + +EAPI void * +eina_inarray_alloc_at(Eina_Inarray *array, unsigned int position, unsigned int member_count) +{ + unsigned int sz; + unsigned char *p; + + EINA_MAGIC_CHECK_INARRAY(array, NULL); + EINA_SAFETY_ON_TRUE_RETURN_VAL(position > array->len, NULL); + EINA_SAFETY_ON_TRUE_RETURN_VAL(member_count == 0, NULL); + + if (!_eina_inarray_resize(array, array->len + member_count)) + return NULL; + + p = _eina_inarray_get(array, position); + sz = array->member_size; + if (array->len > position) + memmove(p + member_count * sz, p, (array->len - position) * sz); + + array->len += member_count; + return p; +} + +EAPI Eina_Bool +eina_inarray_replace_at(Eina_Inarray *array, unsigned int position, const void *data) +{ + unsigned char *p; + + EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); + EINA_SAFETY_ON_TRUE_RETURN_VAL(position >= array->len, EINA_FALSE); + + p = _eina_inarray_get(array, position); + memcpy(p, data, array->member_size); + + return EINA_TRUE; +} + +EAPI Eina_Bool +eina_inarray_remove_at(Eina_Inarray *array, unsigned int position) +{ + EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); + EINA_SAFETY_ON_TRUE_RETURN_VAL(position >= array->len, EINA_FALSE); + + if (position + 1 < array->len) + { + unsigned int sz = array->member_size; + unsigned char *p = _eina_inarray_get(array, position); + memmove(p, p + sz, (array->len - position - 1) * sz); + } + + _eina_inarray_resize(array, array->len - 1); + array->len--; + return EINA_TRUE; +} + +EAPI void +eina_inarray_reverse(Eina_Inarray *array) +{ + size_t sz; + unsigned char *fwd, *rev, *fwd_end; + void *tmp; + + EINA_MAGIC_CHECK_INARRAY(array); + + if (array->len < 2) + return; + + sz = array->member_size; + + tmp = alloca(sz); + EINA_SAFETY_ON_NULL_RETURN(tmp); + + fwd = array->members; + fwd_end = fwd + (array->len / 2) * sz; + + rev = fwd + (array->len - 1) * sz; + + for (; fwd < fwd_end; fwd += sz, rev -= sz) + { + memcpy(tmp, fwd, sz); + memcpy(fwd, rev, sz); + memcpy(rev, tmp, sz); + } +} + +EAPI void +eina_inarray_sort(Eina_Inarray *array, Eina_Compare_Cb compare) +{ + EINA_MAGIC_CHECK_INARRAY(array); + EINA_SAFETY_ON_NULL_RETURN(compare); + qsort(array->members, array->len, array->member_size, compare); +} + +EAPI int +eina_inarray_search(const Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) +{ + EINA_MAGIC_CHECK_INARRAY(array, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(compare, -1); + return _eina_inarray_search(array, data, compare); +} + +EAPI int +eina_inarray_search_sorted(const Eina_Inarray *array, const void *data, Eina_Compare_Cb compare) +{ + unsigned int pos; + int cmp; + + EINA_MAGIC_CHECK_INARRAY(array, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(data, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(compare, -1); + + pos = _eina_inarray_search_sorted_near(array, data, compare, &cmp); + if (cmp == 0) + return pos; + return -1; +} + +EAPI Eina_Bool +eina_inarray_foreach(const Eina_Inarray *array, Eina_Each_Cb function, const void *user_data) +{ + unsigned char *itr, *itr_end; + unsigned int sz; + Eina_Bool ret = EINA_TRUE; + + EINA_MAGIC_CHECK_INARRAY(array, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(function, EINA_FALSE); + + sz = array->member_size; + itr = array->members; + itr_end = itr + array->len * sz; + for (; (itr < itr_end) && (ret); itr += sz) + ret = function(array, itr, (void *)user_data); + return ret; +} + +EAPI int +eina_inarray_foreach_remove(Eina_Inarray *array, Eina_Each_Cb match, const void *user_data) +{ + unsigned int i = 0, count = 0; + + EINA_MAGIC_CHECK_INARRAY(array, -1); + EINA_SAFETY_ON_NULL_RETURN_VAL(match, -1); + + while (i < array->len) + { + void *p = _eina_inarray_get(array, i); + if (match(array, p, (void *)user_data) == EINA_FALSE) + { + i++; + continue; + } + + eina_inarray_remove_at(array, i); + count++; + } + + return count; +} + +EAPI unsigned int +eina_inarray_count(const Eina_Inarray *array) +{ + EINA_MAGIC_CHECK_INARRAY(array, 0); + return array->len; +} + +EAPI Eina_Iterator * +eina_inarray_iterator_new(const Eina_Inarray *array) +{ + Eina_Iterator_Inarray *it; + + EINA_MAGIC_CHECK_INARRAY(array, NULL); + + eina_error_set(0); + it = calloc(1, sizeof(Eina_Iterator_Inarray)); + if (!it) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return NULL; + } + + EINA_MAGIC_SET(it, EINA_MAGIC_INARRAY_ITERATOR); + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + + it->array = array; + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = FUNC_ITERATOR_NEXT(_eina_inarray_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER + (_eina_inarray_iterator_get_container); + it->iterator.free = FUNC_ITERATOR_FREE(_eina_inarray_iterator_free); + + return &it->iterator; +} + +EAPI Eina_Iterator * +eina_inarray_iterator_reversed_new(const Eina_Inarray *array) +{ + Eina_Iterator_Inarray *it; + + EINA_MAGIC_CHECK_INARRAY(array, NULL); + + eina_error_set(0); + it = calloc(1, sizeof(Eina_Iterator_Inarray)); + if (!it) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return NULL; + } + + EINA_MAGIC_SET(it, EINA_MAGIC_INARRAY_ITERATOR); + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + + it->array = array; + it->pos = array->len; + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = FUNC_ITERATOR_NEXT(_eina_inarray_iterator_prev); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER + (_eina_inarray_iterator_get_container); + it->iterator.free = FUNC_ITERATOR_FREE(_eina_inarray_iterator_free); + + return &it->iterator; +} + +EAPI Eina_Accessor * +eina_inarray_accessor_new(const Eina_Inarray *array) +{ + Eina_Accessor_Inarray *ac; + + EINA_MAGIC_CHECK_INARRAY(array, NULL); + + eina_error_set(0); + ac = calloc(1, sizeof(Eina_Accessor_Inarray)); + if (!ac) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return NULL; + } + + EINA_MAGIC_SET(ac, EINA_MAGIC_INARRAY_ACCESSOR); + EINA_MAGIC_SET(&ac->accessor, EINA_MAGIC_ACCESSOR); + + ac->array = array; + + ac->accessor.version = EINA_ACCESSOR_VERSION; + ac->accessor.get_at = FUNC_ACCESSOR_GET_AT(_eina_inarray_accessor_get_at); + ac->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER + (_eina_inarray_accessor_get_container); + ac->accessor.free = FUNC_ACCESSOR_FREE(_eina_inarray_accessor_free); + + return &ac->accessor; +} diff --git a/libraries/eina/src/lib/eina_log.c b/libraries/eina/src/lib/eina_log.c index dd772d2..4e2bb6d 100644 --- a/libraries/eina/src/lib/eina_log.c +++ b/libraries/eina/src/lib/eina_log.c @@ -71,6 +71,7 @@ #define EINA_LOG_ENV_FILE_DISABLE "EINA_LOG_FILE_DISABLE" #define EINA_LOG_ENV_FUNCTION_DISABLE "EINA_LOG_FUNCTION_DISABLE" +#ifdef EINA_ENABLE_LOG // Structure for storing domain level settings passed from the command line // that will be matched with application-defined domains. @@ -1294,6 +1295,8 @@ eina_log_print_unlocked(int domain, abort(); } +#endif + /** * @endcond */ @@ -1321,6 +1324,7 @@ eina_log_print_unlocked(int domain, Eina_Bool eina_log_init(void) { +#ifdef EINA_ENABLE_LOG const char *level, *tmp; int color_disable; @@ -1392,6 +1396,7 @@ eina_log_init(void) // Parse pending domains passed through EINA_LOG_LEVELS eina_log_domain_parse_pendings(); +#endif return EINA_TRUE; } @@ -1413,6 +1418,7 @@ eina_log_init(void) Eina_Bool eina_log_shutdown(void) { +#ifdef EINA_ENABLE_LOG Eina_Inlist *tmp; while (_log_domains_count--) @@ -1443,6 +1449,7 @@ eina_log_shutdown(void) free(tmp); } +#endif return EINA_TRUE; } @@ -1460,10 +1467,12 @@ eina_log_shutdown(void) void eina_log_threads_init(void) { +#ifdef EINA_ENABLE_LOG if (_threads_inited) return; _main_thread = SELF(); if (!INIT()) return; _threads_inited = EINA_TRUE; +#endif } /** @@ -1478,11 +1487,13 @@ eina_log_threads_init(void) void eina_log_threads_shutdown(void) { +#ifdef EINA_ENABLE_LOG if (!_threads_inited) return; CHECK_MAIN(); SHUTDOWN(); _threads_enabled = EINA_FALSE; _threads_inited = EINA_FALSE; +#endif } #endif @@ -1504,7 +1515,7 @@ EAPI int EINA_LOG_DOMAIN_GLOBAL = 0; EAPI void eina_log_threads_enable(void) { -#ifdef EFL_HAVE_THREADS +#if defined (EFL_HAVE_THREADS) && defined (EINA_ENABLE_LOG) if (_threads_enabled) return; if (!_threads_inited) eina_log_threads_init(); _threads_enabled = EINA_TRUE; @@ -1515,32 +1526,45 @@ eina_log_threads_enable(void) EAPI void eina_log_print_cb_set(Eina_Log_Print_Cb cb, void *data) { +#ifdef EINA_ENABLE_LOG LOG_LOCK(); _print_cb = cb; _print_cb_data = data; eina_log_print_prefix_update(); LOG_UNLOCK(); +#else + (void) cb; + (void) data; +#endif } EAPI void eina_log_level_set(int level) { +#ifdef EINA_ENABLE_LOG _log_level = level; if (EINA_LIKELY((EINA_LOG_DOMAIN_GLOBAL >= 0) && ((unsigned int)EINA_LOG_DOMAIN_GLOBAL < _log_domains_count))) _log_domains[EINA_LOG_DOMAIN_GLOBAL].level = level; +#else + (void) level; +#endif } EAPI int eina_log_level_get(void) { +#ifdef EINA_ENABLE_LOG return _log_level; +#else + return 0; +#endif } EAPI Eina_Bool eina_log_main_thread_check(void) { -#ifdef EFL_HAVE_THREADS +#if defined (EFL_HAVE_THREADS) && defined (EINA_ENABLE_LOG) return ((!_threads_enabled) || IS_MAIN(SELF())); #else return EINA_TRUE; @@ -1550,66 +1574,107 @@ eina_log_main_thread_check(void) EAPI void eina_log_color_disable_set(Eina_Bool disabled) { +#ifdef EINA_ENABLE_LOG _disable_color = disabled; +#else + (void) disabled; +#endif } EAPI Eina_Bool eina_log_color_disable_get(void) { +#ifdef EINA_ENABLE_LOG return _disable_color; +#else + return EINA_TRUE; +#endif } EAPI void eina_log_file_disable_set(Eina_Bool disabled) { +#ifdef EINA_ENABLE_LOG _disable_file = disabled; +#else + (void) disabled; +#endif } EAPI Eina_Bool eina_log_file_disable_get(void) { +#ifdef EINA_ENABLE_LOG return _disable_file; +#else + return EINA_TRUE; +#endif } EAPI void eina_log_function_disable_set(Eina_Bool disabled) { +#ifdef EINA_ENABLE_LOG _disable_function = disabled; +#else + (void) disabled; +#endif } EAPI Eina_Bool eina_log_function_disable_get(void) { +#ifdef EINA_ENABLE_LOG return _disable_function; +#else + return EINA_TRUE; +#endif } EAPI void eina_log_abort_on_critical_set(Eina_Bool abort_on_critical) { +#ifdef EINA_ENABLE_LOG _abort_on_critical = abort_on_critical; +#else + (void) abort_on_critical; +#endif } EAPI Eina_Bool eina_log_abort_on_critical_get(void) { +#ifdef EINA_ENABLE_LOG return _abort_on_critical; +#else + return EINA_FALSE; +#endif } EAPI void eina_log_abort_on_critical_level_set(int critical_level) { +#ifdef EINA_ENABLE_LOG _abort_level_on_critical = critical_level; +#else + (void) critical_level; +#endif } EAPI int eina_log_abort_on_critical_level_get(void) { +#ifdef EINA_ENABLE_LOG return _abort_level_on_critical; +#else + return 0; +#endif } EAPI int eina_log_domain_register(const char *name, const char *color) { +#ifdef EINA_ENABLE_LOG int r; EINA_SAFETY_ON_NULL_RETURN_VAL(name, -1); @@ -1618,20 +1683,30 @@ eina_log_domain_register(const char *name, const char *color) r = eina_log_domain_register_unlocked(name, color); LOG_UNLOCK(); return r; +#else + (void) name; + (void) color; + return 0; +#endif } EAPI void eina_log_domain_unregister(int domain) { +#ifdef EINA_ENABLE_LOG EINA_SAFETY_ON_FALSE_RETURN(domain >= 0); LOG_LOCK(); eina_log_domain_unregister_unlocked(domain); LOG_UNLOCK(); +#else + (void) domain; +#endif } EAPI void eina_log_domain_level_set(const char *domain_name, int level) { +#ifdef EINA_ENABLE_LOG Eina_Log_Domain_Level_Pending *pending; size_t namelen; unsigned int i; @@ -1672,11 +1747,16 @@ eina_log_domain_level_set(const char *domain_name, int level) memcpy(pending->name, domain_name, namelen + 1); _pending_list = eina_inlist_append(_pending_list, EINA_INLIST_GET(pending)); +#else + (void) domain_name; + (void) level; +#endif } EAPI int eina_log_domain_level_get(const char *domain_name) { +#ifdef EINA_ENABLE_LOG Eina_Log_Domain_Level_Pending *pending; size_t namelen; unsigned int i; @@ -1711,17 +1791,26 @@ eina_log_domain_level_get(const char *domain_name) } return _log_level; +#else + (void) domain_name; + return 0; +#endif } EAPI int eina_log_domain_registered_level_get(int domain) { +#ifdef EINA_ENABLE_LOG EINA_SAFETY_ON_FALSE_RETURN_VAL(domain >= 0, EINA_LOG_LEVEL_UNKNOWN); EINA_SAFETY_ON_FALSE_RETURN_VAL((unsigned int)domain < _log_domains_count, EINA_LOG_LEVEL_UNKNOWN); EINA_SAFETY_ON_TRUE_RETURN_VAL(_log_domains[domain].deleted, EINA_LOG_LEVEL_UNKNOWN); return _log_domains[domain].level; +#else + (void) domain; + return 0; +#endif } EAPI void @@ -1734,9 +1823,20 @@ eina_log_print_cb_stderr(const Eina_Log_Domain *d, __UNUSED__ void *data, va_list args) { +#ifdef EINA_ENABLE_LOG _eina_log_print_prefix(stderr, d, level, file, fnc, line); vfprintf(stderr, fmt, args); putc('\n', stderr); +#else + (void) d; + (void) level; + (void) file; + (void) fnc; + (void) line; + (void) fmt; + (void) data; + (void) args; +#endif } EAPI void @@ -1749,9 +1849,20 @@ eina_log_print_cb_stdout(const Eina_Log_Domain *d, __UNUSED__ void *data, va_list args) { +#ifdef EINA_ENABLE_LOG _eina_log_print_prefix(stdout, d, level, file, fnc, line); vprintf(fmt, args); putchar('\n'); +#else + (void) d; + (void) level; + (void) file; + (void) fnc; + (void) line; + (void) fmt; + (void) data; + (void) args; +#endif } EAPI void @@ -1764,6 +1875,7 @@ eina_log_print_cb_file(const Eina_Log_Domain *d, void *data, va_list args) { +#ifdef EINA_ENABLE_LOG FILE *f = data; #ifdef EFL_HAVE_THREADS if (_threads_enabled) @@ -1787,12 +1899,22 @@ end: #endif vfprintf(f, fmt, args); putc('\n', f); +#else + (void) d; + (void) file; + (void) fnc; + (void) line; + (void) fmt; + (void) data; + (void) args; +#endif } EAPI void eina_log_print(int domain, Eina_Log_Level level, const char *file, const char *fnc, int line, const char *fmt, ...) { +#ifdef EINA_ENABLE_LOG va_list args; #ifdef EINA_SAFETY_CHECKS @@ -1820,12 +1942,22 @@ eina_log_print(int domain, Eina_Log_Level level, const char *file, eina_log_print_unlocked(domain, level, file, fnc, line, fmt, args); LOG_UNLOCK(); va_end(args); +#else + (void) domain; + (void) level; + (void) file; + (void) fnc; + (void) line; + (void) fmt; +#endif } EAPI void eina_log_vprint(int domain, Eina_Log_Level level, const char *file, const char *fnc, int line, const char *fmt, va_list args) { +#ifdef EINA_ENABLE_LOG + #ifdef EINA_SAFETY_CHECKS if (EINA_UNLIKELY(!file)) { @@ -1849,4 +1981,13 @@ eina_log_vprint(int domain, Eina_Log_Level level, const char *file, LOG_LOCK(); eina_log_print_unlocked(domain, level, file, fnc, line, fmt, args); LOG_UNLOCK(); +#else + (void) domain; + (void) level; + (void) file; + (void) fnc; + (void) line; + (void) fmt; + (void) args; +#endif } diff --git a/libraries/eina/src/lib/eina_magic.c b/libraries/eina/src/lib/eina_magic.c index 1adde92..d1f71cc 100644 --- a/libraries/eina/src/lib/eina_magic.c +++ b/libraries/eina/src/lib/eina_magic.c @@ -79,7 +79,7 @@ _eina_magic_strings_sort_cmp(const void *p1, const void *p2) static int _eina_magic_strings_find_cmp(const void *p1, const void *p2) { - Eina_Magic a = (Eina_Magic)p1; + Eina_Magic a = (Eina_Magic)(size_t)p1; const Eina_Magic_String *b = p2; return a - b->magic; } @@ -129,6 +129,10 @@ _eina_magic_strings_alloc(void) * Global * *============================================================================*/ +EAPI Eina_Error EINA_ERROR_MAGIC_FAILED = 0; + +static const char EINA_ERROR_MAGIC_FAILED_STR[] = "Magic check failed."; + /** * @internal * @brief Initialize the magic string module. @@ -150,6 +154,8 @@ eina_magic_string_init(void) EINA_LOG_ERR("Could not register log domain: eina_magic_string"); return EINA_FALSE; } + EINA_ERROR_MAGIC_FAILED = eina_error_msg_static_register( + EINA_ERROR_MAGIC_FAILED_STR); return EINA_TRUE; } @@ -206,7 +212,7 @@ eina_magic_string_get(Eina_Magic magic) _eina_magic_strings_dirty = 0; } - ems = bsearch((void *)magic, _eina_magic_strings, + ems = bsearch((void *)(size_t)magic, _eina_magic_strings, _eina_magic_strings_count, sizeof(Eina_Magic_String), _eina_magic_strings_find_cmp); if (ems) @@ -271,6 +277,7 @@ eina_magic_fail(void *d, const char *fnc, int line) { + eina_error_set(EINA_ERROR_MAGIC_FAILED); if (!d) eina_log_print(EINA_LOG_DOMAIN_GLOBAL, EINA_LOG_LEVEL_CRITICAL, file, fnc, line, diff --git a/libraries/eina/src/lib/eina_main.c b/libraries/eina/src/lib/eina_main.c index 8727f83..79f8a36 100644 --- a/libraries/eina/src/lib/eina_main.c +++ b/libraries/eina/src/lib/eina_main.c @@ -67,6 +67,8 @@ #include "eina_rectangle.h" #include "eina_safety_checks.h" #include "eina_inlist.h" +#include "eina_inarray.h" +#include "eina_value.h" /*============================================================================* * Local * @@ -131,6 +133,7 @@ EAPI Eina_Inlist *_eina_tracking = NULL; S(magic_string); S(iterator); S(accessor); + S(inarray); S(array); S(module); S(mempool); @@ -149,6 +152,7 @@ EAPI Eina_Inlist *_eina_tracking = NULL; S(simple_xml); S(file); S(prefix); + S(value); #undef S struct eina_desc_setup @@ -161,17 +165,18 @@ struct eina_desc_setup static const struct eina_desc_setup _eina_desc_setup[] = { #define S(x) {# x, eina_ ## x ## _init, eina_ ## x ## _shutdown} /* log is a special case as it needs printf */ + S(stringshare), S(error), S(safety_checks), S(magic_string), S(iterator), S(accessor), + S(inarray), S(array), S(module), S(mempool), S(list), S(binshare), - S(stringshare), S(ustringshare), S(matrixsparse), S(convert), @@ -183,7 +188,8 @@ static const struct eina_desc_setup _eina_desc_setup[] = { S(quadtree), S(simple_xml), S(file), - S(prefix) + S(prefix), + S(value) #undef S }; static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) / @@ -236,8 +242,8 @@ eina_init(void) _mt_enabled = 1; mtrace(); } -#endif - +#endif + if (!eina_log_init()) { fprintf(stderr, "Could not initialize eina logging system.\n"); @@ -304,7 +310,7 @@ eina_shutdown(void) muntrace(); _mt_enabled = 0; } -#endif +#endif } return _eina_main_count; diff --git a/libraries/eina/src/lib/eina_mmap.c b/libraries/eina/src/lib/eina_mmap.c index fb27bd7..7929f0e 100644 --- a/libraries/eina/src/lib/eina_mmap.c +++ b/libraries/eina/src/lib/eina_mmap.c @@ -110,6 +110,8 @@ _eina_mmap_safe_sigbus(int sig __UNUSED__, errno = perrno; abort(); } + /* Look into mmaped Eina_File if it was one of them, just to remember for later request */ + eina_file_mmap_faulty(addr, _eina_mmap_pagesize); /* restore previous errno */ errno = perrno; } @@ -162,6 +164,9 @@ eina_mmap_safety_enabled_set(Eina_Bool enabled) sa.sa_sigaction = _eina_mmap_safe_sigbus; sa.sa_flags = SA_RESTART | SA_SIGINFO; sigemptyset(&sa.sa_mask); + /* FIXME: This is rubbish. We return EINA_FALSE whether sigaction + * fails or not. And we never set mmap_safe, so we always hit this + * code path. */ if (sigaction(SIGBUS, &sa, NULL) == 0) return EINA_FALSE; /* setup of SIGBUS handler failed, lets close zero page dev and fail */ close(_eina_mmap_zero_fd); diff --git a/libraries/eina/src/lib/eina_module.c b/libraries/eina/src/lib/eina_module.c index 0dd19a6..26df980 100644 --- a/libraries/eina/src/lib/eina_module.c +++ b/libraries/eina/src/lib/eina_module.c @@ -37,6 +37,7 @@ extern "C" void *alloca (size_t); #endif +#include #include #include #include diff --git a/libraries/eina/src/lib/eina_prefix.c b/libraries/eina/src/lib/eina_prefix.c index 9445222..5b4b0c0 100644 --- a/libraries/eina/src/lib/eina_prefix.c +++ b/libraries/eina/src/lib/eina_prefix.c @@ -150,25 +150,24 @@ _fallback(Eina_Prefix *pfx, const char *pkg_bin, const char *pkg_lib, STRDUP_REP(pfx->prefix_path_lib, pkg_lib); STRDUP_REP(pfx->prefix_path_data, pkg_data); STRDUP_REP(pfx->prefix_path_locale, pkg_locale); - fprintf(stderr, - "WARNING: Could not determine its installed prefix for '%s'\n" - " so am falling back on the compiled in default:\n" - " %s\n" - " implied by the following:\n" - " bindir = %s\n" - " libdir = %s\n" - " datadir = %s\n" - " localedir = %s\n" - " Try setting the following environment variables:\n" - " %s_PREFIX - points to the base prefix of install\n" - " or the next 4 variables\n" - " %s_BIN_DIR - provide a specific binary directory\n" - " %s_LIB_DIR - provide a specific library directory\n" - " %s_DATA_DIR - provide a specific data directory\n" - " %s_LOCALE_DIR - provide a specific locale directory\n" - , envprefix, - pfx->prefix_path, pkg_bin, pkg_lib, pkg_data, pkg_locale, - envprefix, envprefix, envprefix, envprefix, envprefix); + WRN("Could not determine its installed prefix for '%s'\n" + " so am falling back on the compiled in default:\n" + " %s\n" + " implied by the following:\n" + " bindir = %s\n" + " libdir = %s\n" + " datadir = %s\n" + " localedir = %s\n" + " Try setting the following environment variables:\n" + " %s_PREFIX - points to the base prefix of install\n" + " or the next 4 variables\n" + " %s_BIN_DIR - provide a specific binary directory\n" + " %s_LIB_DIR - provide a specific library directory\n" + " %s_DATA_DIR - provide a specific data directory\n" + " %s_LOCALE_DIR - provide a specific locale directory", + envprefix, + pfx->prefix_path, pkg_bin, pkg_lib, pkg_data, pkg_locale, + envprefix, envprefix, envprefix, envprefix, envprefix); pfx->fallback = 1; return 1; } diff --git a/libraries/eina/src/lib/eina_private.h b/libraries/eina/src/lib/eina_private.h index d390397..e31ab47 100644 --- a/libraries/eina/src/lib/eina_private.h +++ b/libraries/eina/src/lib/eina_private.h @@ -91,6 +91,10 @@ #define EINA_MAGIC_SIMPLE_XML_DATA 0x98761261 #define EINA_MAGIC_SIMPLE_XML_ATTRIBUTE 0x98761262 +#define EINA_MAGIC_INARRAY 0x98761270 +#define EINA_MAGIC_INARRAY_ITERATOR 0x98761271 +#define EINA_MAGIC_INARRAY_ACCESSOR 0x98761272 + #define EINA_MAGIC_CLASS 0x9877CB30 /* undef the following, we want out version */ @@ -136,5 +140,7 @@ void eina_log_threads_init(void); void eina_log_threads_shutdown(void); #endif +void eina_file_mmap_faulty(void *addr, long page_size); + #endif /* EINA_PRIVATE_H_ */ diff --git a/libraries/eina/src/lib/eina_rbtree.c b/libraries/eina/src/lib/eina_rbtree.c index c0c9f9e..5f1232c 100644 --- a/libraries/eina/src/lib/eina_rbtree.c +++ b/libraries/eina/src/lib/eina_rbtree.c @@ -83,7 +83,7 @@ _eina_rbtree_iterator_list_new(const Eina_Rbtree *tree) static Eina_Rbtree * _eina_rbtree_iterator_get_content(Eina_Iterator_Rbtree *it) { - if (eina_array_count_get(it->stack) <= 0) + if (eina_array_count(it->stack) <= 0) return NULL; return eina_array_data_get(it->stack, 0); @@ -110,10 +110,10 @@ _eina_rbtree_iterator_next(Eina_Iterator_Rbtree *it, void **data) Eina_Iterator_Rbtree_List *new; Eina_Rbtree *tree; - if (eina_array_count_get(it->stack) <= 0) + if (eina_array_count(it->stack) <= 0) return EINA_FALSE; - last = eina_array_data_get(it->stack, eina_array_count_get(it->stack) - 1); + last = eina_array_data_get(it->stack, eina_array_count(it->stack) - 1); tree = last->tree; if (!last->tree || last->up == EINA_TRUE) @@ -128,10 +128,10 @@ _eina_rbtree_iterator_next(Eina_Iterator_Rbtree *it, void **data) { free(last); - if (eina_array_count_get(it->stack) > 0) + if (eina_array_count(it->stack) > 0) { last = eina_array_data_get(it->stack, - eina_array_count_get( + eina_array_count( it-> stack) - 1); diff --git a/libraries/eina/src/lib/eina_simple_xml_parser.c b/libraries/eina/src/lib/eina_simple_xml_parser.c index 08a8259..4e357ba 100644 --- a/libraries/eina/src/lib/eina_simple_xml_parser.c +++ b/libraries/eina/src/lib/eina_simple_xml_parser.c @@ -38,7 +38,10 @@ extern "C" void *alloca (size_t); #endif -#include +#ifdef HAVE_STRINGS_H +# include +#endif +#include #include #include @@ -121,7 +124,7 @@ static inline const char * _eina_simple_xml_whitespace_find(const char *itr, const char *itr_end) { for (; itr < itr_end; itr++) - if (isspace(*itr)) break; + if (isspace((unsigned char)*itr)) break; return itr; } @@ -129,7 +132,7 @@ static inline const char * _eina_simple_xml_whitespace_skip(const char *itr, const char *itr_end) { for (; itr < itr_end; itr++) - if (!isspace(*itr)) break; + if (!isspace((unsigned char)*itr)) break; return itr; } @@ -137,7 +140,7 @@ static inline const char * _eina_simple_xml_whitespace_unskip(const char *itr, const char *itr_start) { for (itr--; itr > itr_start; itr--) - if (!isspace(*itr)) break; + if (!isspace((unsigned char)*itr)) break; return itr + 1; } @@ -309,7 +312,7 @@ eina_simple_xml_parse(const char *buf, unsigned buflen, Eina_Bool strip, Eina_Si (!memcmp(itr + 2, "DOCTYPE", sizeof("DOCTYPE") - 1)) && ((itr[2 + sizeof("DOCTYPE") - 1] == '>') || - (isspace(itr[2 + sizeof("DOCTYPE") - 1])))) + (isspace((unsigned char)itr[2 + sizeof("DOCTYPE") - 1])))) { type = EINA_SIMPLE_XML_DOCTYPE; toff = sizeof("!DOCTYPE") - 1; @@ -455,7 +458,7 @@ eina_simple_xml_tag_attributes_find(const char *buf, unsigned buflen) for (; itr < itr_end; itr++) { - if (!isspace(*itr)) + if (!isspace((unsigned char)*itr)) { /* user skip tagname and already gave it the attributes */ if (*itr == '=') @@ -492,7 +495,7 @@ eina_simple_xml_attributes_parse(const char *buf, unsigned buflen, Eina_Simple_X key = p; for (key_end = key; key_end < itr_end; key_end++) - if ((*key_end == '=') || (isspace(*key_end))) break; + if ((*key_end == '=') || (isspace((unsigned char)*key_end))) break; if (key_end == itr_end) return EINA_FALSE; if (key_end == key) continue; @@ -504,7 +507,7 @@ eina_simple_xml_attributes_parse(const char *buf, unsigned buflen, Eina_Simple_X value++; } for (; value < itr_end; value++) - if (!isspace(*value)) break; + if (!isspace((unsigned char)*value)) break; if (value == itr_end) return EINA_FALSE; if ((*value == '"') || (*value == '\'')) diff --git a/libraries/eina/src/lib/eina_strbuf.c b/libraries/eina/src/lib/eina_strbuf.c index 74b1eb9..828d842 100644 --- a/libraries/eina/src/lib/eina_strbuf.c +++ b/libraries/eina/src/lib/eina_strbuf.c @@ -162,9 +162,9 @@ eina_strbuf_insert_vprintf(Eina_Strbuf *buf, EAPI void eina_strbuf_trim(Eina_Strbuf *buf) { - char *c = buf->buf; + unsigned char *c = buf->buf; - while (buf->len > 0 && isspace(((unsigned char*)(buf->buf))[buf->len - 1])) + while (buf->len > 0 && isspace(c[buf->len - 1])) buf->len--; while (buf->len > 0 && isspace(*c)) { @@ -178,7 +178,7 @@ eina_strbuf_trim(Eina_Strbuf *buf) EAPI void eina_strbuf_ltrim(Eina_Strbuf *buf) { - char *c = buf->buf; + unsigned char *c = buf->buf; while (buf->len > 0 && isspace(*c)) { diff --git a/libraries/eina/src/lib/eina_value.c b/libraries/eina/src/lib/eina_value.c index 554f907..ba8af52 100644 --- a/libraries/eina/src/lib/eina_value.c +++ b/libraries/eina/src/lib/eina_value.c @@ -28,8 +28,4762 @@ # include "config.h" #endif +#ifdef HAVE_ALLOCA_H +# include +#elif defined __GNUC__ +# define alloca __builtin_alloca +#elif defined _AIX +# define alloca __alloca +#elif defined _MSC_VER +# include +# define alloca _alloca +#else +# include +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +#endif + +#include /* asprintf() */ +#include /* PRId64 and PRIu64 */ +#include /* struct timeval */ + #include "eina_config.h" #include "eina_private.h" +#include "eina_error.h" +#include "eina_log.h" +#include "eina_strbuf.h" +#include "eina_mempool.h" +#include "eina_lock.h" + +/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */ +#include "eina_safety_checks.h" +#include "eina_value.h" + +/*============================================================================* +* Local * +*============================================================================*/ + +/** + * @cond LOCAL + */ + +static Eina_Mempool *_eina_value_mp = NULL; +static Eina_Hash *_eina_value_inner_mps = NULL; +static Eina_Lock _eina_value_inner_mps_lock; +static char *_eina_value_mp_choice = NULL; +static int _eina_value_log_dom = -1; + +#ifdef ERR +#undef ERR +#endif +#define ERR(...) EINA_LOG_DOM_ERR(_eina_value_log_dom, __VA_ARGS__) + +#ifdef DBG +#undef DBG +#endif +#define DBG(...) EINA_LOG_DOM_DBG(_eina_value_log_dom, __VA_ARGS__) + +static const unsigned char eina_value_uchar_max = 255U; +static const char eina_value_char_max = 127; +static const char eina_value_char_min = -127 - 1; + +static const unsigned short eina_value_ushort_max = 65535U; +static const short eina_value_short_max = 32767; +static const short eina_value_short_min = -32767 - 1; + +static const unsigned int eina_value_uint_max = 4294967295U; +static const int eina_value_int_max = 2147483647; +static const int eina_value_int_min = -2147483647 - 1; + +static const uint64_t eina_value_uint64_max = 18446744073709551615ULL; +static const int64_t eina_value_int64_max = 9223372036854775807LL; +static const int64_t eina_value_int64_min = -9223372036854775807LL - 1LL; + +#if __WORDSIZE == 64 +static const unsigned long eina_value_ulong_max = 18446744073709551615ULL; +static const long eina_value_long_max = 9223372036854775807LL; +static const long eina_value_long_min = -9223372036854775807LL - 1LL; +#else +static const unsigned long eina_value_ulong_max = 4294967295U; +static const long eina_value_long_max = 2147483647; +static const long eina_value_long_min = -2147483647 - 1; +#endif + + +static Eina_Bool +_eina_value_type_uchar_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + unsigned char *tmem = mem; + *tmem = 0; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uchar_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uchar_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const unsigned char *s = src; + unsigned char *d = dst; + *d = *s; + return EINA_TRUE; +} + +static int +_eina_value_type_uchar_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const unsigned char *ta = a, *tb = b; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; +} + +static Eina_Bool +_eina_value_type_uchar_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const unsigned char v = *(const unsigned char *)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v; + if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%hhu", v); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uchar_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + unsigned char *tmem = mem; + *tmem = va_arg(args, unsigned int); /* char is promoted to int for va_arg */ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uchar_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + unsigned char *tmem = mem; + const unsigned char *p = ptr; + *tmem = *p; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uchar_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + const unsigned char *tmem = mem; + unsigned char *p = ptr; + *p = *tmem; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_ushort_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + unsigned short *tmem = mem; + *tmem = 0; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_ushort_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_ushort_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const unsigned short *s = src; + unsigned short *d = dst; + *d = *s; + return EINA_TRUE; +} + +static int +_eina_value_type_ushort_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const unsigned short *ta = a, *tb = b; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; +} + +static Eina_Bool +_eina_value_type_ushort_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const unsigned short v = *(const unsigned short *)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v; + if (EINA_UNLIKELY(v > eina_value_uchar_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v; + if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v; + if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%hu", v); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_ushort_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + unsigned short *tmem = mem; + *tmem = va_arg(args, unsigned int); /* short is promoted to int for va_arg */ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_ushort_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + unsigned short *tmem = mem; + const unsigned short *p = ptr; + *tmem = *p; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_ushort_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + const unsigned short *tmem = mem; + unsigned short *p = ptr; + *p = *tmem; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uint_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + unsigned int *tmem = mem; + *tmem = 0; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uint_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uint_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const unsigned int *s = src; + unsigned int *d = dst; + *d = *s; + return EINA_TRUE; +} + +static int +_eina_value_type_uint_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const unsigned int *ta = a, *tb = b; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; +} + +static Eina_Bool +_eina_value_type_uint_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const unsigned int v = *(const unsigned int *)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v; + if (EINA_UNLIKELY(v > eina_value_uchar_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v; + if (EINA_UNLIKELY(v > eina_value_ushort_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v; + if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v; + if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v; + if (EINA_UNLIKELY(v > (unsigned int)eina_value_int_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%u", v); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uint_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + unsigned int *tmem = mem; + *tmem = va_arg(args, unsigned int); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uint_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + unsigned int *tmem = mem; + const unsigned int *p = ptr; + *tmem = *p; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uint_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + const unsigned int *tmem = mem; + unsigned int *p = ptr; + *p = *tmem; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_ulong_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + unsigned long *tmem = mem; + *tmem = 0; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_ulong_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_ulong_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const unsigned long *s = src; + unsigned long *d = dst; + *d = *s; + return EINA_TRUE; +} + +static int +_eina_value_type_ulong_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const unsigned long *ta = a, *tb = b; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; +} + +static Eina_Bool +_eina_value_type_ulong_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const unsigned long v = *(const unsigned long *)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v; + if (EINA_UNLIKELY(v > eina_value_uchar_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v; + if (EINA_UNLIKELY(v > eina_value_ushort_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v; + if (EINA_UNLIKELY(v > eina_value_uint_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v; + if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v; + if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v; + if (EINA_UNLIKELY(v > (unsigned int)eina_value_int_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v; + if (EINA_UNLIKELY(v > (unsigned long)eina_value_long_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%lu", v); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_ulong_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + unsigned long *tmem = mem; + *tmem = va_arg(args, unsigned long); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_ulong_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + unsigned long *tmem = mem; + const unsigned long *p = ptr; + *tmem = *p; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_ulong_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + const unsigned long *tmem = mem; + unsigned long *p = ptr; + *p = *tmem; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uint64_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + uint64_t *tmem = mem; + *tmem = 0; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uint64_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uint64_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const uint64_t *s = src; + uint64_t *d = dst; + *d = *s; + return EINA_TRUE; +} + +static int +_eina_value_type_uint64_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const uint64_t *ta = a, *tb = b; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; +} + +static Eina_Bool +_eina_value_type_uint64_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const uint64_t v = *(const uint64_t *)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v; + if (EINA_UNLIKELY(v > eina_value_uchar_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v; + if (EINA_UNLIKELY(v > eina_value_ushort_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v; + if (EINA_UNLIKELY(v > eina_value_uint_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v; + if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) && + (v > eina_value_ulong_max))) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v; + if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v; + if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v; + if (EINA_UNLIKELY(v > (unsigned int)eina_value_int_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v; + if (EINA_UNLIKELY(v > (unsigned long)eina_value_long_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v; + if (EINA_UNLIKELY(v > (uint64_t)eina_value_int64_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%"PRIu64, v); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uint64_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + uint64_t *tmem = mem; + *tmem = va_arg(args, uint64_t); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uint64_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + uint64_t *tmem = mem; + const uint64_t *p = ptr; + *tmem = *p; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_uint64_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + const uint64_t *tmem = mem; + uint64_t *p = ptr; + *p = *tmem; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_char_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + char *tmem = mem; + *tmem = 0; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_char_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_char_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const char *s = src; + char *d = dst; + *d = *s; + return EINA_TRUE; +} + +static int +_eina_value_type_char_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const char *ta = a, *tb = b; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; +} + +static Eina_Bool +_eina_value_type_char_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const signed char v = *(const signed char *)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%hhd", v); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_char_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + char *tmem = mem; + *tmem = va_arg(args, int); /* char is promoted to int for va_arg */ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_char_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + char *tmem = mem; + const char *p = ptr; + *tmem = *p; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_char_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + const char *tmem = mem; + char *p = ptr; + *p = *tmem; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_short_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + short *tmem = mem; + *tmem = 0; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_short_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_short_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const short *s = src; + short *d = dst; + *d = *s; + return EINA_TRUE; +} + +static int +_eina_value_type_short_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const short *ta = a, *tb = b; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; +} + +static Eina_Bool +_eina_value_type_short_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const short v = *(const short *)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_uchar_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v; + if (EINA_UNLIKELY(v < eina_value_char_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_char_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%hd", v); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_short_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + short *tmem = mem; + *tmem = va_arg(args, int); /* short int is promoted to int for va_arg */ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_short_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + short *tmem = mem; + const short *p = ptr; + *tmem = *p; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_short_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + const short *tmem = mem; + short *p = ptr; + *p = *tmem; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_int_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + int *tmem = mem; + *tmem = 0; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_int_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_int_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const int *s = src; + int *d = dst; + *d = *s; + return EINA_TRUE; +} + +static int +_eina_value_type_int_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const int *ta = a, *tb = b; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; +} + +static Eina_Bool +_eina_value_type_int_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const int v = *(const int *)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_uchar_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_ushort_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v; + if (EINA_UNLIKELY(v < eina_value_char_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_char_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v; + if (EINA_UNLIKELY(v < eina_value_short_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_short_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%d", v); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_int_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + int *tmem = mem; + *tmem = va_arg(args, int); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_int_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + int *tmem = mem; + const int *p = ptr; + *tmem = *p; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_int_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + const int *tmem = mem; + int *p = ptr; + *p = *tmem; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_long_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + long *tmem = mem; + *tmem = 0; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_long_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_long_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const long *s = src; + long *d = dst; + *d = *s; + return EINA_TRUE; +} + +static int +_eina_value_type_long_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const long *ta = a, *tb = b; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; +} + +static Eina_Bool +_eina_value_type_long_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const long v = *(const long *)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY((unsigned long) v > eina_value_uchar_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY((unsigned long) v > eina_value_ushort_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY((unsigned long) v > eina_value_uint_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v; + if (EINA_UNLIKELY(v < eina_value_char_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_char_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v; + if (EINA_UNLIKELY(v < eina_value_short_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_short_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v; + if (EINA_UNLIKELY(v < eina_value_int_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_int_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%ld", v); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_long_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + long *tmem = mem; + *tmem = va_arg(args, long); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_long_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + long *tmem = mem; + const long *p = ptr; + *tmem = *p; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_long_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + const long *tmem = mem; + long *p = ptr; + *p = *tmem; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_int64_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + int64_t *tmem = mem; + *tmem = 0; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_int64_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_int64_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const int64_t *s = src; + int64_t *d = dst; + *d = *s; + return EINA_TRUE; +} + +static int +_eina_value_type_int64_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const int64_t *ta = a, *tb = b; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; +} + +static Eina_Bool +_eina_value_type_int64_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const int64_t v = *(const int64_t *)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_uchar_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_ushort_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_uint_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) && + (v > eina_value_ulong_max))) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v; + if (EINA_UNLIKELY(v < eina_value_char_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_char_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v; + if (EINA_UNLIKELY(v < eina_value_short_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_short_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v; + if (EINA_UNLIKELY(v < eina_value_int_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_int_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v; + if (EINA_UNLIKELY(v < eina_value_long_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_long_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%"PRId64, v); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_int64_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + int64_t *tmem = mem; + *tmem = va_arg(args, int64_t); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_int64_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + int64_t *tmem = mem; + const int64_t *p = ptr; + *tmem = *p; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_int64_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + const int64_t *tmem = mem; + int64_t *p = ptr; + *p = *tmem; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_float_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + float *tmem = mem; + *tmem = 0; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_float_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_float_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const float *s = src; + float *d = dst; + *d = *s; + return EINA_TRUE; +} + +static int +_eina_value_type_float_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const float *ta = a, *tb = b; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; +} + +static Eina_Bool +_eina_value_type_float_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const float v = *(const float *)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_uchar_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_ushort_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_uint_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) && + (v > eina_value_ulong_max))) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_uint64_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v; + if (EINA_UNLIKELY(v < eina_value_char_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_char_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v; + if (EINA_UNLIKELY(v < eina_value_short_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_short_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v; + if (EINA_UNLIKELY(v < eina_value_int_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_int_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v; + if (EINA_UNLIKELY(v < eina_value_long_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_long_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v; + if (EINA_UNLIKELY(v < eina_value_int64_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_int64_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%f", v); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_float_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + float *tmem = mem; + *tmem = va_arg(args, double); /* float is promoted to double for va_args */ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_float_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + float *tmem = mem; + const float *p = ptr; + *tmem = *p; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_float_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + const float *tmem = mem; + float *p = ptr; + *p = *tmem; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_double_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + double *tmem = mem; + *tmem = 0; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_double_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_double_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const double *s = src; + double *d = dst; + *d = *s; + return EINA_TRUE; +} + +static int +_eina_value_type_double_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const double *ta = a, *tb = b; + if (*ta < *tb) + return -1; + else if (*ta > *tb) + return 1; + return 0; +} + +static Eina_Bool +_eina_value_type_double_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const double v = *(const double *)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_uchar_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_ushort_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_uint_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) && + (v > eina_value_ulong_max))) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v; + if (EINA_UNLIKELY(v < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v; + if (EINA_UNLIKELY(v < eina_value_char_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_char_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v; + if (EINA_UNLIKELY(v < eina_value_short_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_short_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v; + if (EINA_UNLIKELY(v < eina_value_int_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_int_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v; + if (EINA_UNLIKELY(v < eina_value_long_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v > eina_value_long_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = v; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%g", (double)v); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_double_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + double *tmem = mem; + *tmem = va_arg(args, double); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_double_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + double *tmem = mem; + const double *p = ptr; + *tmem = *p; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_double_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + const double *tmem = mem; + double *p = ptr; + *p = *tmem; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_string_common_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + const char **tmem = mem; + *tmem = NULL; + return EINA_TRUE; +} + +static int +_eina_value_type_string_common_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const char *sa = *(const char **)a; + const char *sb = *(const char **)b; + if (sa == sb) + return 0; + if (sa == NULL) + return -1; + if (sb == NULL) + return 1; + return strcmp(sa, sb); +} + +static Eina_Bool +_eina_value_type_string_common_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const char *v = *(const char **)type_mem; + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem; + if ((sscanf(v, "%hhu", &other_mem) != 1) && + (sscanf(v, "%hhx", &other_mem) != 1) && + (sscanf(v, "%hho", &other_mem) != 1)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem; + if ((sscanf(v, "%hu", &other_mem) != 1) && + (sscanf(v, "%hx", &other_mem) != 1) && + (sscanf(v, "%ho", &other_mem) != 1)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem; + if ((sscanf(v, "%u", &other_mem) != 1) && + (sscanf(v, "%x", &other_mem) != 1) && + (sscanf(v, "%o", &other_mem) != 1)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem; + if ((sscanf(v, "%lu", &other_mem) != 1) && + (sscanf(v, "%lx", &other_mem) != 1) && + (sscanf(v, "%lo", &other_mem) != 1)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem; + if ((sscanf(v, "%"SCNu64, &other_mem) != 1) && + (sscanf(v, "%"SCNx64, &other_mem) != 1) && + (sscanf(v, "%"SCNo64, &other_mem) != 1)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem; + if ((sscanf(v, "%hhd", &other_mem) != 1) && + (sscanf(v, "%hhx", &other_mem) != 1) && + (sscanf(v, "%hho", &other_mem) != 1)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem; + if ((sscanf(v, "%hd", &other_mem) != 1) && + (sscanf(v, "%hx", &other_mem) != 1) && + (sscanf(v, "%ho", &other_mem) != 1)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem; + if ((sscanf(v, "%d", &other_mem) != 1) && + (sscanf(v, "%x", &other_mem) != 1) && + (sscanf(v, "%o", &other_mem) != 1)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem; + if ((sscanf(v, "%ld", &other_mem) != 1) && + (sscanf(v, "%lx", &other_mem) != 1) && + (sscanf(v, "%lo", &other_mem) != 1)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem; + if ((sscanf(v, "%"SCNd64, &other_mem) != 1) && + (sscanf(v, "%"SCNx64, &other_mem) != 1) && + (sscanf(v, "%"SCNo64, &other_mem) != 1)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem; + if (sscanf(v, "%f", &other_mem) != 1) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem; + if (sscanf(v, "%lf", &other_mem) != 1) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + return eina_value_type_pset(convert, convert_mem, &v); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_string_common_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + memcpy(ptr, mem, sizeof(const char *)); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_stringshare_flush(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + const char **tmem = mem; + if (*tmem) eina_stringshare_del(*tmem); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_stringshare_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const char * const*s = src; + const char **d = dst; + *d = *s; + eina_stringshare_ref(*d); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_stringshare_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + const char *str = va_arg(args, const char *); + return eina_stringshare_replace((const char **)mem, str); +} + +static Eina_Bool +_eina_value_type_stringshare_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + const char * const *str = ptr; + return eina_stringshare_replace((const char **)mem, *str); +} + +static Eina_Bool +_eina_value_type_string_flush(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + char **tmem = mem; + if (*tmem) free(*tmem); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_string_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const char * const *s = src; + char **d = dst; + if (*s == NULL) + *d = NULL; + else + { + *d = strdup(*s); + if (*d == NULL) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + } + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_string_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args) +{ + char **tmem = mem; + const char *str = va_arg(args, const char *); + free(*tmem); + if (str == NULL) + *tmem = NULL; + else + { + *tmem = strdup(str); + if (*tmem == NULL) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + } + eina_error_set(0); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_string_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + char **tmem = mem; + const char * const *str = ptr; + free(*tmem); + if (*str == NULL) + *tmem = NULL; + else + { + *tmem = strdup(*str); + if (*tmem == NULL) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + } + eina_error_set(0); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_array_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + memset(mem, 0, sizeof(Eina_Value_Array)); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_array_flush_elements(Eina_Value_Array *tmem) +{ + const Eina_Value_Type *subtype = tmem->subtype; + Eina_Bool ret = EINA_TRUE; + unsigned char sz; + char *ptr, *ptr_end; + + if (!tmem->array) return EINA_TRUE; + + sz = tmem->array->member_size; + ptr = tmem->array->members; + ptr_end = ptr + tmem->array->len * sz; + + for (; ptr < ptr_end; ptr += sz) + ret &= eina_value_type_flush(subtype, ptr); + + eina_inarray_flush(tmem->array); + return ret; +} + +static Eina_Bool +_eina_value_type_array_flush(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + Eina_Value_Array *tmem = mem; + Eina_Bool ret =_eina_value_type_array_flush_elements(tmem); + + if (tmem->array) eina_inarray_free(tmem->array); + tmem->array = NULL; + tmem->subtype = NULL; + return ret; +} + +static Eina_Bool +_eina_value_type_array_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const Eina_Value_Type *subtype; + const Eina_Value_Array *s = src; + Eina_Value_Array *d = dst; + unsigned int i, count, sz; + char *ptr, *ptr_end; + + d->subtype = subtype = s->subtype; + d->step = s->step; + + if ((!s->array) || (!s->subtype)) + { + d->array = NULL; + return EINA_TRUE; + } + + if (!subtype->copy) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + d->array = eina_inarray_new(subtype->value_size, s->step); + if (!d->array) + return EINA_FALSE; + + sz = s->array->member_size; + + count = eina_inarray_count(s->array); + ptr = s->array->members; + ptr_end = ptr + (count * sz); + + for (i = 0; ptr < ptr_end; ptr += sz, i++) + { + void *imem = eina_inarray_alloc_at(d->array, i, 1); + if (!imem) goto error; + if (!subtype->copy(subtype, ptr, imem)) + { + eina_inarray_pop(d->array); + goto error; + } + } + + return EINA_TRUE; + + error: + _eina_value_type_array_flush_elements(d); + return EINA_FALSE; +} + +static int +_eina_value_type_array_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const Eina_Value_Type *subtype; + const Eina_Value_Array *eva_a = a, *eva_b = b; + const char *a_ptr, *a_ptr_end, *b_ptr; + unsigned int count_a, count_b, count, sz; + int cmp = 0; + + if (eva_a->subtype != eva_b->subtype) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return -1; + } + + subtype = eva_a->subtype; + if (!subtype->compare) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return 0; + } + + if ((!eva_a->array) && (!eva_b->array)) + return 0; + else if (!eva_a->array) + return -1; + else if (!eva_b->array) + return 1; + + count_a = eina_inarray_count(eva_a->array); + count_b = eina_inarray_count(eva_b->array); + + if (count_a <= count_b) + count = count_a; + else + count = count_b; + + sz = eva_a->array->member_size; + + a_ptr = eva_a->array->members; + a_ptr_end = a_ptr + (count * sz); + b_ptr = eva_b->array->members; + + for (; (cmp == 0) && (a_ptr < a_ptr_end); a_ptr += sz, b_ptr += sz) + cmp = subtype->compare(subtype, a_ptr, b_ptr); + + if (cmp == 0) + { + if (count_a < count_b) + return -1; + else if (count_a > count_b) + return 1; + return 0; + } + + return cmp; +} + +static Eina_Bool +_eina_value_type_array_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const Eina_Value_Array *tmem = type_mem; + Eina_Bool ret = EINA_FALSE; + + if ((convert == EINA_VALUE_TYPE_STRING) || + (convert == EINA_VALUE_TYPE_STRINGSHARE)) + { + Eina_Strbuf *str = eina_strbuf_new(); + if (!tmem->array) eina_strbuf_append(str, "[]"); + else + { + const Eina_Value_Type *subtype = tmem->subtype; + unsigned char sz; + const char *ptr, *ptr_end; + Eina_Value tmp; + Eina_Bool first = EINA_TRUE; + + eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING); + + eina_strbuf_append_char(str, '['); + + sz = tmem->array->member_size; + ptr = tmem->array->members; + ptr_end = ptr + tmem->array->len * sz; + for (; ptr < ptr_end; ptr += sz) + { + Eina_Bool r = EINA_FALSE; + if (subtype->convert_to) + { + r = subtype->convert_to(subtype, EINA_VALUE_TYPE_STRING, + ptr, tmp.value.buf); + if (r) + { + if (first) first = EINA_FALSE; + else eina_strbuf_append_length(str, ", ", 2); + eina_strbuf_append(str, tmp.value.ptr); + free(tmp.value.ptr); + tmp.value.ptr = NULL; + } + } + + if (!r) + { + if (first) + { + first = EINA_FALSE; + eina_strbuf_append_char(str, '?'); + } + else + eina_strbuf_append_length(str, ", ?", 3); + } + } + + eina_strbuf_append_char(str, ']'); + ptr = eina_strbuf_string_get(str); + ret = eina_value_type_pset(convert, convert_mem, &ptr); + eina_strbuf_free(str); + } + } + else if ((tmem->array) && (tmem->array->len == 1)) + { + const Eina_Value_Type *subtype = tmem->subtype; + void *imem = tmem->array->members; + + if (subtype->convert_to) + ret = subtype->convert_to(subtype, convert, imem, convert_mem); + if ((!ret) && (convert->convert_from)) + ret = convert->convert_from(convert, subtype, convert_mem, imem); + } + + if (!ret) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_array_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem) +{ + Eina_Value_Array *tmem = type_mem; + Eina_Value_Array desc = {convert, tmem->step, NULL}; + char *buf; + void *imem; + + if (!eina_value_type_pset(type, tmem, &desc)) + return EINA_FALSE; + + buf = alloca(convert->value_size); + if (!eina_value_type_pget(convert, convert_mem, &buf)) + return EINA_FALSE; + + imem = eina_inarray_alloc_at(tmem->array, 0, 1); + if (!imem) + return EINA_FALSE; + + if (!eina_value_type_setup(convert, imem)) goto error_setup; + if (!eina_value_type_pset(convert, imem, &buf)) goto error_set; + return EINA_TRUE; + + error_set: + eina_value_type_flush(convert, imem); + error_setup: + eina_inarray_remove_at(tmem->array, 0); + return EINA_FALSE; +} + +static Eina_Bool +_eina_value_type_array_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + Eina_Value_Array *tmem = mem; + const Eina_Value_Array *desc = ptr; + Eina_Inarray *desc_array; + + if ((!tmem->subtype) && (!desc->subtype)) + return EINA_TRUE; + + desc_array = desc->array; + if (desc_array) + { + EINA_SAFETY_ON_FALSE_RETURN_VAL + (desc_array->member_size == desc->subtype->value_size, EINA_FALSE); + } + + if (tmem->array) + { + _eina_value_type_array_flush_elements(tmem); + if (desc_array) + eina_inarray_free(tmem->array); + else + eina_inarray_setup(tmem->array, desc->subtype->value_size, + desc->step); + } + else if (!desc_array) + { + tmem->array = eina_inarray_new(desc->subtype->value_size, desc->step); + if (!tmem->array) + return EINA_FALSE; + } + + if (desc_array) + tmem->array = desc_array; + + tmem->subtype = desc->subtype; + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_array_vset(const Eina_Value_Type *type, void *mem, va_list args) +{ + const Eina_Value_Array desc = va_arg(args, Eina_Value_Array); + _eina_value_type_array_pset(type, mem, &desc); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_array_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + memcpy(ptr, mem, sizeof(Eina_Value_Array)); + return EINA_TRUE; +} + +static const Eina_Value_Type _EINA_VALUE_TYPE_ARRAY = { + EINA_VALUE_TYPE_VERSION, + sizeof(Eina_Value_Array), + "Eina_Value_Array", + _eina_value_type_array_setup, + _eina_value_type_array_flush, + _eina_value_type_array_copy, + _eina_value_type_array_compare, + _eina_value_type_array_convert_to, + _eina_value_type_array_convert_from, + _eina_value_type_array_vset, + _eina_value_type_array_pset, + _eina_value_type_array_pget +}; + +static Eina_Bool +_eina_value_type_list_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + memset(mem, 0, sizeof(Eina_Value_List)); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_list_flush_elements(Eina_Value_List *tmem) +{ + const Eina_Value_Type *subtype = tmem->subtype; + Eina_Bool ret = EINA_TRUE; + + if (!tmem->list) return EINA_TRUE; + + while (tmem->list) + { + void *mem = eina_value_list_node_memory_get(tmem->subtype, tmem->list); + ret &= eina_value_type_flush(subtype, mem); + eina_value_list_node_memory_flush(tmem->subtype, tmem->list); + tmem->list = eina_list_remove_list(tmem->list, tmem->list); + } + + return ret; +} + +static Eina_Bool +_eina_value_type_list_flush(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + Eina_Value_List *tmem = mem; + Eina_Bool ret =_eina_value_type_list_flush_elements(tmem); + + if (tmem->list) eina_list_free(tmem->list); + tmem->list = NULL; + tmem->subtype = NULL; + return ret; +} + +static Eina_Bool +_eina_value_type_list_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const Eina_Value_Type *subtype; + const Eina_Value_List *s = src; + Eina_Value_List *d = dst; + const Eina_List *snode; + + d->subtype = subtype = s->subtype; + if ((!s->list) || (!s->subtype)) + { + d->list = NULL; + return EINA_TRUE; + } + + if (!subtype->copy) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + d->list = NULL; + for (snode = s->list; snode != NULL; snode = snode->next) + { + const void *ptr = eina_value_list_node_memory_get(subtype, snode); + Eina_List *dnode; + void *imem; + + d->list = eina_list_append(d->list, (void*)1L); + dnode = eina_list_last(d->list); + EINA_SAFETY_ON_NULL_GOTO(dnode, error); + EINA_SAFETY_ON_FALSE_GOTO(dnode->data == (void*)1L, error); + + imem = eina_value_list_node_memory_setup(subtype, dnode); + if (!subtype->copy(subtype, ptr, imem)) + { + eina_value_list_node_memory_flush(subtype, dnode); + d->list = eina_list_remove_list(d->list, dnode); + goto error; + } + } + return EINA_TRUE; + + error: + _eina_value_type_list_flush_elements(d); + return EINA_FALSE; +} + +static int +_eina_value_type_list_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const Eina_Value_Type *subtype; + const Eina_Value_List *eva_a = a, *eva_b = b; + const Eina_List *anode, *bnode; + int cmp = 0; + + if (eva_a->subtype != eva_b->subtype) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return -1; + } + + subtype = eva_a->subtype; + if (!subtype->compare) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return 0; + } + + if ((!eva_a->list) && (!eva_b->list)) + return 0; + else if (!eva_a->list) + return -1; + else if (!eva_b->list) + return 1; + + for (anode = eva_a->list, bnode = eva_b->list; + (cmp == 0) && (anode) && (bnode); + anode = anode->next, bnode = bnode->next) + { + const void *amem = eina_value_list_node_memory_get(subtype, anode); + const void *bmem = eina_value_list_node_memory_get(subtype, bnode); + cmp = subtype->compare(subtype, amem, bmem); + } + + if (cmp == 0) + { + if ((!anode) && (bnode)) + return -1; + else if ((anode) && (!bnode)) + return 1; + return 0; + } + + return cmp; +} + +static Eina_Bool +_eina_value_type_list_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const Eina_Value_List *tmem = type_mem; + Eina_Bool ret = EINA_FALSE; + + if ((convert == EINA_VALUE_TYPE_STRING) || + (convert == EINA_VALUE_TYPE_STRINGSHARE)) + { + Eina_Strbuf *str = eina_strbuf_new(); + if (!tmem->list) eina_strbuf_append(str, "[]"); + else + { + const Eina_Value_Type *subtype = tmem->subtype; + const Eina_List *node; + Eina_Value tmp; + const char *s; + Eina_Bool first = EINA_TRUE; + + eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING); + + eina_strbuf_append_char(str, '['); + + for (node = tmem->list; node != NULL; node = node->next) + { + Eina_Bool r = EINA_FALSE; + + if (subtype->convert_to) + { + const void *ptr; + ptr = eina_value_list_node_memory_get(subtype, node); + r = subtype->convert_to(subtype, EINA_VALUE_TYPE_STRING, + ptr, tmp.value.buf); + if (r) + { + if (first) first = EINA_FALSE; + else eina_strbuf_append_length(str, ", ", 2); + eina_strbuf_append(str, tmp.value.ptr); + free(tmp.value.ptr); + tmp.value.ptr = NULL; + } + } + + if (!r) + { + if (first) + { + first = EINA_FALSE; + eina_strbuf_append_char(str, '?'); + } + else + eina_strbuf_append_length(str, ", ?", 3); + } + } + + eina_strbuf_append_char(str, ']'); + s = eina_strbuf_string_get(str); + ret = eina_value_type_pset(convert, convert_mem, &s); + eina_strbuf_free(str); + } + } + else if ((tmem->list) && (tmem->list->next == NULL)) + { + const Eina_Value_Type *subtype = tmem->subtype; + void *imem = eina_value_list_node_memory_get(subtype, tmem->list); + + if (subtype->convert_to) + ret = subtype->convert_to(subtype, convert, imem, convert_mem); + if ((!ret) && (convert->convert_from)) + ret = convert->convert_from(convert, subtype, convert_mem, imem); + } + + if (!ret) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_list_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem) +{ + Eina_Value_List *tmem = type_mem; + Eina_Value_List desc = {convert, NULL}; + Eina_List *node; + char *buf; + void *imem; + + if (!eina_value_type_pset(type, tmem, &desc)) + return EINA_FALSE; + + buf = alloca(convert->value_size); + if (!eina_value_type_pget(convert, convert_mem, &buf)) + return EINA_FALSE; + + tmem->list = eina_list_append(tmem->list, (void*)1L); + node = eina_list_last(tmem->list); + EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE); + + imem = eina_value_list_node_memory_setup(tmem->subtype, node); + if (!imem) + { + tmem->list = eina_list_remove_list(tmem->list, node); + return EINA_FALSE; + } + + if (!eina_value_type_setup(tmem->subtype, imem)) goto error_setup; + if (!eina_value_type_pset(tmem->subtype, imem, &buf)) goto error_set; + return EINA_TRUE; + + error_set: + eina_value_type_flush(tmem->subtype, imem); + error_setup: + eina_value_list_node_memory_flush(tmem->subtype, node); + tmem->list = eina_list_remove_list(tmem->list, node); + return EINA_FALSE; +} + +static Eina_Bool +_eina_value_type_list_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + Eina_Value_List *tmem = mem; + const Eina_Value_List *desc = ptr; + + if ((!tmem->subtype) && (!desc->subtype)) + return EINA_TRUE; + + _eina_value_type_list_flush_elements(tmem); + tmem->subtype = desc->subtype; + tmem->list = desc->list; + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_list_vset(const Eina_Value_Type *type, void *mem, va_list args) +{ + const Eina_Value_List desc = va_arg(args, Eina_Value_List); + _eina_value_type_list_pset(type, mem, &desc); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_list_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + memcpy(ptr, mem, sizeof(Eina_Value_List)); + return EINA_TRUE; +} + +static const Eina_Value_Type _EINA_VALUE_TYPE_LIST = { + EINA_VALUE_TYPE_VERSION, + sizeof(Eina_Value_List), + "Eina_Value_List", + _eina_value_type_list_setup, + _eina_value_type_list_flush, + _eina_value_type_list_copy, + _eina_value_type_list_compare, + _eina_value_type_list_convert_to, + _eina_value_type_list_convert_from, + _eina_value_type_list_vset, + _eina_value_type_list_pset, + _eina_value_type_list_pget +}; + +static Eina_Bool +_eina_value_type_hash_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + memset(mem, 0, sizeof(Eina_Value_Hash)); + return EINA_TRUE; +} + +struct _eina_value_type_hash_flush_each_ctx +{ + const Eina_Value_Type *subtype; + Eina_Bool ret; +}; + +static Eina_Bool +_eina_value_type_hash_flush_each(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *mem, void *user_data) +{ + struct _eina_value_type_hash_flush_each_ctx *ctx = user_data; + ctx->ret &= eina_value_type_flush(ctx->subtype, mem); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_hash_flush_elements(Eina_Value_Hash *tmem) +{ + struct _eina_value_type_hash_flush_each_ctx ctx = { + tmem->subtype, + EINA_TRUE + }; + + if (!tmem->hash) return EINA_TRUE; + + eina_hash_foreach(tmem->hash, _eina_value_type_hash_flush_each, &ctx); + eina_hash_free(tmem->hash); + tmem->hash = NULL; + return ctx.ret; +} + +static Eina_Bool +_eina_value_type_hash_flush(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + Eina_Value_Hash *tmem = mem; + Eina_Bool ret =_eina_value_type_hash_flush_elements(tmem); + tmem->subtype = NULL; + return ret; +} + +static unsigned int +_eina_value_hash_key_length(const void *key) +{ + if (!key) + return 0; + return (int)strlen(key) + 1; +} + +static int +_eina_value_hash_key_cmp(const void *key1, int key1_len, const void *key2, int key2_len) +{ + int r = key1_len - key2_len; + if (r != 0) + return r; + return strcmp(key1, key2); +} + +static Eina_Bool +_eina_value_type_hash_create(Eina_Value_Hash *desc) +{ + if (!desc->buckets_power_size) + desc->buckets_power_size = 5; + + desc->hash = eina_hash_new(_eina_value_hash_key_length, + _eina_value_hash_key_cmp, + EINA_KEY_HASH(eina_hash_superfast), + NULL, desc->buckets_power_size); + return !!desc->hash; +} + +struct _eina_value_type_hash_copy_each_ctx +{ + const Eina_Value_Type *subtype; + Eina_Value_Hash *dest; + Eina_Bool ret; +}; + +static Eina_Bool +_eina_value_type_hash_copy_each(const Eina_Hash *hash __UNUSED__, const void *key, void *_ptr, void *user_data) +{ + struct _eina_value_type_hash_copy_each_ctx *ctx = user_data; + const void *ptr = _ptr; + void *imem = malloc(ctx->subtype->value_size); + if (!imem) + { + ctx->ret = EINA_FALSE; + return EINA_FALSE; + } + if (!ctx->subtype->copy(ctx->subtype, ptr, imem)) + { + free(imem); + ctx->ret = EINA_FALSE; + return EINA_FALSE; + } + if (!eina_hash_add(ctx->dest->hash, key, imem)) + { + eina_value_type_flush(ctx->subtype, imem); + free(imem); + ctx->ret = EINA_FALSE; + return EINA_FALSE; + } + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_hash_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const Eina_Value_Hash *s = src; + Eina_Value_Hash *d = dst; + struct _eina_value_type_hash_copy_each_ctx ctx = {s->subtype, d, EINA_TRUE}; + + d->subtype = s->subtype; + d->buckets_power_size = s->buckets_power_size; + + if ((!s->hash) || (!s->subtype)) + { + d->hash = NULL; + return EINA_TRUE; + } + + if (!s->subtype->copy) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + if (!_eina_value_type_hash_create(d)) + return EINA_FALSE; + + eina_hash_foreach(s->hash, _eina_value_type_hash_copy_each, &ctx); + if (!ctx.ret) + { + _eina_value_type_hash_flush_elements(d); + return EINA_FALSE; + } + return EINA_TRUE; +} + +struct _eina_value_type_hash_compare_each_ctx +{ + const Eina_Value_Type *subtype; + const Eina_Hash *other; + int cmp; +}; + +static Eina_Bool +_eina_value_type_hash_compare_each(const Eina_Hash *hash __UNUSED__, const void *key, void *_ptr, void *user_data) +{ + struct _eina_value_type_hash_compare_each_ctx *ctx = user_data; + const void *self_ptr = _ptr; + const void *other_ptr = eina_hash_find(ctx->other, key); + if (!other_ptr) return EINA_TRUE; + ctx->cmp = ctx->subtype->compare(ctx->subtype, self_ptr, other_ptr); + return ctx->cmp == 0; +} + +static int +_eina_value_type_hash_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const Eina_Value_Hash *eva_a = a, *eva_b = b; + struct _eina_value_type_hash_compare_each_ctx ctx = { + eva_a->subtype, eva_b->hash, 0 + }; + + if (eva_a->subtype != eva_b->subtype) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return -1; + } + + if (!eva_a->subtype->compare) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return 0; + } + + if ((!eva_a->hash) && (!eva_b->hash)) + return 0; + else if (!eva_a->hash) + return -1; + else if (!eva_b->hash) + return 1; + + eina_hash_foreach(eva_a->hash, _eina_value_type_hash_compare_each, &ctx); + if (ctx.cmp == 0) + { + unsigned int count_a = eina_hash_population(eva_a->hash); + unsigned int count_b = eina_hash_population(eva_b->hash); + if (count_a < count_b) + return -1; + else if (count_a > count_b) + return 1; + return 0; + } + + return ctx.cmp; +} + +static Eina_Bool +_eina_value_type_hash_find_first(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *ptr, void *user_data) +{ + void **ret = user_data; + *ret = ptr; + return EINA_FALSE; +} + +struct _eina_value_type_hash_convert_to_string_each_ctx +{ + const Eina_Value_Type *subtype; + Eina_Strbuf *str; + Eina_Value tmp; + Eina_Bool first; +}; + +static Eina_Bool +_eina_value_type_hash_convert_to_string_each(const Eina_Hash *hash __UNUSED__, const void *_key, void *_ptr, void *user_data) +{ + struct _eina_value_type_hash_convert_to_string_each_ctx *ctx = user_data; + const char *key = _key; + const void *ptr = _ptr; + Eina_Bool r = EINA_FALSE; + + if (ctx->first) ctx->first = EINA_FALSE; + else eina_strbuf_append_length(ctx->str, ", ", 2); + + eina_strbuf_append(ctx->str, key); + eina_strbuf_append_length(ctx->str, ": ", 2); + + if (ctx->subtype->convert_to) + { + r = ctx->subtype->convert_to(ctx->subtype, EINA_VALUE_TYPE_STRING, + ptr, ctx->tmp.value.buf); + if (r) + { + eina_strbuf_append(ctx->str, ctx->tmp.value.ptr); + free(ctx->tmp.value.ptr); + ctx->tmp.value.ptr = NULL; + } + } + + if (!r) + eina_strbuf_append_char(ctx->str, '?'); + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_hash_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const Eina_Value_Hash *tmem = type_mem; + Eina_Bool ret = EINA_FALSE; + + if ((convert == EINA_VALUE_TYPE_STRING) || + (convert == EINA_VALUE_TYPE_STRINGSHARE)) + { + Eina_Strbuf *str = eina_strbuf_new(); + if (!tmem->hash) eina_strbuf_append(str, "{}"); + else + { + struct _eina_value_type_hash_convert_to_string_each_ctx ctx; + const char *s; + + ctx.subtype = tmem->subtype; + ctx.str = str; + ctx.first = EINA_TRUE; + eina_value_setup(&ctx.tmp, EINA_VALUE_TYPE_STRING); + + eina_strbuf_append_char(str, '{'); + + eina_hash_foreach(tmem->hash, + _eina_value_type_hash_convert_to_string_each, + &ctx); + + eina_strbuf_append_char(str, '}'); + s = eina_strbuf_string_get(str); + ret = eina_value_type_pset(convert, convert_mem, &s); + eina_strbuf_free(str); + } + } + else if ((tmem->hash) && (eina_hash_population(tmem->hash) == 1)) + { + const Eina_Value_Type *subtype = tmem->subtype; + void *imem = NULL; + + eina_hash_foreach(tmem->hash, _eina_value_type_hash_find_first, &imem); + if (!imem) /* shouldn't happen... */ + ret = EINA_FALSE; + else + { + if (subtype->convert_to) + ret = subtype->convert_to(subtype, convert, imem, convert_mem); + if ((!ret) && (convert->convert_from)) + ret = convert->convert_from(convert, subtype, convert_mem, imem); + } + } + + if (!ret) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_hash_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + Eina_Value_Hash *tmem = mem; + const Eina_Value_Hash *desc = ptr; + + if ((!tmem->subtype) && (!desc->subtype)) + return EINA_TRUE; + + if (tmem->hash) _eina_value_type_hash_flush_elements(tmem); + + if (desc->hash) + tmem->hash = desc->hash; + else if (!_eina_value_type_hash_create(tmem)) + return EINA_FALSE; + + tmem->subtype = desc->subtype; + + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_hash_vset(const Eina_Value_Type *type, void *mem, va_list args) +{ + const Eina_Value_Hash desc = va_arg(args, Eina_Value_Hash); + _eina_value_type_hash_pset(type, mem, &desc); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_hash_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + memcpy(ptr, mem, sizeof(Eina_Value_Hash)); + return EINA_TRUE; +} + +static const Eina_Value_Type _EINA_VALUE_TYPE_HASH = { + EINA_VALUE_TYPE_VERSION, + sizeof(Eina_Value_Hash), + "Eina_Value_Hash", + _eina_value_type_hash_setup, + _eina_value_type_hash_flush, + _eina_value_type_hash_copy, + _eina_value_type_hash_compare, + _eina_value_type_hash_convert_to, + NULL, /* no convert from */ + _eina_value_type_hash_vset, + _eina_value_type_hash_pset, + _eina_value_type_hash_pget +}; + +static Eina_Bool +_eina_value_type_timeval_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + memset(mem, 0, sizeof(struct timeval)); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_timeval_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__) +{ + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_timeval_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const struct timeval *s = src; + struct timeval *d = dst; + *d = *s; + return EINA_TRUE; +} + +static inline struct timeval _eina_value_type_timeval_fix(const struct timeval *input) +{ + struct timeval ret = *input; + if (EINA_UNLIKELY(ret.tv_usec < 0)) + { + ret.tv_sec -= 1; + ret.tv_usec += 1e6; + } + return ret; +} + +static int +_eina_value_type_timeval_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + struct timeval va = _eina_value_type_timeval_fix(a); + struct timeval vb = _eina_value_type_timeval_fix(b); + + if (va.tv_sec < vb.tv_sec) + return -1; + else if (va.tv_sec > vb.tv_sec) + return 1; + + if (va.tv_usec < vb.tv_usec) + return -1; + else if (va.tv_usec > vb.tv_usec) + return 1; + + return 0; +} + +static Eina_Bool +_eina_value_type_timeval_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + struct timeval v = _eina_value_type_timeval_fix(type_mem); + + eina_error_set(0); + + if (convert == EINA_VALUE_TYPE_UCHAR) + { + unsigned char other_mem = v.tv_sec; + if (EINA_UNLIKELY(v.tv_sec < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v.tv_sec > eina_value_uchar_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_USHORT) + { + unsigned short other_mem = v.tv_sec; + if (EINA_UNLIKELY(v.tv_sec < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY(v.tv_sec > eina_value_ushort_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT) + { + unsigned int other_mem = v.tv_sec; + if (EINA_UNLIKELY(v.tv_sec < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY((unsigned long) v.tv_sec > eina_value_uint_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_ULONG) + { + unsigned long other_mem = v.tv_sec; + if (EINA_UNLIKELY(v.tv_sec < 0)) + return EINA_FALSE; + if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) && + ((unsigned long)v.tv_sec > eina_value_ulong_max))) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_UINT64) + { + uint64_t other_mem = v.tv_sec; + if (EINA_UNLIKELY(v.tv_sec < 0)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_CHAR) + { + char other_mem = v.tv_sec; + if (EINA_UNLIKELY(v.tv_sec < eina_value_char_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v.tv_sec > eina_value_char_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_SHORT) + { + short other_mem = v.tv_sec; + if (EINA_UNLIKELY(v.tv_sec < eina_value_short_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v.tv_sec > eina_value_short_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT) + { + int other_mem = v.tv_sec; + if (EINA_UNLIKELY(v.tv_sec < eina_value_int_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v.tv_sec > eina_value_int_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_LONG) + { + long other_mem = v.tv_sec; + if (EINA_UNLIKELY(v.tv_sec < eina_value_long_min)) + return EINA_FALSE; + if (EINA_UNLIKELY(v.tv_sec > eina_value_long_max)) + return EINA_FALSE; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_INT64) + { + int64_t other_mem = v.tv_sec; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_FLOAT) + { + float other_mem = (float)v.tv_sec + (float)v.tv_usec / 1.0e6; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_DOUBLE) + { + double other_mem = (double)v.tv_sec + (double)v.tv_usec / 1.0e6; + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const char *other_mem; + char buf[64]; + snprintf(buf, sizeof(buf), "%ld.%06ld", v.tv_sec, v.tv_usec); + other_mem = buf; /* required due &buf == buf */ + return eina_value_type_pset(convert, convert_mem, &other_mem); + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } +} + +static Eina_Bool +_eina_value_type_timeval_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + struct timeval *tmem = mem; + *tmem = _eina_value_type_timeval_fix(ptr); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_timeval_vset(const Eina_Value_Type *type, void *mem, va_list args) +{ + const struct timeval desc = va_arg(args, struct timeval); + _eina_value_type_timeval_pset(type, mem, &desc); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_timeval_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + memcpy(ptr, mem, sizeof(struct timeval)); + return EINA_TRUE; +} + +static const Eina_Value_Type _EINA_VALUE_TYPE_TIMEVAL = { + EINA_VALUE_TYPE_VERSION, + sizeof(struct timeval), + "struct timeval", + _eina_value_type_timeval_setup, + _eina_value_type_timeval_flush, + _eina_value_type_timeval_copy, + _eina_value_type_timeval_compare, + _eina_value_type_timeval_convert_to, + NULL, /* no convert from */ + _eina_value_type_timeval_vset, + _eina_value_type_timeval_pset, + _eina_value_type_timeval_pget +}; + +static Eina_Bool +_eina_value_type_blob_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + memset(mem, 0, sizeof(Eina_Value_Blob)); + return EINA_TRUE; +} + +static inline const Eina_Value_Blob_Operations * +_eina_value_type_blob_ops_get(const Eina_Value_Blob *blob) +{ + if (!blob) return NULL; + if (!blob->ops) return NULL; + EINA_SAFETY_ON_FALSE_RETURN_VAL + (blob->ops->version == EINA_VALUE_BLOB_OPERATIONS_VERSION, NULL); + return blob->ops; +} + +static Eina_Bool +_eina_value_type_blob_flush(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + const Eina_Value_Blob_Operations *ops = _eina_value_type_blob_ops_get(mem); + Eina_Value_Blob *tmem = mem; + if ((ops) && (ops->free)) + ops->free(ops, (void *)tmem->memory, tmem->size); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_blob_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const Eina_Value_Blob_Operations *ops = _eina_value_type_blob_ops_get(src); + const Eina_Value_Blob *s = src; + Eina_Value_Blob *d = dst; + + *d = *s; + + if ((ops) && (ops->copy)) + { + d->memory = ops->copy(ops, s->memory, s->size); + if ((d->memory == NULL) && (s->size > 0)) + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static int +_eina_value_type_blob_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const Eina_Value_Blob_Operations *ops = _eina_value_type_blob_ops_get(a); + const Eina_Value_Blob *ta = a, *tb = b; + size_t minsize; + if (ta->ops != tb->ops) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return -1; + } + if ((ops) && (ops->compare)) + return ops->compare(ops, ta->memory, ta->size, tb->memory, tb->size); + + if (ta->size < tb->size) + minsize = ta->size; + else + minsize = tb->size; + + return memcmp(ta->memory, tb->memory, minsize); +} + +static Eina_Bool +_eina_value_type_blob_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const Eina_Value_Blob *tmem = type_mem; + + eina_error_set(0); + if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + const Eina_Value_Blob_Operations *ops; + Eina_Strbuf *str; + const char *other_mem; + Eina_Bool ret = EINA_FALSE, first = EINA_TRUE; + const unsigned char *ptr, *ptr_end; + + ops = _eina_value_type_blob_ops_get(tmem); + if ((ops) && (ops->to_string)) + { + char *x = ops->to_string(ops, tmem->memory, tmem->size); + if (x) + { + ret = eina_value_type_pset(convert, convert_mem, &x); + free(x); + } + return ret; + } + + str = eina_strbuf_new(); + if (!str) + return EINA_FALSE; + + if (!eina_strbuf_append_printf(str, "BLOB(%u, [", tmem->size)) + goto error; + + ptr = tmem->memory; + ptr_end = ptr + tmem->size; + for (; ptr < ptr_end; ptr++) + { + if (first) + { + first = EINA_FALSE; + if (!eina_strbuf_append_printf(str, "%02hhx", *ptr)) + goto error; + } + else + { + if (!eina_strbuf_append_printf(str, " %02hhx", *ptr)) + goto error; + } + } + + if (!eina_strbuf_append(str, "])")) + goto error; + + other_mem = eina_strbuf_string_get(str); + ret = eina_value_type_pset(convert, convert_mem, &other_mem); + + error: + eina_strbuf_free(str); + return ret; + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } +} + +static Eina_Bool +_eina_value_type_blob_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem) +{ + Eina_Value_Blob desc; + char *buf; + + desc.ops = EINA_VALUE_BLOB_OPERATIONS_MALLOC; + + if ((convert == EINA_VALUE_TYPE_STRING) || + (convert == EINA_VALUE_TYPE_STRINGSHARE)) + { + const char *str = *(const char **)convert_mem; + if (!str) + { + desc.size = 0; + desc.memory = NULL; + } + else + { + desc.size = strlen(str) + 1; + desc.memory = buf = malloc(desc.size); + if (!desc.memory) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + memcpy(buf, str, desc.size); + } + } + else if (convert == EINA_VALUE_TYPE_ARRAY) + { + const Eina_Value_Array *a = convert_mem; + if ((!a->array) || (a->array->len == 0)) + { + desc.size = 0; + desc.memory = NULL; + } + else + { + desc.size = a->array->len * a->array->member_size; + desc.memory = buf = malloc(desc.size); + if (!desc.memory) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + memcpy(buf, a->array->members, desc.size); + } + } + else if (convert == EINA_VALUE_TYPE_BLOB) + { + const Eina_Value_Blob *b = convert_mem; + if (b->size == 0) + { + desc.size = 0; + desc.memory = NULL; + } + else + { + desc.size = b->size; + desc.memory = buf = malloc(desc.size); + if (!desc.memory) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + memcpy(buf, b->memory, desc.size); + } + } + else + { + desc.size = convert->value_size; + desc.memory = buf = malloc(convert->value_size); + if (!desc.memory) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + if (!eina_value_type_pget(convert, convert_mem, buf)) + { + free(buf); + return EINA_FALSE; + } + } + return eina_value_type_pset(type, type_mem, &desc); +} + +static Eina_Bool +_eina_value_type_blob_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + const Eina_Value_Blob_Operations *ops = _eina_value_type_blob_ops_get(mem); + Eina_Value_Blob *tmem = mem; + const Eina_Value_Blob *desc = ptr; + + if ((ops) && (ops->free)) + ops->free(ops, (void *)tmem->memory, tmem->size); + + *tmem = *desc; + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_blob_vset(const Eina_Value_Type *type, void *mem, va_list args) +{ + const Eina_Value_Blob desc = va_arg(args, Eina_Value_Blob); + _eina_value_type_blob_pset(type, mem, &desc); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_blob_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + memcpy(ptr, mem, sizeof(Eina_Value_Blob)); + return EINA_TRUE; +} + +static const Eina_Value_Type _EINA_VALUE_TYPE_BLOB = { + EINA_VALUE_TYPE_VERSION, + sizeof(Eina_Value_Blob), + "Eina_Value_Blob", + _eina_value_type_blob_setup, + _eina_value_type_blob_flush, + _eina_value_type_blob_copy, + _eina_value_type_blob_compare, + _eina_value_type_blob_convert_to, + _eina_value_type_blob_convert_from, + _eina_value_type_blob_vset, + _eina_value_type_blob_pset, + _eina_value_type_blob_pget +}; + +static int +_eina_value_struct_operations_binsearch_cmp(const void *pa, const void *pb) +{ + const Eina_Value_Struct_Member *a = pa, *b = pb; + return strcmp(a->name, b->name); +} + +static const Eina_Value_Struct_Member * +_eina_value_struct_operations_binsearch_find_member(const Eina_Value_Struct_Operations *ops __UNUSED__, const Eina_Value_Struct_Desc *desc, const char *name) +{ + unsigned int count = desc->member_count; + Eina_Value_Struct_Member search; + if (count == 0) + { + const Eina_Value_Struct_Member *itr = desc->members; + for (; itr->name != NULL; itr++) + count++; + } + + search.name = name; + return bsearch(&search, desc->members, count, + sizeof(Eina_Value_Struct_Member), + _eina_value_struct_operations_binsearch_cmp); +} + +static Eina_Value_Struct_Operations _EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH = { + EINA_VALUE_STRUCT_OPERATIONS_VERSION, + NULL, /* default alloc */ + NULL, /* default free */ + NULL, /* default copy */ + NULL, /* default compare */ + _eina_value_struct_operations_binsearch_find_member +}; + +static const Eina_Value_Struct_Member * +_eina_value_struct_operations_stringshare_find_member(const Eina_Value_Struct_Operations *ops __UNUSED__, const Eina_Value_Struct_Desc *desc, const char *name) +{ + const Eina_Value_Struct_Member *itr = desc->members; + + /* assumes name is stringshared. + * + * we do this because it's the recommended usage pattern, moreover + * we expect to find the member, as users shouldn't look for + * non-existent members! + */ + if (desc->member_count > 0) + { + const Eina_Value_Struct_Member *itr_end = itr + desc->member_count; + for (; itr < itr_end; itr++) + if (itr->name == name) + return itr; + } + else + { + for (; itr->name != NULL; itr++) + if (itr->name == name) + return itr; + } + + name = eina_stringshare_add(name); + eina_stringshare_del(name); /* we'll not use the contents, this is fine */ + /* stringshare and look again */ + if (desc->member_count > 0) + { + const Eina_Value_Struct_Member *itr_end = itr + desc->member_count; + for (; itr < itr_end; itr++) + if (itr->name == name) + return itr; + } + else + { + for (; itr->name != NULL; itr++) + if (itr->name == name) + return itr; + } + + return NULL; +} + +static Eina_Value_Struct_Operations _EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE = { + EINA_VALUE_STRUCT_OPERATIONS_VERSION, + NULL, /* default alloc */ + NULL, /* default free */ + NULL, /* default copy */ + NULL, /* default compare */ + _eina_value_struct_operations_stringshare_find_member +}; + +static inline const Eina_Value_Struct_Operations * +_eina_value_type_struct_ops_get(const Eina_Value_Struct *st) +{ + if (!st) return NULL; + if (!st->desc) return NULL; + if (!st->desc->ops) return NULL; + EINA_SAFETY_ON_FALSE_RETURN_VAL + (st->desc->ops->version == EINA_VALUE_STRUCT_OPERATIONS_VERSION, NULL); + return st->desc->ops; +} + +EAPI const Eina_Value_Struct_Member * +eina_value_struct_member_find(const Eina_Value_Struct *st, const char *name) +{ + const Eina_Value_Struct_Operations *ops; + const Eina_Value_Struct_Member *itr; + + EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(st->desc, NULL); + + ops = _eina_value_type_struct_ops_get(st); + if ((ops) && (ops->find_member)) + return ops->find_member(ops, st->desc, name); + + itr = st->desc->members; + if (st->desc->member_count) + { + const Eina_Value_Struct_Member *itr_end = itr + st->desc->member_count; + for (; itr < itr_end; itr++) + { + if (strcmp(name, itr->name) == 0) + return itr; + } + return NULL; + } + else + { + for (; itr->name != NULL; itr++) + { + if (strcmp(name, itr->name) == 0) + return itr; + } + return NULL; + } +} + +static Eina_Bool +_eina_value_type_struct_setup(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + memset(mem, 0, sizeof(Eina_Value_Struct)); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_struct_flush_member(const Eina_Value_Struct_Member *member, Eina_Value_Struct *st) +{ + unsigned char *base = st->memory; + return eina_value_type_flush(member->type, base + member->offset); +} + +static Eina_Bool +_eina_value_type_struct_flush(const Eina_Value_Type *type __UNUSED__, void *mem) +{ + const Eina_Value_Struct_Operations *ops; + const Eina_Value_Struct_Member *itr; + Eina_Value_Struct *tmem = mem; + Eina_Bool ret = EINA_TRUE; + + itr = tmem->desc->members; + if (tmem->desc->member_count > 0) + { + const Eina_Value_Struct_Member *itr_end; + itr_end = itr + tmem->desc->member_count; + for (; itr < itr_end; itr++) + ret &= _eina_value_type_struct_flush_member(itr, tmem); + } + else + { + for (; itr->name != NULL; itr++) + ret &= _eina_value_type_struct_flush_member(itr, tmem); + } + + ops = _eina_value_type_struct_ops_get(mem); + if ((ops) && (ops->free)) + ops->free(ops, tmem->desc, tmem->memory); + else + free(tmem->memory); + + return ret; +} + +static Eina_Bool +_eina_value_type_struct_copy_member(const Eina_Value_Struct_Member *member, const Eina_Value_Struct *s, Eina_Value_Struct *d) +{ + const unsigned char *base_s = s->memory; + unsigned char *base_d = d->memory; + return eina_value_type_copy(member->type, + base_s + member->offset, + base_d + member->offset); +} + +static Eina_Bool +_eina_value_type_struct_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst) +{ + const Eina_Value_Struct_Operations *ops; + const Eina_Value_Struct_Member *itr; + const Eina_Value_Struct *s = src; + Eina_Value_Struct *d = dst; + + *d = *s; + + ops = _eina_value_type_struct_ops_get(src); + if ((ops) && (ops->copy)) + { + d->memory = ops->copy(ops, s->desc, s->memory); + if (d->memory == NULL) + return EINA_FALSE; + return EINA_TRUE; + } + + d->memory = malloc(s->desc->size); + if (!d->memory) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + + itr = s->desc->members; + if (s->desc->member_count > 0) + { + const Eina_Value_Struct_Member *itr_end = itr + s->desc->member_count; + for (; itr < itr_end; itr++) + if (!_eina_value_type_struct_copy_member(itr, s, d)) + goto error; + } + else + { + for (; itr->name != NULL; itr++) + if (!_eina_value_type_struct_copy_member(itr, s, d)) + goto error; + } + + + return EINA_TRUE; + + error: + itr--; + for (; itr >= s->desc->members; itr--) + _eina_value_type_struct_flush_member(itr, d); + free(d->memory); + return EINA_FALSE; +} + +static inline int +_eina_value_type_struct_compare_member(const Eina_Value_Struct_Member *member, const Eina_Value_Struct *ta, const Eina_Value_Struct *tb) +{ + const unsigned char *base_a = ta->memory; + const unsigned char *base_b = tb->memory; + return eina_value_type_compare(member->type, + base_a + member->offset, + base_b + member->offset); +} + +static int +_eina_value_type_struct_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b) +{ + const Eina_Value_Struct_Operations *ops = _eina_value_type_struct_ops_get(a); + const Eina_Value_Struct *ta = a, *tb = b; + const Eina_Value_Struct_Member *itr; + int cmp = 0; + + if (ta->desc != tb->desc) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return -1; + } + if (ta->desc->ops != tb->desc->ops) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return -1; + } + if ((!ta->memory) && (!tb->memory)) + return 0; + else if (!ta->memory) + return -1; + else if (!tb->memory) + return 1; + + if ((ops) && (ops->compare)) + return ops->compare(ops, ta->desc, ta->memory, tb->memory); + + itr = ta->desc->members; + if (ta->desc->member_count > 0) + { + const Eina_Value_Struct_Member *itr_end = itr + ta->desc->member_count; + for (; (cmp == 0) && (itr < itr_end); itr++) + cmp = _eina_value_type_struct_compare_member(itr, ta, tb); + } + else + { + for (; (cmp == 0) && (itr->name != NULL); itr++) + cmp = _eina_value_type_struct_compare_member(itr, ta, tb); + } + return cmp; +} + +static void +_eina_value_type_struct_convert_to_string_member(const Eina_Value_Struct *st, const Eina_Value_Struct_Member *member, Eina_Strbuf *str) +{ + const unsigned char *p = st->memory; + Eina_Bool first = st->desc->members == member; + Eina_Bool r = EINA_FALSE; + + if (first) eina_strbuf_append_printf(str, "%s: ", member->name); + else eina_strbuf_append_printf(str, ", %s: ", member->name); + + if ((member->type) && (member->type->convert_to)) + { + const Eina_Value_Type *type = member->type; + char *conv = NULL; + + r = eina_value_type_convert_to(type, EINA_VALUE_TYPE_STRING, + p + member->offset, &conv); + if (r) + { + eina_strbuf_append(str, conv); + free(conv); + } + } + + if (!r) + eina_strbuf_append_char(str, '?'); +} + +static Eina_Bool +_eina_value_type_struct_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem) +{ + const Eina_Value_Struct *tmem = type_mem; + + eina_error_set(0); + if (convert == EINA_VALUE_TYPE_STRINGSHARE || + convert == EINA_VALUE_TYPE_STRING) + { + Eina_Strbuf *str = eina_strbuf_new(); + const char *s; + Eina_Bool ret; + + if (!tmem->memory) eina_strbuf_append(str, "{}"); + else + { + const Eina_Value_Struct_Member *itr = tmem->desc->members; + + eina_strbuf_append_char(str, '{'); + + if (tmem->desc->member_count > 0) + { + const Eina_Value_Struct_Member *itr_end; + + itr_end = itr + tmem->desc->member_count; + for (; itr < itr_end; itr++) + _eina_value_type_struct_convert_to_string_member + (tmem, itr, str); + } + else + { + for (; itr->name != NULL; itr++) + _eina_value_type_struct_convert_to_string_member + (tmem, itr, str); + } + + eina_strbuf_append_char(str, '}'); + } + s = eina_strbuf_string_get(str); + ret = eina_value_type_pset(convert, convert_mem, &s); + eina_strbuf_free(str); + return ret; + } + else + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } +} + +static Eina_Bool +_eina_value_type_struct_desc_check(const Eina_Value_Struct_Desc *desc) +{ + unsigned int minsize = 0; + const Eina_Value_Struct_Member *itr; + + EINA_SAFETY_ON_NULL_RETURN_VAL(desc, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL + (desc->version == EINA_VALUE_STRUCT_DESC_VERSION, EINA_FALSE); + + itr = desc->members; + if (desc->member_count > 0) + { + const Eina_Value_Struct_Member *itr_end = itr + desc->member_count; + for (; itr < itr_end; itr++) + { + unsigned int member_end; + + EINA_SAFETY_ON_FALSE_RETURN_VAL + (eina_value_type_check(itr->type), EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL + (itr->type->value_size > 0, EINA_FALSE); + + member_end = itr->offset + itr->type->value_size; + if (minsize < member_end) + minsize = member_end; + } + } + else + { + for (; itr->name != NULL; itr++) + { + unsigned int member_end; + + EINA_SAFETY_ON_FALSE_RETURN_VAL + (eina_value_type_check(itr->type), EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL + (itr->type->value_size > 0, EINA_FALSE); + + member_end = itr->offset + itr->type->value_size; + if (minsize < member_end) + minsize = member_end; + } + } + + EINA_SAFETY_ON_FALSE_RETURN_VAL(minsize > 0, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(desc->size >= minsize, EINA_FALSE); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_struct_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr) +{ + const Eina_Value_Struct_Operations *ops = _eina_value_type_struct_ops_get(mem); + Eina_Value_Struct *tmem = mem; + const Eina_Value_Struct *desc = ptr; + + if (!_eina_value_type_struct_desc_check(desc->desc)) + { + eina_error_set(EINA_ERROR_VALUE_FAILED); + return EINA_FALSE; + } + + if ((ops) && (ops->free)) + ops->free(ops, tmem->desc, tmem->memory); + else + free(tmem->memory); + + *tmem = *desc; + + ops = _eina_value_type_struct_ops_get(desc); + if (!tmem->memory) + { + if ((ops) && (ops->alloc)) + tmem->memory = ops->alloc(ops, tmem->desc); + else + tmem->memory = malloc(tmem->desc->size); + + if (!tmem->memory) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return EINA_FALSE; + } + } + + eina_error_set(0); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_struct_vset(const Eina_Value_Type *type, void *mem, va_list args) +{ + const Eina_Value_Struct desc = va_arg(args, Eina_Value_Struct); + _eina_value_type_struct_pset(type, mem, &desc); + return EINA_TRUE; +} + +static Eina_Bool +_eina_value_type_struct_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr) +{ + memcpy(ptr, mem, sizeof(Eina_Value_Struct)); + return EINA_TRUE; +} + +static const Eina_Value_Type _EINA_VALUE_TYPE_STRUCT = { + EINA_VALUE_TYPE_VERSION, + sizeof(Eina_Value_Struct), + "Eina_Value_Struct", + _eina_value_type_struct_setup, + _eina_value_type_struct_flush, + _eina_value_type_struct_copy, + _eina_value_type_struct_compare, + _eina_value_type_struct_convert_to, + NULL, /* no convert from */ + _eina_value_type_struct_vset, + _eina_value_type_struct_pset, + _eina_value_type_struct_pget +}; + +/* keep all basic types inlined in an array so we can compare if it's + * a basic type using pointer arithmetic. + * + * NOTE-1: JUST BASIC TYPES, DO NOT ADD MORE TYPES HERE!!! + * NOTE-2: KEEP ORDER, see eina_value_init() + */ +static const Eina_Value_Type _EINA_VALUE_TYPE_BASICS[] = { + { + EINA_VALUE_TYPE_VERSION, + sizeof(unsigned char), + "unsigned char", + _eina_value_type_uchar_setup, + _eina_value_type_uchar_flush, + _eina_value_type_uchar_copy, + _eina_value_type_uchar_compare, + _eina_value_type_uchar_convert_to, + NULL, /* no convert from */ + _eina_value_type_uchar_vset, + _eina_value_type_uchar_pset, + _eina_value_type_uchar_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(unsigned short), + "unsigned short", + _eina_value_type_ushort_setup, + _eina_value_type_ushort_flush, + _eina_value_type_ushort_copy, + _eina_value_type_ushort_compare, + _eina_value_type_ushort_convert_to, + NULL, /* no convert from */ + _eina_value_type_ushort_vset, + _eina_value_type_ushort_pset, + _eina_value_type_ushort_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(unsigned int), + "unsigned int", + _eina_value_type_uint_setup, + _eina_value_type_uint_flush, + _eina_value_type_uint_copy, + _eina_value_type_uint_compare, + _eina_value_type_uint_convert_to, + NULL, /* no convert from */ + _eina_value_type_uint_vset, + _eina_value_type_uint_pset, + _eina_value_type_uint_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(unsigned long), + "unsigned long", + _eina_value_type_ulong_setup, + _eina_value_type_ulong_flush, + _eina_value_type_ulong_copy, + _eina_value_type_ulong_compare, + _eina_value_type_ulong_convert_to, + NULL, /* no convert from */ + _eina_value_type_ulong_vset, + _eina_value_type_ulong_pset, + _eina_value_type_ulong_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(uint64_t), + "uint64_t", + _eina_value_type_uint64_setup, + _eina_value_type_uint64_flush, + _eina_value_type_uint64_copy, + _eina_value_type_uint64_compare, + _eina_value_type_uint64_convert_to, + NULL, /* no convert from */ + _eina_value_type_uint64_vset, + _eina_value_type_uint64_pset, + _eina_value_type_uint64_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(char), + "char", + _eina_value_type_char_setup, + _eina_value_type_char_flush, + _eina_value_type_char_copy, + _eina_value_type_char_compare, + _eina_value_type_char_convert_to, + NULL, /* no convert from */ + _eina_value_type_char_vset, + _eina_value_type_char_pset, + _eina_value_type_char_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(short), + "short", + _eina_value_type_short_setup, + _eina_value_type_short_flush, + _eina_value_type_short_copy, + _eina_value_type_short_compare, + _eina_value_type_short_convert_to, + NULL, /* no convert from */ + _eina_value_type_short_vset, + _eina_value_type_short_pset, + _eina_value_type_short_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(int), + "int", + _eina_value_type_int_setup, + _eina_value_type_int_flush, + _eina_value_type_int_copy, + _eina_value_type_int_compare, + _eina_value_type_int_convert_to, + NULL, /* no convert from */ + _eina_value_type_int_vset, + _eina_value_type_int_pset, + _eina_value_type_int_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(long), + "long", + _eina_value_type_long_setup, + _eina_value_type_long_flush, + _eina_value_type_long_copy, + _eina_value_type_long_compare, + _eina_value_type_long_convert_to, + NULL, /* no convert from */ + _eina_value_type_long_vset, + _eina_value_type_long_pset, + _eina_value_type_long_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(int64_t), + "int64_t", + _eina_value_type_int64_setup, + _eina_value_type_int64_flush, + _eina_value_type_int64_copy, + _eina_value_type_int64_compare, + _eina_value_type_int64_convert_to, + NULL, /* no convert from */ + _eina_value_type_int64_vset, + _eina_value_type_int64_pset, + _eina_value_type_int64_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(float), + "float", + _eina_value_type_float_setup, + _eina_value_type_float_flush, + _eina_value_type_float_copy, + _eina_value_type_float_compare, + _eina_value_type_float_convert_to, + NULL, /* no convert from */ + _eina_value_type_float_vset, + _eina_value_type_float_pset, + _eina_value_type_float_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(double), + "double", + _eina_value_type_double_setup, + _eina_value_type_double_flush, + _eina_value_type_double_copy, + _eina_value_type_double_compare, + _eina_value_type_double_convert_to, + NULL, /* no convert from */ + _eina_value_type_double_vset, + _eina_value_type_double_pset, + _eina_value_type_double_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(const char *), + "stringshare", + _eina_value_type_string_common_setup, + _eina_value_type_stringshare_flush, + _eina_value_type_stringshare_copy, + _eina_value_type_string_common_compare, + _eina_value_type_string_common_convert_to, + NULL, /* no convert from */ + _eina_value_type_stringshare_vset, + _eina_value_type_stringshare_pset, + _eina_value_type_string_common_pget + }, + { + EINA_VALUE_TYPE_VERSION, + sizeof(char *), + "string", + _eina_value_type_string_common_setup, + _eina_value_type_string_flush, + _eina_value_type_string_copy, + _eina_value_type_string_common_compare, + _eina_value_type_string_common_convert_to, + NULL, /* no convert from */ + _eina_value_type_string_vset, + _eina_value_type_string_pset, + _eina_value_type_string_common_pget + } +}; + +static void +_eina_value_blob_operations_malloc_free(const Eina_Value_Blob_Operations *ops __UNUSED__, void *memory, size_t size __UNUSED__) +{ + free(memory); +} + +static void * +_eina_value_blob_operations_malloc_copy(const Eina_Value_Blob_Operations *ops __UNUSED__, const void *memory, size_t size) +{ + void *ret = malloc(size); + if (!ret) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return NULL; + } + memcpy(ret, memory, size); + return ret; +} + +static const Eina_Value_Blob_Operations _EINA_VALUE_BLOB_OPERATIONS_MALLOC = { + EINA_VALUE_BLOB_OPERATIONS_VERSION, + _eina_value_blob_operations_malloc_free, + _eina_value_blob_operations_malloc_copy, + NULL, + NULL +}; + +typedef struct _Eina_Value_Inner_Mp Eina_Value_Inner_Mp; +struct _Eina_Value_Inner_Mp +{ + Eina_Mempool *mempool; + int references; +}; + +/** + * @endcond + */ + +static const char EINA_ERROR_VALUE_FAILED_STR[] = "Value check failed."; + +/** + */ + +static inline void +_eina_value_inner_mp_dispose(int size, Eina_Value_Inner_Mp *imp) +{ + EINA_SAFETY_ON_FALSE_RETURN(imp->references == 0); + + eina_hash_del_by_key(_eina_value_inner_mps, &size); + eina_mempool_del(imp->mempool); + free(imp); +} + +static inline Eina_Value_Inner_Mp * +_eina_value_inner_mp_get(int size) +{ + Eina_Value_Inner_Mp *imp = eina_hash_find(_eina_value_inner_mps, &size); + if (imp) return imp; + + imp = malloc(sizeof(Eina_Value_Inner_Mp)); + if (!imp) + return NULL; + + imp->references = 0; + + imp->mempool = eina_mempool_add(_eina_value_mp_choice, + "Eina_Value_Inner_Mp", NULL, size, 128); + if (!imp->mempool) + { + free(imp); + return NULL; + } + + if (!eina_hash_add(_eina_value_inner_mps, &size, imp)) + { + eina_mempool_del(imp->mempool); + free(imp); + return NULL; + } + + return imp; +} + +static inline void * +_eina_value_inner_alloc_internal(int size) +{ + Eina_Value_Inner_Mp *imp; + void *mem; + + imp = _eina_value_inner_mp_get(size); + if (!imp) return NULL; + + mem = eina_mempool_malloc(imp->mempool, size); + if (mem) imp->references++; + else if (imp->references == 0) _eina_value_inner_mp_dispose(size, imp); + + return mem; +} + +static inline void +_eina_value_inner_free_internal(int size, void *mem) +{ + Eina_Value_Inner_Mp *imp = eina_hash_find(_eina_value_inner_mps, &size); + EINA_SAFETY_ON_NULL_RETURN(imp); + + eina_mempool_free(imp->mempool, mem); + + imp->references--; + if (imp->references > 0) return; + _eina_value_inner_mp_dispose(size, imp); +} + +EAPI void * +eina_value_inner_alloc(size_t size) +{ + void *mem; + + if (size > 256) return malloc(size); + + eina_lock_take(&_eina_value_inner_mps_lock); + mem = _eina_value_inner_alloc_internal(size); + eina_lock_release(&_eina_value_inner_mps_lock); + + return mem; +} + +EAPI void +eina_value_inner_free(size_t size, void *mem) +{ + if (size > 256) + { + free(mem); + return; + } + + eina_lock_take(&_eina_value_inner_mps_lock); + _eina_value_inner_free_internal(size, mem); + eina_lock_release(&_eina_value_inner_mps_lock); +} + +/** + * @internal + * @brief Initialize the value module. + * + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function sets up the value module of Eina. It is called + * by eina_init(). + * + * @see eina_init() + */ +Eina_Bool +eina_value_init(void) +{ + const char *choice, *tmp; + + _eina_value_log_dom = eina_log_domain_register("eina_value", + EINA_LOG_COLOR_DEFAULT); + if (_eina_value_log_dom < 0) + { + EINA_LOG_ERR("Could not register log domain: eina_value"); + return EINA_FALSE; + } + +#ifdef EINA_DEFAULT_MEMPOOL + choice = "pass_through"; +#else + choice = "chained_mempool"; +#endif + tmp = getenv("EINA_MEMPOOL"); + if (tmp && tmp[0]) + choice = tmp; + + if (choice) + _eina_value_mp_choice = strdup(choice); + + _eina_value_mp = eina_mempool_add + (_eina_value_mp_choice, "value", NULL, sizeof(Eina_Value), 320); + if (!_eina_value_mp) + { + ERR("Mempool for value cannot be allocated in value init."); + goto on_init_fail_mp; + } + + if (!eina_lock_new(&_eina_value_inner_mps_lock)) + { + ERR("Cannot create lock in value init."); + goto on_init_fail_lock; + } + _eina_value_inner_mps = eina_hash_int32_new(NULL); + if (!_eina_value_inner_mps) + { + ERR("Cannot create hash for inner mempools in value init."); + goto on_init_fail_hash; + } + + EINA_ERROR_VALUE_FAILED = eina_error_msg_static_register( + EINA_ERROR_VALUE_FAILED_STR); + + EINA_VALUE_TYPE_UCHAR = _EINA_VALUE_TYPE_BASICS + 0; + EINA_VALUE_TYPE_USHORT = _EINA_VALUE_TYPE_BASICS + 1; + EINA_VALUE_TYPE_UINT = _EINA_VALUE_TYPE_BASICS + 2; + EINA_VALUE_TYPE_ULONG = _EINA_VALUE_TYPE_BASICS + 3; + EINA_VALUE_TYPE_UINT64 = _EINA_VALUE_TYPE_BASICS + 4; + EINA_VALUE_TYPE_CHAR = _EINA_VALUE_TYPE_BASICS + 5; + EINA_VALUE_TYPE_SHORT = _EINA_VALUE_TYPE_BASICS + 6; + EINA_VALUE_TYPE_INT = _EINA_VALUE_TYPE_BASICS + 7; + EINA_VALUE_TYPE_LONG = _EINA_VALUE_TYPE_BASICS + 8; + EINA_VALUE_TYPE_INT64 = _EINA_VALUE_TYPE_BASICS + 9; + EINA_VALUE_TYPE_FLOAT = _EINA_VALUE_TYPE_BASICS + 10; + EINA_VALUE_TYPE_DOUBLE = _EINA_VALUE_TYPE_BASICS + 11; + EINA_VALUE_TYPE_STRINGSHARE = _EINA_VALUE_TYPE_BASICS + 12; + EINA_VALUE_TYPE_STRING = _EINA_VALUE_TYPE_BASICS + 13; + + _EINA_VALUE_TYPE_BASICS_START = _EINA_VALUE_TYPE_BASICS + 0; + _EINA_VALUE_TYPE_BASICS_END = _EINA_VALUE_TYPE_BASICS + 13; + + EINA_SAFETY_ON_FALSE_RETURN_VAL((sizeof(_EINA_VALUE_TYPE_BASICS)/sizeof(_EINA_VALUE_TYPE_BASICS[0])) == 14, EINA_FALSE); + + + EINA_VALUE_TYPE_ARRAY = &_EINA_VALUE_TYPE_ARRAY; + EINA_VALUE_TYPE_LIST = &_EINA_VALUE_TYPE_LIST; + EINA_VALUE_TYPE_HASH = &_EINA_VALUE_TYPE_HASH; + EINA_VALUE_TYPE_TIMEVAL = &_EINA_VALUE_TYPE_TIMEVAL; + EINA_VALUE_TYPE_BLOB = &_EINA_VALUE_TYPE_BLOB; + EINA_VALUE_TYPE_STRUCT = &_EINA_VALUE_TYPE_STRUCT; + + EINA_VALUE_BLOB_OPERATIONS_MALLOC = &_EINA_VALUE_BLOB_OPERATIONS_MALLOC; + + EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH = &_EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH; + EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE = &_EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE; + + return EINA_TRUE; + + on_init_fail_hash: + eina_lock_free(&_eina_value_inner_mps_lock); + on_init_fail_lock: + eina_mempool_del(_eina_value_mp); + on_init_fail_mp: + free(_eina_value_mp_choice); + _eina_value_mp_choice = NULL; + eina_log_domain_unregister(_eina_value_log_dom); + _eina_value_log_dom = -1; + return EINA_FALSE; +} + +/** + * @internal + * @brief Shut down the value module. + * + * @return #EINA_TRUE on success, #EINA_FALSE on failure. + * + * This function shuts down the value module set up by + * eina_value_init(). It is called by eina_shutdown(). + * + * @see eina_shutdown() + */ +Eina_Bool +eina_value_shutdown(void) +{ + eina_lock_take(&_eina_value_inner_mps_lock); + if (eina_hash_population(_eina_value_inner_mps) != 0) + ERR("Cannot free eina_value internal memory pools -- still in use!"); + else + eina_hash_free(_eina_value_inner_mps); + eina_lock_release(&_eina_value_inner_mps_lock); + eina_lock_free(&_eina_value_inner_mps_lock); + + free(_eina_value_mp_choice); + _eina_value_mp_choice = NULL; + eina_mempool_del(_eina_value_mp); + eina_log_domain_unregister(_eina_value_log_dom); + _eina_value_log_dom = -1; + return EINA_TRUE; +} /*============================================================================* * Global * @@ -39,9 +4793,232 @@ * API * *============================================================================*/ +EAPI const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_START = NULL; +EAPI const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_END = NULL; + +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UCHAR = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_USHORT = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ULONG = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT64 = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_CHAR = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_SHORT = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_INT = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_LONG = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_INT64 = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_FLOAT = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_DOUBLE = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRINGSHARE = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRING = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ARRAY = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_LIST = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_HASH = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMEVAL = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_BLOB = NULL; +EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRUCT = NULL; + +EAPI const Eina_Value_Blob_Operations *EINA_VALUE_BLOB_OPERATIONS_MALLOC = NULL; + +EAPI const Eina_Value_Struct_Operations *EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH = NULL; +EAPI const Eina_Value_Struct_Operations *EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE = NULL; + +EAPI Eina_Error EINA_ERROR_VALUE_FAILED = 0; + EAPI const unsigned int eina_prime_table[] = { 17, 31, 61, 127, 257, 509, 1021, 2053, 4093, 8191, 16381, 32771, 65537, 131071, 262147, 524287, 1048573, 2097143, 4194301, 8388617, 16777213 }; + +EAPI Eina_Value * +eina_value_new(const Eina_Value_Type *type) +{ + Eina_Value *value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));; + if (!value) + { + eina_error_set(EINA_ERROR_OUT_OF_MEMORY); + return NULL; + } + if (!eina_value_setup(value, type)) + { + free(value); + return NULL; + } + return value; +} + +EAPI void +eina_value_free(Eina_Value *value) +{ + EINA_SAFETY_ON_NULL_RETURN(value); + eina_value_flush(value); + eina_mempool_free(_eina_value_mp, value); +} + + +EAPI Eina_Bool +eina_value_copy(const Eina_Value *value, Eina_Value *copy) +{ + const Eina_Value_Type *type; + const void *src; + void *dst; + Eina_Bool ret; + + EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), + EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(copy, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(value->type->copy, EINA_FALSE); + + type = value->type; + if (!eina_value_setup(copy, type)) + return EINA_FALSE; + + src = eina_value_memory_get(value); + dst = eina_value_memory_get(copy); + ret = type->copy(type, src, dst); + if (!ret) + eina_value_flush(copy); + + return ret; +} + +EAPI Eina_Bool +eina_value_convert(const Eina_Value *value, Eina_Value *convert) +{ + Eina_Bool ret = EINA_FALSE; + const Eina_Value_Type *type, *convert_type; + const void *type_mem; + void *convert_mem; + + EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(convert, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), + EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(convert->type), + EINA_FALSE); + + type = value->type; + convert_type = convert->type; + + type_mem = eina_value_memory_get(value); + convert_mem = eina_value_memory_get(convert); + + if (type->convert_to) + ret = type->convert_to(type, convert_type, type_mem, convert_mem); + + if ((!ret) && (convert_type->convert_from)) + ret = convert_type->convert_from(convert_type, type, convert_mem, + type_mem); + + return ret; +} + +EAPI char * +eina_value_to_string(const Eina_Value *value) +{ + Eina_Value tmp; + + EINA_SAFETY_ON_NULL_RETURN_VAL(value, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), NULL); + + if (!eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING)) + return NULL; + if (!eina_value_convert(value, &tmp)) + return NULL; + + return tmp.value.ptr; /* steal value */ +} + +EAPI Eina_Value * +eina_value_array_new(const Eina_Value_Type *subtype, unsigned int step) +{ + Eina_Value *value; + + EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(subtype), EINA_FALSE); + + value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));; + if (!value) + return NULL; + + if (!eina_value_array_setup(value, subtype, step)) + { + eina_mempool_free(_eina_value_mp, value); + return NULL; + } + + return value; +} + +EAPI Eina_Value * +eina_value_list_new(const Eina_Value_Type *subtype) +{ + Eina_Value *value; + + EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(subtype), EINA_FALSE); + + value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));; + if (!value) + return NULL; + + if (!eina_value_list_setup(value, subtype)) + { + eina_mempool_free(_eina_value_mp, value); + return NULL; + } + + return value; +} + +EAPI Eina_Value * +eina_value_hash_new(const Eina_Value_Type *subtype, unsigned int buckets_power_size) +{ + Eina_Value *value; + + EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(subtype), EINA_FALSE); + + value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));; + if (!value) + return NULL; + + if (!eina_value_hash_setup(value, subtype, buckets_power_size)) + { + eina_mempool_free(_eina_value_mp, value); + return NULL; + } + + return value; +} + +EAPI Eina_Value * +eina_value_struct_new(const Eina_Value_Struct_Desc *desc) +{ + Eina_Value *value; + + value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));; + if (!value) + return NULL; + + if (!eina_value_struct_setup(value, desc)) + { + eina_mempool_free(_eina_value_mp, value); + return NULL; + } + + return value; +} + +EAPI Eina_Bool +eina_value_type_check(const Eina_Value_Type *type) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE); + return type->version == EINA_VALUE_TYPE_VERSION; +} + +EAPI const char * +eina_value_type_name_get(const Eina_Value_Type *type) +{ + EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), NULL); + return type->name; +} diff --git a/libraries/eina/src/lib/eina_xattr.c b/libraries/eina/src/lib/eina_xattr.c index bd5b98e..d4ed139 100644 --- a/libraries/eina/src/lib/eina_xattr.c +++ b/libraries/eina/src/lib/eina_xattr.c @@ -20,6 +20,7 @@ # include "config.h" #endif +#include #include #include #include @@ -34,6 +35,7 @@ #include "eina_safety_checks.h" #include "eina_xattr.h" #include "eina_convert.h" +#include "eina_stringshare.h" /*============================================================================* * Local * @@ -49,14 +51,83 @@ struct _Eina_Xattr_Iterator { Eina_Iterator iterator; + const char *file; + Eina_Xattr *attr; + ssize_t length; ssize_t offset; + int fd; + char xattr[1]; }; #ifdef HAVE_XATTR static Eina_Bool +_eina_xattr_value_ls_fd_iterator_next(Eina_Xattr_Iterator *it, void **data) +{ + char *tmp; + + if (it->offset >= it->length) + return EINA_FALSE; + + *data = it->attr; + it->attr->name = it->xattr + it->offset; + + it->attr->length = fgetxattr(it->fd, it->attr->name, NULL, 0); + if (it->attr->length) + { + tmp = realloc((void*) it->attr->value, it->attr->length); + if (!tmp) + { + free((void*) it->attr->value); + it->attr->value = NULL; + it->attr->length = 0; + } + else + { + it->attr->length = fgetxattr(it->fd, it->attr->name, + (void *) it->attr->value, + it->attr->length); + } + } + + return EINA_TRUE; +} + +static Eina_Bool +_eina_xattr_value_ls_iterator_next(Eina_Xattr_Iterator *it, void **data) +{ + char *tmp; + + if (it->offset >= it->length) + return EINA_FALSE; + + *data = it->attr; + it->attr->name = it->xattr + it->offset; + + it->attr->length = getxattr(it->file, it->attr->name, NULL, 0); + if (it->attr->length) + { + tmp = realloc((void*) it->attr->value, it->attr->length); + if (!tmp) + { + free((void*) it->attr->value); + it->attr->value = NULL; + it->attr->length = 0; + } + else + { + it->attr->length = getxattr(it->file, it->attr->name, + (void*) it->attr->value, + it->attr->length); + } + } + + return EINA_TRUE; +} + +static Eina_Bool _eina_xattr_ls_iterator_next(Eina_Xattr_Iterator *it, void **data) { if (it->offset >= it->length) @@ -78,6 +149,9 @@ static void _eina_xattr_ls_iterator_free(Eina_Xattr_Iterator *it) { EINA_MAGIC_SET(&it->iterator, 0); + if (it->attr) free((void *) it->attr->value); + eina_stringshare_del(it->file); + free(it->attr); free(it); } #endif @@ -96,6 +170,85 @@ _eina_xattr_ls_iterator_free(Eina_Xattr_Iterator *it) * API * *============================================================================*/ +EAPI Eina_Iterator * +eina_xattr_value_fd_ls(int fd) +{ +#ifdef HAVE_XATTR + Eina_Xattr_Iterator *it; + ssize_t length; + + if (fd < 0) return NULL; + + length = flistxattr(fd, NULL, 0); + if (length <= 0) return NULL; + + it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); + if (!it) return NULL; + + it->attr = calloc(1, sizeof (Eina_Xattr)); + if (!it->attr) + { + free(it); + return NULL; + } + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + + it->fd = fd; + it->length = flistxattr(fd, it->xattr, length); + if (it->length != length) + { + free(it); + return NULL; + } + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_value_ls_fd_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); + it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); + + return &it->iterator; +#else + return NULL; + (void)fd; +#endif +} + +EAPI Eina_Iterator * +eina_xattr_fd_ls(int fd) +{ +#ifdef HAVE_XATTR + Eina_Xattr_Iterator *it; + ssize_t length; + + if (fd < 0) return NULL; + + length = flistxattr(fd, NULL, 0); + if (length <= 0) return NULL; + + it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + + it->length = flistxattr(fd, it->xattr, length); + if (it->length != length) + { + free(it); + return NULL; + } + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_ls_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); + it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); + + return &it->iterator; +#else + return NULL; + (void)fd; +#endif +} EAPI Eina_Iterator * eina_xattr_ls(const char *file) @@ -133,6 +286,44 @@ eina_xattr_ls(const char *file) #endif } +EAPI Eina_Iterator * +eina_xattr_value_ls(const char *file) +{ +#ifdef HAVE_XATTR + Eina_Xattr_Iterator *it; + ssize_t length; + + EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL); + + length = listxattr(file, NULL, 0); + if (length <= 0) return NULL; + + it = calloc(1, sizeof (Eina_Xattr_Iterator) + length - 1); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + + it->length = listxattr(file, it->xattr, length); + if (it->length != length) + { + free(it); + return NULL; + } + + it->file = eina_stringshare_add(file); + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = FUNC_ITERATOR_NEXT(_eina_xattr_value_ls_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_eina_xattr_ls_iterator_container); + it->iterator.free = FUNC_ITERATOR_FREE(_eina_xattr_ls_iterator_free); + + return &it->iterator; +#else + return NULL; + (void)file; +#endif +} + EAPI void * eina_xattr_get(const char *file, const char *attribute, ssize_t *size) { diff --git a/libraries/eina/src/modules/Makefile.in b/libraries/eina/src/modules/Makefile.in index f3385f1..1ee8386 100644 --- a/libraries/eina/src/modules/Makefile.in +++ b/libraries/eina/src/modules/Makefile.in @@ -147,7 +147,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@ @@ -199,8 +201,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@ diff --git a/libraries/eina/src/modules/mp/Makefile.in b/libraries/eina/src/modules/mp/Makefile.in index d7e67ad..d3a6dd9 100644 --- a/libraries/eina/src/modules/mp/Makefile.in +++ b/libraries/eina/src/modules/mp/Makefile.in @@ -155,7 +155,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@ @@ -207,8 +209,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@ diff --git a/libraries/eina/src/modules/mp/buddy/Makefile.in b/libraries/eina/src/modules/mp/buddy/Makefile.in index 64d7fc7..5619b2c 100644 --- a/libraries/eina/src/modules/mp/buddy/Makefile.in +++ b/libraries/eina/src/modules/mp/buddy/Makefile.in @@ -163,7 +163,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 +217,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@ diff --git a/libraries/eina/src/modules/mp/buddy/eina_buddy.c b/libraries/eina/src/modules/mp/buddy/eina_buddy.c index f402c6f..7d830db 100644 --- a/libraries/eina/src/modules/mp/buddy/eina_buddy.c +++ b/libraries/eina/src/modules/mp/buddy/eina_buddy.c @@ -133,23 +133,23 @@ static void _free(void *data, void *element) Buddy *b = data; Block *block, *buddy; size_t offset; - size_t index; + size_t idx; offset = (unsigned char *)element - (unsigned char *)b->heap; if (offset > b->size) return; - index = offset >> b->min_order; - block = &b->blocks[index]; + idx = offset >> b->min_order; + block = &b->blocks[idx]; - //printf("free %x index = %d order = %d buddy = %d\n", offset, index, block->order, index ^ (1 << block->order)); + //printf("free %x idx = %d order = %d buddy = %d\n", offset, idx, block->order, idx ^ (1 << block->order)); /* we should always work with the buddy at right */ - if (index & (1 << block->order)) + if (idx & (1 << block->order)) { Block *left; - index = index ^ (1 << block->order); - left = &b->blocks[index]; + idx = idx ^ (1 << block->order); + left = &b->blocks[idx]; if (!left->available) goto end; else @@ -170,7 +170,7 @@ check: } - buddy = &b->blocks[index ^ (1 << block->order)]; + buddy = &b->blocks[idx ^ (1 << block->order)]; if (!buddy->available) { goto end; /* merge two blocks */ @@ -239,7 +239,7 @@ static void _statistics(void *data) printf("Information:\n"); printf( - "size = %li, min_order = %d, max_order = %d, num_order = %d, num_blocks = %d (%luKB)\n", + "size = %zu, min_order = %d, max_order = %d, num_order = %d, num_blocks = %d (%uKB)\n", b->size, b->min_order, b->max_order, @@ -255,7 +255,7 @@ static void _statistics(void *data) printf("\n2^%d:", b->min_order + i); EINA_INLIST_FOREACH(b->areas[i], block) { - printf(" %li", (block - &b->blocks[0])); + printf(" %d", (block - &b->blocks[0])); } } printf("\nBlocks dumping:\n"); diff --git a/libraries/eina/src/modules/mp/chained_pool/Makefile.in b/libraries/eina/src/modules/mp/chained_pool/Makefile.in index b728672..03b639f 100644 --- a/libraries/eina/src/modules/mp/chained_pool/Makefile.in +++ b/libraries/eina/src/modules/mp/chained_pool/Makefile.in @@ -163,7 +163,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 +217,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@ diff --git a/libraries/eina/src/modules/mp/chained_pool/eina_chained_mempool.c b/libraries/eina/src/modules/mp/chained_pool/eina_chained_mempool.c index 009b62b..020d0ad 100644 --- a/libraries/eina/src/modules/mp/chained_pool/eina_chained_mempool.c +++ b/libraries/eina/src/modules/mp/chained_pool/eina_chained_mempool.c @@ -31,6 +31,10 @@ # endif #endif +#ifdef EINA_DEBUG_MALLOC +# include +#endif + #ifdef EFL_HAVE_WIN32_THREADS # define WIN32_LEAN_AND_MEAN # include @@ -51,7 +55,7 @@ # include #endif -#ifdef DEBUG +#if defined DEBUG || defined EINA_DEBUG_MALLOC #include #include "eina_log.h" @@ -74,6 +78,9 @@ struct _Chained_Mempool int alloc_size; int group_size; int usage; +#ifdef EINA_DEBUG_MALLOC + int minimal_size; +#endif #ifdef EFL_DEBUG_THREADS pthread_t self; #endif @@ -125,6 +132,20 @@ _eina_chained_mp_pool_new(Chained_Mempool *pool) return NULL; } +#ifdef EINA_DEBUG_MALLOC + { + size_t sz; + + sz = malloc_usable_size(p); + if (sz - pool->minimal_size > 0) + INF("Just allocated %0.2f%% to much memory in '%s' for one block of size %i that means %i bytes to much.", + ((float)(sz - pool->minimal_size) * 100) / (float) (pool->alloc_size), + pool->name, + pool->alloc_size, + sz - pool->minimal_size); + } +#endif + alignof = eina_mempool_alignof(sizeof(Chained_Pool)); ptr = (unsigned char *)p + alignof; p->usage = 0; @@ -444,6 +465,10 @@ eina_chained_mempool_init(const char *context, memcpy((char *)mp->name, context, length); } +#ifdef EINA_DEBUG_MALLOC + mp->minimal_size = item_size * mp->pool_size + sizeof(Chained_Pool); +#endif + mp->item_alloc = eina_mempool_alignof(item_size); mp->group_size = mp->item_alloc * mp->pool_size; mp->alloc_size = mp->group_size + eina_mempool_alignof(sizeof(Chained_Pool)); @@ -517,7 +542,7 @@ static Eina_Mempool_Backend _eina_chained_mp_backend = { Eina_Bool chained_init(void) { -#ifdef DEBUG +#if defined DEBUG || defined EINA_DEBUG_MALLOC _eina_chained_mp_log_dom = eina_log_domain_register("eina_mempool", EINA_LOG_COLOR_DEFAULT); if (_eina_chained_mp_log_dom < 0) @@ -533,7 +558,7 @@ Eina_Bool chained_init(void) void chained_shutdown(void) { eina_mempool_unregister(&_eina_chained_mp_backend); -#ifdef DEBUG +#if defined DEBUG || defined EINA_DEBUG_MALLOC eina_log_domain_unregister(_eina_chained_mp_log_dom); _eina_chained_mp_log_dom = -1; #endif diff --git a/libraries/eina/src/modules/mp/ememoa_fixed/Makefile.in b/libraries/eina/src/modules/mp/ememoa_fixed/Makefile.in index ec97bb1..ccc4f1a 100644 --- a/libraries/eina/src/modules/mp/ememoa_fixed/Makefile.in +++ b/libraries/eina/src/modules/mp/ememoa_fixed/Makefile.in @@ -163,7 +163,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 +217,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@ diff --git a/libraries/eina/src/modules/mp/ememoa_unknown/Makefile.in b/libraries/eina/src/modules/mp/ememoa_unknown/Makefile.in index b295c64..8b0ec6e 100644 --- a/libraries/eina/src/modules/mp/ememoa_unknown/Makefile.in +++ b/libraries/eina/src/modules/mp/ememoa_unknown/Makefile.in @@ -163,7 +163,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 +217,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@ diff --git a/libraries/eina/src/modules/mp/fixed_bitmap/Makefile.in b/libraries/eina/src/modules/mp/fixed_bitmap/Makefile.in index c1541fc..337f820 100644 --- a/libraries/eina/src/modules/mp/fixed_bitmap/Makefile.in +++ b/libraries/eina/src/modules/mp/fixed_bitmap/Makefile.in @@ -163,7 +163,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 +217,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@ diff --git a/libraries/eina/src/modules/mp/one_big/Makefile.in b/libraries/eina/src/modules/mp/one_big/Makefile.in index e999b78..c8560c9 100644 --- a/libraries/eina/src/modules/mp/one_big/Makefile.in +++ b/libraries/eina/src/modules/mp/one_big/Makefile.in @@ -163,7 +163,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 +217,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@ diff --git a/libraries/eina/src/modules/mp/pass_through/Makefile.in b/libraries/eina/src/modules/mp/pass_through/Makefile.in index 01e7b51..f5664be 100644 --- a/libraries/eina/src/modules/mp/pass_through/Makefile.in +++ b/libraries/eina/src/modules/mp/pass_through/Makefile.in @@ -163,7 +163,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 +217,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@ diff --git a/libraries/eina/src/tests/Makefile.am b/libraries/eina/src/tests/Makefile.am index a413e6e..7e05ba9 100644 --- a/libraries/eina/src/tests/Makefile.am +++ b/libraries/eina/src/tests/Makefile.am @@ -28,7 +28,7 @@ endif if EFL_ENABLE_TESTS -check_PROGRAMS = eina_suite +check_PROGRAMS = eina_suite cxx_compile_test eina_suite_SOURCES = \ eina_suite.c \ @@ -38,6 +38,7 @@ eina_test_ustringshare.c\ eina_test_ustr.c \ eina_test_binshare.c \ eina_test_binbuf.c \ +eina_test_inarray.c \ eina_test_array.c \ eina_test_clist.c \ eina_test_error.c \ @@ -64,10 +65,14 @@ eina_test_tiler.c \ eina_test_strbuf.c \ eina_test_str.c \ eina_test_quadtree.c \ -eina_test_simple_xml_parser.c +eina_test_simple_xml_parser.c \ +eina_test_value.c eina_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libeina.la -lm +cxx_compile_test_SOURCES = cxx_compile_test.cxx +cxx_compile_test_LDADD = $(top_builddir)/src/lib/libeina.la + module_dummydir = $(libdir)/eina/test module_dummy_LTLIBRARIES = module_dummy.la diff --git a/libraries/eina/src/tests/Makefile.in b/libraries/eina/src/tests/Makefile.in index b5983b3..c56211a 100644 --- a/libraries/eina/src/tests/Makefile.in +++ b/libraries/eina/src/tests/Makefile.in @@ -37,7 +37,8 @@ build_triplet = @build@ host_triplet = @host@ @EINA_HAVE_GLIB_TRUE@am__append_1 = -DEINA_BENCH_HAVE_GLIB @EINA_ENABLE_BENCHMARK_E17_TRUE@am__append_2 = -DEINA_ENABLE_BENCH_E17 -@EFL_ENABLE_TESTS_TRUE@check_PROGRAMS = eina_suite$(EXEEXT) +@EFL_ENABLE_TESTS_TRUE@check_PROGRAMS = eina_suite$(EXEEXT) \ +@EFL_ENABLE_TESTS_TRUE@ cxx_compile_test$(EXEEXT) @EFL_ENABLE_BENCHMARK_TRUE@bench_PROGRAMS = eina_bench$(EXEEXT) subdir = src/tests DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in @@ -107,6 +108,12 @@ module_dummy_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @EFL_ENABLE_TESTS_TRUE@am_module_dummy_la_rpath = -rpath \ @EFL_ENABLE_TESTS_TRUE@ $(module_dummydir) PROGRAMS = $(bench_PROGRAMS) +am__cxx_compile_test_SOURCES_DIST = cxx_compile_test.cxx +@EFL_ENABLE_TESTS_TRUE@am_cxx_compile_test_OBJECTS = \ +@EFL_ENABLE_TESTS_TRUE@ cxx_compile_test.$(OBJEXT) +cxx_compile_test_OBJECTS = $(am_cxx_compile_test_OBJECTS) +@EFL_ENABLE_TESTS_TRUE@cxx_compile_test_DEPENDENCIES = \ +@EFL_ENABLE_TESTS_TRUE@ $(top_builddir)/src/lib/libeina.la am__eina_bench_SOURCES_DIST = eina_bench.c eina_bench_sort.c \ eina_bench_hash.c eina_bench_stringshare.c \ eina_bench_convert.c eina_bench_mempool.c \ @@ -142,16 +149,17 @@ eina_bench_OBJECTS = $(am_eina_bench_OBJECTS) am__eina_suite_SOURCES_DIST = eina_suite.c eina_test_fp.c \ eina_test_stringshare.c eina_test_ustringshare.c \ eina_test_ustr.c eina_test_binshare.c eina_test_binbuf.c \ - eina_test_array.c eina_test_clist.c eina_test_error.c \ - eina_test_sched.c eina_test_log.c eina_test_magic.c \ - eina_test_inlist.c eina_test_main.c eina_test_counter.c \ - eina_test_lalloc.c eina_test_hash.c eina_test_iterator.c \ - eina_test_accessor.c eina_test_module.c eina_test_convert.c \ - eina_test_rbtree.c eina_test_file.c eina_test_benchmark.c \ - eina_test_mempool.c eina_test_rectangle.c eina_test_list.c \ + eina_test_inarray.c eina_test_array.c eina_test_clist.c \ + eina_test_error.c eina_test_sched.c eina_test_log.c \ + eina_test_magic.c eina_test_inlist.c eina_test_main.c \ + eina_test_counter.c eina_test_lalloc.c eina_test_hash.c \ + eina_test_iterator.c eina_test_accessor.c eina_test_module.c \ + eina_test_convert.c eina_test_rbtree.c eina_test_file.c \ + eina_test_benchmark.c eina_test_mempool.c \ + eina_test_rectangle.c eina_test_list.c \ eina_test_matrixsparse.c eina_test_tiler.c eina_test_strbuf.c \ eina_test_str.c eina_test_quadtree.c \ - eina_test_simple_xml_parser.c + eina_test_simple_xml_parser.c eina_test_value.c @EFL_ENABLE_TESTS_TRUE@am_eina_suite_OBJECTS = eina_suite.$(OBJEXT) \ @EFL_ENABLE_TESTS_TRUE@ eina_test_fp.$(OBJEXT) \ @EFL_ENABLE_TESTS_TRUE@ eina_test_stringshare.$(OBJEXT) \ @@ -159,6 +167,7 @@ am__eina_suite_SOURCES_DIST = eina_suite.c eina_test_fp.c \ @EFL_ENABLE_TESTS_TRUE@ eina_test_ustr.$(OBJEXT) \ @EFL_ENABLE_TESTS_TRUE@ eina_test_binshare.$(OBJEXT) \ @EFL_ENABLE_TESTS_TRUE@ eina_test_binbuf.$(OBJEXT) \ +@EFL_ENABLE_TESTS_TRUE@ eina_test_inarray.$(OBJEXT) \ @EFL_ENABLE_TESTS_TRUE@ eina_test_array.$(OBJEXT) \ @EFL_ENABLE_TESTS_TRUE@ eina_test_clist.$(OBJEXT) \ @EFL_ENABLE_TESTS_TRUE@ eina_test_error.$(OBJEXT) \ @@ -185,7 +194,8 @@ am__eina_suite_SOURCES_DIST = eina_suite.c eina_test_fp.c \ @EFL_ENABLE_TESTS_TRUE@ eina_test_strbuf.$(OBJEXT) \ @EFL_ENABLE_TESTS_TRUE@ eina_test_str.$(OBJEXT) \ @EFL_ENABLE_TESTS_TRUE@ eina_test_quadtree.$(OBJEXT) \ -@EFL_ENABLE_TESTS_TRUE@ eina_test_simple_xml_parser.$(OBJEXT) +@EFL_ENABLE_TESTS_TRUE@ eina_test_simple_xml_parser.$(OBJEXT) \ +@EFL_ENABLE_TESTS_TRUE@ eina_test_value.$(OBJEXT) eina_suite_OBJECTS = $(am_eina_suite_OBJECTS) @EFL_ENABLE_TESTS_TRUE@eina_suite_DEPENDENCIES = \ @EFL_ENABLE_TESTS_TRUE@ $(top_builddir)/src/lib/libeina.la @@ -232,10 +242,11 @@ AM_V_GEN = $(am__v_GEN_$(V)) am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libcity_la_SOURCES) $(module_dummy_la_SOURCES) \ - $(eina_bench_SOURCES) $(nodist_EXTRA_eina_bench_SOURCES) \ - $(eina_suite_SOURCES) + $(cxx_compile_test_SOURCES) $(eina_bench_SOURCES) \ + $(nodist_EXTRA_eina_bench_SOURCES) $(eina_suite_SOURCES) DIST_SOURCES = $(am__libcity_la_SOURCES_DIST) \ $(am__module_dummy_la_SOURCES_DIST) \ + $(am__cxx_compile_test_SOURCES_DIST) \ $(am__eina_bench_SOURCES_DIST) $(am__eina_suite_SOURCES_DIST) ETAGS = etags CTAGS = ctags @@ -282,7 +293,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@ @@ -334,8 +347,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@ @@ -426,6 +437,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/include \ @EFL_ENABLE_TESTS_TRUE@eina_test_ustr.c \ @EFL_ENABLE_TESTS_TRUE@eina_test_binshare.c \ @EFL_ENABLE_TESTS_TRUE@eina_test_binbuf.c \ +@EFL_ENABLE_TESTS_TRUE@eina_test_inarray.c \ @EFL_ENABLE_TESTS_TRUE@eina_test_array.c \ @EFL_ENABLE_TESTS_TRUE@eina_test_clist.c \ @EFL_ENABLE_TESTS_TRUE@eina_test_error.c \ @@ -452,9 +464,12 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_srcdir)/src/include \ @EFL_ENABLE_TESTS_TRUE@eina_test_strbuf.c \ @EFL_ENABLE_TESTS_TRUE@eina_test_str.c \ @EFL_ENABLE_TESTS_TRUE@eina_test_quadtree.c \ -@EFL_ENABLE_TESTS_TRUE@eina_test_simple_xml_parser.c +@EFL_ENABLE_TESTS_TRUE@eina_test_simple_xml_parser.c \ +@EFL_ENABLE_TESTS_TRUE@eina_test_value.c @EFL_ENABLE_TESTS_TRUE@eina_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libeina.la -lm +@EFL_ENABLE_TESTS_TRUE@cxx_compile_test_SOURCES = cxx_compile_test.cxx +@EFL_ENABLE_TESTS_TRUE@cxx_compile_test_LDADD = $(top_builddir)/src/lib/libeina.la @EFL_ENABLE_TESTS_TRUE@module_dummydir = $(libdir)/eina/test @EFL_ENABLE_TESTS_TRUE@module_dummy_LTLIBRARIES = module_dummy.la @EFL_ENABLE_TESTS_TRUE@module_dummy_la_SOURCES = \ @@ -506,7 +521,7 @@ EXTRA_DIST = eina_bench.h \ all: all-am .SUFFIXES: -.SUFFIXES: .c .cc .lo .o .obj +.SUFFIXES: .c .cc .cxx .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -633,6 +648,9 @@ clean-checkPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list +cxx_compile_test$(EXEEXT): $(cxx_compile_test_OBJECTS) $(cxx_compile_test_DEPENDENCIES) + @rm -f cxx_compile_test$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(cxx_compile_test_OBJECTS) $(cxx_compile_test_LDADD) $(LIBS) eina_bench$(EXEEXT): $(eina_bench_OBJECTS) $(eina_bench_DEPENDENCIES) @rm -f eina_bench$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(eina_bench_OBJECTS) $(eina_bench_LDADD) $(LIBS) @@ -647,6 +665,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/city.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cxx_compile_test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_hash.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecore_list.Po@am__quote@ @@ -675,6 +694,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eina_test_file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eina_test_fp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eina_test_hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eina_test_inarray.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eina_test_inlist.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eina_test_iterator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eina_test_lalloc.Po@am__quote@ @@ -696,6 +716,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eina_test_tiler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eina_test_ustr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eina_test_ustringshare.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eina_test_value.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evas_hash.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evas_list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evas_mempool.Po@am__quote@ @@ -759,6 +780,30 @@ module_dummy_la-eina_test_module_dummy.lo: eina_test_module_dummy.c @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< +.cxx.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cxx.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cxx.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + mostlyclean-libtool: -rm -f *.lo diff --git a/libraries/eina/src/tests/cxx_compile_test.cxx b/libraries/eina/src/tests/cxx_compile_test.cxx new file mode 100644 index 0000000..7d8af76 --- /dev/null +++ b/libraries/eina/src/tests/cxx_compile_test.cxx @@ -0,0 +1,34 @@ +/* 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 . + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "Eina.h" + +#include +using namespace std; + +int main() +{ + eina_init(); + cout << "Eina compiles with C++!"; + eina_shutdown(); + return 0; +} diff --git a/libraries/eina/src/tests/eina_bench.c b/libraries/eina/src/tests/eina_bench.c index a4eadbe..03aaaf9 100644 --- a/libraries/eina/src/tests/eina_bench.c +++ b/libraries/eina/src/tests/eina_bench.c @@ -73,7 +73,6 @@ int main(int argc, char **argv) { Eina_Benchmark *test; - Eina_Array *ea; unsigned int i; if (argc != 2) @@ -91,7 +90,7 @@ main(int argc, char **argv) etc[i].build(test); - ea = eina_benchmark_run(test); + eina_benchmark_run(test); eina_benchmark_free(test); } diff --git a/libraries/eina/src/tests/eina_bench_hash.c b/libraries/eina/src/tests/eina_bench_hash.c index 5b42318..0429097 100644 --- a/libraries/eina/src/tests/eina_bench_hash.c +++ b/libraries/eina/src/tests/eina_bench_hash.c @@ -139,6 +139,8 @@ eina_bench_lookup_rbtree(int request) EINA_RBTREE_CMP_KEY_CB( _eina_bench_rbtree_key), NULL); + /* Suppress warnings as we really don't want to do anything. */ + (void) tmp; } eina_rbtree_delete(root, EINA_RBTREE_FREE_CB(_eina_bench_rbtree_free), NULL); diff --git a/libraries/eina/src/tests/eina_bench_quad.c b/libraries/eina/src/tests/eina_bench_quad.c index 76d6667..8401fd4 100644 --- a/libraries/eina/src/tests/eina_bench_quad.c +++ b/libraries/eina/src/tests/eina_bench_quad.c @@ -19,6 +19,8 @@ #define WIDTH 720 #define HEIGHT 576 +#include + #include "eina_main.h" #include "eina_mempool.h" #include "eina_rectangle.h" diff --git a/libraries/eina/src/tests/eina_bench_stringshare.c b/libraries/eina/src/tests/eina_bench_stringshare.c index a2c7b38..22d18fa 100644 --- a/libraries/eina/src/tests/eina_bench_stringshare.c +++ b/libraries/eina/src/tests/eina_bench_stringshare.c @@ -64,6 +64,8 @@ eina_bench_stringshare_job(int request) tmp = eina_stringshare_add(build); } + /* Suppress warnings as we really don't want to do anything. */ + (void) tmp; eina_shutdown(); } @@ -125,6 +127,9 @@ eina_bench_evas_job(int request) eina_convert_xtoa(rand() % request, build + 7); tmp = evas_stringshare_add(build); } + + /* Suppress warnings as we really don't want to do anything. */ + (void) tmp; } static void @@ -155,6 +160,9 @@ eina_bench_ecore_job(int request) tmp = ecore_string_instance(build); } + /* Suppress warnings as we really don't want to do anything. */ + (void) tmp; + ecore_string_shutdown(); } diff --git a/libraries/eina/src/tests/eina_suite.c b/libraries/eina/src/tests/eina_suite.c index 9b748fc..648a717 100644 --- a/libraries/eina/src/tests/eina_suite.c +++ b/libraries/eina/src/tests/eina_suite.c @@ -34,6 +34,7 @@ struct _Eina_Test_Case static const Eina_Test_Case etc[] = { { "FixedPoint", eina_test_fp }, + { "Inarray", eina_test_inarray }, { "Array", eina_test_array }, { "Binary Share", eina_test_binshare }, { "String Share", eina_test_stringshare }, @@ -66,6 +67,7 @@ static const Eina_Test_Case etc[] = { { "QuadTree", eina_test_quadtree }, { "Sched", eina_test_sched }, { "Simple Xml Parser", eina_test_simple_xml_parser}, + { "Value", eina_test_value }, { NULL, NULL } }; diff --git a/libraries/eina/src/tests/eina_suite.h b/libraries/eina/src/tests/eina_suite.h index 643d6cc..6eaaec7 100644 --- a/libraries/eina/src/tests/eina_suite.h +++ b/libraries/eina/src/tests/eina_suite.h @@ -24,6 +24,7 @@ void eina_test_stringshare(TCase *tc); void eina_test_ustringshare(TCase *tc); void eina_test_binshare(TCase *tc); +void eina_test_inarray(TCase *tc); void eina_test_array(TCase *tc); void eina_test_log(TCase *tc); void eina_test_error(TCase *tc); @@ -54,5 +55,6 @@ void eina_test_quadtree(TCase *tc); void eina_test_fp(TCase *tc); void eina_test_sched(TCase *tc); void eina_test_simple_xml_parser(TCase *tc); +void eina_test_value(TCase *tc); #endif /* EINA_SUITE_H_ */ diff --git a/libraries/eina/src/tests/eina_test_array.c b/libraries/eina/src/tests/eina_test_array.c index 0b054ea..1929601 100644 --- a/libraries/eina/src/tests/eina_test_array.c +++ b/libraries/eina/src/tests/eina_test_array.c @@ -151,7 +151,7 @@ START_TEST(eina_array_remove_stuff) } fail_if(eina_array_remove(ea, keep_int, NULL) != EINA_TRUE); - fail_if(eina_array_count_get(ea) != 990); + fail_if(eina_array_count(ea) != 990); EINA_ARRAY_ITER_NEXT(ea, i, tmp, it) fail_if(*tmp == 0); @@ -165,7 +165,7 @@ START_TEST(eina_array_remove_stuff) eina_array_remove(ea, keep_int, NULL); // Remove all items - fail_if(eina_array_count_get(ea) != 980); + fail_if(eina_array_count(ea) != 980); EINA_ARRAY_ITER_NEXT(ea, i, tmp, it) { fail_if(*tmp == 0); @@ -174,7 +174,7 @@ START_TEST(eina_array_remove_stuff) eina_array_remove(ea, keep_int, NULL); - fail_if(eina_array_count_get(ea) != 0); + fail_if(eina_array_count(ea) != 0); eina_array_free(ea); diff --git a/libraries/eina/src/tests/eina_test_binbuf.c b/libraries/eina/src/tests/eina_test_binbuf.c index 713e078..d62072e 100644 --- a/libraries/eina/src/tests/eina_test_binbuf.c +++ b/libraries/eina/src/tests/eina_test_binbuf.c @@ -27,8 +27,8 @@ START_TEST(binbuf_simple) { Eina_Binbuf *buf; - char *txt; - const char cbuf[] = "Null in the middle \0 and more text afterwards and \0 anotehr null just there and another one \0 here."; + unsigned char *txt; + const unsigned char cbuf[] = "Null in the middle \0 and more text afterwards and \0 anotehr null just there and another one \0 here."; size_t size = sizeof(cbuf) - 1; /* We don't care about the real NULL */ @@ -69,7 +69,7 @@ END_TEST START_TEST(binbuf_remove) { Eina_Binbuf *buf; - const char cbuf[] = "12\0 456 78\0 abcthis is some more random junk here!"; + const unsigned char cbuf[] = "12\0 456 78\0 abcthis is some more random junk here!"; size_t size = sizeof(cbuf) - 1; /* We don't care about the real NULL */ eina_init(); @@ -98,6 +98,33 @@ START_TEST(binbuf_remove) } END_TEST +START_TEST(binbuf_manage_simple) +{ + Eina_Binbuf *buf; + const char *_cbuf = "12\0 456 78\0 abcthis is some more random junk here!"; + const unsigned char *cbuf = (const unsigned char *) _cbuf; + size_t size = sizeof(cbuf) - 1; /* We don't care about the real NULL */ + unsigned char *alloc_buf = malloc(size); + memcpy(alloc_buf, cbuf, size); + + eina_init(); + + buf = eina_binbuf_manage_new_length(alloc_buf, size); + fail_if(!buf); + + fail_if(memcmp(eina_binbuf_string_get(buf), cbuf, size)); + fail_if(size != eina_binbuf_length_get(buf)); + eina_binbuf_append_length(buf, cbuf, size); + fail_if(memcmp(eina_binbuf_string_get(buf), cbuf, size)); + fail_if(memcmp(eina_binbuf_string_get(buf) + size, cbuf, size)); + fail_if(2 * size != eina_binbuf_length_get(buf)); + + eina_binbuf_free(buf); + + eina_shutdown(); +} +END_TEST + START_TEST(binbuf_insert) { #if 0 @@ -154,7 +181,7 @@ END_TEST START_TEST(binbuf_realloc) { Eina_Binbuf *buf; - char pattern[1024 * 16]; + unsigned char pattern[1024 * 16]; unsigned int i; size_t sz; @@ -232,4 +259,5 @@ eina_test_binbuf(TCase *tc) tcase_add_test(tc, binbuf_remove); tcase_add_test(tc, binbuf_insert); tcase_add_test(tc, binbuf_realloc); + tcase_add_test(tc, binbuf_manage_simple); } diff --git a/libraries/eina/src/tests/eina_test_file.c b/libraries/eina/src/tests/eina_test_file.c index aeb5461..55e9976 100644 --- a/libraries/eina/src/tests/eina_test_file.c +++ b/libraries/eina/src/tests/eina_test_file.c @@ -48,7 +48,7 @@ START_TEST(eina_file_split_simple) #endif fail_if(!ea); - fail_if(eina_array_count_get(ea) != 5); + fail_if(eina_array_count(ea) != 5); fail_if(strcmp(eina_array_data_get(ea, 0), "this")); fail_if(strcmp(eina_array_data_get(ea, 1), "is")); fail_if(strcmp(eina_array_data_get(ea, 2), "a")); @@ -66,7 +66,7 @@ START_TEST(eina_file_split_simple) #endif fail_if(!ea); - fail_if(eina_array_count_get(ea) != 6); + fail_if(eina_array_count(ea) != 6); fail_if(strcmp(eina_array_data_get(ea, 0), "this")); fail_if(strcmp(eina_array_data_get(ea, 1), "is")); fail_if(strcmp(eina_array_data_get(ea, 2), "a ")); diff --git a/libraries/eina/src/tests/eina_test_inarray.c b/libraries/eina/src/tests/eina_test_inarray.c new file mode 100644 index 0000000..22ba763 --- /dev/null +++ b/libraries/eina/src/tests/eina_test_inarray.c @@ -0,0 +1,401 @@ +/* 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 . + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "eina_suite.h" +#include "Eina.h" + +START_TEST(eina_inarray_test_simple) +{ + const int test_members = 5; + Eina_Inarray *array; + int i, pos, *member; + const struct spec { + int pos, value; + } *s, specs[] = { + {test_members, 1234}, + {5, 0x1337}, + {0, 0xbeef}, + {-1, -1} + }; + + eina_init(); + + array = eina_inarray_new(sizeof(int), 2); + fail_unless(array != NULL); + + for (i = 0; i < test_members; i++) + { + pos = eina_inarray_append(array, &i); + fail_unless(pos == i); + } + fail_unless(eina_inarray_count(array) == (unsigned)test_members); + + for (i = 0; i < test_members; i++) + { + member = eina_inarray_nth(array, i); + fail_unless(*member == i); + } + + for (s = specs; s->pos >= 0; s++) + { + fail_unless(eina_inarray_insert_at(array, s->pos, &s->value)); + + for (i = 0; i < s->pos; i++) + { + member = eina_inarray_nth(array, i); + fail_unless(*member == i); + } + member = eina_inarray_nth(array, s->pos); + fail_unless(*member == s->value); + for (i = s->pos + 1; i < test_members + 1; i++) + { + member = eina_inarray_nth(array, i); + fail_unless(*member == i - 1); + } + + fail_unless(eina_inarray_remove_at(array, s->pos)); + for (i = 0; i < test_members; i++) + { + member = eina_inarray_nth(array, i); + fail_unless(*member == i); + } + } + + eina_inarray_free(array); + eina_shutdown(); +} +END_TEST + + +START_TEST(eina_inarray_test_alloc_at) +{ + Eina_Inarray *array; + int *member; + int i; + + eina_init(); + + array = eina_inarray_new(sizeof(int), 2); + fail_unless(array != NULL); + + member = eina_inarray_alloc_at(array, 0, 4); + fail_unless(member != NULL); + fail_unless(eina_inarray_count(array) == 4); + + for (i = 0; i < 4; i++) + member[i] = i + 2; + + member = eina_inarray_alloc_at(array, 0, 2); + fail_unless(member != NULL); + fail_unless(eina_inarray_count(array) == 6); + for (i = 0; i < 2; i++) + member[i] = i; + + member = eina_inarray_alloc_at(array, 6, 2); + fail_unless(member != NULL); + fail_unless(eina_inarray_count(array) == 8); + for (i = 0; i < 2; i++) + member[i] = i + 6; + + member = array->members; + for (i = 0; i < 8; i++) + fail_unless(member[i] == i); + + eina_inarray_free(array); + eina_shutdown(); +} +END_TEST + +static const short rand_numbers[] = { + 9, 0, 2, 3, 6, 5, 4, 7, 8, 1, 10 +}; +static const int numbers_count = sizeof(rand_numbers)/sizeof(rand_numbers[0]); + +static void +show_sort_array(const Eina_Inarray *array) +{ + int i, len = eina_inarray_count(array); + printf("array with %d members:\n", len); + for (i = 0; i < len; i++) + { + short *member = eina_inarray_nth(array, i); + printf("\tarray[%2d]=%5hd\n", i, *member); + } +} + +static Eina_Bool +check_short_sorted(const Eina_Inarray *array) +{ + int i; + for (i = 0; i < numbers_count; i++) + { + short *member = eina_inarray_nth(array, i); + if (*member != (short)i) + { + show_sort_array(array); + fprintf(stderr, "not sorted at %d: %hd\n", i, *member); + return EINA_FALSE; + } + } + return EINA_TRUE; +} + +static int +short_cmp(const void *pa, const void *pb) +{ + const short *a = pa, *b = pb; + return *a - *b; +} + +START_TEST(eina_inarray_test_insert_sort) +{ + Eina_Inarray *array; + int i, pos; + + eina_init(); + + array = eina_inarray_new(sizeof(short), 1); + fail_unless(array != NULL); + + /* insert sorted and already sorted sequence */ + for (i = 0; i < numbers_count; i++) + { + short val = i; + pos = eina_inarray_insert(array, &val, short_cmp); + fail_unless(pos == (int)val); + } + fail_unless(check_short_sorted(array)); + eina_inarray_flush(array); + + for (i = 0; i < numbers_count; i++) + { + short val = i; + pos = eina_inarray_insert_sorted(array, &val, short_cmp); + fail_unless(pos == (int)val); + } + fail_unless(check_short_sorted(array)); + eina_inarray_flush(array); + + /* insert sorted the reverse sequence */ + for (i = 0; i < numbers_count; i++) + { + short val = numbers_count - i - 1; + pos = eina_inarray_insert(array, &val, short_cmp); + fail_unless(pos == 0); + } + fail_unless(check_short_sorted(array)); + eina_inarray_flush(array); + + for (i = 0; i < numbers_count; i++) + { + short val = numbers_count - i - 1; + pos = eina_inarray_insert_sorted(array, &val, short_cmp); + fail_unless(pos == 0); + } + fail_unless(check_short_sorted(array)); + eina_inarray_flush(array); + + /* insert sorted random numbers */ + for (i = 0; i < numbers_count; i++) + { + short val = rand_numbers[i]; + eina_inarray_insert(array, &val, short_cmp); + } + fail_unless(check_short_sorted(array)); + eina_inarray_flush(array); + + for (i = 0; i < numbers_count; i++) + { + short val = rand_numbers[i]; + eina_inarray_insert_sorted(array, &val, short_cmp); + } + fail_unless(check_short_sorted(array)); + eina_inarray_flush(array); + + eina_inarray_free(array); + eina_shutdown(); +} +END_TEST + +START_TEST(eina_inarray_test_sort) +{ + Eina_Inarray *array; + int i; + + eina_init(); + + array = eina_inarray_new(sizeof(short), 1); + fail_unless(array != NULL); + + for (i = 0; i < numbers_count; i++) + { + short val = rand_numbers[i]; + eina_inarray_append(array, &val); + } + eina_inarray_sort(array, short_cmp); + fail_unless(check_short_sorted(array)); + eina_inarray_free(array); + eina_shutdown(); +} +END_TEST + +START_TEST(eina_inarray_test_reverse) +{ + Eina_Inarray *array; + int i; + + eina_init(); + + array = eina_inarray_new(sizeof(short), 1); + fail_unless(array != NULL); + + for (i = 0; i < numbers_count; i++) + { + short val = i; + eina_inarray_append(array, &val); + } + eina_inarray_reverse(array); + + for (i = 0; i < numbers_count; i++) + { + short *member = eina_inarray_nth(array, i); + fail_unless(*member == (numbers_count - i - 1)); + } + + eina_inarray_free(array); + eina_shutdown(); +} +END_TEST + +static Eina_Bool +array_foreach(const void *array __UNUSED__, void *p, void *user_data __UNUSED__) +{ + short *member = p; + int *i = user_data; + fail_unless(*i == *member); + (*i)++; + return EINA_TRUE; +} + +static Eina_Bool +array_foreach_stop_2nd(const void *array __UNUSED__, void *p, void *user_data __UNUSED__) +{ + short *member = p; + int *i = user_data; + fail_unless(*i == *member); + if (*i == 1) + return EINA_FALSE; + (*i)++; + return EINA_TRUE; +} + +START_TEST(eina_inarray_test_itr) +{ + Eina_Inarray *array; + Eina_Iterator *it; + Eina_Accessor *ac; + short *member; + int i; + + eina_init(); + + array = eina_inarray_new(sizeof(short), 1); + fail_unless(array != NULL); + + for (i = 0; i < numbers_count; i++) + { + short val = i; + eina_inarray_append(array, &val); + } + i = 0; + EINA_INARRAY_FOREACH(array, member) + { + fail_unless(*member == i); + i++; + } + fail_unless(i == numbers_count); + + i--; + EINA_INARRAY_REVERSE_FOREACH(array, member) + { + fail_unless(*member == i); + i--; + } + fail_unless(i == -1); + + i = 0; + fail_unless(eina_inarray_foreach(array, array_foreach, &i)); + fail_unless(i == numbers_count); + + i = 0; + fail_if(eina_inarray_foreach(array, array_foreach_stop_2nd, &i)); + fail_unless(i == 1); + + it = eina_inarray_iterator_new(array); + fail_unless(it != NULL); + i = 0; + EINA_ITERATOR_FOREACH(it, member) + { + fail_unless(*member == i); + i++; + } + fail_unless(i == numbers_count); + eina_iterator_free(it); + + it = eina_inarray_iterator_reversed_new(array); + fail_unless(it != NULL); + i--; + EINA_ITERATOR_FOREACH(it, member) + { + fail_unless(*member == i); + i--; + } + fail_unless(i == -1); + eina_iterator_free(it); + + ac = eina_inarray_accessor_new(array); + fail_unless(ac != NULL); + for (i = 0; i < numbers_count; i++) + { + fail_unless(eina_accessor_data_get(ac, i, (void **)&member)); + fail_unless(*member == i); + } + fail_unless(i == numbers_count); + eina_accessor_free(ac); + + eina_inarray_free(array); + eina_shutdown(); +} +END_TEST + +void +eina_test_inarray(TCase *tc) +{ + tcase_add_test(tc, eina_inarray_test_simple); + tcase_add_test(tc, eina_inarray_test_alloc_at); + tcase_add_test(tc, eina_inarray_test_insert_sort); + tcase_add_test(tc, eina_inarray_test_sort); + tcase_add_test(tc, eina_inarray_test_reverse); + tcase_add_test(tc, eina_inarray_test_itr); +} diff --git a/libraries/eina/src/tests/eina_test_value.c b/libraries/eina/src/tests/eina_test_value.c new file mode 100644 index 0000000..2d04c2f --- /dev/null +++ b/libraries/eina/src/tests/eina_test_value.c @@ -0,0 +1,1799 @@ +/* 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 . + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "eina_suite.h" +#include "Eina.h" + +#define FP_ERR (0.0000001) +#define CHECK_FP(a, b) ((a - b) < FP_ERR) + +START_TEST(eina_value_test_simple) +{ + Eina_Value *value; + char c; + short s; + int i; + long l; + int64_t i64; + unsigned char uc; + unsigned short us; + unsigned int ui; + unsigned long ul; + uint64_t u64; + float f; + double d; + + eina_init(); + + value = eina_value_new(EINA_VALUE_TYPE_CHAR); + fail_unless(value != NULL); + fail_unless(eina_value_set(value, 'x')); + fail_unless(eina_value_get(value, &c)); + fail_unless(c == 'x'); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_SHORT)); + fail_unless(eina_value_set(value, 300)); + fail_unless(eina_value_get(value, &s)); + fail_unless(s == 300); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_INT)); + fail_unless(eina_value_set(value, -12345)); + fail_unless(eina_value_get(value, &i)); + fail_unless(i == -12345); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_LONG)); + fail_unless(eina_value_set(value, 0xb33f)); + fail_unless(eina_value_get(value, &l)); + fail_unless(l == 0xb33f); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_INT64)); + fail_unless(eina_value_set(value, 0x0011223344556677)); + fail_unless(eina_value_get(value, &i64)); + fail_unless(i64 == 0x0011223344556677); + eina_value_flush(value); + + /* unsigned: */ + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UCHAR)); + fail_unless(eina_value_set(value, 200)); + fail_unless(eina_value_get(value, &uc)); + fail_unless(uc == 200); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_USHORT)); + fail_unless(eina_value_set(value, 65535)); + fail_unless(eina_value_get(value, &us)); + fail_unless(us == 65535); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UINT)); + fail_unless(eina_value_set(value, 4000000000U)); + fail_unless(eina_value_get(value, &ui)); + fail_unless(ui == 4000000000U); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_ULONG)); + fail_unless(eina_value_set(value, 3000000001U)); + fail_unless(eina_value_get(value, &ul)); + fail_unless(ul == 3000000001U); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UINT64)); + fail_unless(eina_value_set(value, 0x1122334455667788)); + fail_unless(eina_value_get(value, &u64)); + fail_unless(u64 == 0x1122334455667788); + eina_value_flush(value); + + /* floating point */ + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_FLOAT)); + fail_unless(eina_value_set(value, 0.1234)); + fail_unless(eina_value_get(value, &f)); + fail_unless(CHECK_FP(0.1234, f)); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_DOUBLE)); + fail_unless(eina_value_set(value, 34567.8)); + fail_unless(eina_value_get(value, &d)); + fail_unless(CHECK_FP(34567.8, d)); + eina_value_flush(value); + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + +START_TEST(eina_value_test_compare) +{ + Eina_Value *a, *b; + + eina_init(); + + a = eina_value_new(EINA_VALUE_TYPE_CHAR); + fail_unless(a != NULL); + b = eina_value_new(EINA_VALUE_TYPE_CHAR); + fail_unless(b != NULL); + + fail_unless(eina_value_set(a, 123)); + fail_unless(eina_value_set(b, 123)); + fail_unless(eina_value_compare(a, b) == 0); + fail_unless(eina_value_set(a, -10)); + fail_unless(eina_value_set(b, 123)); + fail_unless(eina_value_compare(a, b) < 0); + fail_unless(eina_value_set(a, 123)); + fail_unless(eina_value_set(b, 10)); + fail_unless(eina_value_compare(a, b) > 0); + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_SHORT)); + fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_SHORT)); + fail_unless(eina_value_set(a, 1230)); + fail_unless(eina_value_set(b, 1230)); + fail_unless(eina_value_compare(a, b) == 0); + fail_unless(eina_value_set(a, -100)); + fail_unless(eina_value_set(b, 1230)); + fail_unless(eina_value_compare(a, b) < 0); + fail_unless(eina_value_set(a, 1230)); + fail_unless(eina_value_set(b, -100)); + fail_unless(eina_value_compare(a, b) > 0); + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_INT)); + fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_INT)); + fail_unless(eina_value_set(a, 300000)); + fail_unless(eina_value_set(b, 300000)); + fail_unless(eina_value_compare(a, b) == 0); + fail_unless(eina_value_set(a, -100)); + fail_unless(eina_value_set(b, 300000)); + fail_unless(eina_value_compare(a, b) < 0); + fail_unless(eina_value_set(a, 300000)); + fail_unless(eina_value_set(b, -100)); + fail_unless(eina_value_compare(a, b) > 0); + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_LONG)); + fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_LONG)); + fail_unless(eina_value_set(a, 300000L)); + fail_unless(eina_value_set(b, 300000L)); + fail_unless(eina_value_compare(a, b) == 0); + fail_unless(eina_value_set(a, -100L)); + fail_unless(eina_value_set(b, 300000L)); + fail_unless(eina_value_compare(a, b) < 0); + fail_unless(eina_value_set(a, 300000L)); + fail_unless(eina_value_set(b, -100L)); + fail_unless(eina_value_compare(a, b) > 0); + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_INT64)); + fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_INT64)); + fail_unless(eina_value_set(a, (int64_t)800000)); + fail_unless(eina_value_set(b, (int64_t)800000)); + fail_unless(eina_value_compare(a, b) == 0); + fail_unless(eina_value_set(a, (int64_t)-100)); + fail_unless(eina_value_set(b, (int64_t)8000000)); + fail_unless(eina_value_compare(a, b) < 0); + fail_unless(eina_value_set(a, (int64_t)8000000)); + fail_unless(eina_value_set(b, (int64_t)-100)); + fail_unless(eina_value_compare(a, b) > 0); + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_UCHAR)); + fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_UCHAR)); + fail_unless(eina_value_set(a, 123)); + fail_unless(eina_value_set(b, 123)); + fail_unless(eina_value_compare(a, b) == 0); + fail_unless(eina_value_set(a, 10)); + fail_unless(eina_value_set(b, 123)); + fail_unless(eina_value_compare(a, b) < 0); + fail_unless(eina_value_set(a, 123)); + fail_unless(eina_value_set(b, 10)); + fail_unless(eina_value_compare(a, b) > 0); + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_USHORT)); + fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_USHORT)); + fail_unless(eina_value_set(a, 1230)); + fail_unless(eina_value_set(b, 1230)); + fail_unless(eina_value_compare(a, b) == 0); + fail_unless(eina_value_set(a, 100)); + fail_unless(eina_value_set(b, 1230)); + fail_unless(eina_value_compare(a, b) < 0); + fail_unless(eina_value_set(a, 1230)); + fail_unless(eina_value_set(b, 100)); + fail_unless(eina_value_compare(a, b) > 0); + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_UINT)); + fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_UINT)); + fail_unless(eina_value_set(a, 300000)); + fail_unless(eina_value_set(b, 300000)); + fail_unless(eina_value_compare(a, b) == 0); + fail_unless(eina_value_set(a, 100)); + fail_unless(eina_value_set(b, 300000)); + fail_unless(eina_value_compare(a, b) < 0); + fail_unless(eina_value_set(a, 300000)); + fail_unless(eina_value_set(b, 100)); + fail_unless(eina_value_compare(a, b) > 0); + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_ULONG)); + fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_ULONG)); + fail_unless(eina_value_set(a, 300000UL)); + fail_unless(eina_value_set(b, 300000UL)); + fail_unless(eina_value_compare(a, b) == 0); + fail_unless(eina_value_set(a, 100UL)); + fail_unless(eina_value_set(b, 300000UL)); + fail_unless(eina_value_compare(a, b) < 0); + fail_unless(eina_value_set(a, 300000UL)); + fail_unless(eina_value_set(b, 100UL)); + fail_unless(eina_value_compare(a, b) > 0); + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_UINT64)); + fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_UINT64)); + fail_unless(eina_value_set(a, (uint64_t)8000000)); + fail_unless(eina_value_set(b, (uint64_t)8000000)); + fail_unless(eina_value_compare(a, b) == 0); + fail_unless(eina_value_set(a, (uint64_t)100)); + fail_unless(eina_value_set(b, (uint64_t)8000000)); + fail_unless(eina_value_compare(a, b) < 0); + fail_unless(eina_value_set(a, (uint64_t)8000000)); + fail_unless(eina_value_set(b, (uint64_t)100)); + fail_unless(eina_value_compare(a, b) > 0); + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_setup(a, EINA_VALUE_TYPE_STRING)); + fail_unless(eina_value_setup(b, EINA_VALUE_TYPE_STRING)); + fail_unless(eina_value_set(a, "aaa")); + fail_unless(eina_value_set(b, "aaa")); + fail_unless(eina_value_compare(a, b) == 0); + fail_unless(eina_value_set(a, "abc")); + fail_unless(eina_value_set(b, "acd")); + fail_unless(eina_value_compare(a, b) < 0); + fail_unless(eina_value_set(a, "acd")); + fail_unless(eina_value_set(b, "abc")); + fail_unless(eina_value_compare(a, b) > 0); + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_array_setup(a, EINA_VALUE_TYPE_CHAR, 0)); + fail_unless(eina_value_array_setup(b, EINA_VALUE_TYPE_CHAR, 0)); + fail_unless(eina_value_compare(a, b) == 0); + + fail_unless(eina_value_array_append(a, 1)); + fail_unless(eina_value_array_append(a, 2)); + fail_unless(eina_value_array_append(a, 3)); + + fail_unless(eina_value_array_append(b, 1)); + fail_unless(eina_value_array_append(b, 2)); + fail_unless(eina_value_array_append(b, 3)); + + fail_unless(eina_value_compare(a, b) == 0); + + fail_unless(eina_value_array_set(a, 0, 0)); + fail_unless(eina_value_compare(a, b) < 0); + + fail_unless(eina_value_array_set(a, 0, 10)); + fail_unless(eina_value_compare(a, b) > 0); + + fail_unless(eina_value_array_set(a, 0, 1)); + + fail_unless(eina_value_array_set(b, 0, 0)); + fail_unless(eina_value_compare(a, b) > 0); + + fail_unless(eina_value_array_set(b, 0, 10)); + fail_unless(eina_value_compare(a, b) < 0); + + fail_unless(eina_value_array_set(b, 0, 1)); + fail_unless(eina_value_compare(a, b) == 0); + + /* bigger arrays are greater */ + fail_unless(eina_value_array_append(b, 0)); + fail_unless(eina_value_compare(a, b) < 0); + + fail_unless(eina_value_array_append(a, 0)); + fail_unless(eina_value_array_append(a, 0)); + fail_unless(eina_value_compare(a, b) > 0); + + /* bigger arrays are greater, unless an element says otherwise */ + fail_unless(eina_value_array_set(b, 0, 10)); + fail_unless(eina_value_compare(a, b) < 0); + + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_list_setup(a, EINA_VALUE_TYPE_CHAR)); + fail_unless(eina_value_list_setup(b, EINA_VALUE_TYPE_CHAR)); + fail_unless(eina_value_compare(a, b) == 0); + + fail_unless(eina_value_list_append(a, 1)); + fail_unless(eina_value_list_append(a, 2)); + fail_unless(eina_value_list_append(a, 3)); + + fail_unless(eina_value_list_append(b, 1)); + fail_unless(eina_value_list_append(b, 2)); + fail_unless(eina_value_list_append(b, 3)); + + fail_unless(eina_value_compare(a, b) == 0); + + fail_unless(eina_value_list_set(a, 0, 0)); + fail_unless(eina_value_compare(a, b) < 0); + + fail_unless(eina_value_list_set(a, 0, 10)); + fail_unless(eina_value_compare(a, b) > 0); + + fail_unless(eina_value_list_set(a, 0, 1)); + + fail_unless(eina_value_list_set(b, 0, 0)); + fail_unless(eina_value_compare(a, b) > 0); + + fail_unless(eina_value_list_set(b, 0, 10)); + fail_unless(eina_value_compare(a, b) < 0); + + fail_unless(eina_value_list_set(b, 0, 1)); + fail_unless(eina_value_compare(a, b) == 0); + + /* bigger lists are greater */ + fail_unless(eina_value_list_append(b, 0)); + fail_unless(eina_value_compare(a, b) < 0); + + fail_unless(eina_value_list_append(a, 0)); + fail_unless(eina_value_list_append(a, 0)); + fail_unless(eina_value_compare(a, b) > 0); + + /* bigger lists are greater, unless an element says otherwise */ + fail_unless(eina_value_list_set(b, 0, 10)); + fail_unless(eina_value_compare(a, b) < 0); + + eina_value_flush(a); + eina_value_flush(b); + + fail_unless(eina_value_hash_setup(a, EINA_VALUE_TYPE_CHAR, 0)); + fail_unless(eina_value_hash_setup(b, EINA_VALUE_TYPE_CHAR, 0)); + fail_unless(eina_value_compare(a, b) == 0); + + fail_unless(eina_value_hash_set(a, "abc", 1)); + fail_unless(eina_value_hash_set(a, "xyz", 2)); + fail_unless(eina_value_hash_set(a, "hello", 3)); + + fail_unless(eina_value_hash_set(b, "abc", 1)); + fail_unless(eina_value_hash_set(b, "xyz", 2)); + fail_unless(eina_value_hash_set(b, "hello", 3)); + + fail_unless(eina_value_compare(a, b) == 0); + + fail_unless(eina_value_hash_set(a, "abc", 0)); + fail_unless(eina_value_compare(a, b) < 0); + + fail_unless(eina_value_hash_set(a, "abc", 10)); + fail_unless(eina_value_compare(a, b) > 0); + + fail_unless(eina_value_hash_set(a, "abc", 1)); + + fail_unless(eina_value_hash_set(b, "abc", 0)); + fail_unless(eina_value_compare(a, b) > 0); + + fail_unless(eina_value_hash_set(b, "abc", 10)); + fail_unless(eina_value_compare(a, b) < 0); + + fail_unless(eina_value_hash_set(b, "abc", 1)); + fail_unless(eina_value_compare(a, b) == 0); + + /* bigger hashs are greater */ + fail_unless(eina_value_hash_set(b,"newkey", 0)); + fail_unless(eina_value_compare(a, b) < 0); + + fail_unless(eina_value_hash_set(a, "newkey", 0)); + fail_unless(eina_value_hash_set(a, "onemorenewkey", 0)); + fail_unless(eina_value_compare(a, b) > 0); + + /* bigger hashs are greater, unless an element says otherwise */ + fail_unless(eina_value_hash_set(b, "abc", 10)); + fail_unless(eina_value_compare(a, b) < 0); + + eina_value_free(a); + eina_value_free(b); + eina_shutdown(); +} +END_TEST + +START_TEST(eina_value_test_string) +{ + Eina_Value *value; + const char *s; + + eina_init(); + + value = eina_value_new(EINA_VALUE_TYPE_STRING); + fail_unless(value != NULL); + fail_unless(eina_value_set(value, "hello world!")); + fail_unless(eina_value_get(value, &s)); + fail_unless(strcmp(s, "hello world!") == 0); + + fail_unless(eina_value_set(value, "eina-value")); + fail_unless(eina_value_get(value, &s)); + fail_unless(strcmp(s, "eina-value") == 0); + + eina_value_flush(value); + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_STRING)); + + fail_unless(eina_value_set(value, "profusion")); + fail_unless(eina_value_get(value, &s)); + fail_unless(strcmp(s, "profusion") == 0); + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + +START_TEST(eina_value_test_pvariant) +{ + Eina_Value *value; + char c, in_c; + short s, in_s; + int i, in_i; + long l, in_l; + int64_t i64, in_i64; + unsigned char uc, in_uc; + unsigned short us, in_us; + unsigned int ui, in_ui; + unsigned long ul, in_ul; + uint64_t u64, in_u64; + float f, in_f; + double d, in_d; + const char *str, *in_str; + + eina_init(); + + value = eina_value_new(EINA_VALUE_TYPE_CHAR); + fail_unless(value != NULL); + in_c = 'x'; + fail_unless(eina_value_pset(value, &in_c)); + fail_unless(eina_value_pget(value, &c)); + fail_unless(c == 'x'); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_SHORT)); + in_s = 300; + fail_unless(eina_value_pset(value, &in_s)); + fail_unless(eina_value_pget(value, &s)); + fail_unless(s == 300); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_INT)); + in_i = -12345; + fail_unless(eina_value_pset(value, &in_i)); + fail_unless(eina_value_pget(value, &i)); + fail_unless(i == -12345); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_LONG)); + in_l = 0xb33f; + fail_unless(eina_value_pset(value, &in_l)); + fail_unless(eina_value_pget(value, &l)); + fail_unless(l == 0xb33f); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_INT64)); + in_i64 = 0x0011223344556677; + fail_unless(eina_value_pset(value, &in_i64)); + fail_unless(eina_value_pget(value, &i64)); + fail_unless(i64 == 0x0011223344556677); + eina_value_flush(value); + + /* unsigned: */ + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UCHAR)); + in_uc = 200; + fail_unless(eina_value_pset(value, &in_uc)); + fail_unless(eina_value_pget(value, &uc)); + fail_unless(uc == 200); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_USHORT)); + in_us = 65535; + fail_unless(eina_value_pset(value, &in_us)); + fail_unless(eina_value_pget(value, &us)); + fail_unless(us == 65535); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UINT)); + in_ui = 4000000000U; + fail_unless(eina_value_pset(value, &in_ui)); + fail_unless(eina_value_pget(value, &ui)); + fail_unless(ui == 4000000000U); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_ULONG)); + in_ul = 3000000001U; + fail_unless(eina_value_pset(value, &in_ul)); + fail_unless(eina_value_pget(value, &ul)); + fail_unless(ul == 3000000001U); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UINT64)); + in_u64 = 0x1122334455667788; + fail_unless(eina_value_pset(value, &in_u64)); + fail_unless(eina_value_pget(value, &u64)); + fail_unless(u64 == 0x1122334455667788); + eina_value_flush(value); + + /* floating point */ + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_FLOAT)); + in_f = 0.1234; + fail_unless(eina_value_pset(value, &in_f)); + fail_unless(eina_value_pget(value, &f)); + fail_unless(CHECK_FP(0.1234, f)); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_DOUBLE)); + in_d = 34567.8; + fail_unless(eina_value_pset(value, &in_d)); + fail_unless(eina_value_pget(value, &d)); + fail_unless(CHECK_FP(34567.8, d)); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_STRING)); + in_str = "hello world!"; + fail_unless(eina_value_pset(value, &in_str)); + fail_unless(eina_value_pget(value, &str)); + fail_unless(strcmp(str, "hello world!") == 0); + + in_str = "eina-value"; + fail_unless(eina_value_pset(value, &in_str)); + fail_unless(eina_value_pget(value, &str)); + fail_unless(strcmp(str, "eina-value") == 0); + + eina_value_flush(value); + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_STRING)); + + in_str = "profusion"; + fail_unless(eina_value_pset(value, &in_str)); + fail_unless(eina_value_pget(value, &str)); + fail_unless(strcmp(str, "profusion") == 0); + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + +START_TEST(eina_value_test_to_string) +{ + Eina_Value *value; + char c, in_c; + short s, in_s; + int i, in_i; + long l, in_l; + int64_t i64, in_i64; + unsigned char uc, in_uc; + unsigned short us, in_us; + unsigned int ui, in_ui; + unsigned long ul, in_ul; + uint64_t u64, in_u64; + float f, in_f; + double d, in_d; + const char *str, *in_str; + char *out; + char buf[256]; + + eina_init(); + + value = eina_value_new(EINA_VALUE_TYPE_CHAR); + fail_unless(value != NULL); + in_c = 'x'; + fail_unless(eina_value_pset(value, &in_c)); + fail_unless(eina_value_pget(value, &c)); + fail_unless(c == 'x'); + snprintf(buf, sizeof(buf), "%hhd", in_c); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(buf, out) == 0); + free(out); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_SHORT)); + in_s = 300; + fail_unless(eina_value_pset(value, &in_s)); + fail_unless(eina_value_pget(value, &s)); + fail_unless(s == 300); + snprintf(buf, sizeof(buf), "%hd", in_s); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(buf, out) == 0); + free(out); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_INT)); + in_i = -12345; + fail_unless(eina_value_pset(value, &in_i)); + fail_unless(eina_value_pget(value, &i)); + fail_unless(i == -12345); + snprintf(buf, sizeof(buf), "%d", in_i); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(buf, out) == 0); + free(out); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_LONG)); + in_l = 0xb33f; + fail_unless(eina_value_pset(value, &in_l)); + fail_unless(eina_value_pget(value, &l)); + fail_unless(l == 0xb33f); + snprintf(buf, sizeof(buf), "%ld", in_l); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(buf, out) == 0); + free(out); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_INT64)); + in_i64 = 0x0011223344556677; + fail_unless(eina_value_pset(value, &in_i64)); + fail_unless(eina_value_pget(value, &i64)); + fail_unless(i64 == 0x0011223344556677); + snprintf(buf, sizeof(buf), "%"PRId64, in_i64); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(buf, out) == 0); + free(out); + eina_value_flush(value); + + /* unsigned: */ + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UCHAR)); + in_uc = 200; + fail_unless(eina_value_pset(value, &in_uc)); + fail_unless(eina_value_pget(value, &uc)); + fail_unless(uc == 200); + snprintf(buf, sizeof(buf), "%hhu", in_uc); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(buf, out) == 0); + free(out); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_USHORT)); + in_us = 65535; + fail_unless(eina_value_pset(value, &in_us)); + fail_unless(eina_value_pget(value, &us)); + fail_unless(us == 65535); + snprintf(buf, sizeof(buf), "%hu", in_us); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(buf, out) == 0); + free(out); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UINT)); + in_ui = 4000000000U; + fail_unless(eina_value_pset(value, &in_ui)); + fail_unless(eina_value_pget(value, &ui)); + fail_unless(ui == 4000000000U); + snprintf(buf, sizeof(buf), "%u", in_ui); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(buf, out) == 0); + free(out); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_ULONG)); + in_ul = 3000000001U; + fail_unless(eina_value_pset(value, &in_ul)); + fail_unless(eina_value_pget(value, &ul)); + fail_unless(ul == 3000000001U); + snprintf(buf, sizeof(buf), "%lu", in_ul); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(buf, out) == 0); + free(out); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_UINT64)); + in_u64 = 0x1122334455667788; + fail_unless(eina_value_pset(value, &in_u64)); + fail_unless(eina_value_pget(value, &u64)); + fail_unless(u64 == 0x1122334455667788); + snprintf(buf, sizeof(buf), "%"PRIu64, in_u64); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(buf, out) == 0); + free(out); + eina_value_flush(value); + + /* floating point */ + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_FLOAT)); + in_f = 0.1234; + fail_unless(eina_value_pset(value, &in_f)); + fail_unless(eina_value_pget(value, &f)); + fail_unless(CHECK_FP(0.1234, f)); + snprintf(buf, sizeof(buf), "%g", in_f); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strncmp(buf, out, 6) == 0); /* stupid float... */ + free(out); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_DOUBLE)); + in_d = 34567.8; + fail_unless(eina_value_pset(value, &in_d)); + fail_unless(eina_value_pget(value, &d)); + fail_unless(CHECK_FP(34567.8, d)); + snprintf(buf, sizeof(buf), "%g", in_d); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strncmp(buf, out, 7) == 0); /* stupid double... */ + free(out); + eina_value_flush(value); + + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_STRING)); + in_str = "hello world!"; + fail_unless(eina_value_pset(value, &in_str)); + fail_unless(eina_value_pget(value, &str)); + fail_unless(strcmp(str, "hello world!") == 0); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(in_str, out) == 0); + free(out); + + in_str = "eina-value"; + fail_unless(eina_value_pset(value, &in_str)); + fail_unless(eina_value_pget(value, &str)); + fail_unless(strcmp(str, "eina-value") == 0); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(in_str, out) == 0); + free(out); + + eina_value_flush(value); + fail_unless(eina_value_setup(value, EINA_VALUE_TYPE_STRING)); + + in_str = "profusion"; + fail_unless(eina_value_pset(value, &in_str)); + fail_unless(eina_value_pget(value, &str)); + fail_unless(strcmp(str, "profusion") == 0); + out = eina_value_to_string(value); + fail_unless(out != NULL); + fail_unless(strcmp(in_str, out) == 0); + free(out); + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + +START_TEST(eina_value_test_convert_char) +{ + Eina_Value *value, conv; + char c; + short s; + int i; + long l; + int64_t i64; + unsigned char uc; + unsigned short us; + unsigned int ui; + unsigned long ul; + uint64_t u64; + float f; + double d; + const char *str; + + eina_init(); + + value = eina_value_new(EINA_VALUE_TYPE_CHAR); + fail_unless(value != NULL); + + fail_unless(eina_value_set(value, 123)); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UCHAR)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &uc)); + fail_unless(uc == 123); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_USHORT)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &us)); + fail_unless(us == 123); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UINT)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &ui)); + fail_unless(ui == 123); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_ULONG)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &ul)); + fail_unless(ul == 123); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UINT64)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &u64)); + fail_unless(u64 == 123); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_CHAR)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &c)); + fail_unless(c == 123); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_SHORT)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &s)); + fail_unless(s == 123); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_INT)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &i)); + fail_unless(i == 123); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_LONG)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &l)); + fail_unless(l == 123); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_INT64)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &i64)); + fail_unless(i64 == 123); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_FLOAT)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &f)); + fail_unless(CHECK_FP(f, 123)); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_DOUBLE)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &d)); + fail_unless(CHECK_FP(d, 123)); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_STRING)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &str)); + fail_unless(str != NULL); + fail_unless(strcmp(str, "123") == 0); + eina_value_flush(&conv); + + /* negative tests */ + fail_unless(eina_value_set(value, -123)); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UCHAR)); + fail_if(eina_value_convert(value, &conv)); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_USHORT)); + fail_if(eina_value_convert(value, &conv)); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UINT)); + fail_if(eina_value_convert(value, &conv)); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_ULONG)); + fail_if(eina_value_convert(value, &conv)); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UINT64)); + fail_if(eina_value_convert(value, &conv)); + eina_value_flush(&conv); + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + +START_TEST(eina_value_test_convert_uchar) +{ + Eina_Value *value, conv; + char c; + short s; + int i; + long l; + int64_t i64; + unsigned char uc; + unsigned short us; + unsigned int ui; + unsigned long ul; + uint64_t u64; + float f; + double d; + const char *str; + + eina_init(); + + value = eina_value_new(EINA_VALUE_TYPE_UCHAR); + fail_unless(value != NULL); + + fail_unless(eina_value_set(value, 31)); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UCHAR)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &uc)); + fail_unless(uc == 31); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_USHORT)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &us)); + fail_unless(us == 31); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UINT)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &ui)); + fail_unless(ui == 31); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_ULONG)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &ul)); + fail_unless(ul == 31); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_UINT64)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &u64)); + fail_unless(u64 == 31); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_CHAR)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &c)); + fail_unless(c == 31); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_SHORT)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &s)); + fail_unless(s == 31); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_INT)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &i)); + fail_unless(i == 31); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_LONG)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &l)); + fail_unless(l == 31); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_INT64)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &i64)); + fail_unless(i64 == 31); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_FLOAT)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &f)); + fail_unless(CHECK_FP(f, 31)); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_DOUBLE)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &d)); + fail_unless(CHECK_FP(d, 31)); + eina_value_flush(&conv); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_STRING)); + fail_unless(eina_value_convert(value, &conv)); + fail_unless(eina_value_get(&conv, &str)); + fail_unless(str != NULL); + fail_unless(strcmp(str, "31") == 0); + eina_value_flush(&conv); + + /* negative tests */ + fail_unless(eina_value_set(value, 200)); + + fail_unless(eina_value_setup(&conv, EINA_VALUE_TYPE_CHAR)); + fail_if(eina_value_convert(value, &conv)); + eina_value_flush(&conv); + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + + +START_TEST(eina_value_test_array) +{ + Eina_Value *value, other; + Eina_Value_Array desc; + Eina_Inarray *inarray; + char c; + char buf[1024]; + char *str; + + eina_init(); + + value = eina_value_array_new(EINA_VALUE_TYPE_CHAR, 0); + fail_unless(value != NULL); + + fail_unless(eina_value_array_append(value, 'k')); + fail_unless(eina_value_array_append(value, '-')); + fail_unless(eina_value_array_append(value, 's')); + + fail_unless(eina_value_array_get(value, 0, &c)); + fail_unless(c == 'k'); + fail_unless(eina_value_array_get(value, 1, &c)); + fail_unless(c == '-'); + fail_unless(eina_value_array_get(value, 2, &c)); + fail_unless(c == 's'); + + fail_unless(eina_value_array_insert(value, 0, '!')); + fail_unless(eina_value_array_get(value, 0, &c)); + fail_unless(c == '!'); + fail_unless(eina_value_array_get(value, 1, &c)); + fail_unless(c == 'k'); + fail_unless(eina_value_array_get(value, 2, &c)); + fail_unless(c == '-'); + fail_unless(eina_value_array_get(value, 3, &c)); + fail_unless(c == 's'); + + fail_unless(eina_value_array_set(value, 0, '*')); + fail_unless(eina_value_array_get(value, 0, &c)); + fail_unless(c == '*'); + fail_unless(eina_value_array_get(value, 1, &c)); + fail_unless(c == 'k'); + fail_unless(eina_value_array_get(value, 2, &c)); + fail_unless(c == '-'); + fail_unless(eina_value_array_get(value, 3, &c)); + fail_unless(c == 's'); + + snprintf(buf, sizeof(buf), "[%hhd, %hhd, %hhd, %hhd]", + '*', 'k', '-', 's'); + + str = eina_value_to_string(value); + fail_unless(str != NULL); + fail_unless(strcmp(str, buf) == 0); + free(str); + + eina_value_flush(value); + fail_unless(eina_value_array_setup(value, EINA_VALUE_TYPE_STRINGSHARE, 2)); + + fail_unless(eina_value_array_append(value, "Enlightenment.org")); + fail_unless(eina_value_array_append(value, "X11")); + fail_unless(eina_value_array_append(value, "Pants")); + fail_unless(eina_value_array_append(value, "on!!!")); + fail_unless(eina_value_array_append(value, "k-s")); + + str = eina_value_to_string(value); + fail_unless(str != NULL); + fail_unless(strcmp(str, "[Enlightenment.org, X11, Pants, on!!!, k-s]") == 0); + free(str); + + eina_value_flush(value); + fail_unless(eina_value_array_setup(value, EINA_VALUE_TYPE_CHAR, 0)); + fail_unless(eina_value_setup(&other, EINA_VALUE_TYPE_CHAR)); + + fail_unless(eina_value_set(&other, 100)); + fail_unless(eina_value_get(&other, &c)); + fail_unless(c == 100); + + fail_unless(eina_value_convert(&other, value)); + str = eina_value_to_string(value); + fail_unless(str != NULL); + fail_unless(strcmp(str, "[100]") == 0); + free(str); + + fail_unless(eina_value_array_set(value, 0, 33)); + fail_unless(eina_value_convert(value, &other)); + fail_unless(eina_value_get(&other, &c)); + fail_unless(c == 33); + + inarray = eina_inarray_new(sizeof(char), 0); + fail_unless(inarray != NULL); + c = 11; + fail_unless(eina_inarray_append(inarray, &c) >= 0); + c = 21; + fail_unless(eina_inarray_append(inarray, &c) >= 0); + c = 31; + fail_unless(eina_inarray_append(inarray, &c) >= 0); + desc.subtype = EINA_VALUE_TYPE_CHAR; + desc.step = 0; + desc.array = inarray; /* will be adopted and freed by value */ + fail_unless(eina_value_set(value, desc)); /* manually configure */ + fail_unless(eina_value_array_get(value, 0, &c)); + fail_unless(c == 11); + fail_unless(eina_value_array_get(value, 1, &c)); + fail_unless(c == 21); + fail_unless(eina_value_array_get(value, 2, &c)); + fail_unless(c == 31); + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + +START_TEST(eina_value_test_list) +{ + Eina_Value *value, other; + Eina_Value_List desc; + char c; + char buf[1024]; + char *str; + const char *s; + + eina_init(); + + value = eina_value_list_new(EINA_VALUE_TYPE_CHAR); + fail_unless(value != NULL); + + fail_unless(eina_value_list_append(value, 'k')); + fail_unless(eina_value_list_append(value, '-')); + fail_unless(eina_value_list_append(value, 's')); + + fail_unless(eina_value_list_get(value, 0, &c)); + fail_unless(c == 'k'); + fail_unless(eina_value_list_get(value, 1, &c)); + fail_unless(c == '-'); + fail_unless(eina_value_list_get(value, 2, &c)); + fail_unless(c == 's'); + + fail_unless(eina_value_list_insert(value, 0, '!')); + fail_unless(eina_value_list_get(value, 0, &c)); + fail_unless(c == '!'); + fail_unless(eina_value_list_get(value, 1, &c)); + fail_unless(c == 'k'); + fail_unless(eina_value_list_get(value, 2, &c)); + fail_unless(c == '-'); + fail_unless(eina_value_list_get(value, 3, &c)); + fail_unless(c == 's'); + + fail_unless(eina_value_list_set(value, 0, '*')); + fail_unless(eina_value_list_get(value, 0, &c)); + fail_unless(c == '*'); + fail_unless(eina_value_list_get(value, 1, &c)); + fail_unless(c == 'k'); + fail_unless(eina_value_list_get(value, 2, &c)); + fail_unless(c == '-'); + fail_unless(eina_value_list_get(value, 3, &c)); + fail_unless(c == 's'); + + snprintf(buf, sizeof(buf), "[%hhd, %hhd, %hhd, %hhd]", + '*', 'k', '-', 's'); + + str = eina_value_to_string(value); + fail_unless(str != NULL); + fail_unless(strcmp(str, buf) == 0); + free(str); + + eina_value_flush(value); + fail_unless(eina_value_list_setup(value, EINA_VALUE_TYPE_STRINGSHARE)); + + fail_unless(eina_value_list_append(value, "Enlightenment.org")); + fail_unless(eina_value_list_append(value, "X11")); + fail_unless(eina_value_list_append(value, "Pants")); + fail_unless(eina_value_list_append(value, "on!!!")); + fail_unless(eina_value_list_append(value, "k-s")); + + str = eina_value_to_string(value); + fail_unless(str != NULL); + fail_unless(strcmp(str, "[Enlightenment.org, X11, Pants, on!!!, k-s]") == 0); + free(str); + + eina_value_flush(value); + fail_unless(eina_value_list_setup(value, EINA_VALUE_TYPE_CHAR)); + fail_unless(eina_value_setup(&other, EINA_VALUE_TYPE_CHAR)); + + fail_unless(eina_value_set(&other, 100)); + fail_unless(eina_value_get(&other, &c)); + fail_unless(c == 100); + + fail_unless(eina_value_convert(&other, value)); + str = eina_value_to_string(value); + fail_unless(str != NULL); + fail_unless(strcmp(str, "[100]") == 0); + free(str); + + fail_unless(eina_value_list_set(value, 0, 33)); + fail_unless(eina_value_convert(value, &other)); + fail_unless(eina_value_get(&other, &c)); + fail_unless(c == 33); + + desc.subtype = EINA_VALUE_TYPE_STRING; + desc.list = NULL; + desc.list = eina_list_append(desc.list, strdup("hello")); + desc.list = eina_list_append(desc.list, strdup("world")); + desc.list = eina_list_append(desc.list, strdup("eina")); + fail_unless(eina_list_count(desc.list) == 3); + fail_unless(eina_value_set(value, desc)); + fail_unless(eina_value_list_get(value, 0, &s)); + fail_unless(s != NULL); + fail_unless(strcmp(s, "hello") == 0); + fail_unless(eina_value_list_get(value, 1, &s)); + fail_unless(s != NULL); + fail_unless(strcmp(s, "world") == 0); + fail_unless(eina_value_list_get(value, 2, &s)); + fail_unless(s != NULL); + fail_unless(strcmp(s, "eina") == 0); + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + +START_TEST(eina_value_test_hash) +{ + Eina_Value *value, other; + Eina_Value_Hash desc; + char c; + char buf[1024]; + char **ptr; + char *str; + const char *s; + + eina_init(); + + value = eina_value_hash_new(EINA_VALUE_TYPE_CHAR, 0); + fail_unless(value != NULL); + + fail_unless(eina_value_hash_set(value, "first", 'k')); + fail_unless(eina_value_hash_set(value, "second", '-')); + fail_unless(eina_value_hash_set(value, "third", 's')); + + fail_unless(eina_value_hash_get(value, "first", &c)); + fail_unless(c == 'k'); + fail_unless(eina_value_hash_get(value, "second", &c)); + fail_unless(c == '-'); + fail_unless(eina_value_hash_get(value, "third", &c)); + fail_unless(c == 's'); + + fail_unless(eina_value_hash_set(value, "first", '!')); + fail_unless(eina_value_hash_get(value, "first", &c)); + fail_unless(c == '!'); + fail_unless(eina_value_hash_get(value, "second", &c)); + fail_unless(c == '-'); + fail_unless(eina_value_hash_get(value, "third", &c)); + fail_unless(c == 's'); + + puts("testing hash to string -- may fail due hash algorithm changes!"); + + /* watchout, this is the order I got -- hash algorithm changes may change + * the order! + */ + snprintf(buf, sizeof(buf), "{first: %hhd, second: %hhd, third: %hhd}", + '!', '-', 's'); + + str = eina_value_to_string(value); + fail_unless(str != NULL); + printf("want: %s\n", buf); + printf("got.: %s\n", str); + fail_unless(strcmp(str, buf) == 0); + free(str); + + eina_value_flush(value); + fail_unless(eina_value_hash_setup(value, EINA_VALUE_TYPE_STRINGSHARE, 0)); + + fail_unless(eina_value_hash_set(value, "a", "Enlightenment.org")); + fail_unless(eina_value_hash_set(value, "b", "X11")); + fail_unless(eina_value_hash_set(value, "c", "Pants")); + fail_unless(eina_value_hash_set(value, "d", "on!!!")); + fail_unless(eina_value_hash_set(value, "e", "k-s")); + + /* watchout, this is the order I got -- hash algorithm changes may change + * the order! + */ + strcpy(buf, "{e: k-s, d: on!!!, a: Enlightenment.org, b: X11, c: Pants}"); + + str = eina_value_to_string(value); + fail_unless(str != NULL); + printf("want: %s\n", buf); + printf("got.: %s\n", str); + fail_unless(strcmp(str, buf) == 0); + free(str); + + eina_value_flush(value); + fail_unless(eina_value_hash_setup(value, EINA_VALUE_TYPE_CHAR, 0)); + fail_unless(eina_value_setup(&other, EINA_VALUE_TYPE_CHAR)); + + fail_unless(eina_value_set(&other, 100)); + fail_unless(eina_value_get(&other, &c)); + fail_unless(c == 100); + + fail_unless(eina_value_hash_set(value, "first", 33)); + fail_unless(eina_value_convert(value, &other)); + fail_unless(eina_value_get(&other, &c)); + fail_unless(c == 33); + + desc.subtype = EINA_VALUE_TYPE_STRING; + desc.buckets_power_size = 0; + desc.hash = eina_hash_string_small_new(NULL); + fail_unless(desc.hash != NULL); + /* watch out hash pointer is to a size of subtype->value_size! */ + ptr = malloc(sizeof(char *)); + *ptr = strdup("there"); + fail_unless(eina_hash_add(desc.hash, "hi", ptr)); + ptr = malloc(sizeof(char *)); + *ptr = strdup("y"); + fail_unless(eina_hash_add(desc.hash, "x", ptr)); + + fail_unless(eina_value_set(value, desc)); + + fail_unless(eina_value_hash_get(value, "hi", &s)); + fail_unless(s != NULL); + fail_unless(strcmp(s, "there") == 0); + + fail_unless(eina_value_hash_get(value, "x", &s)); + fail_unless(s != NULL); + fail_unless(strcmp(s, "y") == 0); + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + + +START_TEST(eina_value_test_timeval) +{ + Eina_Value *value, other; + struct timeval itv, otv; + char c; + char *str; + + eina_init(); + + value = eina_value_new(EINA_VALUE_TYPE_TIMEVAL); + fail_unless(value != NULL); + + itv.tv_sec = 1; + itv.tv_usec = 123; + fail_unless(eina_value_set(value, itv)); + fail_unless(eina_value_get(value, &otv)); + fail_unless(memcmp(&itv, &otv, sizeof(struct timeval)) == 0); + + itv.tv_sec = 3; + itv.tv_usec = -1; + fail_unless(eina_value_set(value, itv)); + fail_unless(eina_value_get(value, &otv)); + itv.tv_sec = 2; + itv.tv_usec = 999999; + fail_unless(memcmp(&itv, &otv, sizeof(struct timeval)) == 0); + + fail_unless(eina_value_setup(&other, EINA_VALUE_TYPE_CHAR)); + fail_unless(eina_value_convert(value, &other)); + fail_unless(eina_value_get(&other, &c)); + fail_unless(c == 2); + eina_value_flush(&other); + + itv.tv_sec = 12345; + itv.tv_usec = 6789; + fail_unless(eina_value_set(value, itv)); + str = eina_value_to_string(value); + fail_unless(str != NULL); + fail_unless(strcmp(str, "12345.006789") == 0); + free(str); + + fail_unless(eina_value_setup(&other, EINA_VALUE_TYPE_TIMEVAL)); + fail_unless(eina_value_set(&other, itv)); + fail_unless(eina_value_compare(value, &other) == 0); + + itv.tv_sec++; + fail_unless(eina_value_set(&other, itv)); + fail_unless(eina_value_compare(value, &other) < 0); + + itv.tv_sec -= 2; + fail_unless(eina_value_set(&other, itv)); + fail_unless(eina_value_compare(value, &other) > 0); + + itv.tv_sec++; + fail_unless(eina_value_set(&other, itv)); + fail_unless(eina_value_compare(value, &other) == 0); + + itv.tv_usec++; + fail_unless(eina_value_set(&other, itv)); + fail_unless(eina_value_compare(value, &other) < 0); + + itv.tv_usec -= 2; + fail_unless(eina_value_set(&other, itv)); + fail_unless(eina_value_compare(value, &other) > 0); + + itv.tv_usec++; + fail_unless(eina_value_set(&other, itv)); + fail_unless(eina_value_compare(value, &other) == 0); + + eina_value_flush(&other); + + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + + +START_TEST(eina_value_test_blob) +{ + Eina_Value *value, other; + Eina_Value_Blob in, out; + unsigned char blob[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + int i = 0x11223344; + char *str; + + eina_init(); + + value = eina_value_new(EINA_VALUE_TYPE_BLOB); + fail_unless(value != NULL); + + in.ops = NULL; + in.memory = blob; + in.size = sizeof(blob); + fail_unless(eina_value_set(value, in)); + fail_unless(eina_value_get(value, &out)); + fail_unless(out.memory == blob); + fail_unless(out.size == sizeof(blob)); + fail_unless(memcmp(&in, &out, sizeof(Eina_Value_Blob)) == 0); + + str = eina_value_to_string(value); + fail_unless(str != NULL); + fail_unless(strcmp(str, "BLOB(10, [01 02 03 04 05 06 07 08 09 0a])") == 0); + free(str); + + fail_unless(eina_value_setup(&other, EINA_VALUE_TYPE_INT)); + fail_unless(eina_value_set(&other, i)); + fail_unless(eina_value_convert(&other, value)); + fail_unless(eina_value_get(value, &out)); + + fail_unless(out.memory != NULL); + fail_unless(out.size == sizeof(int)); + fail_unless(memcmp(&i, out.memory, sizeof(int)) == 0); + + eina_value_flush(&other); + + fail_unless(eina_value_setup(&other, EINA_VALUE_TYPE_STRING)); + fail_unless(eina_value_set(&other, "hi there!")); + fail_unless(eina_value_convert(&other, value)); + fail_unless(eina_value_get(value, &out)); + fail_unless(out.memory != NULL); + fail_unless(out.size == sizeof("hi there!")); + fail_unless(strcmp(out.memory, "hi there!") == 0); + + str = eina_value_to_string(value); + fail_unless(str != NULL); + fail_unless(strcmp(str, "BLOB(10, [68 69 20 74 68 65 72 65 21 00])") == 0); + free(str); + + eina_value_flush(&other); + + fail_unless(eina_value_array_setup(&other, EINA_VALUE_TYPE_CHAR, 0)); + fail_unless(eina_value_array_append(&other, 0xa)); + fail_unless(eina_value_array_append(&other, 0xb)); + fail_unless(eina_value_array_append(&other, 0xc)); + fail_unless(eina_value_convert(&other, value)); + fail_unless(eina_value_get(value, &out)); + fail_unless(out.memory != NULL); + fail_unless(out.size == 3); + + str = eina_value_to_string(value); + fail_unless(str != NULL); + fail_unless(strcmp(str, "BLOB(3, [0a 0b 0c])") == 0); + free(str); + + eina_value_flush(&other); + + fail_unless(eina_value_setup(&other, EINA_VALUE_TYPE_BLOB)); + fail_unless(eina_value_set(&other, in)); + fail_unless(eina_value_convert(value, &other)); + fail_unless(eina_value_get(&other, &out)); + fail_unless(out.memory != NULL); + fail_unless(out.size == 3); + + str = eina_value_to_string(&other); + fail_unless(str != NULL); + fail_unless(strcmp(str, "BLOB(3, [0a 0b 0c])") == 0); + free(str); + + eina_value_flush(&other); + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + + +START_TEST(eina_value_test_struct) +{ + struct mybigst { + int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, x; + }; + const Eina_Value_Struct_Member mybigst_members[] = { + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, a), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, b), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, c), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, d), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, e), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, f), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, g), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, h), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, i), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, j), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, k), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, l), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, m), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, n), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, o), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, p), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, q), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, r), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, s), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, t), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, u), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, v), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct mybigst, x), + EINA_VALUE_STRUCT_MEMBER_SENTINEL + }; + const Eina_Value_Struct_Desc mybigst_desc = { + EINA_VALUE_STRUCT_DESC_VERSION, + EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH, + mybigst_members, 23, sizeof(struct mybigst) + }; + 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, other; + int i; + char c; + char *str; + + eina_init(); + + value = eina_value_struct_new(&myst_desc); + fail_unless(value != NULL); + + fail_unless(eina_value_struct_set(value, "i", 5678)); + fail_unless(eina_value_struct_set(value, "c", 0xf)); + + fail_unless(eina_value_struct_get(value, "i", &i)); + fail_unless(i == 5678); + fail_unless(eina_value_struct_get(value, "c", &c)); + fail_unless(c == 0xf); + + str = eina_value_to_string(value); + fail_unless(str != NULL); + fail_unless(strcmp(str, "{i: 5678, c: 15}") == 0); + free(str); + + fail_if(eina_value_struct_get(value, "x", 1234)); + + i = 0x11223344; + fail_unless(eina_value_struct_pset(value, "i", &i)); + i = -1; + fail_unless(eina_value_struct_pget(value, "i", &i)); + fail_unless(i == 0x11223344); + + fail_unless(eina_value_copy(value, &other)); + str = eina_value_to_string(&other); + fail_unless(str != NULL); + fail_unless(strcmp(str, "{i: 287454020, c: 15}") == 0); + free(str); + + eina_value_flush(&other); + + fail_unless(eina_value_struct_setup(&other, &mybigst_desc)); + fail_unless(eina_value_struct_set(&other, "a", 1) ); + fail_unless(eina_value_struct_set(&other, "b", 2)); + fail_unless(eina_value_struct_set(&other, "c", 3)); + fail_unless(eina_value_struct_set(&other, "d", 4)); + fail_unless(eina_value_struct_set(&other, "e", 5)); + fail_unless(eina_value_struct_set(&other, "f", 6)); + fail_unless(eina_value_struct_set(&other, "g", 7)); + fail_unless(eina_value_struct_set(&other, "h", 8)); + fail_unless(eina_value_struct_set(&other, "i", 9)); + fail_unless(eina_value_struct_set(&other, "j", 10)); + fail_unless(eina_value_struct_set(&other, "k", 12)); + fail_unless(eina_value_struct_set(&other, "l", 13)); + fail_unless(eina_value_struct_set(&other, "m", 14)); + fail_unless(eina_value_struct_set(&other, "n", 15)); + fail_unless(eina_value_struct_set(&other, "o", 16)); + fail_unless(eina_value_struct_set(&other, "p", 17)); + fail_unless(eina_value_struct_set(&other, "q", 18)); + fail_unless(eina_value_struct_set(&other, "r", 19)); + fail_unless(eina_value_struct_set(&other, "s", 20)); + fail_unless(eina_value_struct_set(&other, "t", 21)); + fail_unless(eina_value_struct_set(&other, "u", 22)); + fail_unless(eina_value_struct_set(&other, "v", 23)); + fail_unless(eina_value_struct_set(&other, "x", 24)); + + fail_unless(eina_value_struct_get(&other, "a", &i)); + fail_unless(i == 1); + fail_unless(eina_value_struct_get(&other, "b", &i)); + fail_unless(i == 2); + fail_unless(eina_value_struct_get(&other, "c", &i)); + fail_unless(i == 3); + fail_unless(eina_value_struct_get(&other, "d", &i)); + fail_unless(i == 4); + fail_unless(eina_value_struct_get(&other, "e", &i)); + fail_unless(i == 5); + fail_unless(eina_value_struct_get(&other, "f", &i)); + fail_unless(i == 6); + fail_unless(eina_value_struct_get(&other, "g", &i)); + fail_unless(i == 7); + fail_unless(eina_value_struct_get(&other, "h", &i)); + fail_unless(i == 8); + fail_unless(eina_value_struct_get(&other, "i", &i)); + fail_unless(i == 9); + fail_unless(eina_value_struct_get(&other, "j", &i)); + fail_unless(i == 10); + fail_unless(eina_value_struct_get(&other, "k", &i)); + fail_unless(i == 12); + fail_unless(eina_value_struct_get(&other, "l", &i)); + fail_unless(i == 13); + fail_unless(eina_value_struct_get(&other, "m", &i)); + fail_unless(i == 14); + fail_unless(eina_value_struct_get(&other, "n", &i)); + fail_unless(i == 15); + fail_unless(eina_value_struct_get(&other, "o", &i)); + fail_unless(i == 16); + fail_unless(eina_value_struct_get(&other, "p", &i)); + fail_unless(i == 17); + fail_unless(eina_value_struct_get(&other, "q", &i)); + fail_unless(i == 18); + fail_unless(eina_value_struct_get(&other, "r", &i)); + fail_unless(i == 19); + fail_unless(eina_value_struct_get(&other, "s", &i)); + fail_unless(i == 20); + fail_unless(eina_value_struct_get(&other, "t", &i)); + fail_unless(i == 21); + fail_unless(eina_value_struct_get(&other, "u", &i)); + fail_unless(i == 22); + fail_unless(eina_value_struct_get(&other, "v", &i)); + fail_unless(i == 23); + fail_unless(eina_value_struct_get(&other, "x", &i)); + fail_unless(i == 24); + + str = eina_value_to_string(&other); + fail_unless(str != NULL); + fail_unless(strcmp(str, "{a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10, k: 12, l: 13, m: 14, n: 15, o: 16, p: 17, q: 18, r: 19, s: 20, t: 21, u: 22, v: 23, x: 24}") == 0); + free(str); + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + + +START_TEST(eina_value_test_array_of_struct) +{ + struct myst { + int a, b, c; + const char *s; + }; + const Eina_Value_Struct_Member myst_members[] = { + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct myst, a), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct myst, b), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_INT, struct myst, c), + EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_STRING, struct myst, s), + EINA_VALUE_STRUCT_MEMBER_SENTINEL + }; + const Eina_Value_Struct_Desc myst_desc = { + EINA_VALUE_STRUCT_DESC_VERSION, + EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH, + myst_members, 4, sizeof(struct myst) + }; + Eina_Value *value; + char *str; + int i; + + eina_init(); + + value = eina_value_array_new(EINA_VALUE_TYPE_STRUCT, 0); + fail_unless(value != NULL); + + for (i = 0; i < 10; i++) + { + Eina_Value_Struct desc; + struct myst *st; + char buf[64]; + + snprintf(buf, sizeof(buf), "item%02d", i); + st = malloc(sizeof(struct myst)); + fail_unless(st != NULL); + st->a = i; + st->b = i * 10; + st->c = i * 100; + st->s = strdup(buf); + fail_unless(st->s != NULL); + + desc.desc = &myst_desc; + desc.memory = st; + fail_unless(eina_value_array_append(value, desc)); + } + + str = eina_value_to_string(value); + fail_unless(str != NULL); + fail_unless(strcmp(str, "[" + "{a: 0, b: 0, c: 0, s: item00}, " + "{a: 1, b: 10, c: 100, s: item01}, " + "{a: 2, b: 20, c: 200, s: item02}, " + "{a: 3, b: 30, c: 300, s: item03}, " + "{a: 4, b: 40, c: 400, s: item04}, " + "{a: 5, b: 50, c: 500, s: item05}, " + "{a: 6, b: 60, c: 600, s: item06}, " + "{a: 7, b: 70, c: 700, s: item07}, " + "{a: 8, b: 80, c: 800, s: item08}, " + "{a: 9, b: 90, c: 900, s: item09}" + "]") == 0); + free(str); + + eina_value_free(value); + eina_shutdown(); +} +END_TEST + +void +eina_test_value(TCase *tc) +{ + tcase_add_test(tc, eina_value_test_simple); + tcase_add_test(tc, eina_value_test_string); + tcase_add_test(tc, eina_value_test_pvariant); + tcase_add_test(tc, eina_value_test_compare); + tcase_add_test(tc, eina_value_test_to_string); + tcase_add_test(tc, eina_value_test_convert_char); + tcase_add_test(tc, eina_value_test_convert_uchar); + // TODO: other converters... + tcase_add_test(tc, eina_value_test_array); + tcase_add_test(tc, eina_value_test_list); + tcase_add_test(tc, eina_value_test_hash); + tcase_add_test(tc, eina_value_test_timeval); + tcase_add_test(tc, eina_value_test_blob); + tcase_add_test(tc, eina_value_test_struct); + tcase_add_test(tc, eina_value_test_array_of_struct); +} diff --git a/libraries/eina/src/tests/evas_list.c b/libraries/eina/src/tests/evas_list.c index 55e301f..3df15ed 100644 --- a/libraries/eina/src/tests/evas_list.c +++ b/libraries/eina/src/tests/evas_list.c @@ -962,7 +962,7 @@ evas_list_sort(Evas_List *list, int size, int (*func)(void *, void *)) Evas_List *last; unsigned int list_number; unsigned int middle; - int list_size; + unsigned int list_size; if (!list || !func) return NULL; diff --git a/libraries/eina/src/tests/evas_mempool.c b/libraries/eina/src/tests/evas_mempool.c index fbc48fa..7098214 100644 --- a/libraries/eina/src/tests/evas_mempool.c +++ b/libraries/eina/src/tests/evas_mempool.c @@ -56,7 +56,7 @@ _evas_mp_pool_free(Pool *p) } void * -evas_mempool_malloc(Evas_Mempool *pool, int size) +evas_mempool_malloc(Evas_Mempool *pool, int size __UNUSED__) { #ifdef NOPOOL return malloc(size); -- cgit v1.1