eina: fix copyright
[profile/ivi/eina.git] / src / lib / eina_value.c
1 /* EINA - EFL data type library
2  * Copyright (C) 2012 ProFUSION embedded systems
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library;
16  * if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22
23 #ifdef HAVE_ALLOCA_H
24 # include <alloca.h>
25 #elif defined __GNUC__
26 # define alloca __builtin_alloca
27 #elif defined _AIX
28 # define alloca __alloca
29 #elif defined _MSC_VER
30 # include <malloc.h>
31 # define alloca _alloca
32 #else
33 # include <stddef.h>
34 # ifdef  __cplusplus
35 extern "C"
36 # endif
37 void *alloca (size_t);
38 #endif
39
40 #include <stdio.h> /* asprintf() */
41 #include <inttypes.h> /* PRId64 and PRIu64 */
42 #include <sys/time.h> /* struct timeval */
43
44 #ifdef HAVE_EVIL
45 # include <Evil.h>
46 #endif
47
48 #include "eina_config.h"
49 #include "eina_private.h"
50 #include "eina_error.h"
51 #include "eina_log.h"
52 #include "eina_strbuf.h"
53 #include "eina_mempool.h"
54 #include "eina_lock.h"
55
56 /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
57 #include "eina_safety_checks.h"
58 #include "eina_value.h"
59 /* no model for now
60 #include "eina_model.h" // uses eina_value.h
61  */
62
63 /*============================================================================*
64 *                                  Local                                     *
65 *============================================================================*/
66
67 /**
68  * @cond LOCAL
69  */
70
71 static Eina_Mempool *_eina_value_mp = NULL;
72 static Eina_Hash *_eina_value_inner_mps = NULL;
73 static Eina_Lock _eina_value_inner_mps_lock;
74 static char *_eina_value_mp_choice = NULL;
75 static int _eina_value_log_dom = -1;
76
77 #ifdef ERR
78 #undef ERR
79 #endif
80 #define ERR(...) EINA_LOG_DOM_ERR(_eina_value_log_dom, __VA_ARGS__)
81
82 #ifdef DBG
83 #undef DBG
84 #endif
85 #define DBG(...) EINA_LOG_DOM_DBG(_eina_value_log_dom, __VA_ARGS__)
86
87 static const unsigned char eina_value_uchar_max = 255U;
88 static const char eina_value_char_max =  127;
89 static const char eina_value_char_min = -127 - 1;
90
91 static const unsigned short eina_value_ushort_max = 65535U;
92 static const short eina_value_short_max =  32767;
93 static const short eina_value_short_min = -32767 - 1;
94
95 static const unsigned int eina_value_uint_max = 4294967295U;
96 static const int eina_value_int_max =  2147483647;
97 static const int eina_value_int_min = -2147483647 - 1;
98
99 static const uint64_t eina_value_uint64_max = 18446744073709551615ULL;
100 static const int64_t eina_value_int64_max =  9223372036854775807LL;
101 static const int64_t eina_value_int64_min = -9223372036854775807LL - 1LL;
102
103 #if __WORDSIZE == 64
104 static const unsigned long eina_value_ulong_max = 18446744073709551615ULL;
105 static const long eina_value_long_max =  9223372036854775807LL;
106 static const long eina_value_long_min = -9223372036854775807LL - 1LL;
107 #else
108 static const unsigned long eina_value_ulong_max = 4294967295U;
109 static const long eina_value_long_max =  2147483647;
110 static const long eina_value_long_min = -2147483647 - 1;
111 #endif
112
113
114 static Eina_Bool
115 _eina_value_type_uchar_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
116 {
117    unsigned char *tmem = mem;
118    *tmem = 0;
119    return EINA_TRUE;
120 }
121
122 static Eina_Bool
123 _eina_value_type_uchar_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
124 {
125    return EINA_TRUE;
126 }
127
128 static Eina_Bool
129 _eina_value_type_uchar_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
130 {
131    const unsigned char *s = src;
132    unsigned char *d = dst;
133    *d = *s;
134    return EINA_TRUE;
135 }
136
137 static int
138 _eina_value_type_uchar_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
139 {
140    const unsigned char *ta = a, *tb = b;
141    if (*ta < *tb)
142      return -1;
143    else if (*ta > *tb)
144      return 1;
145    return 0;
146 }
147
148 static Eina_Bool
149 _eina_value_type_uchar_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
150 {
151    const unsigned char v = *(const unsigned char *)type_mem;
152
153    eina_error_set(0);
154
155    if (convert == EINA_VALUE_TYPE_UCHAR)
156      {
157         unsigned char other_mem = v;
158         return eina_value_type_pset(convert, convert_mem, &other_mem);
159      }
160    else if (convert == EINA_VALUE_TYPE_USHORT)
161      {
162         unsigned short other_mem = v;
163         return eina_value_type_pset(convert, convert_mem, &other_mem);
164      }
165    else if (convert == EINA_VALUE_TYPE_UINT)
166      {
167         unsigned int other_mem = v;
168         return eina_value_type_pset(convert, convert_mem, &other_mem);
169      }
170    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
171      {
172         unsigned long other_mem = v;
173         return eina_value_type_pset(convert, convert_mem, &other_mem);
174      }
175    else if (convert == EINA_VALUE_TYPE_UINT64)
176      {
177         uint64_t other_mem = v;
178         return eina_value_type_pset(convert, convert_mem, &other_mem);
179      }
180    else if (convert == EINA_VALUE_TYPE_CHAR)
181      {
182         char other_mem = v;
183         if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max))
184           return EINA_FALSE;
185         return eina_value_type_pset(convert, convert_mem, &other_mem);
186      }
187    else if (convert == EINA_VALUE_TYPE_SHORT)
188      {
189         short other_mem = v;
190         return eina_value_type_pset(convert, convert_mem, &other_mem);
191      }
192    else if (convert == EINA_VALUE_TYPE_INT)
193      {
194         int other_mem = v;
195         return eina_value_type_pset(convert, convert_mem, &other_mem);
196      }
197    else if (convert == EINA_VALUE_TYPE_LONG)
198      {
199         long other_mem = v;
200         return eina_value_type_pset(convert, convert_mem, &other_mem);
201      }
202    else if (convert == EINA_VALUE_TYPE_INT64)
203      {
204         int64_t other_mem = v;
205         return eina_value_type_pset(convert, convert_mem, &other_mem);
206      }
207    else if (convert == EINA_VALUE_TYPE_FLOAT)
208      {
209         float other_mem = v;
210         return eina_value_type_pset(convert, convert_mem, &other_mem);
211      }
212    else if (convert == EINA_VALUE_TYPE_DOUBLE)
213      {
214         double other_mem = v;
215         return eina_value_type_pset(convert, convert_mem, &other_mem);
216      }
217    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
218             convert == EINA_VALUE_TYPE_STRING)
219      {
220         const char *other_mem;
221         char buf[64];
222         snprintf(buf, sizeof(buf), "%hhu", v);
223         other_mem = buf; /* required due &buf == buf */
224         return eina_value_type_pset(convert, convert_mem, &other_mem);
225      }
226    else
227      {
228         eina_error_set(EINA_ERROR_VALUE_FAILED);
229         return EINA_FALSE;
230      }
231
232    return EINA_TRUE;
233 }
234
235 static Eina_Bool
236 _eina_value_type_uchar_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
237 {
238    unsigned char *tmem = mem;
239    *tmem = va_arg(args, unsigned int); /* char is promoted to int for va_arg */
240    return EINA_TRUE;
241 }
242
243 static Eina_Bool
244 _eina_value_type_uchar_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
245 {
246    unsigned char *tmem = mem;
247    const unsigned char *p = ptr;
248    *tmem = *p;
249    return EINA_TRUE;
250 }
251
252 static Eina_Bool
253 _eina_value_type_uchar_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
254 {
255    const unsigned char *tmem = mem;
256    unsigned char *p = ptr;
257    *p = *tmem;
258    return EINA_TRUE;
259 }
260
261 static Eina_Bool
262 _eina_value_type_ushort_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
263 {
264    unsigned short *tmem = mem;
265    *tmem = 0;
266    return EINA_TRUE;
267 }
268
269 static Eina_Bool
270 _eina_value_type_ushort_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
271 {
272    return EINA_TRUE;
273 }
274
275 static Eina_Bool
276 _eina_value_type_ushort_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
277 {
278    const unsigned short *s = src;
279    unsigned short *d = dst;
280    *d = *s;
281    return EINA_TRUE;
282 }
283
284 static int
285 _eina_value_type_ushort_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
286 {
287    const unsigned short *ta = a, *tb = b;
288    if (*ta < *tb)
289      return -1;
290    else if (*ta > *tb)
291      return 1;
292    return 0;
293 }
294
295 static Eina_Bool
296 _eina_value_type_ushort_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
297 {
298    const unsigned short v = *(const unsigned short *)type_mem;
299
300    eina_error_set(0);
301
302    if (convert == EINA_VALUE_TYPE_UCHAR)
303      {
304         unsigned char other_mem = v;
305         if (EINA_UNLIKELY(v > eina_value_uchar_max))
306             return EINA_FALSE;
307         return eina_value_type_pset(convert, convert_mem, &other_mem);
308      }
309    else if (convert == EINA_VALUE_TYPE_USHORT)
310      {
311         unsigned short other_mem = v;
312         return eina_value_type_pset(convert, convert_mem, &other_mem);
313      }
314    else if (convert == EINA_VALUE_TYPE_UINT)
315      {
316         unsigned int other_mem = v;
317         return eina_value_type_pset(convert, convert_mem, &other_mem);
318      }
319    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
320      {
321         unsigned long other_mem = v;
322         return eina_value_type_pset(convert, convert_mem, &other_mem);
323      }
324    else if (convert == EINA_VALUE_TYPE_UINT64)
325      {
326         uint64_t other_mem = v;
327         return eina_value_type_pset(convert, convert_mem, &other_mem);
328      }
329    else if (convert == EINA_VALUE_TYPE_CHAR)
330      {
331         char other_mem = v;
332         if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max))
333           return EINA_FALSE;
334         return eina_value_type_pset(convert, convert_mem, &other_mem);
335      }
336    else if (convert == EINA_VALUE_TYPE_SHORT)
337      {
338         short other_mem = v;
339         if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max))
340           return EINA_FALSE;
341         return eina_value_type_pset(convert, convert_mem, &other_mem);
342      }
343    else if (convert == EINA_VALUE_TYPE_INT)
344      {
345         int other_mem = v;
346         return eina_value_type_pset(convert, convert_mem, &other_mem);
347      }
348    else if (convert == EINA_VALUE_TYPE_LONG)
349      {
350         long other_mem = v;
351         return eina_value_type_pset(convert, convert_mem, &other_mem);
352      }
353    else if (convert == EINA_VALUE_TYPE_INT64)
354      {
355         int64_t other_mem = v;
356         return eina_value_type_pset(convert, convert_mem, &other_mem);
357      }
358    else if (convert == EINA_VALUE_TYPE_FLOAT)
359      {
360         float other_mem = v;
361         return eina_value_type_pset(convert, convert_mem, &other_mem);
362      }
363    else if (convert == EINA_VALUE_TYPE_DOUBLE)
364      {
365         double other_mem = v;
366         return eina_value_type_pset(convert, convert_mem, &other_mem);
367      }
368    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
369             convert == EINA_VALUE_TYPE_STRING)
370      {
371         const char *other_mem;
372         char buf[64];
373         snprintf(buf, sizeof(buf), "%hu", v);
374         other_mem = buf; /* required due &buf == buf */
375         return eina_value_type_pset(convert, convert_mem, &other_mem);
376      }
377    else
378      {
379         eina_error_set(EINA_ERROR_VALUE_FAILED);
380         return EINA_FALSE;
381      }
382
383    return EINA_TRUE;
384 }
385
386 static Eina_Bool
387 _eina_value_type_ushort_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
388 {
389    unsigned short *tmem = mem;
390    *tmem = va_arg(args, unsigned int); /* short is promoted to int for va_arg */
391    return EINA_TRUE;
392 }
393
394 static Eina_Bool
395 _eina_value_type_ushort_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
396 {
397    unsigned short *tmem = mem;
398    const unsigned short *p = ptr;
399    *tmem = *p;
400    return EINA_TRUE;
401 }
402
403 static Eina_Bool
404 _eina_value_type_ushort_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
405 {
406    const unsigned short *tmem = mem;
407    unsigned short *p = ptr;
408    *p = *tmem;
409    return EINA_TRUE;
410 }
411
412 static Eina_Bool
413 _eina_value_type_uint_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
414 {
415    unsigned int *tmem = mem;
416    *tmem = 0;
417    return EINA_TRUE;
418 }
419
420 static Eina_Bool
421 _eina_value_type_uint_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
422 {
423    return EINA_TRUE;
424 }
425
426 static Eina_Bool
427 _eina_value_type_uint_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
428 {
429    const unsigned int *s = src;
430    unsigned int *d = dst;
431    *d = *s;
432    return EINA_TRUE;
433 }
434
435 static int
436 _eina_value_type_uint_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
437 {
438    const unsigned int *ta = a, *tb = b;
439    if (*ta < *tb)
440      return -1;
441    else if (*ta > *tb)
442      return 1;
443    return 0;
444 }
445
446 static Eina_Bool
447 _eina_value_type_uint_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
448 {
449    const unsigned int v = *(const unsigned int *)type_mem;
450
451    eina_error_set(0);
452
453    if (convert == EINA_VALUE_TYPE_UCHAR)
454      {
455         unsigned char other_mem = v;
456         if (EINA_UNLIKELY(v > eina_value_uchar_max))
457             return EINA_FALSE;
458         return eina_value_type_pset(convert, convert_mem, &other_mem);
459      }
460    else if (convert == EINA_VALUE_TYPE_USHORT)
461      {
462         unsigned short other_mem = v;
463         if (EINA_UNLIKELY(v > eina_value_ushort_max))
464           return EINA_FALSE;
465         return eina_value_type_pset(convert, convert_mem, &other_mem);
466      }
467    else if (convert == EINA_VALUE_TYPE_UINT)
468      {
469         unsigned int other_mem = v;
470         return eina_value_type_pset(convert, convert_mem, &other_mem);
471      }
472    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
473      {
474         unsigned long other_mem = v;
475         return eina_value_type_pset(convert, convert_mem, &other_mem);
476      }
477    else if (convert == EINA_VALUE_TYPE_UINT64)
478      {
479         uint64_t other_mem = v;
480         return eina_value_type_pset(convert, convert_mem, &other_mem);
481      }
482    else if (convert == EINA_VALUE_TYPE_CHAR)
483      {
484         char other_mem = v;
485         if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max))
486           return EINA_FALSE;
487         return eina_value_type_pset(convert, convert_mem, &other_mem);
488      }
489    else if (convert == EINA_VALUE_TYPE_SHORT)
490      {
491         short other_mem = v;
492         if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max))
493           return EINA_FALSE;
494         return eina_value_type_pset(convert, convert_mem, &other_mem);
495      }
496    else if (convert == EINA_VALUE_TYPE_INT)
497      {
498         int other_mem = v;
499         if (EINA_UNLIKELY(v > (unsigned int)eina_value_int_max))
500           return EINA_FALSE;
501         return eina_value_type_pset(convert, convert_mem, &other_mem);
502      }
503    else if (convert == EINA_VALUE_TYPE_LONG)
504      {
505         long other_mem = v;
506         return eina_value_type_pset(convert, convert_mem, &other_mem);
507      }
508    else if (convert == EINA_VALUE_TYPE_INT64)
509      {
510         int64_t other_mem = v;
511         return eina_value_type_pset(convert, convert_mem, &other_mem);
512      }
513    else if (convert == EINA_VALUE_TYPE_FLOAT)
514      {
515         float other_mem = v;
516         return eina_value_type_pset(convert, convert_mem, &other_mem);
517      }
518    else if (convert == EINA_VALUE_TYPE_DOUBLE)
519      {
520         double other_mem = v;
521         return eina_value_type_pset(convert, convert_mem, &other_mem);
522      }
523    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
524             convert == EINA_VALUE_TYPE_STRING)
525      {
526         const char *other_mem;
527         char buf[64];
528         snprintf(buf, sizeof(buf), "%u", v);
529         other_mem = buf; /* required due &buf == buf */
530         return eina_value_type_pset(convert, convert_mem, &other_mem);
531      }
532    else
533      {
534         eina_error_set(EINA_ERROR_VALUE_FAILED);
535         return EINA_FALSE;
536      }
537
538    return EINA_TRUE;
539 }
540
541 static Eina_Bool
542 _eina_value_type_uint_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
543 {
544    unsigned int *tmem = mem;
545    *tmem = va_arg(args, unsigned int);
546    return EINA_TRUE;
547 }
548
549 static Eina_Bool
550 _eina_value_type_uint_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
551 {
552    unsigned int *tmem = mem;
553    const unsigned int *p = ptr;
554    *tmem = *p;
555    return EINA_TRUE;
556 }
557
558 static Eina_Bool
559 _eina_value_type_uint_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
560 {
561    const unsigned int *tmem = mem;
562    unsigned int *p = ptr;
563    *p = *tmem;
564    return EINA_TRUE;
565 }
566
567 static Eina_Bool
568 _eina_value_type_ulong_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
569 {
570    unsigned long *tmem = mem;
571    *tmem = 0;
572    return EINA_TRUE;
573 }
574
575 static Eina_Bool
576 _eina_value_type_ulong_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
577 {
578    return EINA_TRUE;
579 }
580
581 static Eina_Bool
582 _eina_value_type_ulong_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
583 {
584    const unsigned long *s = src;
585    unsigned long *d = dst;
586    *d = *s;
587    return EINA_TRUE;
588 }
589
590 static int
591 _eina_value_type_ulong_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
592 {
593    const unsigned long *ta = a, *tb = b;
594    if (*ta < *tb)
595      return -1;
596    else if (*ta > *tb)
597      return 1;
598    return 0;
599 }
600
601 static Eina_Bool
602 _eina_value_type_ulong_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
603 {
604    const unsigned long v = *(const unsigned long *)type_mem;
605
606    eina_error_set(0);
607
608    if (convert == EINA_VALUE_TYPE_UCHAR)
609      {
610         unsigned char other_mem = v;
611         if (EINA_UNLIKELY(v > eina_value_uchar_max))
612             return EINA_FALSE;
613         return eina_value_type_pset(convert, convert_mem, &other_mem);
614      }
615    else if (convert == EINA_VALUE_TYPE_USHORT)
616      {
617         unsigned short other_mem = v;
618         if (EINA_UNLIKELY(v > eina_value_ushort_max))
619           return EINA_FALSE;
620         return eina_value_type_pset(convert, convert_mem, &other_mem);
621      }
622    else if (convert == EINA_VALUE_TYPE_UINT)
623      {
624         unsigned int other_mem = v;
625         if (EINA_UNLIKELY(v > eina_value_uint_max))
626           return EINA_FALSE;
627         return eina_value_type_pset(convert, convert_mem, &other_mem);
628      }
629    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
630      {
631         unsigned long other_mem = v;
632         return eina_value_type_pset(convert, convert_mem, &other_mem);
633      }
634    else if (convert == EINA_VALUE_TYPE_UINT64)
635      {
636         uint64_t other_mem = v;
637         return eina_value_type_pset(convert, convert_mem, &other_mem);
638      }
639    else if (convert == EINA_VALUE_TYPE_CHAR)
640      {
641         char other_mem = v;
642         if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max))
643           return EINA_FALSE;
644         return eina_value_type_pset(convert, convert_mem, &other_mem);
645      }
646    else if (convert == EINA_VALUE_TYPE_SHORT)
647      {
648         short other_mem = v;
649         if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max))
650           return EINA_FALSE;
651         return eina_value_type_pset(convert, convert_mem, &other_mem);
652      }
653    else if (convert == EINA_VALUE_TYPE_INT)
654      {
655         int other_mem = v;
656         if (EINA_UNLIKELY(v > (unsigned int)eina_value_int_max))
657           return EINA_FALSE;
658         return eina_value_type_pset(convert, convert_mem, &other_mem);
659      }
660    else if (convert == EINA_VALUE_TYPE_LONG)
661      {
662         long other_mem = v;
663         if (EINA_UNLIKELY(v > (unsigned long)eina_value_long_max))
664           return EINA_FALSE;
665         return eina_value_type_pset(convert, convert_mem, &other_mem);
666      }
667    else if (convert == EINA_VALUE_TYPE_INT64)
668      {
669         int64_t other_mem = v;
670         return eina_value_type_pset(convert, convert_mem, &other_mem);
671      }
672    else if (convert == EINA_VALUE_TYPE_FLOAT)
673      {
674         float other_mem = v;
675         return eina_value_type_pset(convert, convert_mem, &other_mem);
676      }
677    else if (convert == EINA_VALUE_TYPE_DOUBLE)
678      {
679         double other_mem = v;
680         return eina_value_type_pset(convert, convert_mem, &other_mem);
681      }
682    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
683             convert == EINA_VALUE_TYPE_STRING)
684      {
685         const char *other_mem;
686         char buf[64];
687         snprintf(buf, sizeof(buf), "%lu", v);
688         other_mem = buf; /* required due &buf == buf */
689         return eina_value_type_pset(convert, convert_mem, &other_mem);
690      }
691    else
692      {
693         eina_error_set(EINA_ERROR_VALUE_FAILED);
694         return EINA_FALSE;
695      }
696
697    return EINA_TRUE;
698 }
699
700 static Eina_Bool
701 _eina_value_type_ulong_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
702 {
703    unsigned long *tmem = mem;
704    *tmem = va_arg(args, unsigned long);
705    return EINA_TRUE;
706 }
707
708 static Eina_Bool
709 _eina_value_type_ulong_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
710 {
711    unsigned long *tmem = mem;
712    const unsigned long *p = ptr;
713    *tmem = *p;
714    return EINA_TRUE;
715 }
716
717 static Eina_Bool
718 _eina_value_type_ulong_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
719 {
720    const unsigned long *tmem = mem;
721    unsigned long *p = ptr;
722    *p = *tmem;
723    return EINA_TRUE;
724 }
725
726 static Eina_Bool
727 _eina_value_type_uint64_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
728 {
729    uint64_t *tmem = mem;
730    *tmem = 0;
731    return EINA_TRUE;
732 }
733
734 static Eina_Bool
735 _eina_value_type_uint64_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
736 {
737    return EINA_TRUE;
738 }
739
740 static Eina_Bool
741 _eina_value_type_uint64_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
742 {
743    const uint64_t *s = src;
744    uint64_t *d = dst;
745    *d = *s;
746    return EINA_TRUE;
747 }
748
749 static int
750 _eina_value_type_uint64_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
751 {
752    const uint64_t *ta = a, *tb = b;
753    if (*ta < *tb)
754      return -1;
755    else if (*ta > *tb)
756      return 1;
757    return 0;
758 }
759
760 static Eina_Bool
761 _eina_value_type_uint64_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
762 {
763    const uint64_t v = *(const uint64_t *)type_mem;
764
765    eina_error_set(0);
766
767    if (convert == EINA_VALUE_TYPE_UCHAR)
768      {
769         unsigned char other_mem = v;
770         if (EINA_UNLIKELY(v > eina_value_uchar_max))
771             return EINA_FALSE;
772         return eina_value_type_pset(convert, convert_mem, &other_mem);
773      }
774    else if (convert == EINA_VALUE_TYPE_USHORT)
775      {
776         unsigned short other_mem = v;
777         if (EINA_UNLIKELY(v > eina_value_ushort_max))
778           return EINA_FALSE;
779         return eina_value_type_pset(convert, convert_mem, &other_mem);
780      }
781    else if (convert == EINA_VALUE_TYPE_UINT)
782      {
783         unsigned int other_mem = v;
784         if (EINA_UNLIKELY(v > eina_value_uint_max))
785           return EINA_FALSE;
786         return eina_value_type_pset(convert, convert_mem, &other_mem);
787      }
788    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
789      {
790         unsigned long other_mem = v;
791         if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) &&
792                           (v > eina_value_ulong_max)))
793           return EINA_FALSE;
794         return eina_value_type_pset(convert, convert_mem, &other_mem);
795      }
796    else if (convert == EINA_VALUE_TYPE_UINT64)
797      {
798         uint64_t other_mem = v;
799         return eina_value_type_pset(convert, convert_mem, &other_mem);
800      }
801    else if (convert == EINA_VALUE_TYPE_CHAR)
802      {
803         char other_mem = v;
804         if (EINA_UNLIKELY(v > (unsigned char)eina_value_char_max))
805           return EINA_FALSE;
806         return eina_value_type_pset(convert, convert_mem, &other_mem);
807      }
808    else if (convert == EINA_VALUE_TYPE_SHORT)
809      {
810         short other_mem = v;
811         if (EINA_UNLIKELY(v > (unsigned short)eina_value_short_max))
812           return EINA_FALSE;
813         return eina_value_type_pset(convert, convert_mem, &other_mem);
814      }
815    else if (convert == EINA_VALUE_TYPE_INT)
816      {
817         int other_mem = v;
818         if (EINA_UNLIKELY(v > (unsigned int)eina_value_int_max))
819           return EINA_FALSE;
820         return eina_value_type_pset(convert, convert_mem, &other_mem);
821      }
822    else if (convert == EINA_VALUE_TYPE_LONG)
823      {
824         long other_mem = v;
825         if (EINA_UNLIKELY(v > (unsigned long)eina_value_long_max))
826           return EINA_FALSE;
827         return eina_value_type_pset(convert, convert_mem, &other_mem);
828      }
829    else if (convert == EINA_VALUE_TYPE_INT64)
830      {
831         int64_t other_mem = v;
832         if (EINA_UNLIKELY(v > (uint64_t)eina_value_int64_max))
833           return EINA_FALSE;
834         return eina_value_type_pset(convert, convert_mem, &other_mem);
835      }
836    else if (convert == EINA_VALUE_TYPE_FLOAT)
837      {
838         float other_mem = v;
839         return eina_value_type_pset(convert, convert_mem, &other_mem);
840      }
841    else if (convert == EINA_VALUE_TYPE_DOUBLE)
842      {
843         double other_mem = v;
844         return eina_value_type_pset(convert, convert_mem, &other_mem);
845      }
846    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
847             convert == EINA_VALUE_TYPE_STRING)
848      {
849         const char *other_mem;
850         char buf[64];
851         snprintf(buf, sizeof(buf), "%"PRIu64, v);
852         other_mem = buf; /* required due &buf == buf */
853         return eina_value_type_pset(convert, convert_mem, &other_mem);
854      }
855    else
856      {
857         eina_error_set(EINA_ERROR_VALUE_FAILED);
858         return EINA_FALSE;
859      }
860
861    return EINA_TRUE;
862 }
863
864 static Eina_Bool
865 _eina_value_type_uint64_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
866 {
867    uint64_t *tmem = mem;
868    *tmem = va_arg(args, uint64_t);
869    return EINA_TRUE;
870 }
871
872 static Eina_Bool
873 _eina_value_type_uint64_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
874 {
875    uint64_t *tmem = mem;
876    const uint64_t *p = ptr;
877    *tmem = *p;
878    return EINA_TRUE;
879 }
880
881 static Eina_Bool
882 _eina_value_type_uint64_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
883 {
884    const uint64_t *tmem = mem;
885    uint64_t *p = ptr;
886    *p = *tmem;
887    return EINA_TRUE;
888 }
889
890 static Eina_Bool
891 _eina_value_type_char_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
892 {
893    char *tmem = mem;
894    *tmem = 0;
895    return EINA_TRUE;
896 }
897
898 static Eina_Bool
899 _eina_value_type_char_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
900 {
901    return EINA_TRUE;
902 }
903
904 static Eina_Bool
905 _eina_value_type_char_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
906 {
907    const char *s = src;
908    char *d = dst;
909    *d = *s;
910    return EINA_TRUE;
911 }
912
913 static int
914 _eina_value_type_char_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
915 {
916    const char *ta = a, *tb = b;
917    if (*ta < *tb)
918      return -1;
919    else if (*ta > *tb)
920      return 1;
921    return 0;
922 }
923
924 static Eina_Bool
925 _eina_value_type_char_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
926 {
927    const signed char v = *(const signed char *)type_mem;
928
929    eina_error_set(0);
930
931    if (convert == EINA_VALUE_TYPE_UCHAR)
932      {
933         unsigned char other_mem = v;
934         if (EINA_UNLIKELY(v < 0))
935           return EINA_FALSE;
936         return eina_value_type_pset(convert, convert_mem, &other_mem);
937      }
938    else if (convert == EINA_VALUE_TYPE_USHORT)
939      {
940         unsigned short other_mem = v;
941         if (EINA_UNLIKELY(v < 0))
942           return EINA_FALSE;
943         return eina_value_type_pset(convert, convert_mem, &other_mem);
944      }
945    else if (convert == EINA_VALUE_TYPE_UINT)
946      {
947         unsigned int other_mem = v;
948         if (EINA_UNLIKELY(v < 0))
949           return EINA_FALSE;
950         return eina_value_type_pset(convert, convert_mem, &other_mem);
951      }
952    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
953      {
954         unsigned long other_mem = v;
955         if (EINA_UNLIKELY(v < 0))
956           return EINA_FALSE;
957         return eina_value_type_pset(convert, convert_mem, &other_mem);
958      }
959    else if (convert == EINA_VALUE_TYPE_UINT64)
960      {
961         uint64_t other_mem = v;
962         if (EINA_UNLIKELY(v < 0))
963           return EINA_FALSE;
964         return eina_value_type_pset(convert, convert_mem, &other_mem);
965      }
966    else if (convert == EINA_VALUE_TYPE_CHAR)
967      {
968         char other_mem = v;
969         return eina_value_type_pset(convert, convert_mem, &other_mem);
970      }
971    else if (convert == EINA_VALUE_TYPE_SHORT)
972      {
973         short other_mem = v;
974         return eina_value_type_pset(convert, convert_mem, &other_mem);
975      }
976    else if (convert == EINA_VALUE_TYPE_INT)
977      {
978         int other_mem = v;
979         return eina_value_type_pset(convert, convert_mem, &other_mem);
980      }
981    else if (convert == EINA_VALUE_TYPE_LONG)
982      {
983         long other_mem = v;
984         return eina_value_type_pset(convert, convert_mem, &other_mem);
985      }
986    else if (convert == EINA_VALUE_TYPE_INT64)
987      {
988         int64_t other_mem = v;
989         return eina_value_type_pset(convert, convert_mem, &other_mem);
990      }
991    else if (convert == EINA_VALUE_TYPE_FLOAT)
992      {
993         float other_mem = v;
994         return eina_value_type_pset(convert, convert_mem, &other_mem);
995      }
996    else if (convert == EINA_VALUE_TYPE_DOUBLE)
997      {
998         double other_mem = v;
999         return eina_value_type_pset(convert, convert_mem, &other_mem);
1000      }
1001    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
1002             convert == EINA_VALUE_TYPE_STRING)
1003      {
1004         const char *other_mem;
1005         char buf[64];
1006         snprintf(buf, sizeof(buf), "%hhd", v);
1007         other_mem = buf; /* required due &buf == buf */
1008         return eina_value_type_pset(convert, convert_mem, &other_mem);
1009      }
1010    else
1011      {
1012         eina_error_set(EINA_ERROR_VALUE_FAILED);
1013         return EINA_FALSE;
1014      }
1015
1016    return EINA_TRUE;
1017 }
1018
1019 static Eina_Bool
1020 _eina_value_type_char_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
1021 {
1022    char *tmem = mem;
1023    *tmem = va_arg(args, int); /* char is promoted to int for va_arg */
1024    return EINA_TRUE;
1025 }
1026
1027 static Eina_Bool
1028 _eina_value_type_char_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
1029 {
1030    char *tmem = mem;
1031    const char *p = ptr;
1032    *tmem = *p;
1033    return EINA_TRUE;
1034 }
1035
1036 static Eina_Bool
1037 _eina_value_type_char_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
1038 {
1039    const char *tmem = mem;
1040    char *p = ptr;
1041    *p = *tmem;
1042    return EINA_TRUE;
1043 }
1044
1045 static Eina_Bool
1046 _eina_value_type_short_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
1047 {
1048    short *tmem = mem;
1049    *tmem = 0;
1050    return EINA_TRUE;
1051 }
1052
1053 static Eina_Bool
1054 _eina_value_type_short_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
1055 {
1056    return EINA_TRUE;
1057 }
1058
1059 static Eina_Bool
1060 _eina_value_type_short_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
1061 {
1062    const short *s = src;
1063    short *d = dst;
1064    *d = *s;
1065    return EINA_TRUE;
1066 }
1067
1068 static int
1069 _eina_value_type_short_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
1070 {
1071    const short *ta = a, *tb = b;
1072    if (*ta < *tb)
1073      return -1;
1074    else if (*ta > *tb)
1075      return 1;
1076    return 0;
1077 }
1078
1079 static Eina_Bool
1080 _eina_value_type_short_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
1081 {
1082    const short v = *(const short *)type_mem;
1083
1084    eina_error_set(0);
1085
1086    if (convert == EINA_VALUE_TYPE_UCHAR)
1087      {
1088         unsigned char other_mem = v;
1089         if (EINA_UNLIKELY(v < 0))
1090           return EINA_FALSE;
1091         if (EINA_UNLIKELY(v > eina_value_uchar_max))
1092             return EINA_FALSE;
1093         return eina_value_type_pset(convert, convert_mem, &other_mem);
1094      }
1095    else if (convert == EINA_VALUE_TYPE_USHORT)
1096      {
1097         unsigned short other_mem = v;
1098         if (EINA_UNLIKELY(v < 0))
1099           return EINA_FALSE;
1100         return eina_value_type_pset(convert, convert_mem, &other_mem);
1101      }
1102    else if (convert == EINA_VALUE_TYPE_UINT)
1103      {
1104         unsigned int other_mem = v;
1105         if (EINA_UNLIKELY(v < 0))
1106           return EINA_FALSE;
1107         return eina_value_type_pset(convert, convert_mem, &other_mem);
1108      }
1109    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
1110      {
1111         unsigned long other_mem = v;
1112         if (EINA_UNLIKELY(v < 0))
1113           return EINA_FALSE;
1114         return eina_value_type_pset(convert, convert_mem, &other_mem);
1115      }
1116    else if (convert == EINA_VALUE_TYPE_UINT64)
1117      {
1118         uint64_t other_mem = v;
1119         if (EINA_UNLIKELY(v < 0))
1120           return EINA_FALSE;
1121         return eina_value_type_pset(convert, convert_mem, &other_mem);
1122      }
1123    else if (convert == EINA_VALUE_TYPE_CHAR)
1124      {
1125         char other_mem = v;
1126         if (EINA_UNLIKELY(v < eina_value_char_min))
1127           return EINA_FALSE;
1128         if (EINA_UNLIKELY(v > eina_value_char_max))
1129           return EINA_FALSE;
1130         return eina_value_type_pset(convert, convert_mem, &other_mem);
1131      }
1132    else if (convert == EINA_VALUE_TYPE_SHORT)
1133      {
1134         short other_mem = v;
1135         return eina_value_type_pset(convert, convert_mem, &other_mem);
1136      }
1137    else if (convert == EINA_VALUE_TYPE_INT)
1138      {
1139         int other_mem = v;
1140         return eina_value_type_pset(convert, convert_mem, &other_mem);
1141      }
1142    else if (convert == EINA_VALUE_TYPE_LONG)
1143      {
1144         long other_mem = v;
1145         return eina_value_type_pset(convert, convert_mem, &other_mem);
1146      }
1147    else if (convert == EINA_VALUE_TYPE_INT64)
1148      {
1149         int64_t other_mem = v;
1150         return eina_value_type_pset(convert, convert_mem, &other_mem);
1151      }
1152    else if (convert == EINA_VALUE_TYPE_FLOAT)
1153      {
1154         float other_mem = v;
1155         return eina_value_type_pset(convert, convert_mem, &other_mem);
1156      }
1157    else if (convert == EINA_VALUE_TYPE_DOUBLE)
1158      {
1159         double other_mem = v;
1160         return eina_value_type_pset(convert, convert_mem, &other_mem);
1161      }
1162    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
1163             convert == EINA_VALUE_TYPE_STRING)
1164      {
1165         const char *other_mem;
1166         char buf[64];
1167         snprintf(buf, sizeof(buf), "%hd", v);
1168         other_mem = buf; /* required due &buf == buf */
1169         return eina_value_type_pset(convert, convert_mem, &other_mem);
1170      }
1171    else
1172      {
1173         eina_error_set(EINA_ERROR_VALUE_FAILED);
1174         return EINA_FALSE;
1175      }
1176
1177    return EINA_TRUE;
1178 }
1179
1180 static Eina_Bool
1181 _eina_value_type_short_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
1182 {
1183    short *tmem = mem;
1184    *tmem = va_arg(args, int); /* short int is promoted to int for va_arg */
1185    return EINA_TRUE;
1186 }
1187
1188 static Eina_Bool
1189 _eina_value_type_short_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
1190 {
1191    short *tmem = mem;
1192    const short *p = ptr;
1193    *tmem = *p;
1194    return EINA_TRUE;
1195 }
1196
1197 static Eina_Bool
1198 _eina_value_type_short_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
1199 {
1200    const short *tmem = mem;
1201    short *p = ptr;
1202    *p = *tmem;
1203    return EINA_TRUE;
1204 }
1205
1206 static Eina_Bool
1207 _eina_value_type_int_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
1208 {
1209    int *tmem = mem;
1210    *tmem = 0;
1211    return EINA_TRUE;
1212 }
1213
1214 static Eina_Bool
1215 _eina_value_type_int_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
1216 {
1217    return EINA_TRUE;
1218 }
1219
1220 static Eina_Bool
1221 _eina_value_type_int_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
1222 {
1223    const int *s = src;
1224    int *d = dst;
1225    *d = *s;
1226    return EINA_TRUE;
1227 }
1228
1229 static int
1230 _eina_value_type_int_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
1231 {
1232    const int *ta = a, *tb = b;
1233    if (*ta < *tb)
1234      return -1;
1235    else if (*ta > *tb)
1236      return 1;
1237    return 0;
1238 }
1239
1240 static Eina_Bool
1241 _eina_value_type_int_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
1242 {
1243    const int v = *(const int *)type_mem;
1244
1245    eina_error_set(0);
1246
1247    if (convert == EINA_VALUE_TYPE_UCHAR)
1248      {
1249         unsigned char other_mem = v;
1250         if (EINA_UNLIKELY(v < 0))
1251           return EINA_FALSE;
1252         if (EINA_UNLIKELY(v > eina_value_uchar_max))
1253             return EINA_FALSE;
1254         return eina_value_type_pset(convert, convert_mem, &other_mem);
1255      }
1256    else if (convert == EINA_VALUE_TYPE_USHORT)
1257      {
1258         unsigned short other_mem = v;
1259         if (EINA_UNLIKELY(v < 0))
1260           return EINA_FALSE;
1261         if (EINA_UNLIKELY(v > eina_value_ushort_max))
1262           return EINA_FALSE;
1263         return eina_value_type_pset(convert, convert_mem, &other_mem);
1264      }
1265    else if (convert == EINA_VALUE_TYPE_UINT)
1266      {
1267         unsigned int other_mem = v;
1268         if (EINA_UNLIKELY(v < 0))
1269           return EINA_FALSE;
1270         return eina_value_type_pset(convert, convert_mem, &other_mem);
1271      }
1272    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
1273      {
1274         unsigned long other_mem = v;
1275         if (EINA_UNLIKELY(v < 0))
1276           return EINA_FALSE;
1277         return eina_value_type_pset(convert, convert_mem, &other_mem);
1278      }
1279    else if (convert == EINA_VALUE_TYPE_UINT64)
1280      {
1281         uint64_t other_mem = v;
1282         if (EINA_UNLIKELY(v < 0))
1283           return EINA_FALSE;
1284         return eina_value_type_pset(convert, convert_mem, &other_mem);
1285      }
1286    else if (convert == EINA_VALUE_TYPE_CHAR)
1287      {
1288         char other_mem = v;
1289         if (EINA_UNLIKELY(v < eina_value_char_min))
1290           return EINA_FALSE;
1291         if (EINA_UNLIKELY(v > eina_value_char_max))
1292           return EINA_FALSE;
1293         return eina_value_type_pset(convert, convert_mem, &other_mem);
1294      }
1295    else if (convert == EINA_VALUE_TYPE_SHORT)
1296      {
1297         short other_mem = v;
1298         if (EINA_UNLIKELY(v < eina_value_short_min))
1299           return EINA_FALSE;
1300         if (EINA_UNLIKELY(v > eina_value_short_max))
1301           return EINA_FALSE;
1302         return eina_value_type_pset(convert, convert_mem, &other_mem);
1303      }
1304    else if (convert == EINA_VALUE_TYPE_INT)
1305      {
1306         int other_mem = v;
1307         return eina_value_type_pset(convert, convert_mem, &other_mem);
1308      }
1309    else if (convert == EINA_VALUE_TYPE_LONG)
1310      {
1311         long other_mem = v;
1312         return eina_value_type_pset(convert, convert_mem, &other_mem);
1313      }
1314    else if (convert == EINA_VALUE_TYPE_INT64)
1315      {
1316         int64_t other_mem = v;
1317         return eina_value_type_pset(convert, convert_mem, &other_mem);
1318      }
1319    else if (convert == EINA_VALUE_TYPE_FLOAT)
1320      {
1321         float other_mem = v;
1322         return eina_value_type_pset(convert, convert_mem, &other_mem);
1323      }
1324    else if (convert == EINA_VALUE_TYPE_DOUBLE)
1325      {
1326         double other_mem = v;
1327         return eina_value_type_pset(convert, convert_mem, &other_mem);
1328      }
1329    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
1330             convert == EINA_VALUE_TYPE_STRING)
1331      {
1332         const char *other_mem;
1333         char buf[64];
1334         snprintf(buf, sizeof(buf), "%d", v);
1335         other_mem = buf; /* required due &buf == buf */
1336         return eina_value_type_pset(convert, convert_mem, &other_mem);
1337      }
1338    else
1339      {
1340         eina_error_set(EINA_ERROR_VALUE_FAILED);
1341         return EINA_FALSE;
1342      }
1343
1344    return EINA_TRUE;
1345 }
1346
1347 static Eina_Bool
1348 _eina_value_type_int_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
1349 {
1350    int *tmem = mem;
1351    *tmem = va_arg(args, int);
1352    return EINA_TRUE;
1353 }
1354
1355 static Eina_Bool
1356 _eina_value_type_int_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
1357 {
1358    int *tmem = mem;
1359    const int *p = ptr;
1360    *tmem = *p;
1361    return EINA_TRUE;
1362 }
1363
1364 static Eina_Bool
1365 _eina_value_type_int_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
1366 {
1367    const int *tmem = mem;
1368    int *p = ptr;
1369    *p = *tmem;
1370    return EINA_TRUE;
1371 }
1372
1373 static Eina_Bool
1374 _eina_value_type_long_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
1375 {
1376    long *tmem = mem;
1377    *tmem = 0;
1378    return EINA_TRUE;
1379 }
1380
1381 static Eina_Bool
1382 _eina_value_type_long_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
1383 {
1384    return EINA_TRUE;
1385 }
1386
1387 static Eina_Bool
1388 _eina_value_type_long_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
1389 {
1390    const long *s = src;
1391    long *d = dst;
1392    *d = *s;
1393    return EINA_TRUE;
1394 }
1395
1396 static int
1397 _eina_value_type_long_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
1398 {
1399    const long *ta = a, *tb = b;
1400    if (*ta < *tb)
1401      return -1;
1402    else if (*ta > *tb)
1403      return 1;
1404    return 0;
1405 }
1406
1407 static Eina_Bool
1408 _eina_value_type_long_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
1409 {
1410    const long v = *(const long *)type_mem;
1411
1412    eina_error_set(0);
1413
1414    if (convert == EINA_VALUE_TYPE_UCHAR)
1415      {
1416         unsigned char other_mem = v;
1417         if (EINA_UNLIKELY(v < 0))
1418           return EINA_FALSE;
1419         if (EINA_UNLIKELY((unsigned long) v > eina_value_uchar_max))
1420             return EINA_FALSE;
1421         return eina_value_type_pset(convert, convert_mem, &other_mem);
1422      }
1423    else if (convert == EINA_VALUE_TYPE_USHORT)
1424      {
1425         unsigned short other_mem = v;
1426         if (EINA_UNLIKELY(v < 0))
1427           return EINA_FALSE;
1428         if (EINA_UNLIKELY((unsigned long) v > eina_value_ushort_max))
1429           return EINA_FALSE;
1430         return eina_value_type_pset(convert, convert_mem, &other_mem);
1431      }
1432    else if (convert == EINA_VALUE_TYPE_UINT)
1433      {
1434         unsigned int other_mem = v;
1435         if (EINA_UNLIKELY(v < 0))
1436           return EINA_FALSE;
1437         if (EINA_UNLIKELY((unsigned long) v > eina_value_uint_max))
1438           return EINA_FALSE;
1439         return eina_value_type_pset(convert, convert_mem, &other_mem);
1440      }
1441    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
1442      {
1443         unsigned long other_mem = v;
1444         if (EINA_UNLIKELY(v < 0))
1445           return EINA_FALSE;
1446         return eina_value_type_pset(convert, convert_mem, &other_mem);
1447      }
1448    else if (convert == EINA_VALUE_TYPE_UINT64)
1449      {
1450         uint64_t other_mem = v;
1451         if (EINA_UNLIKELY(v < 0))
1452           return EINA_FALSE;
1453         return eina_value_type_pset(convert, convert_mem, &other_mem);
1454      }
1455    else if (convert == EINA_VALUE_TYPE_CHAR)
1456      {
1457         char other_mem = v;
1458         if (EINA_UNLIKELY(v < eina_value_char_min))
1459           return EINA_FALSE;
1460         if (EINA_UNLIKELY(v > eina_value_char_max))
1461           return EINA_FALSE;
1462         return eina_value_type_pset(convert, convert_mem, &other_mem);
1463      }
1464    else if (convert == EINA_VALUE_TYPE_SHORT)
1465      {
1466         short other_mem = v;
1467         if (EINA_UNLIKELY(v < eina_value_short_min))
1468           return EINA_FALSE;
1469         if (EINA_UNLIKELY(v > eina_value_short_max))
1470           return EINA_FALSE;
1471         return eina_value_type_pset(convert, convert_mem, &other_mem);
1472      }
1473    else if (convert == EINA_VALUE_TYPE_INT)
1474      {
1475         int other_mem = v;
1476         if (EINA_UNLIKELY(v < eina_value_int_min))
1477           return EINA_FALSE;
1478         if (EINA_UNLIKELY(v > eina_value_int_max))
1479           return EINA_FALSE;
1480         return eina_value_type_pset(convert, convert_mem, &other_mem);
1481      }
1482    else if (convert == EINA_VALUE_TYPE_LONG)
1483      {
1484         long other_mem = v;
1485         return eina_value_type_pset(convert, convert_mem, &other_mem);
1486      }
1487    else if (convert == EINA_VALUE_TYPE_INT64)
1488      {
1489         int64_t other_mem = v;
1490         return eina_value_type_pset(convert, convert_mem, &other_mem);
1491      }
1492    else if (convert == EINA_VALUE_TYPE_FLOAT)
1493      {
1494         float other_mem = v;
1495         return eina_value_type_pset(convert, convert_mem, &other_mem);
1496      }
1497    else if (convert == EINA_VALUE_TYPE_DOUBLE)
1498      {
1499         double other_mem = v;
1500         return eina_value_type_pset(convert, convert_mem, &other_mem);
1501      }
1502    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
1503             convert == EINA_VALUE_TYPE_STRING)
1504      {
1505         const char *other_mem;
1506         char buf[64];
1507         snprintf(buf, sizeof(buf), "%ld", v);
1508         other_mem = buf; /* required due &buf == buf */
1509         return eina_value_type_pset(convert, convert_mem, &other_mem);
1510      }
1511    else
1512      {
1513         eina_error_set(EINA_ERROR_VALUE_FAILED);
1514         return EINA_FALSE;
1515      }
1516
1517    return EINA_TRUE;
1518 }
1519
1520 static Eina_Bool
1521 _eina_value_type_long_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
1522 {
1523    long *tmem = mem;
1524    *tmem = va_arg(args, long);
1525    return EINA_TRUE;
1526 }
1527
1528 static Eina_Bool
1529 _eina_value_type_long_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
1530 {
1531    long *tmem = mem;
1532    const long *p = ptr;
1533    *tmem = *p;
1534    return EINA_TRUE;
1535 }
1536
1537 static Eina_Bool
1538 _eina_value_type_long_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
1539 {
1540    const long *tmem = mem;
1541    long *p = ptr;
1542    *p = *tmem;
1543    return EINA_TRUE;
1544 }
1545
1546 static Eina_Bool
1547 _eina_value_type_int64_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
1548 {
1549    int64_t *tmem = mem;
1550    *tmem = 0;
1551    return EINA_TRUE;
1552 }
1553
1554 static Eina_Bool
1555 _eina_value_type_int64_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
1556 {
1557    return EINA_TRUE;
1558 }
1559
1560 static Eina_Bool
1561 _eina_value_type_int64_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
1562 {
1563    const int64_t *s = src;
1564    int64_t *d = dst;
1565    *d = *s;
1566    return EINA_TRUE;
1567 }
1568
1569 static int
1570 _eina_value_type_int64_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
1571 {
1572    const int64_t *ta = a, *tb = b;
1573    if (*ta < *tb)
1574      return -1;
1575    else if (*ta > *tb)
1576      return 1;
1577    return 0;
1578 }
1579
1580 static Eina_Bool
1581 _eina_value_type_int64_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
1582 {
1583    const int64_t v = *(const int64_t *)type_mem;
1584
1585    eina_error_set(0);
1586
1587    if (convert == EINA_VALUE_TYPE_UCHAR)
1588      {
1589         unsigned char other_mem = v;
1590         if (EINA_UNLIKELY(v < 0))
1591           return EINA_FALSE;
1592         if (EINA_UNLIKELY(v > eina_value_uchar_max))
1593             return EINA_FALSE;
1594         return eina_value_type_pset(convert, convert_mem, &other_mem);
1595      }
1596    else if (convert == EINA_VALUE_TYPE_USHORT)
1597      {
1598         unsigned short other_mem = v;
1599         if (EINA_UNLIKELY(v < 0))
1600           return EINA_FALSE;
1601         if (EINA_UNLIKELY(v > eina_value_ushort_max))
1602           return EINA_FALSE;
1603         return eina_value_type_pset(convert, convert_mem, &other_mem);
1604      }
1605    else if (convert == EINA_VALUE_TYPE_UINT)
1606      {
1607         unsigned int other_mem = v;
1608         if (EINA_UNLIKELY(v < 0))
1609           return EINA_FALSE;
1610         if (EINA_UNLIKELY(v > eina_value_uint_max))
1611           return EINA_FALSE;
1612         return eina_value_type_pset(convert, convert_mem, &other_mem);
1613      }
1614    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
1615      {
1616         unsigned long other_mem = v;
1617         if (EINA_UNLIKELY(v < 0))
1618           return EINA_FALSE;
1619         if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) &&
1620                           (v > eina_value_ulong_max)))
1621           return EINA_FALSE;
1622         return eina_value_type_pset(convert, convert_mem, &other_mem);
1623      }
1624    else if (convert == EINA_VALUE_TYPE_UINT64)
1625      {
1626         uint64_t other_mem = v;
1627         if (EINA_UNLIKELY(v < 0))
1628           return EINA_FALSE;
1629         return eina_value_type_pset(convert, convert_mem, &other_mem);
1630      }
1631    else if (convert == EINA_VALUE_TYPE_CHAR)
1632      {
1633         char other_mem = v;
1634         if (EINA_UNLIKELY(v < eina_value_char_min))
1635           return EINA_FALSE;
1636         if (EINA_UNLIKELY(v > eina_value_char_max))
1637           return EINA_FALSE;
1638         return eina_value_type_pset(convert, convert_mem, &other_mem);
1639      }
1640    else if (convert == EINA_VALUE_TYPE_SHORT)
1641      {
1642         short other_mem = v;
1643         if (EINA_UNLIKELY(v < eina_value_short_min))
1644           return EINA_FALSE;
1645         if (EINA_UNLIKELY(v > eina_value_short_max))
1646           return EINA_FALSE;
1647         return eina_value_type_pset(convert, convert_mem, &other_mem);
1648      }
1649    else if (convert == EINA_VALUE_TYPE_INT)
1650      {
1651         int other_mem = v;
1652         if (EINA_UNLIKELY(v < eina_value_int_min))
1653           return EINA_FALSE;
1654         if (EINA_UNLIKELY(v > eina_value_int_max))
1655           return EINA_FALSE;
1656         return eina_value_type_pset(convert, convert_mem, &other_mem);
1657      }
1658    else if (convert == EINA_VALUE_TYPE_LONG)
1659      {
1660         long other_mem = v;
1661         if (EINA_UNLIKELY(v < eina_value_long_min))
1662           return EINA_FALSE;
1663         if (EINA_UNLIKELY(v > eina_value_long_max))
1664           return EINA_FALSE;
1665         return eina_value_type_pset(convert, convert_mem, &other_mem);
1666      }
1667    else if (convert == EINA_VALUE_TYPE_INT64)
1668      {
1669         int64_t other_mem = v;
1670         return eina_value_type_pset(convert, convert_mem, &other_mem);
1671      }
1672    else if (convert == EINA_VALUE_TYPE_FLOAT)
1673      {
1674         float other_mem = v;
1675         return eina_value_type_pset(convert, convert_mem, &other_mem);
1676      }
1677    else if (convert == EINA_VALUE_TYPE_DOUBLE)
1678      {
1679         double other_mem = v;
1680         return eina_value_type_pset(convert, convert_mem, &other_mem);
1681      }
1682    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
1683             convert == EINA_VALUE_TYPE_STRING)
1684      {
1685         const char *other_mem;
1686         char buf[64];
1687         snprintf(buf, sizeof(buf), "%"PRId64, v);
1688         other_mem = buf; /* required due &buf == buf */
1689         return eina_value_type_pset(convert, convert_mem, &other_mem);
1690      }
1691    else
1692      {
1693         eina_error_set(EINA_ERROR_VALUE_FAILED);
1694         return EINA_FALSE;
1695      }
1696
1697    return EINA_TRUE;
1698 }
1699
1700 static Eina_Bool
1701 _eina_value_type_int64_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
1702 {
1703    int64_t *tmem = mem;
1704    *tmem = va_arg(args, int64_t);
1705    return EINA_TRUE;
1706 }
1707
1708 static Eina_Bool
1709 _eina_value_type_int64_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
1710 {
1711    int64_t *tmem = mem;
1712    const int64_t *p = ptr;
1713    *tmem = *p;
1714    return EINA_TRUE;
1715 }
1716
1717 static Eina_Bool
1718 _eina_value_type_int64_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
1719 {
1720    const int64_t *tmem = mem;
1721    int64_t *p = ptr;
1722    *p = *tmem;
1723    return EINA_TRUE;
1724 }
1725
1726 static Eina_Bool
1727 _eina_value_type_float_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
1728 {
1729    float *tmem = mem;
1730    *tmem = 0;
1731    return EINA_TRUE;
1732 }
1733
1734 static Eina_Bool
1735 _eina_value_type_float_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
1736 {
1737    return EINA_TRUE;
1738 }
1739
1740 static Eina_Bool
1741 _eina_value_type_float_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
1742 {
1743    const float *s = src;
1744    float *d = dst;
1745    *d = *s;
1746    return EINA_TRUE;
1747 }
1748
1749 static int
1750 _eina_value_type_float_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
1751 {
1752    const float *ta = a, *tb = b;
1753    if (*ta < *tb)
1754      return -1;
1755    else if (*ta > *tb)
1756      return 1;
1757    return 0;
1758 }
1759
1760 static Eina_Bool
1761 _eina_value_type_float_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
1762 {
1763    const float v = *(const float *)type_mem;
1764
1765    eina_error_set(0);
1766
1767    if (convert == EINA_VALUE_TYPE_UCHAR)
1768      {
1769         unsigned char other_mem = v;
1770         if (EINA_UNLIKELY(v < 0))
1771           return EINA_FALSE;
1772         if (EINA_UNLIKELY(v > eina_value_uchar_max))
1773             return EINA_FALSE;
1774         return eina_value_type_pset(convert, convert_mem, &other_mem);
1775      }
1776    else if (convert == EINA_VALUE_TYPE_USHORT)
1777      {
1778         unsigned short other_mem = v;
1779         if (EINA_UNLIKELY(v < 0))
1780           return EINA_FALSE;
1781         if (EINA_UNLIKELY(v > eina_value_ushort_max))
1782           return EINA_FALSE;
1783         return eina_value_type_pset(convert, convert_mem, &other_mem);
1784      }
1785    else if (convert == EINA_VALUE_TYPE_UINT)
1786      {
1787         unsigned int other_mem = v;
1788         if (EINA_UNLIKELY(v < 0))
1789           return EINA_FALSE;
1790         if (EINA_UNLIKELY(v > eina_value_uint_max))
1791           return EINA_FALSE;
1792         return eina_value_type_pset(convert, convert_mem, &other_mem);
1793      }
1794    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
1795      {
1796         unsigned long other_mem = v;
1797         if (EINA_UNLIKELY(v < 0))
1798           return EINA_FALSE;
1799         if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) &&
1800                           (v > eina_value_ulong_max)))
1801           return EINA_FALSE;
1802         return eina_value_type_pset(convert, convert_mem, &other_mem);
1803      }
1804    else if (convert == EINA_VALUE_TYPE_UINT64)
1805      {
1806         uint64_t other_mem = v;
1807         if (EINA_UNLIKELY(v < 0))
1808           return EINA_FALSE;
1809         if (EINA_UNLIKELY(v > eina_value_uint64_max))
1810           return EINA_FALSE;
1811         return eina_value_type_pset(convert, convert_mem, &other_mem);
1812      }
1813    else if (convert == EINA_VALUE_TYPE_CHAR)
1814      {
1815         char other_mem = v;
1816         if (EINA_UNLIKELY(v < eina_value_char_min))
1817           return EINA_FALSE;
1818         if (EINA_UNLIKELY(v > eina_value_char_max))
1819           return EINA_FALSE;
1820         return eina_value_type_pset(convert, convert_mem, &other_mem);
1821      }
1822    else if (convert == EINA_VALUE_TYPE_SHORT)
1823      {
1824         short other_mem = v;
1825         if (EINA_UNLIKELY(v < eina_value_short_min))
1826           return EINA_FALSE;
1827         if (EINA_UNLIKELY(v > eina_value_short_max))
1828           return EINA_FALSE;
1829         return eina_value_type_pset(convert, convert_mem, &other_mem);
1830      }
1831    else if (convert == EINA_VALUE_TYPE_INT)
1832      {
1833         int other_mem = v;
1834         if (EINA_UNLIKELY(v < eina_value_int_min))
1835           return EINA_FALSE;
1836         if (EINA_UNLIKELY(v > eina_value_int_max))
1837           return EINA_FALSE;
1838         return eina_value_type_pset(convert, convert_mem, &other_mem);
1839      }
1840    else if (convert == EINA_VALUE_TYPE_LONG)
1841      {
1842         long other_mem = v;
1843         if (EINA_UNLIKELY(v < eina_value_long_min))
1844           return EINA_FALSE;
1845         if (EINA_UNLIKELY(v > eina_value_long_max))
1846           return EINA_FALSE;
1847         return eina_value_type_pset(convert, convert_mem, &other_mem);
1848      }
1849    else if (convert == EINA_VALUE_TYPE_INT64)
1850      {
1851         int64_t other_mem = v;
1852         if (EINA_UNLIKELY(v < eina_value_int64_min))
1853           return EINA_FALSE;
1854         if (EINA_UNLIKELY(v > eina_value_int64_max))
1855           return EINA_FALSE;
1856         return eina_value_type_pset(convert, convert_mem, &other_mem);
1857      }
1858    else if (convert == EINA_VALUE_TYPE_FLOAT)
1859      {
1860         float other_mem = v;
1861         return eina_value_type_pset(convert, convert_mem, &other_mem);
1862      }
1863    else if (convert == EINA_VALUE_TYPE_DOUBLE)
1864      {
1865         double other_mem = v;
1866         return eina_value_type_pset(convert, convert_mem, &other_mem);
1867      }
1868    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
1869             convert == EINA_VALUE_TYPE_STRING)
1870      {
1871         const char *other_mem;
1872         char buf[64];
1873         snprintf(buf, sizeof(buf), "%f", v);
1874         other_mem = buf; /* required due &buf == buf */
1875         return eina_value_type_pset(convert, convert_mem, &other_mem);
1876      }
1877    else
1878      {
1879         eina_error_set(EINA_ERROR_VALUE_FAILED);
1880         return EINA_FALSE;
1881      }
1882
1883    return EINA_TRUE;
1884 }
1885
1886 static Eina_Bool
1887 _eina_value_type_float_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
1888 {
1889    float *tmem = mem;
1890    *tmem = va_arg(args, double); /* float is promoted to double for va_args */
1891    return EINA_TRUE;
1892 }
1893
1894 static Eina_Bool
1895 _eina_value_type_float_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
1896 {
1897    float *tmem = mem;
1898    const float *p = ptr;
1899    *tmem = *p;
1900    return EINA_TRUE;
1901 }
1902
1903 static Eina_Bool
1904 _eina_value_type_float_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
1905 {
1906    const float *tmem = mem;
1907    float *p = ptr;
1908    *p = *tmem;
1909    return EINA_TRUE;
1910 }
1911
1912 static Eina_Bool
1913 _eina_value_type_double_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
1914 {
1915    double *tmem = mem;
1916    *tmem = 0;
1917    return EINA_TRUE;
1918 }
1919
1920 static Eina_Bool
1921 _eina_value_type_double_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
1922 {
1923    return EINA_TRUE;
1924 }
1925
1926 static Eina_Bool
1927 _eina_value_type_double_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
1928 {
1929    const double *s = src;
1930    double *d = dst;
1931    *d = *s;
1932    return EINA_TRUE;
1933 }
1934
1935 static int
1936 _eina_value_type_double_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
1937 {
1938    const double *ta = a, *tb = b;
1939    if (*ta < *tb)
1940      return -1;
1941    else if (*ta > *tb)
1942      return 1;
1943    return 0;
1944 }
1945
1946 static Eina_Bool
1947 _eina_value_type_double_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
1948 {
1949    const double v = *(const double *)type_mem;
1950
1951    eina_error_set(0);
1952
1953    if (convert == EINA_VALUE_TYPE_UCHAR)
1954      {
1955         unsigned char other_mem = v;
1956         if (EINA_UNLIKELY(v < 0))
1957           return EINA_FALSE;
1958         if (EINA_UNLIKELY(v > eina_value_uchar_max))
1959             return EINA_FALSE;
1960         return eina_value_type_pset(convert, convert_mem, &other_mem);
1961      }
1962    else if (convert == EINA_VALUE_TYPE_USHORT)
1963      {
1964         unsigned short other_mem = v;
1965         if (EINA_UNLIKELY(v < 0))
1966           return EINA_FALSE;
1967         if (EINA_UNLIKELY(v > eina_value_ushort_max))
1968           return EINA_FALSE;
1969         return eina_value_type_pset(convert, convert_mem, &other_mem);
1970      }
1971    else if (convert == EINA_VALUE_TYPE_UINT)
1972      {
1973         unsigned int other_mem = v;
1974         if (EINA_UNLIKELY(v < 0))
1975           return EINA_FALSE;
1976         if (EINA_UNLIKELY(v > eina_value_uint_max))
1977           return EINA_FALSE;
1978         return eina_value_type_pset(convert, convert_mem, &other_mem);
1979      }
1980    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
1981      {
1982         unsigned long other_mem = v;
1983         if (EINA_UNLIKELY(v < 0))
1984           return EINA_FALSE;
1985         if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) &&
1986                           (v > eina_value_ulong_max)))
1987           return EINA_FALSE;
1988         return eina_value_type_pset(convert, convert_mem, &other_mem);
1989      }
1990    else if (convert == EINA_VALUE_TYPE_UINT64)
1991      {
1992         uint64_t other_mem = v;
1993         if (EINA_UNLIKELY(v < 0))
1994           return EINA_FALSE;
1995         return eina_value_type_pset(convert, convert_mem, &other_mem);
1996      }
1997    else if (convert == EINA_VALUE_TYPE_CHAR)
1998      {
1999         char other_mem = v;
2000         if (EINA_UNLIKELY(v < eina_value_char_min))
2001           return EINA_FALSE;
2002         if (EINA_UNLIKELY(v > eina_value_char_max))
2003           return EINA_FALSE;
2004         return eina_value_type_pset(convert, convert_mem, &other_mem);
2005      }
2006    else if (convert == EINA_VALUE_TYPE_SHORT)
2007      {
2008         short other_mem = v;
2009         if (EINA_UNLIKELY(v < eina_value_short_min))
2010           return EINA_FALSE;
2011         if (EINA_UNLIKELY(v > eina_value_short_max))
2012           return EINA_FALSE;
2013         return eina_value_type_pset(convert, convert_mem, &other_mem);
2014      }
2015    else if (convert == EINA_VALUE_TYPE_INT)
2016      {
2017         int other_mem = v;
2018         if (EINA_UNLIKELY(v < eina_value_int_min))
2019           return EINA_FALSE;
2020         if (EINA_UNLIKELY(v > eina_value_int_max))
2021           return EINA_FALSE;
2022         return eina_value_type_pset(convert, convert_mem, &other_mem);
2023      }
2024    else if (convert == EINA_VALUE_TYPE_LONG)
2025      {
2026         long other_mem = v;
2027         if (EINA_UNLIKELY(v < eina_value_long_min))
2028           return EINA_FALSE;
2029         if (EINA_UNLIKELY(v > eina_value_long_max))
2030           return EINA_FALSE;
2031         return eina_value_type_pset(convert, convert_mem, &other_mem);
2032      }
2033    else if (convert == EINA_VALUE_TYPE_INT64)
2034      {
2035         int64_t other_mem = v;
2036         return eina_value_type_pset(convert, convert_mem, &other_mem);
2037      }
2038    else if (convert == EINA_VALUE_TYPE_FLOAT)
2039      {
2040         float other_mem = v;
2041         return eina_value_type_pset(convert, convert_mem, &other_mem);
2042      }
2043    else if (convert == EINA_VALUE_TYPE_DOUBLE)
2044      {
2045         double other_mem = v;
2046         return eina_value_type_pset(convert, convert_mem, &other_mem);
2047      }
2048    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
2049             convert == EINA_VALUE_TYPE_STRING)
2050      {
2051         const char *other_mem;
2052         char buf[64];
2053         snprintf(buf, sizeof(buf), "%g", (double)v);
2054         other_mem = buf; /* required due &buf == buf */
2055         return eina_value_type_pset(convert, convert_mem, &other_mem);
2056      }
2057    else
2058      {
2059         eina_error_set(EINA_ERROR_VALUE_FAILED);
2060         return EINA_FALSE;
2061      }
2062
2063    return EINA_TRUE;
2064 }
2065
2066 static Eina_Bool
2067 _eina_value_type_double_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
2068 {
2069    double *tmem = mem;
2070    *tmem = va_arg(args, double);
2071    return EINA_TRUE;
2072 }
2073
2074 static Eina_Bool
2075 _eina_value_type_double_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
2076 {
2077    double *tmem = mem;
2078    const double *p = ptr;
2079    *tmem = *p;
2080    return EINA_TRUE;
2081 }
2082
2083 static Eina_Bool
2084 _eina_value_type_double_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
2085 {
2086    const double *tmem = mem;
2087    double *p = ptr;
2088    *p = *tmem;
2089    return EINA_TRUE;
2090 }
2091
2092 static Eina_Bool
2093 _eina_value_type_string_common_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
2094 {
2095    const char **tmem = mem;
2096    *tmem = NULL;
2097    return EINA_TRUE;
2098 }
2099
2100 static int
2101 _eina_value_type_string_common_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
2102 {
2103    const char *sa = *(const char **)a;
2104    const char *sb = *(const char **)b;
2105    if (sa == sb)
2106      return 0;
2107    if (sa == NULL)
2108      return -1;
2109    if (sb == NULL)
2110      return 1;
2111    return strcmp(sa, sb);
2112 }
2113
2114 static Eina_Bool
2115 _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)
2116 {
2117    const char *v = *(const char **)type_mem;
2118
2119    eina_error_set(0);
2120
2121    if (convert == EINA_VALUE_TYPE_UCHAR)
2122      {
2123         unsigned char other_mem;
2124         if ((sscanf(v, "%hhu", &other_mem) != 1) &&
2125             (sscanf(v, "%hhx", &other_mem) != 1) &&
2126             (sscanf(v, "%hho", &other_mem) != 1))
2127           return EINA_FALSE;
2128         return eina_value_type_pset(convert, convert_mem, &other_mem);
2129      }
2130    else if (convert == EINA_VALUE_TYPE_USHORT)
2131      {
2132         unsigned short other_mem;
2133         if ((sscanf(v, "%hu", &other_mem) != 1) &&
2134             (sscanf(v, "%hx", &other_mem) != 1) &&
2135             (sscanf(v, "%ho", &other_mem) != 1))
2136           return EINA_FALSE;
2137         return eina_value_type_pset(convert, convert_mem, &other_mem);
2138      }
2139    else if (convert == EINA_VALUE_TYPE_UINT)
2140      {
2141         unsigned int other_mem;
2142         if ((sscanf(v, "%u", &other_mem) != 1) &&
2143             (sscanf(v, "%x", &other_mem) != 1) &&
2144             (sscanf(v, "%o", &other_mem) != 1))
2145           return EINA_FALSE;
2146         return eina_value_type_pset(convert, convert_mem, &other_mem);
2147      }
2148    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
2149      {
2150         unsigned long other_mem;
2151         if ((sscanf(v, "%lu", &other_mem) != 1) &&
2152             (sscanf(v, "%lx", &other_mem) != 1) &&
2153             (sscanf(v, "%lo", &other_mem) != 1))
2154           return EINA_FALSE;
2155         return eina_value_type_pset(convert, convert_mem, &other_mem);
2156      }
2157    else if (convert == EINA_VALUE_TYPE_UINT64)
2158      {
2159         uint64_t other_mem;
2160         if ((sscanf(v, "%"SCNu64, &other_mem) != 1) &&
2161             (sscanf(v, "%"SCNx64, &other_mem) != 1) &&
2162             (sscanf(v, "%"SCNo64, &other_mem) != 1))
2163           return EINA_FALSE;
2164         return eina_value_type_pset(convert, convert_mem, &other_mem);
2165      }
2166    else if (convert == EINA_VALUE_TYPE_CHAR)
2167      {
2168         char other_mem;
2169         if ((sscanf(v, "%hhd", &other_mem) != 1) &&
2170             (sscanf(v, "%hhx", &other_mem) != 1) &&
2171             (sscanf(v, "%hho", &other_mem) != 1))
2172           return EINA_FALSE;
2173         return eina_value_type_pset(convert, convert_mem, &other_mem);
2174      }
2175    else if (convert == EINA_VALUE_TYPE_SHORT)
2176      {
2177         short other_mem;
2178         if ((sscanf(v, "%hd", &other_mem) != 1) &&
2179             (sscanf(v, "%hx", &other_mem) != 1) &&
2180             (sscanf(v, "%ho", &other_mem) != 1))
2181           return EINA_FALSE;
2182         return eina_value_type_pset(convert, convert_mem, &other_mem);
2183      }
2184    else if (convert == EINA_VALUE_TYPE_INT)
2185      {
2186         int other_mem;
2187         if ((sscanf(v, "%d", &other_mem) != 1) &&
2188             (sscanf(v, "%x", &other_mem) != 1) &&
2189             (sscanf(v, "%o", &other_mem) != 1))
2190           return EINA_FALSE;
2191         return eina_value_type_pset(convert, convert_mem, &other_mem);
2192      }
2193    else if (convert == EINA_VALUE_TYPE_LONG)
2194      {
2195         long other_mem;
2196         if ((sscanf(v, "%ld", &other_mem) != 1) &&
2197             (sscanf(v, "%lx", &other_mem) != 1) &&
2198             (sscanf(v, "%lo", &other_mem) != 1))
2199           return EINA_FALSE;
2200         return eina_value_type_pset(convert, convert_mem, &other_mem);
2201      }
2202    else if (convert == EINA_VALUE_TYPE_INT64)
2203      {
2204         int64_t other_mem;
2205         if ((sscanf(v, "%"SCNd64, &other_mem) != 1) &&
2206             (sscanf(v, "%"SCNx64, &other_mem) != 1) &&
2207             (sscanf(v, "%"SCNo64, &other_mem) != 1))
2208           return EINA_FALSE;
2209         return eina_value_type_pset(convert, convert_mem, &other_mem);
2210      }
2211    else if (convert == EINA_VALUE_TYPE_FLOAT)
2212      {
2213         float other_mem;
2214         if (sscanf(v, "%f", &other_mem) != 1)
2215           return EINA_FALSE;
2216         return eina_value_type_pset(convert, convert_mem, &other_mem);
2217      }
2218    else if (convert == EINA_VALUE_TYPE_DOUBLE)
2219      {
2220         double other_mem;
2221         if (sscanf(v, "%lf", &other_mem) != 1)
2222           return EINA_FALSE;
2223         return eina_value_type_pset(convert, convert_mem, &other_mem);
2224      }
2225    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
2226             convert == EINA_VALUE_TYPE_STRING)
2227      {
2228         return eina_value_type_pset(convert, convert_mem, &v);
2229      }
2230    else
2231      {
2232         eina_error_set(EINA_ERROR_VALUE_FAILED);
2233         return EINA_FALSE;
2234      }
2235
2236    return EINA_TRUE;
2237 }
2238
2239 static Eina_Bool
2240 _eina_value_type_string_common_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
2241 {
2242    memcpy(ptr, mem, sizeof(const char *));
2243    return EINA_TRUE;
2244 }
2245
2246 static Eina_Bool
2247 _eina_value_type_stringshare_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
2248 {
2249    const char **tmem = mem;
2250    if (*tmem)
2251      {
2252         eina_stringshare_del(*tmem);
2253         *tmem = NULL;
2254      }
2255    return EINA_TRUE;
2256 }
2257
2258 static Eina_Bool
2259 _eina_value_type_stringshare_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
2260 {
2261    const char * const*s = src;
2262    const char **d = dst;
2263    *d = eina_stringshare_add(*s);
2264    return EINA_TRUE;
2265 }
2266
2267 static Eina_Bool
2268 _eina_value_type_stringshare_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
2269 {
2270    const char *str = va_arg(args, const char *);
2271    return eina_stringshare_replace((const char **)mem, str);
2272 }
2273
2274 static Eina_Bool
2275 _eina_value_type_stringshare_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
2276 {
2277    const char * const *str = ptr;
2278    return eina_stringshare_replace((const char **)mem, *str);
2279 }
2280
2281 static Eina_Bool
2282 _eina_value_type_string_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
2283 {
2284    char **tmem = mem;
2285    if (*tmem)
2286      {
2287         free(*tmem);
2288         *tmem = NULL;
2289      }
2290    return EINA_TRUE;
2291 }
2292
2293 static Eina_Bool
2294 _eina_value_type_string_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
2295 {
2296    const char * const *s = src;
2297    char **d = dst;
2298    if (*s == NULL)
2299      *d = NULL;
2300    else
2301      {
2302         *d = strdup(*s);
2303         if (*d == NULL)
2304           {
2305              eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
2306              return EINA_FALSE;
2307           }
2308      }
2309    return EINA_TRUE;
2310 }
2311
2312 static Eina_Bool
2313 _eina_value_type_string_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
2314 {
2315    char **tmem = mem;
2316    const char *str = va_arg(args, const char *);
2317    eina_error_set(0);
2318    if (str == *tmem) return EINA_TRUE;
2319    if (!str)
2320      {
2321         free(*tmem);
2322         *tmem = NULL;
2323      }
2324    else
2325      {
2326         char *tmp = strdup(str);
2327         if (!tmp)
2328           {
2329              eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
2330              return EINA_FALSE;
2331           }
2332         free(*tmem);
2333         *tmem = tmp;
2334      }
2335    return EINA_TRUE;
2336 }
2337
2338 static Eina_Bool
2339 _eina_value_type_string_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
2340 {
2341    char **tmem = mem;
2342    const char * const *str = ptr;
2343    eina_error_set(0);
2344    if (*str == *tmem) return EINA_TRUE;
2345    if (!*str)
2346      {
2347         free(*tmem);
2348         *tmem = NULL;
2349      }
2350    else
2351      {
2352         char *tmp = strdup(*str);
2353         if (!tmp)
2354           {
2355              eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
2356              return EINA_FALSE;
2357           }
2358         free(*tmem);
2359         *tmem = tmp;
2360      }
2361    return EINA_TRUE;
2362 }
2363
2364 static Eina_Bool
2365 _eina_value_type_array_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
2366 {
2367    memset(mem, 0, sizeof(Eina_Value_Array));
2368    return EINA_TRUE;
2369 }
2370
2371 static Eina_Bool
2372 _eina_value_type_array_flush_elements(Eina_Value_Array *tmem)
2373 {
2374    const Eina_Value_Type *subtype = tmem->subtype;
2375    Eina_Bool ret = EINA_TRUE;
2376    unsigned char sz;
2377    char *ptr, *ptr_end;
2378
2379    if (!tmem->array) return EINA_TRUE;
2380
2381    sz = tmem->array->member_size;
2382    ptr = tmem->array->members;
2383    ptr_end = ptr + tmem->array->len * sz;
2384
2385    for (; ptr < ptr_end; ptr += sz)
2386      ret &= eina_value_type_flush(subtype, ptr);
2387
2388    eina_inarray_flush(tmem->array);
2389    return ret;
2390 }
2391
2392 static Eina_Bool
2393 _eina_value_type_array_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
2394 {
2395    Eina_Value_Array *tmem = mem;
2396    Eina_Bool ret =_eina_value_type_array_flush_elements(tmem);
2397
2398    if (tmem->array) eina_inarray_free(tmem->array);
2399    tmem->array = NULL;
2400    tmem->subtype = NULL;
2401    return ret;
2402 }
2403
2404 static Eina_Bool
2405 _eina_value_type_array_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
2406 {
2407    const Eina_Value_Type *subtype;
2408    const Eina_Value_Array *s = src;
2409    Eina_Value_Array *d = dst;
2410    unsigned int i, count, sz;
2411    char *ptr, *ptr_end;
2412
2413    d->subtype = subtype = s->subtype;
2414    d->step = s->step;
2415
2416    if ((!s->array) || (!s->subtype))
2417      {
2418         d->array = NULL;
2419         return EINA_TRUE;
2420      }
2421
2422    if (!subtype->copy)
2423      {
2424         eina_error_set(EINA_ERROR_VALUE_FAILED);
2425         return EINA_FALSE;
2426      }
2427
2428    d->array = eina_inarray_new(subtype->value_size, s->step);
2429    if (!d->array)
2430      return EINA_FALSE;
2431
2432    sz = s->array->member_size;
2433
2434    count = eina_inarray_count(s->array);
2435    ptr = s->array->members;
2436    ptr_end = ptr + (count * sz);
2437
2438    for (i = 0; ptr < ptr_end; ptr += sz, i++)
2439      {
2440         void *imem = eina_inarray_alloc_at(d->array, i, 1);
2441         if (!imem) goto error;
2442         if (!subtype->copy(subtype, ptr, imem))
2443           {
2444              eina_inarray_pop(d->array);
2445              goto error;
2446           }
2447      }
2448
2449    return EINA_TRUE;
2450
2451  error:
2452    _eina_value_type_array_flush_elements(d);
2453    return EINA_FALSE;
2454 }
2455
2456 static int
2457 _eina_value_type_array_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
2458 {
2459    const Eina_Value_Type *subtype;
2460    const Eina_Value_Array *eva_a = a, *eva_b = b;
2461    const char *a_ptr, *a_ptr_end, *b_ptr;
2462    unsigned int count_a, count_b, count, sz;
2463    int cmp = 0;
2464
2465    if (eva_a->subtype != eva_b->subtype)
2466      {
2467         eina_error_set(EINA_ERROR_VALUE_FAILED);
2468         return -1;
2469      }
2470
2471    subtype = eva_a->subtype;
2472    if (!subtype->compare)
2473      {
2474         eina_error_set(EINA_ERROR_VALUE_FAILED);
2475         return 0;
2476      }
2477
2478    if ((!eva_a->array) && (!eva_b->array))
2479      return 0;
2480    else if (!eva_a->array)
2481      return -1;
2482    else if (!eva_b->array)
2483      return 1;
2484
2485    count_a = eina_inarray_count(eva_a->array);
2486    count_b = eina_inarray_count(eva_b->array);
2487
2488    if (count_a <= count_b)
2489      count = count_a;
2490    else
2491      count = count_b;
2492
2493    sz = eva_a->array->member_size;
2494
2495    a_ptr = eva_a->array->members;
2496    a_ptr_end = a_ptr + (count * sz);
2497    b_ptr = eva_b->array->members;
2498
2499    for (; (cmp == 0) && (a_ptr < a_ptr_end); a_ptr += sz, b_ptr += sz)
2500      cmp = subtype->compare(subtype, a_ptr, b_ptr);
2501
2502    if (cmp == 0)
2503      {
2504         if (count_a < count_b)
2505           return -1;
2506         else if (count_a > count_b)
2507           return 1;
2508         return 0;
2509      }
2510
2511    return cmp;
2512 }
2513
2514 static Eina_Bool
2515 _eina_value_type_array_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
2516 {
2517    const Eina_Value_Array *tmem = type_mem;
2518    Eina_Bool ret = EINA_FALSE;
2519
2520    if ((convert == EINA_VALUE_TYPE_STRING) ||
2521        (convert == EINA_VALUE_TYPE_STRINGSHARE))
2522      {
2523         Eina_Strbuf *str = eina_strbuf_new();
2524         const char *ptr;
2525         if (!tmem->array) eina_strbuf_append(str, "[]");
2526         else
2527           {
2528              const Eina_Value_Type *subtype = tmem->subtype;
2529              unsigned char sz;
2530              const char *ptr_end;
2531              Eina_Value tmp;
2532              Eina_Bool first = EINA_TRUE;
2533
2534              eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING);
2535
2536              eina_strbuf_append_char(str, '[');
2537
2538              sz = tmem->array->member_size;
2539              ptr = tmem->array->members;
2540              ptr_end = ptr + tmem->array->len * sz;
2541              for (; ptr < ptr_end; ptr += sz)
2542                {
2543                   Eina_Bool r = EINA_FALSE;
2544                   if (subtype->convert_to)
2545                     {
2546                        r = subtype->convert_to(subtype, EINA_VALUE_TYPE_STRING,
2547                                                ptr, tmp.value.buf);
2548                        if (r)
2549                          {
2550                             if (first) first = EINA_FALSE;
2551                             else eina_strbuf_append_length(str, ", ", 2);
2552                             eina_strbuf_append(str, tmp.value.ptr);
2553                             free(tmp.value.ptr);
2554                             tmp.value.ptr = NULL;
2555                          }
2556                     }
2557
2558                   if (!r)
2559                     {
2560                        if (first)
2561                          {
2562                             first = EINA_FALSE;
2563                             eina_strbuf_append_char(str, '?');
2564                          }
2565                        else
2566                          eina_strbuf_append_length(str, ", ?", 3);
2567                     }
2568                }
2569
2570              eina_strbuf_append_char(str, ']');
2571           }
2572         ptr = eina_strbuf_string_get(str);
2573         ret = eina_value_type_pset(convert, convert_mem, &ptr);
2574         eina_strbuf_free(str);
2575      }
2576    else if ((tmem->array) && (tmem->array->len == 1))
2577      {
2578         const Eina_Value_Type *subtype = tmem->subtype;
2579         void *imem = tmem->array->members;
2580
2581         if (subtype->convert_to)
2582           ret = subtype->convert_to(subtype, convert, imem, convert_mem);
2583         if ((!ret) && (convert->convert_from))
2584           ret = convert->convert_from(convert, subtype, convert_mem, imem);
2585      }
2586
2587    if (!ret)
2588      {
2589         eina_error_set(EINA_ERROR_VALUE_FAILED);
2590         return EINA_FALSE;
2591      }
2592    return EINA_TRUE;
2593 }
2594
2595 static Eina_Bool
2596 _eina_value_type_array_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem)
2597 {
2598    Eina_Value_Array *tmem = type_mem;
2599    Eina_Value_Array desc = {convert, tmem->step, NULL};
2600    char *buf;
2601    void *imem;
2602
2603    if (!eina_value_type_pset(type, tmem, &desc))
2604      return EINA_FALSE;
2605
2606    buf = alloca(convert->value_size);
2607    if (!eina_value_type_pget(convert, convert_mem, &buf))
2608      return EINA_FALSE;
2609
2610    imem = eina_inarray_alloc_at(tmem->array, 0, 1);
2611    if (!imem)
2612      return EINA_FALSE;
2613
2614    if (!eina_value_type_setup(convert, imem)) goto error_setup;
2615    if (!eina_value_type_pset(convert, imem, &buf)) goto error_set;
2616    return EINA_TRUE;
2617
2618  error_set:
2619    eina_value_type_flush(convert, imem);
2620  error_setup:
2621    eina_inarray_remove_at(tmem->array, 0);
2622    return EINA_FALSE;
2623 }
2624
2625 static Eina_Bool
2626 _eina_value_type_array_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
2627 {
2628    Eina_Value_Array *tmem = mem;
2629    const Eina_Value_Array *desc = ptr;
2630    Eina_Inarray *desc_array;
2631
2632    eina_error_set(0);
2633    if ((!tmem->subtype) && (!desc->subtype))
2634      return EINA_TRUE;
2635
2636    desc_array = desc->array;
2637    if (desc_array)
2638      {
2639         Eina_Value_Array tmp;
2640
2641         EINA_SAFETY_ON_FALSE_RETURN_VAL
2642           (desc_array->member_size == desc->subtype->value_size, EINA_FALSE);
2643
2644         if (desc_array == tmem->array)
2645           {
2646              tmem->subtype = desc->subtype;
2647              return EINA_TRUE;
2648           }
2649
2650         if (!_eina_value_type_array_copy(type, desc, &tmp))
2651           return EINA_FALSE;
2652
2653         _eina_value_type_array_flush(type, tmem);
2654         memcpy(tmem, &tmp, sizeof(tmp));
2655         return EINA_TRUE;
2656      }
2657
2658    if (tmem->array)
2659      {
2660         _eina_value_type_array_flush_elements(tmem);
2661         eina_inarray_step_set(tmem->array, sizeof (Eina_Inarray), desc->subtype->value_size, desc->step);
2662      }
2663    else
2664      {
2665         tmem->array = eina_inarray_new(desc->subtype->value_size, desc->step);
2666         if (!tmem->array)
2667           return EINA_FALSE;
2668      }
2669
2670    tmem->subtype = desc->subtype;
2671    return EINA_TRUE;
2672 }
2673
2674 static Eina_Bool
2675 _eina_value_type_array_vset(const Eina_Value_Type *type, void *mem, va_list args)
2676 {
2677    const Eina_Value_Array desc = va_arg(args, Eina_Value_Array);
2678    _eina_value_type_array_pset(type, mem, &desc);
2679    return EINA_TRUE;
2680 }
2681
2682 static Eina_Bool
2683 _eina_value_type_array_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
2684 {
2685    memcpy(ptr, mem, sizeof(Eina_Value_Array));
2686    return EINA_TRUE;
2687 }
2688
2689 static const Eina_Value_Type _EINA_VALUE_TYPE_ARRAY = {
2690   EINA_VALUE_TYPE_VERSION,
2691   sizeof(Eina_Value_Array),
2692   "Eina_Value_Array",
2693   _eina_value_type_array_setup,
2694   _eina_value_type_array_flush,
2695   _eina_value_type_array_copy,
2696   _eina_value_type_array_compare,
2697   _eina_value_type_array_convert_to,
2698   _eina_value_type_array_convert_from,
2699   _eina_value_type_array_vset,
2700   _eina_value_type_array_pset,
2701   _eina_value_type_array_pget
2702 };
2703
2704 static Eina_Bool
2705 _eina_value_type_list_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
2706 {
2707    memset(mem, 0, sizeof(Eina_Value_List));
2708    return EINA_TRUE;
2709 }
2710
2711 static Eina_Bool
2712 _eina_value_type_list_flush_elements(Eina_Value_List *tmem)
2713 {
2714    const Eina_Value_Type *subtype = tmem->subtype;
2715    Eina_Bool ret = EINA_TRUE;
2716
2717    if (!tmem->list) return EINA_TRUE;
2718
2719    while (tmem->list)
2720      {
2721         void *mem = eina_value_list_node_memory_get(tmem->subtype, tmem->list);
2722         ret &= eina_value_type_flush(subtype, mem);
2723         eina_value_list_node_memory_flush(tmem->subtype, tmem->list);
2724         tmem->list = eina_list_remove_list(tmem->list, tmem->list);
2725      }
2726
2727    return ret;
2728 }
2729
2730 static Eina_Bool
2731 _eina_value_type_list_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
2732 {
2733    Eina_Value_List *tmem = mem;
2734    Eina_Bool ret =_eina_value_type_list_flush_elements(tmem);
2735
2736    if (tmem->list) eina_list_free(tmem->list);
2737    tmem->list = NULL;
2738    tmem->subtype = NULL;
2739    return ret;
2740 }
2741
2742 static Eina_Bool
2743 _eina_value_type_list_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
2744 {
2745    const Eina_Value_Type *subtype;
2746    const Eina_Value_List *s = src;
2747    Eina_Value_List *d = dst;
2748    const Eina_List *snode;
2749
2750    d->subtype = subtype = s->subtype;
2751    if ((!s->list) || (!s->subtype))
2752      {
2753         d->list = NULL;
2754         return EINA_TRUE;
2755      }
2756
2757    if (!subtype->copy)
2758      {
2759         eina_error_set(EINA_ERROR_VALUE_FAILED);
2760         return EINA_FALSE;
2761      }
2762
2763    d->list = NULL;
2764    for (snode = s->list; snode != NULL; snode = snode->next)
2765      {
2766         const void *ptr = eina_value_list_node_memory_get(subtype, snode);
2767         Eina_List *dnode;
2768         void *imem;
2769
2770         d->list = eina_list_append(d->list, (void*)1L);
2771         dnode = eina_list_last(d->list);
2772         EINA_SAFETY_ON_NULL_GOTO(dnode, error);
2773         EINA_SAFETY_ON_FALSE_GOTO(dnode->data == (void*)1L, error);
2774
2775         imem = eina_value_list_node_memory_setup(subtype, dnode);
2776         if (!subtype->copy(subtype, ptr, imem))
2777           {
2778              eina_value_list_node_memory_flush(subtype, dnode);
2779              d->list = eina_list_remove_list(d->list, dnode);
2780              goto error;
2781           }
2782      }
2783    return EINA_TRUE;
2784
2785  error:
2786    _eina_value_type_list_flush_elements(d);
2787    return EINA_FALSE;
2788 }
2789
2790 static int
2791 _eina_value_type_list_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
2792 {
2793    const Eina_Value_Type *subtype;
2794    const Eina_Value_List *eva_a = a, *eva_b = b;
2795    const Eina_List *anode, *bnode;
2796    int cmp = 0;
2797
2798    if (eva_a->subtype != eva_b->subtype)
2799      {
2800         eina_error_set(EINA_ERROR_VALUE_FAILED);
2801         return -1;
2802      }
2803
2804    subtype = eva_a->subtype;
2805    if (!subtype->compare)
2806      {
2807         eina_error_set(EINA_ERROR_VALUE_FAILED);
2808         return 0;
2809      }
2810
2811    if ((!eva_a->list) && (!eva_b->list))
2812      return 0;
2813    else if (!eva_a->list)
2814      return -1;
2815    else if (!eva_b->list)
2816      return 1;
2817
2818    for (anode = eva_a->list, bnode = eva_b->list;
2819         (cmp == 0) && (anode) && (bnode);
2820         anode = anode->next, bnode = bnode->next)
2821      {
2822         const void *amem = eina_value_list_node_memory_get(subtype, anode);
2823         const void *bmem = eina_value_list_node_memory_get(subtype, bnode);
2824         cmp = subtype->compare(subtype, amem, bmem);
2825      }
2826
2827    if (cmp == 0)
2828      {
2829         if ((!anode) && (bnode))
2830           return -1;
2831         else if ((anode) && (!bnode))
2832           return 1;
2833         return 0;
2834      }
2835
2836    return cmp;
2837 }
2838
2839 static Eina_Bool
2840 _eina_value_type_list_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
2841 {
2842    const Eina_Value_List *tmem = type_mem;
2843    Eina_Bool ret = EINA_FALSE;
2844
2845    if ((convert == EINA_VALUE_TYPE_STRING) ||
2846        (convert == EINA_VALUE_TYPE_STRINGSHARE))
2847      {
2848         Eina_Strbuf *str = eina_strbuf_new();
2849         const char *s;
2850         if (!tmem->list) eina_strbuf_append(str, "[]");
2851         else
2852           {
2853              const Eina_Value_Type *subtype = tmem->subtype;
2854              const Eina_List *node;
2855              Eina_Value tmp;
2856              Eina_Bool first = EINA_TRUE;
2857
2858              eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING);
2859
2860              eina_strbuf_append_char(str, '[');
2861
2862              for (node = tmem->list; node != NULL; node = node->next)
2863                {
2864                   Eina_Bool r = EINA_FALSE;
2865
2866                   if (subtype->convert_to)
2867                     {
2868                        const void *ptr;
2869                        ptr = eina_value_list_node_memory_get(subtype, node);
2870                        r = subtype->convert_to(subtype, EINA_VALUE_TYPE_STRING,
2871                                                ptr, tmp.value.buf);
2872                        if (r)
2873                          {
2874                             if (first) first = EINA_FALSE;
2875                             else eina_strbuf_append_length(str, ", ", 2);
2876                             eina_strbuf_append(str, tmp.value.ptr);
2877                             free(tmp.value.ptr);
2878                             tmp.value.ptr = NULL;
2879                          }
2880                     }
2881
2882                   if (!r)
2883                     {
2884                        if (first)
2885                          {
2886                             first = EINA_FALSE;
2887                             eina_strbuf_append_char(str, '?');
2888                          }
2889                        else
2890                          eina_strbuf_append_length(str, ", ?", 3);
2891                     }
2892                }
2893
2894              eina_strbuf_append_char(str, ']');
2895           }
2896         s = eina_strbuf_string_get(str);
2897         ret = eina_value_type_pset(convert, convert_mem, &s);
2898         eina_strbuf_free(str);
2899      }
2900    else if ((tmem->list) && (tmem->list->next == NULL))
2901      {
2902         const Eina_Value_Type *subtype = tmem->subtype;
2903         void *imem = eina_value_list_node_memory_get(subtype, tmem->list);
2904
2905         if (subtype->convert_to)
2906           ret = subtype->convert_to(subtype, convert, imem, convert_mem);
2907         if ((!ret) && (convert->convert_from))
2908           ret = convert->convert_from(convert, subtype, convert_mem, imem);
2909      }
2910
2911    if (!ret)
2912      {
2913         eina_error_set(EINA_ERROR_VALUE_FAILED);
2914         return EINA_FALSE;
2915      }
2916    return EINA_TRUE;
2917 }
2918
2919 static Eina_Bool
2920 _eina_value_type_list_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem)
2921 {
2922    Eina_Value_List *tmem = type_mem;
2923    Eina_Value_List desc = {convert, NULL};
2924    Eina_List *node;
2925    char *buf;
2926    void *imem;
2927
2928    if (!eina_value_type_pset(type, tmem, &desc))
2929      return EINA_FALSE;
2930
2931    buf = alloca(convert->value_size);
2932    if (!eina_value_type_pget(convert, convert_mem, &buf))
2933      return EINA_FALSE;
2934
2935    tmem->list = eina_list_append(tmem->list, (void*)1L);
2936    node = eina_list_last(tmem->list);
2937    EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
2938    EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
2939
2940    imem = eina_value_list_node_memory_setup(tmem->subtype, node);
2941    if (!imem)
2942      {
2943         tmem->list = eina_list_remove_list(tmem->list, node);
2944         return EINA_FALSE;
2945      }
2946
2947    if (!eina_value_type_setup(tmem->subtype, imem)) goto error_setup;
2948    if (!eina_value_type_pset(tmem->subtype, imem, &buf)) goto error_set;
2949    return EINA_TRUE;
2950
2951  error_set:
2952    eina_value_type_flush(tmem->subtype, imem);
2953  error_setup:
2954    eina_value_list_node_memory_flush(tmem->subtype, node);
2955    tmem->list = eina_list_remove_list(tmem->list, node);
2956    return EINA_FALSE;
2957 }
2958
2959 static Eina_Bool
2960 _eina_value_type_list_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
2961 {
2962    Eina_Value_List *tmem = mem;
2963    const Eina_Value_List *desc = ptr;
2964
2965    eina_error_set(0);
2966    if ((!tmem->subtype) && (!desc->subtype))
2967      return EINA_TRUE;
2968
2969    if ((tmem->list) && (tmem->list == desc->list))
2970      {
2971         tmem->subtype = desc->subtype;
2972         return EINA_TRUE;
2973      }
2974
2975    if (desc->list)
2976      {
2977         Eina_Value_List tmp;
2978
2979         if (!_eina_value_type_list_copy(type, desc, &tmp))
2980           return EINA_FALSE;
2981
2982         _eina_value_type_list_flush(type, tmem);
2983         memcpy(tmem, &tmp, sizeof(tmp));
2984         return EINA_TRUE;
2985      }
2986
2987    _eina_value_type_list_flush_elements(tmem);
2988
2989    tmem->subtype = desc->subtype;
2990    return EINA_TRUE;
2991 }
2992
2993 static Eina_Bool
2994 _eina_value_type_list_vset(const Eina_Value_Type *type, void *mem, va_list args)
2995 {
2996    const Eina_Value_List desc = va_arg(args, Eina_Value_List);
2997    _eina_value_type_list_pset(type, mem, &desc);
2998    return EINA_TRUE;
2999 }
3000
3001 static Eina_Bool
3002 _eina_value_type_list_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
3003 {
3004    memcpy(ptr, mem, sizeof(Eina_Value_List));
3005    return EINA_TRUE;
3006 }
3007
3008 static const Eina_Value_Type _EINA_VALUE_TYPE_LIST = {
3009   EINA_VALUE_TYPE_VERSION,
3010   sizeof(Eina_Value_List),
3011   "Eina_Value_List",
3012   _eina_value_type_list_setup,
3013   _eina_value_type_list_flush,
3014   _eina_value_type_list_copy,
3015   _eina_value_type_list_compare,
3016   _eina_value_type_list_convert_to,
3017   _eina_value_type_list_convert_from,
3018   _eina_value_type_list_vset,
3019   _eina_value_type_list_pset,
3020   _eina_value_type_list_pget
3021 };
3022
3023 static Eina_Bool
3024 _eina_value_type_hash_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
3025 {
3026    memset(mem, 0, sizeof(Eina_Value_Hash));
3027    return EINA_TRUE;
3028 }
3029
3030 struct _eina_value_type_hash_flush_each_ctx
3031 {
3032    const Eina_Value_Type *subtype;
3033    Eina_Bool ret;
3034 };
3035
3036 static Eina_Bool
3037 _eina_value_type_hash_flush_each(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *mem, void *user_data)
3038 {
3039    struct _eina_value_type_hash_flush_each_ctx *ctx = user_data;
3040    ctx->ret &= eina_value_type_flush(ctx->subtype, mem);
3041    free(mem);
3042    return EINA_TRUE;
3043 }
3044
3045 static Eina_Bool
3046 _eina_value_type_hash_flush_elements(Eina_Value_Hash *tmem)
3047 {
3048    struct _eina_value_type_hash_flush_each_ctx ctx = {
3049      tmem->subtype,
3050      EINA_TRUE
3051    };
3052
3053    if (!tmem->hash) return EINA_TRUE;
3054
3055    eina_hash_foreach(tmem->hash, _eina_value_type_hash_flush_each, &ctx);
3056    eina_hash_free(tmem->hash);
3057    tmem->hash = NULL;
3058    return ctx.ret;
3059 }
3060
3061 static Eina_Bool
3062 _eina_value_type_hash_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
3063 {
3064    Eina_Value_Hash *tmem = mem;
3065    Eina_Bool ret =_eina_value_type_hash_flush_elements(tmem);
3066    tmem->subtype = NULL;
3067    return ret;
3068 }
3069
3070 static unsigned int
3071 _eina_value_hash_key_length(const void *key)
3072 {
3073    if (!key)
3074       return 0;
3075    return (int)strlen(key) + 1;
3076 }
3077
3078 static int
3079 _eina_value_hash_key_cmp(const void *key1, int key1_len, const void *key2, int key2_len)
3080 {
3081    int r = key1_len - key2_len;
3082    if (r != 0)
3083      return r;
3084    return strcmp(key1, key2);
3085 }
3086
3087 static Eina_Bool
3088 _eina_value_type_hash_create(Eina_Value_Hash *desc)
3089 {
3090    if (!desc->buckets_power_size)
3091      desc->buckets_power_size = 5;
3092
3093    desc->hash = eina_hash_new(_eina_value_hash_key_length,
3094                               _eina_value_hash_key_cmp,
3095                               EINA_KEY_HASH(eina_hash_superfast),
3096                               NULL, desc->buckets_power_size);
3097    return !!desc->hash;
3098 }
3099
3100 struct _eina_value_type_hash_copy_each_ctx
3101 {
3102    const Eina_Value_Type *subtype;
3103    Eina_Value_Hash *dest;
3104    Eina_Bool ret;
3105 };
3106
3107 static Eina_Bool
3108 _eina_value_type_hash_copy_each(const Eina_Hash *hash __UNUSED__, const void *key, void *_ptr, void *user_data)
3109 {
3110    struct _eina_value_type_hash_copy_each_ctx *ctx = user_data;
3111    const void *ptr = _ptr;
3112    void *imem = malloc(ctx->subtype->value_size);
3113    if (!imem)
3114      {
3115         ctx->ret = EINA_FALSE;
3116         return EINA_FALSE;
3117      }
3118    if (!ctx->subtype->copy(ctx->subtype, ptr, imem))
3119      {
3120         free(imem);
3121         ctx->ret = EINA_FALSE;
3122         return EINA_FALSE;
3123      }
3124    if (!eina_hash_add(ctx->dest->hash, key, imem))
3125      {
3126         eina_value_type_flush(ctx->subtype, imem);
3127         free(imem);
3128         ctx->ret = EINA_FALSE;
3129         return EINA_FALSE;
3130      }
3131    return EINA_TRUE;
3132 }
3133
3134 static Eina_Bool
3135 _eina_value_type_hash_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
3136 {
3137    const Eina_Value_Hash *s = src;
3138    Eina_Value_Hash *d = dst;
3139    struct _eina_value_type_hash_copy_each_ctx ctx = {s->subtype, d, EINA_TRUE};
3140
3141    d->subtype = s->subtype;
3142    d->buckets_power_size = s->buckets_power_size;
3143
3144    if ((!s->hash) || (!s->subtype))
3145      {
3146         d->hash = NULL;
3147         return EINA_TRUE;
3148      }
3149
3150    if (!s->subtype->copy)
3151      {
3152         eina_error_set(EINA_ERROR_VALUE_FAILED);
3153         return EINA_FALSE;
3154      }
3155
3156    if (!_eina_value_type_hash_create(d))
3157      return EINA_FALSE;
3158
3159    eina_hash_foreach(s->hash, _eina_value_type_hash_copy_each, &ctx);
3160    if (!ctx.ret)
3161      {
3162         _eina_value_type_hash_flush_elements(d);
3163         return EINA_FALSE;
3164      }
3165    return EINA_TRUE;
3166 }
3167
3168 struct _eina_value_type_hash_compare_each_ctx
3169 {
3170    const Eina_Value_Type *subtype;
3171    const Eina_Hash *other;
3172    int cmp;
3173 };
3174
3175 static Eina_Bool
3176 _eina_value_type_hash_compare_each(const Eina_Hash *hash __UNUSED__, const void *key, void *_ptr, void *user_data)
3177 {
3178    struct _eina_value_type_hash_compare_each_ctx *ctx = user_data;
3179    const void *self_ptr = _ptr;
3180    const void *other_ptr = eina_hash_find(ctx->other, key);
3181    if (!other_ptr) return EINA_TRUE;
3182    ctx->cmp = ctx->subtype->compare(ctx->subtype, self_ptr, other_ptr);
3183    return ctx->cmp == 0;
3184 }
3185
3186 static int
3187 _eina_value_type_hash_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
3188 {
3189    const Eina_Value_Hash *eva_a = a, *eva_b = b;
3190    struct _eina_value_type_hash_compare_each_ctx ctx = {
3191      eva_a->subtype, eva_b->hash, 0
3192    };
3193
3194    if (eva_a->subtype != eva_b->subtype)
3195      {
3196         eina_error_set(EINA_ERROR_VALUE_FAILED);
3197         return -1;
3198      }
3199
3200    if (!eva_a->subtype->compare)
3201      {
3202         eina_error_set(EINA_ERROR_VALUE_FAILED);
3203         return 0;
3204      }
3205
3206    if ((!eva_a->hash) && (!eva_b->hash))
3207      return 0;
3208    else if (!eva_a->hash)
3209      return -1;
3210    else if (!eva_b->hash)
3211      return 1;
3212
3213    eina_hash_foreach(eva_a->hash, _eina_value_type_hash_compare_each, &ctx);
3214    if (ctx.cmp == 0)
3215      {
3216         unsigned int count_a = eina_hash_population(eva_a->hash);
3217         unsigned int count_b = eina_hash_population(eva_b->hash);
3218         if (count_a < count_b)
3219           return -1;
3220         else if (count_a > count_b)
3221           return 1;
3222         return 0;
3223      }
3224
3225    return ctx.cmp;
3226 }
3227
3228 static Eina_Bool
3229 _eina_value_type_hash_find_first(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *ptr, void *user_data)
3230 {
3231    void **ret = user_data;
3232    *ret = ptr;
3233    return EINA_FALSE;
3234 }
3235
3236 struct _eina_value_type_hash_convert_to_string_each_ctx
3237 {
3238    const Eina_Value_Type *subtype;
3239    Eina_Strbuf *str;
3240    Eina_Value tmp;
3241    Eina_Bool first;
3242 };
3243
3244 static Eina_Bool
3245 _eina_value_type_hash_convert_to_string_each(const Eina_Hash *hash __UNUSED__, const void *_key, void *_ptr, void *user_data)
3246 {
3247    struct _eina_value_type_hash_convert_to_string_each_ctx *ctx = user_data;
3248    const char *key = _key;
3249    const void *ptr = _ptr;
3250    Eina_Bool r = EINA_FALSE;
3251
3252    if (ctx->first) ctx->first = EINA_FALSE;
3253    else eina_strbuf_append_length(ctx->str, ", ", 2);
3254
3255    eina_strbuf_append(ctx->str, key);
3256    eina_strbuf_append_length(ctx->str, ": ", 2);
3257
3258    if (ctx->subtype->convert_to)
3259      {
3260         r = ctx->subtype->convert_to(ctx->subtype, EINA_VALUE_TYPE_STRING,
3261                                      ptr, ctx->tmp.value.buf);
3262         if (r)
3263           {
3264              eina_strbuf_append(ctx->str, ctx->tmp.value.ptr);
3265              free(ctx->tmp.value.ptr);
3266              ctx->tmp.value.ptr = NULL;
3267           }
3268      }
3269
3270    if (!r)
3271      eina_strbuf_append_char(ctx->str, '?');
3272
3273    return EINA_TRUE;
3274 }
3275
3276 static Eina_Bool
3277 _eina_value_type_hash_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
3278 {
3279    const Eina_Value_Hash *tmem = type_mem;
3280    Eina_Bool ret = EINA_FALSE;
3281
3282    if ((convert == EINA_VALUE_TYPE_STRING) ||
3283        (convert == EINA_VALUE_TYPE_STRINGSHARE))
3284      {
3285         Eina_Strbuf *str = eina_strbuf_new();
3286         const char *s;
3287         if (!tmem->hash) eina_strbuf_append(str, "{}");
3288         else
3289           {
3290              struct _eina_value_type_hash_convert_to_string_each_ctx ctx;
3291
3292              ctx.subtype = tmem->subtype;
3293              ctx.str = str;
3294              ctx.first = EINA_TRUE;
3295              eina_value_setup(&ctx.tmp, EINA_VALUE_TYPE_STRING);
3296
3297              eina_strbuf_append_char(str, '{');
3298
3299              eina_hash_foreach(tmem->hash,
3300                                _eina_value_type_hash_convert_to_string_each,
3301                                &ctx);
3302
3303              eina_strbuf_append_char(str, '}');
3304           }
3305         s = eina_strbuf_string_get(str);
3306         ret = eina_value_type_pset(convert, convert_mem, &s);
3307         eina_strbuf_free(str);
3308      }
3309    else if ((tmem->hash) && (eina_hash_population(tmem->hash) == 1))
3310      {
3311         const Eina_Value_Type *subtype = tmem->subtype;
3312         void *imem = NULL;
3313
3314         eina_hash_foreach(tmem->hash, _eina_value_type_hash_find_first, &imem);
3315         if (!imem) /* shouldn't happen... */
3316           ret = EINA_FALSE;
3317         else
3318           {
3319              if (subtype->convert_to)
3320                ret = subtype->convert_to(subtype, convert, imem, convert_mem);
3321              if ((!ret) && (convert->convert_from))
3322                ret = convert->convert_from(convert, subtype, convert_mem, imem);
3323           }
3324      }
3325
3326    if (!ret)
3327      {
3328         eina_error_set(EINA_ERROR_VALUE_FAILED);
3329         return EINA_FALSE;
3330      }
3331    return EINA_TRUE;
3332 }
3333
3334 static Eina_Bool
3335 _eina_value_type_hash_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
3336 {
3337    Eina_Value_Hash *tmem = mem;
3338    const Eina_Value_Hash *desc = ptr;
3339
3340    eina_error_set(0);
3341    if ((!tmem->subtype) && (!desc->subtype))
3342      return EINA_TRUE;
3343
3344    if ((tmem->hash) && (tmem->hash == desc->hash))
3345      {
3346         tmem->subtype = desc->subtype;
3347         return EINA_TRUE;
3348      }
3349
3350    if (desc->hash)
3351      {
3352         Eina_Value_Hash tmp;
3353
3354         if (!_eina_value_type_hash_copy(type, desc, &tmp))
3355           return EINA_FALSE;
3356
3357         _eina_value_type_hash_flush(type, tmem);
3358         memcpy(tmem, &tmp, sizeof(tmp));
3359         return EINA_TRUE;
3360      }
3361
3362    if (tmem->hash) _eina_value_type_hash_flush_elements(tmem);
3363
3364    tmem->subtype = desc->subtype;
3365    if (!_eina_value_type_hash_create(tmem))
3366      return EINA_FALSE;
3367
3368    return EINA_TRUE;
3369 }
3370
3371 static Eina_Bool
3372 _eina_value_type_hash_vset(const Eina_Value_Type *type, void *mem, va_list args)
3373 {
3374    const Eina_Value_Hash desc = va_arg(args, Eina_Value_Hash);
3375    _eina_value_type_hash_pset(type, mem, &desc);
3376    return EINA_TRUE;
3377 }
3378
3379 static Eina_Bool
3380 _eina_value_type_hash_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
3381 {
3382    memcpy(ptr, mem, sizeof(Eina_Value_Hash));
3383    return EINA_TRUE;
3384 }
3385
3386 static const Eina_Value_Type _EINA_VALUE_TYPE_HASH = {
3387   EINA_VALUE_TYPE_VERSION,
3388   sizeof(Eina_Value_Hash),
3389   "Eina_Value_Hash",
3390   _eina_value_type_hash_setup,
3391   _eina_value_type_hash_flush,
3392   _eina_value_type_hash_copy,
3393   _eina_value_type_hash_compare,
3394   _eina_value_type_hash_convert_to,
3395   NULL, /* no convert from */
3396   _eina_value_type_hash_vset,
3397   _eina_value_type_hash_pset,
3398   _eina_value_type_hash_pget
3399 };
3400
3401 static Eina_Bool
3402 _eina_value_type_timeval_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
3403 {
3404    memset(mem, 0, sizeof(struct timeval));
3405    return EINA_TRUE;
3406 }
3407
3408 static Eina_Bool
3409 _eina_value_type_timeval_flush(const Eina_Value_Type *type __UNUSED__, void *mem __UNUSED__)
3410 {
3411    return EINA_TRUE;
3412 }
3413
3414 static Eina_Bool
3415 _eina_value_type_timeval_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
3416 {
3417    const struct timeval *s = src;
3418    struct timeval *d = dst;
3419    *d = *s;
3420    return EINA_TRUE;
3421 }
3422
3423 static inline struct timeval _eina_value_type_timeval_fix(const struct timeval *input)
3424 {
3425    struct timeval ret = *input;
3426    if (EINA_UNLIKELY(ret.tv_usec < 0))
3427      {
3428         ret.tv_sec -= 1;
3429         ret.tv_usec += 1e6;
3430      }
3431    return ret;
3432 }
3433
3434 static int
3435 _eina_value_type_timeval_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
3436 {
3437    struct timeval va = _eina_value_type_timeval_fix(a);
3438    struct timeval vb = _eina_value_type_timeval_fix(b);
3439
3440    if (va.tv_sec < vb.tv_sec)
3441      return -1;
3442    else if (va.tv_sec > vb.tv_sec)
3443      return 1;
3444
3445    if (va.tv_usec < vb.tv_usec)
3446      return -1;
3447    else if (va.tv_usec > vb.tv_usec)
3448      return 1;
3449
3450    return 0;
3451 }
3452
3453 static Eina_Bool
3454 _eina_value_type_timeval_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
3455 {
3456    struct timeval v = _eina_value_type_timeval_fix(type_mem);
3457
3458    eina_error_set(0);
3459
3460    if (convert == EINA_VALUE_TYPE_UCHAR)
3461      {
3462         unsigned char other_mem = v.tv_sec;
3463         if (EINA_UNLIKELY(v.tv_sec < 0))
3464           return EINA_FALSE;
3465         if (EINA_UNLIKELY(v.tv_sec > eina_value_uchar_max))
3466             return EINA_FALSE;
3467         return eina_value_type_pset(convert, convert_mem, &other_mem);
3468      }
3469    else if (convert == EINA_VALUE_TYPE_USHORT)
3470      {
3471         unsigned short other_mem = v.tv_sec;
3472         if (EINA_UNLIKELY(v.tv_sec < 0))
3473           return EINA_FALSE;
3474         if (EINA_UNLIKELY(v.tv_sec > eina_value_ushort_max))
3475           return EINA_FALSE;
3476         return eina_value_type_pset(convert, convert_mem, &other_mem);
3477      }
3478    else if (convert == EINA_VALUE_TYPE_UINT)
3479      {
3480         unsigned int other_mem = v.tv_sec;
3481         if (EINA_UNLIKELY(v.tv_sec < 0))
3482           return EINA_FALSE;
3483         if (EINA_UNLIKELY((unsigned long) v.tv_sec > eina_value_uint_max))
3484           return EINA_FALSE;
3485         return eina_value_type_pset(convert, convert_mem, &other_mem);
3486      }
3487    else if ((convert == EINA_VALUE_TYPE_ULONG) || (convert == EINA_VALUE_TYPE_TIMESTAMP))
3488      {
3489         unsigned long other_mem = v.tv_sec;
3490         if (EINA_UNLIKELY(v.tv_sec < 0))
3491           return EINA_FALSE;
3492         if (EINA_UNLIKELY((sizeof(other_mem) != sizeof(v)) &&
3493                           ((unsigned long)v.tv_sec > eina_value_ulong_max)))
3494           return EINA_FALSE;
3495         return eina_value_type_pset(convert, convert_mem, &other_mem);
3496      }
3497    else if (convert == EINA_VALUE_TYPE_UINT64)
3498      {
3499         uint64_t other_mem = v.tv_sec;
3500         if (EINA_UNLIKELY(v.tv_sec < 0))
3501           return EINA_FALSE;
3502         return eina_value_type_pset(convert, convert_mem, &other_mem);
3503      }
3504    else if (convert == EINA_VALUE_TYPE_CHAR)
3505      {
3506         char other_mem = v.tv_sec;
3507         if (EINA_UNLIKELY(v.tv_sec < eina_value_char_min))
3508           return EINA_FALSE;
3509         if (EINA_UNLIKELY(v.tv_sec > eina_value_char_max))
3510           return EINA_FALSE;
3511         return eina_value_type_pset(convert, convert_mem, &other_mem);
3512      }
3513    else if (convert == EINA_VALUE_TYPE_SHORT)
3514      {
3515         short other_mem = v.tv_sec;
3516         if (EINA_UNLIKELY(v.tv_sec < eina_value_short_min))
3517           return EINA_FALSE;
3518         if (EINA_UNLIKELY(v.tv_sec > eina_value_short_max))
3519           return EINA_FALSE;
3520         return eina_value_type_pset(convert, convert_mem, &other_mem);
3521      }
3522    else if (convert == EINA_VALUE_TYPE_INT)
3523      {
3524         int other_mem = v.tv_sec;
3525         if (EINA_UNLIKELY(v.tv_sec < eina_value_int_min))
3526           return EINA_FALSE;
3527         if (EINA_UNLIKELY(v.tv_sec > eina_value_int_max))
3528           return EINA_FALSE;
3529         return eina_value_type_pset(convert, convert_mem, &other_mem);
3530      }
3531    else if (convert == EINA_VALUE_TYPE_LONG)
3532      {
3533         long other_mem = v.tv_sec;
3534         if (EINA_UNLIKELY(v.tv_sec < eina_value_long_min))
3535           return EINA_FALSE;
3536         if (EINA_UNLIKELY(v.tv_sec > eina_value_long_max))
3537           return EINA_FALSE;
3538         return eina_value_type_pset(convert, convert_mem, &other_mem);
3539      }
3540    else if (convert == EINA_VALUE_TYPE_INT64)
3541      {
3542         int64_t other_mem = v.tv_sec;
3543         return eina_value_type_pset(convert, convert_mem, &other_mem);
3544      }
3545    else if (convert == EINA_VALUE_TYPE_FLOAT)
3546      {
3547         float other_mem = (float)v.tv_sec + (float)v.tv_usec / 1.0e6;
3548         return eina_value_type_pset(convert, convert_mem, &other_mem);
3549      }
3550    else if (convert == EINA_VALUE_TYPE_DOUBLE)
3551      {
3552         double other_mem = (double)v.tv_sec + (double)v.tv_usec / 1.0e6;
3553         return eina_value_type_pset(convert, convert_mem, &other_mem);
3554      }
3555    else if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
3556             convert == EINA_VALUE_TYPE_STRING)
3557      {
3558         const char *other_mem;
3559         char buf[64];
3560         snprintf(buf, sizeof(buf), "%ld.%06ld", v.tv_sec, v.tv_usec);
3561         other_mem = buf; /* required due &buf == buf */
3562         return eina_value_type_pset(convert, convert_mem, &other_mem);
3563      }
3564    else
3565      {
3566         eina_error_set(EINA_ERROR_VALUE_FAILED);
3567         return EINA_FALSE;
3568      }
3569 }
3570
3571 static Eina_Bool
3572 _eina_value_type_timeval_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
3573 {
3574    struct timeval *tmem = mem;
3575    *tmem = _eina_value_type_timeval_fix(ptr);
3576    return EINA_TRUE;
3577 }
3578
3579 static Eina_Bool
3580 _eina_value_type_timeval_vset(const Eina_Value_Type *type, void *mem, va_list args)
3581 {
3582    const struct timeval desc = va_arg(args, struct timeval);
3583    _eina_value_type_timeval_pset(type, mem, &desc);
3584    return EINA_TRUE;
3585 }
3586
3587 static Eina_Bool
3588 _eina_value_type_timeval_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
3589 {
3590    memcpy(ptr, mem, sizeof(struct timeval));
3591    return EINA_TRUE;
3592 }
3593
3594 static const Eina_Value_Type _EINA_VALUE_TYPE_TIMEVAL = {
3595   EINA_VALUE_TYPE_VERSION,
3596   sizeof(struct timeval),
3597   "struct timeval",
3598   _eina_value_type_timeval_setup,
3599   _eina_value_type_timeval_flush,
3600   _eina_value_type_timeval_copy,
3601   _eina_value_type_timeval_compare,
3602   _eina_value_type_timeval_convert_to,
3603   NULL, /* no convert from */
3604   _eina_value_type_timeval_vset,
3605   _eina_value_type_timeval_pset,
3606   _eina_value_type_timeval_pget
3607 };
3608
3609 static Eina_Bool
3610 _eina_value_type_blob_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
3611 {
3612    memset(mem, 0, sizeof(Eina_Value_Blob));
3613    return EINA_TRUE;
3614 }
3615
3616 static inline const Eina_Value_Blob_Operations *
3617 _eina_value_type_blob_ops_get(const Eina_Value_Blob *blob)
3618 {
3619    if (!blob) return NULL;
3620    if (!blob->ops) return NULL;
3621    EINA_SAFETY_ON_FALSE_RETURN_VAL
3622      (blob->ops->version == EINA_VALUE_BLOB_OPERATIONS_VERSION, NULL);
3623    return blob->ops;
3624 }
3625
3626 static Eina_Bool
3627 _eina_value_type_blob_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
3628 {
3629    const Eina_Value_Blob_Operations *ops = _eina_value_type_blob_ops_get(mem);
3630    Eina_Value_Blob *tmem = mem;
3631    if ((ops) && (ops->free))
3632      ops->free(ops, (void *)tmem->memory, tmem->size);
3633    tmem->memory = NULL;
3634    tmem->size = 0;
3635    return EINA_TRUE;
3636 }
3637
3638 static Eina_Bool
3639 _eina_value_type_blob_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
3640 {
3641    const Eina_Value_Blob_Operations *ops = _eina_value_type_blob_ops_get(src);
3642    const Eina_Value_Blob *s = src;
3643    Eina_Value_Blob *d = dst;
3644
3645    *d = *s;
3646
3647    if ((ops) && (ops->copy))
3648      {
3649         d->memory = ops->copy(ops, s->memory, s->size);
3650         if ((d->memory == NULL) && (s->size > 0))
3651           return EINA_FALSE;
3652      }
3653
3654    return EINA_TRUE;
3655 }
3656
3657 static int
3658 _eina_value_type_blob_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
3659 {
3660    const Eina_Value_Blob_Operations *ops = _eina_value_type_blob_ops_get(a);
3661    const Eina_Value_Blob *ta = a, *tb = b;
3662    size_t minsize;
3663    if (ta->ops != tb->ops)
3664      {
3665         eina_error_set(EINA_ERROR_VALUE_FAILED);
3666         return -1;
3667      }
3668    if ((ops) && (ops->compare))
3669      return ops->compare(ops, ta->memory, ta->size, tb->memory, tb->size);
3670
3671    if (ta->size < tb->size)
3672      minsize = ta->size;
3673    else
3674      minsize = tb->size;
3675
3676    return memcmp(ta->memory, tb->memory, minsize);
3677 }
3678
3679 static Eina_Bool
3680 _eina_value_type_blob_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
3681 {
3682    const Eina_Value_Blob *tmem = type_mem;
3683
3684    eina_error_set(0);
3685    if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
3686        convert == EINA_VALUE_TYPE_STRING)
3687      {
3688         const Eina_Value_Blob_Operations *ops;
3689         Eina_Strbuf *str;
3690         const char *other_mem;
3691         Eina_Bool ret = EINA_FALSE, first = EINA_TRUE;
3692         const unsigned char *ptr, *ptr_end;
3693
3694         ops = _eina_value_type_blob_ops_get(tmem);
3695         if ((ops) && (ops->to_string))
3696           {
3697              char *x = ops->to_string(ops, tmem->memory, tmem->size);
3698              if (x)
3699                {
3700                   ret = eina_value_type_pset(convert, convert_mem, &x);
3701                   free(x);
3702                }
3703              return ret;
3704           }
3705
3706         str = eina_strbuf_new();
3707         if (!str)
3708           return EINA_FALSE;
3709
3710         if (!eina_strbuf_append_printf(str, "BLOB(%u, [", tmem->size))
3711           goto error;
3712
3713         ptr = tmem->memory;
3714         ptr_end = ptr + tmem->size;
3715         for (; ptr < ptr_end; ptr++)
3716           {
3717              if (first)
3718                {
3719                   first = EINA_FALSE;
3720                   if (!eina_strbuf_append_printf(str, "%02hhx", *ptr))
3721                     goto error;
3722                }
3723              else
3724                {
3725                   if (!eina_strbuf_append_printf(str, " %02hhx", *ptr))
3726                     goto error;
3727                }
3728           }
3729
3730         if (!eina_strbuf_append(str, "])"))
3731           goto error;
3732
3733         other_mem = eina_strbuf_string_get(str);
3734         ret = eina_value_type_pset(convert, convert_mem, &other_mem);
3735
3736      error:
3737         eina_strbuf_free(str);
3738         return ret;
3739      }
3740    else
3741      {
3742         eina_error_set(EINA_ERROR_VALUE_FAILED);
3743         return EINA_FALSE;
3744      }
3745 }
3746
3747 static Eina_Bool
3748 _eina_value_type_blob_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem)
3749 {
3750    Eina_Value_Blob desc;
3751    char *buf;
3752
3753    desc.ops = EINA_VALUE_BLOB_OPERATIONS_MALLOC;
3754
3755    if ((convert == EINA_VALUE_TYPE_STRING) ||
3756        (convert == EINA_VALUE_TYPE_STRINGSHARE))
3757      {
3758         const char *str = *(const char **)convert_mem;
3759         if (!str)
3760           {
3761              desc.size = 0;
3762              desc.memory = NULL;
3763           }
3764         else
3765           {
3766              desc.size = strlen(str) + 1;
3767              desc.memory = buf = malloc(desc.size);
3768              if (!desc.memory)
3769                {
3770                   eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
3771                   return EINA_FALSE;
3772                }
3773              memcpy(buf, str, desc.size);
3774           }
3775      }
3776    else if (convert == EINA_VALUE_TYPE_ARRAY)
3777      {
3778         const Eina_Value_Array *a = convert_mem;
3779         if ((!a->array) || (a->array->len == 0))
3780           {
3781              desc.size = 0;
3782              desc.memory = NULL;
3783           }
3784         else
3785           {
3786              desc.size = a->array->len * a->array->member_size;
3787              desc.memory = buf = malloc(desc.size);
3788              if (!desc.memory)
3789                {
3790                   eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
3791                   return EINA_FALSE;
3792                }
3793              memcpy(buf, a->array->members, desc.size);
3794           }
3795      }
3796    else if (convert == EINA_VALUE_TYPE_BLOB)
3797      {
3798         const Eina_Value_Blob *b = convert_mem;
3799         if (b->size == 0)
3800           {
3801              desc.size = 0;
3802              desc.memory = NULL;
3803           }
3804         else
3805           {
3806              desc.size = b->size;
3807              desc.memory = buf = malloc(desc.size);
3808              if (!desc.memory)
3809                {
3810                   eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
3811                   return EINA_FALSE;
3812                }
3813              memcpy(buf, b->memory, desc.size);
3814           }
3815      }
3816    else
3817      {
3818         desc.size = convert->value_size;
3819         desc.memory = buf = malloc(convert->value_size);
3820         if (!desc.memory)
3821           {
3822              eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
3823              return EINA_FALSE;
3824           }
3825         if (!eina_value_type_pget(convert, convert_mem, buf))
3826           {
3827              free(buf);
3828              return EINA_FALSE;
3829           }
3830      }
3831    return eina_value_type_pset(type, type_mem, &desc);
3832 }
3833
3834 static Eina_Bool
3835 _eina_value_type_blob_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
3836 {
3837    const Eina_Value_Blob_Operations *ops = _eina_value_type_blob_ops_get(mem);
3838    Eina_Value_Blob *tmem = mem;
3839    const Eina_Value_Blob *desc = ptr;
3840
3841    eina_error_set(0);
3842    if ((tmem->memory) && (tmem->memory == desc->memory))
3843      {
3844         tmem->ops = desc->ops;
3845         tmem->size = desc->size;
3846         return EINA_TRUE;
3847      }
3848
3849    if ((ops) && (ops->free))
3850      ops->free(ops, (void *)tmem->memory, tmem->size);
3851
3852    *tmem = *desc;
3853    return EINA_TRUE;
3854 }
3855
3856 static Eina_Bool
3857 _eina_value_type_blob_vset(const Eina_Value_Type *type, void *mem, va_list args)
3858 {
3859    const Eina_Value_Blob desc = va_arg(args, Eina_Value_Blob);
3860    _eina_value_type_blob_pset(type, mem, &desc);
3861    return EINA_TRUE;
3862 }
3863
3864 static Eina_Bool
3865 _eina_value_type_blob_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
3866 {
3867    memcpy(ptr, mem, sizeof(Eina_Value_Blob));
3868    return EINA_TRUE;
3869 }
3870
3871 static const Eina_Value_Type _EINA_VALUE_TYPE_BLOB = {
3872   EINA_VALUE_TYPE_VERSION,
3873   sizeof(Eina_Value_Blob),
3874   "Eina_Value_Blob",
3875   _eina_value_type_blob_setup,
3876   _eina_value_type_blob_flush,
3877   _eina_value_type_blob_copy,
3878   _eina_value_type_blob_compare,
3879   _eina_value_type_blob_convert_to,
3880   _eina_value_type_blob_convert_from,
3881   _eina_value_type_blob_vset,
3882   _eina_value_type_blob_pset,
3883   _eina_value_type_blob_pget
3884 };
3885
3886 static int
3887 _eina_value_struct_operations_binsearch_cmp(const void *pa, const void *pb)
3888 {
3889    const Eina_Value_Struct_Member *a = pa, *b = pb;
3890    return strcmp(a->name, b->name);
3891 }
3892
3893 static const Eina_Value_Struct_Member *
3894 _eina_value_struct_operations_binsearch_find_member(const Eina_Value_Struct_Operations *ops __UNUSED__, const Eina_Value_Struct_Desc *desc, const char *name)
3895 {
3896    unsigned int count = desc->member_count;
3897    Eina_Value_Struct_Member search;
3898    if (count == 0)
3899      {
3900         const Eina_Value_Struct_Member *itr = desc->members;
3901         for (; itr->name != NULL; itr++)
3902           count++;
3903      }
3904
3905    search.name = name;
3906    return bsearch(&search, desc->members, count,
3907                   sizeof(Eina_Value_Struct_Member),
3908                   _eina_value_struct_operations_binsearch_cmp);
3909 }
3910
3911 static Eina_Value_Struct_Operations _EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH = {
3912   EINA_VALUE_STRUCT_OPERATIONS_VERSION,
3913   NULL, /* default alloc */
3914   NULL, /* default free */
3915   NULL, /* default copy */
3916   NULL, /* default compare */
3917   _eina_value_struct_operations_binsearch_find_member
3918 };
3919
3920 static const Eina_Value_Struct_Member *
3921 _eina_value_struct_operations_stringshare_find_member(const Eina_Value_Struct_Operations *ops __UNUSED__, const Eina_Value_Struct_Desc *desc, const char *name)
3922 {
3923    const Eina_Value_Struct_Member *itr = desc->members;
3924
3925    /* assumes name is stringshared.
3926     *
3927     * we do this because it's the recommended usage pattern, moreover
3928     * we expect to find the member, as users shouldn't look for
3929     * non-existent members!
3930     */
3931    if (desc->member_count > 0)
3932      {
3933         const Eina_Value_Struct_Member *itr_end = itr + desc->member_count;
3934         for (; itr < itr_end; itr++)
3935           if (itr->name == name)
3936             return itr;
3937      }
3938    else
3939      {
3940         for (; itr->name != NULL; itr++)
3941           if (itr->name == name)
3942             return itr;
3943      }
3944
3945    itr = desc->members;
3946    name = eina_stringshare_add(name);
3947    eina_stringshare_del(name); /* we'll not use the contents, this is fine */
3948    /* stringshare and look again */
3949    if (desc->member_count > 0)
3950      {
3951         const Eina_Value_Struct_Member *itr_end = itr + desc->member_count;
3952         for (; itr < itr_end; itr++)
3953           if (itr->name == name)
3954             return itr;
3955      }
3956    else
3957      {
3958         for (; itr->name != NULL; itr++)
3959           if (itr->name == name)
3960             return itr;
3961      }
3962
3963    return NULL;
3964 }
3965
3966 static Eina_Value_Struct_Operations _EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE = {
3967   EINA_VALUE_STRUCT_OPERATIONS_VERSION,
3968   NULL, /* default alloc */
3969   NULL, /* default free */
3970   NULL, /* default copy */
3971   NULL, /* default compare */
3972   _eina_value_struct_operations_stringshare_find_member
3973 };
3974
3975 static inline const Eina_Value_Struct_Operations *
3976 _eina_value_type_struct_ops_get(const Eina_Value_Struct *st)
3977 {
3978    if (!st) return NULL;
3979    if (!st->desc) return NULL;
3980    if (!st->desc->ops) return NULL;
3981    EINA_SAFETY_ON_FALSE_RETURN_VAL
3982      (st->desc->ops->version == EINA_VALUE_STRUCT_OPERATIONS_VERSION, NULL);
3983    return st->desc->ops;
3984 }
3985
3986 EAPI const Eina_Value_Struct_Member *
3987 eina_value_struct_member_find(const Eina_Value_Struct *st, const char *name)
3988 {
3989    const Eina_Value_Struct_Operations *ops;
3990    const Eina_Value_Struct_Member *itr;
3991
3992    EINA_SAFETY_ON_NULL_RETURN_VAL(st, NULL);
3993    EINA_SAFETY_ON_NULL_RETURN_VAL(st->desc, NULL);
3994
3995    ops = _eina_value_type_struct_ops_get(st);
3996    if ((ops) && (ops->find_member))
3997      return ops->find_member(ops, st->desc, name);
3998
3999    itr = st->desc->members;
4000    if (st->desc->member_count)
4001      {
4002         const Eina_Value_Struct_Member *itr_end = itr + st->desc->member_count;
4003         for (; itr < itr_end; itr++)
4004           {
4005              if (strcmp(name, itr->name) == 0)
4006                return itr;
4007           }
4008         return NULL;
4009      }
4010    else
4011      {
4012         for (; itr->name != NULL; itr++)
4013           {
4014              if (strcmp(name, itr->name) == 0)
4015                return itr;
4016           }
4017         return NULL;
4018      }
4019 }
4020
4021 static Eina_Bool
4022 _eina_value_type_struct_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
4023 {
4024    memset(mem, 0, sizeof(Eina_Value_Struct));
4025    return EINA_TRUE;
4026 }
4027
4028 static Eina_Bool
4029 _eina_value_type_struct_setup_member(const Eina_Value_Struct_Member *member, Eina_Value_Struct *st)
4030 {
4031    unsigned char *base = st->memory;
4032    return eina_value_type_setup(member->type, base + member->offset);
4033 }
4034
4035 static Eina_Bool
4036 _eina_value_type_struct_flush_member(const Eina_Value_Struct_Member *member, Eina_Value_Struct *st)
4037 {
4038    unsigned char *base = st->memory;
4039    return eina_value_type_flush(member->type, base + member->offset);
4040 }
4041
4042 static Eina_Bool
4043 _eina_value_type_struct_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
4044 {
4045    const Eina_Value_Struct_Operations *ops;
4046    const Eina_Value_Struct_Member *itr;
4047    Eina_Value_Struct *tmem = mem;
4048    Eina_Bool ret = EINA_TRUE;
4049
4050    if ((!tmem->desc) || (!tmem->memory))
4051      return EINA_TRUE;
4052
4053    itr = tmem->desc->members;
4054    if (tmem->desc->member_count > 0)
4055      {
4056         const Eina_Value_Struct_Member *itr_end;
4057         itr_end = itr + tmem->desc->member_count;
4058         for (; itr < itr_end; itr++)
4059           ret &= _eina_value_type_struct_flush_member(itr, tmem);
4060      }
4061    else
4062      {
4063         for (; itr->name != NULL; itr++)
4064           ret &= _eina_value_type_struct_flush_member(itr, tmem);
4065      }
4066
4067    ops = _eina_value_type_struct_ops_get(mem);
4068    if ((ops) && (ops->free))
4069      ops->free(ops, tmem->desc, tmem->memory);
4070    else
4071      free(tmem->memory);
4072
4073    tmem->memory = NULL;
4074    tmem->desc = NULL;
4075
4076    return ret;
4077 }
4078
4079 static Eina_Bool
4080 _eina_value_type_struct_copy_member(const Eina_Value_Struct_Member *member, const Eina_Value_Struct *s, Eina_Value_Struct *d)
4081 {
4082    const unsigned char *base_s = s->memory;
4083    unsigned char *base_d = d->memory;
4084    return eina_value_type_copy(member->type,
4085                                base_s + member->offset,
4086                                base_d + member->offset);
4087 }
4088
4089 static Eina_Bool
4090 _eina_value_type_struct_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
4091 {
4092    const Eina_Value_Struct_Operations *ops;
4093    const Eina_Value_Struct_Member *itr;
4094    const Eina_Value_Struct *s = src;
4095    Eina_Value_Struct *d = dst;
4096
4097    *d = *s;
4098
4099    if ((!s->desc) || (!s->memory))
4100      return EINA_TRUE;
4101
4102    ops = _eina_value_type_struct_ops_get(src);
4103    if ((ops) && (ops->copy))
4104      {
4105         d->memory = ops->copy(ops, s->desc, s->memory);
4106         if (d->memory == NULL)
4107           return EINA_FALSE;
4108         return EINA_TRUE;
4109      }
4110
4111    if ((ops) && (ops->alloc))
4112      d->memory = ops->alloc(ops, s->desc);
4113    else
4114      d->memory = malloc(s->desc->size);
4115    if (!d->memory)
4116      {
4117         eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
4118         return EINA_FALSE;
4119      }
4120
4121    itr = s->desc->members;
4122    if (s->desc->member_count > 0)
4123      {
4124         const Eina_Value_Struct_Member *itr_end = itr + s->desc->member_count;
4125         for (; itr < itr_end; itr++)
4126           if (!_eina_value_type_struct_copy_member(itr, s, d))
4127             goto error;
4128      }
4129    else
4130      {
4131         for (; itr->name != NULL; itr++)
4132           if (!_eina_value_type_struct_copy_member(itr, s, d))
4133             goto error;
4134      }
4135
4136    return EINA_TRUE;
4137
4138  error:
4139    itr--;
4140    for (; itr >= s->desc->members; itr--)
4141      _eina_value_type_struct_flush_member(itr, d);
4142
4143    if ((ops) && (ops->free))
4144      ops->free(ops, s->desc, d->memory);
4145    else
4146      free(d->memory);
4147    return EINA_FALSE;
4148 }
4149
4150 static inline int
4151 _eina_value_type_struct_compare_member(const Eina_Value_Struct_Member *member, const Eina_Value_Struct *ta, const Eina_Value_Struct *tb)
4152 {
4153    const unsigned char *base_a = ta->memory;
4154    const unsigned char *base_b = tb->memory;
4155    return eina_value_type_compare(member->type,
4156                                   base_a + member->offset,
4157                                   base_b + member->offset);
4158 }
4159
4160 static int
4161 _eina_value_type_struct_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
4162 {
4163    const Eina_Value_Struct_Operations *ops = _eina_value_type_struct_ops_get(a);
4164    const Eina_Value_Struct *ta = a, *tb = b;
4165    const Eina_Value_Struct_Member *itr;
4166    int cmp = 0;
4167
4168    if ((!ta->desc) && (!tb->desc))
4169      return 0;
4170    else if (ta->desc != tb->desc)
4171      {
4172         eina_error_set(EINA_ERROR_VALUE_FAILED);
4173         return -1;
4174      }
4175    if (ta->desc->ops != tb->desc->ops)
4176      {
4177         eina_error_set(EINA_ERROR_VALUE_FAILED);
4178         return -1;
4179      }
4180    if ((!ta->memory) && (!tb->memory))
4181      return 0;
4182    else if (!ta->memory)
4183      return -1;
4184    else if (!tb->memory)
4185      return 1;
4186
4187    if ((ops) && (ops->compare))
4188      return ops->compare(ops, ta->desc, ta->memory, tb->memory);
4189
4190    itr = ta->desc->members;
4191    if (ta->desc->member_count > 0)
4192      {
4193         const Eina_Value_Struct_Member *itr_end = itr + ta->desc->member_count;
4194         for (; (cmp == 0) && (itr < itr_end); itr++)
4195           cmp = _eina_value_type_struct_compare_member(itr, ta, tb);
4196      }
4197    else
4198      {
4199         for (; (cmp == 0) && (itr->name != NULL); itr++)
4200           cmp = _eina_value_type_struct_compare_member(itr, ta, tb);
4201      }
4202    return cmp;
4203 }
4204
4205 static void
4206 _eina_value_type_struct_convert_to_string_member(const Eina_Value_Struct *st, const Eina_Value_Struct_Member *member, Eina_Strbuf *str)
4207 {
4208    const unsigned char *p = st->memory;
4209    Eina_Bool first = st->desc->members == member;
4210    Eina_Bool r = EINA_FALSE;
4211
4212    if (first) eina_strbuf_append_printf(str, "%s: ", member->name);
4213    else eina_strbuf_append_printf(str, ", %s: ", member->name);
4214
4215    if ((member->type) && (member->type->convert_to))
4216      {
4217         const Eina_Value_Type *type = member->type;
4218         char *conv = NULL;
4219
4220         r = eina_value_type_convert_to(type, EINA_VALUE_TYPE_STRING,
4221                                        p + member->offset, &conv);
4222         if (r)
4223           {
4224              eina_strbuf_append(str, conv);
4225              free(conv);
4226           }
4227      }
4228
4229    if (!r)
4230      eina_strbuf_append_char(str, '?');
4231 }
4232
4233 static Eina_Bool
4234 _eina_value_type_struct_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
4235 {
4236    const Eina_Value_Struct *tmem = type_mem;
4237
4238    eina_error_set(0);
4239    if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
4240        convert == EINA_VALUE_TYPE_STRING)
4241      {
4242         Eina_Strbuf *str = eina_strbuf_new();
4243         const char *s;
4244         Eina_Bool ret;
4245
4246         if (!tmem->memory) eina_strbuf_append(str, "{}");
4247         else
4248           {
4249              const Eina_Value_Struct_Member *itr = tmem->desc->members;
4250
4251              eina_strbuf_append_char(str, '{');
4252
4253              if (tmem->desc->member_count > 0)
4254                {
4255                   const Eina_Value_Struct_Member *itr_end;
4256
4257                   itr_end = itr + tmem->desc->member_count;
4258                   for (; itr < itr_end; itr++)
4259                     _eina_value_type_struct_convert_to_string_member
4260                       (tmem, itr, str);
4261                }
4262              else
4263                {
4264                   for (; itr->name != NULL; itr++)
4265                     _eina_value_type_struct_convert_to_string_member
4266                       (tmem, itr, str);
4267                }
4268
4269              eina_strbuf_append_char(str, '}');
4270           }
4271         s = eina_strbuf_string_get(str);
4272         ret = eina_value_type_pset(convert, convert_mem, &s);
4273         eina_strbuf_free(str);
4274         return ret;
4275      }
4276    else
4277      {
4278         eina_error_set(EINA_ERROR_VALUE_FAILED);
4279         return EINA_FALSE;
4280      }
4281 }
4282
4283 static Eina_Bool
4284 _eina_value_type_struct_desc_check(const Eina_Value_Struct_Desc *desc)
4285 {
4286    unsigned int minsize = 0;
4287    const Eina_Value_Struct_Member *itr;
4288
4289    EINA_SAFETY_ON_NULL_RETURN_VAL(desc, EINA_FALSE);
4290    EINA_SAFETY_ON_FALSE_RETURN_VAL
4291      (desc->version == EINA_VALUE_STRUCT_DESC_VERSION, EINA_FALSE);
4292
4293    itr = desc->members;
4294    if (desc->member_count > 0)
4295      {
4296         const Eina_Value_Struct_Member *itr_end = itr + desc->member_count;
4297         for (; itr < itr_end; itr++)
4298           {
4299              unsigned int member_end;
4300
4301              EINA_SAFETY_ON_FALSE_RETURN_VAL
4302                (eina_value_type_check(itr->type), EINA_FALSE);
4303              EINA_SAFETY_ON_FALSE_RETURN_VAL
4304                (itr->type->value_size > 0, EINA_FALSE);
4305
4306              member_end = itr->offset + itr->type->value_size;
4307              if (minsize < member_end)
4308                minsize = member_end;
4309           }
4310      }
4311    else
4312      {
4313         for (; itr->name != NULL; itr++)
4314           {
4315              unsigned int member_end;
4316
4317              EINA_SAFETY_ON_FALSE_RETURN_VAL
4318                (eina_value_type_check(itr->type), EINA_FALSE);
4319              EINA_SAFETY_ON_FALSE_RETURN_VAL
4320                (itr->type->value_size > 0, EINA_FALSE);
4321
4322              member_end = itr->offset + itr->type->value_size;
4323              if (minsize < member_end)
4324                minsize = member_end;
4325           }
4326      }
4327
4328    EINA_SAFETY_ON_FALSE_RETURN_VAL(minsize > 0, EINA_FALSE);
4329    EINA_SAFETY_ON_FALSE_RETURN_VAL(desc->size >= minsize, EINA_FALSE);
4330    return EINA_TRUE;
4331 }
4332
4333 static Eina_Bool
4334 _eina_value_type_struct_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
4335 {
4336    const Eina_Value_Struct_Operations *ops;
4337    Eina_Value_Struct *tmem = mem;
4338    const Eina_Value_Struct *desc = ptr;
4339    const Eina_Value_Struct_Member *itr;
4340
4341    if (!_eina_value_type_struct_desc_check(desc->desc))
4342      {
4343         eina_error_set(EINA_ERROR_VALUE_FAILED);
4344         return EINA_FALSE;
4345      }
4346
4347    eina_error_set(0);
4348    if ((tmem->memory) && (tmem->memory == desc->memory))
4349      {
4350         tmem->desc = desc->desc;
4351         return EINA_TRUE;
4352      }
4353
4354    if (desc->memory)
4355      {
4356         Eina_Value_Struct tmp;
4357
4358         if (!_eina_value_type_struct_copy(type, desc, &tmp))
4359           return EINA_FALSE;
4360
4361         _eina_value_type_struct_flush(type, tmem);
4362         memcpy(tmem, &tmp, sizeof(tmp));
4363         return EINA_TRUE;
4364      }
4365
4366    if (tmem->memory) _eina_value_type_struct_flush(type, mem);
4367
4368    tmem->desc = desc->desc;
4369
4370    ops = _eina_value_type_struct_ops_get(desc);
4371    if ((ops) && (ops->alloc))
4372      tmem->memory = ops->alloc(ops, tmem->desc);
4373    else
4374      tmem->memory = malloc(tmem->desc->size);
4375
4376    if (!tmem->memory)
4377      {
4378         eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
4379         return EINA_FALSE;
4380      }
4381
4382    itr = tmem->desc->members;
4383    if (tmem->desc->member_count > 0)
4384      {
4385         const Eina_Value_Struct_Member *itr_end;
4386         itr_end = itr + tmem->desc->member_count;
4387         for (; itr < itr_end; itr++)
4388           if (!_eina_value_type_struct_setup_member(itr, tmem))
4389             goto error;
4390      }
4391    else
4392      {
4393         for (; itr->name != NULL; itr++)
4394           if (!_eina_value_type_struct_setup_member(itr, tmem))
4395             goto error;
4396      }
4397
4398    return EINA_TRUE;
4399
4400  error:
4401    itr--;
4402    for (; itr >= tmem->desc->members; itr--)
4403      _eina_value_type_struct_flush_member(itr, tmem);
4404
4405    if ((ops) && (ops->free))
4406      ops->free(ops, tmem->desc, tmem->memory);
4407    else
4408      free(tmem->memory);
4409    tmem->memory = NULL;
4410    tmem->desc = NULL;
4411    return EINA_FALSE;
4412 }
4413
4414 static Eina_Bool
4415 _eina_value_type_struct_vset(const Eina_Value_Type *type, void *mem, va_list args)
4416 {
4417    const Eina_Value_Struct desc = va_arg(args, Eina_Value_Struct);
4418    _eina_value_type_struct_pset(type, mem, &desc);
4419    return EINA_TRUE;
4420 }
4421
4422 static Eina_Bool
4423 _eina_value_type_struct_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
4424 {
4425    memcpy(ptr, mem, sizeof(Eina_Value_Struct));
4426    return EINA_TRUE;
4427 }
4428
4429 static const Eina_Value_Type _EINA_VALUE_TYPE_STRUCT = {
4430   EINA_VALUE_TYPE_VERSION,
4431   sizeof(Eina_Value_Struct),
4432   "Eina_Value_Struct",
4433   _eina_value_type_struct_setup,
4434   _eina_value_type_struct_flush,
4435   _eina_value_type_struct_copy,
4436   _eina_value_type_struct_compare,
4437   _eina_value_type_struct_convert_to,
4438   NULL, /* no convert from */
4439   _eina_value_type_struct_vset,
4440   _eina_value_type_struct_pset,
4441   _eina_value_type_struct_pget
4442 };
4443
4444 /* no model for now
4445 static Eina_Bool
4446 _eina_value_type_model_setup(const Eina_Value_Type *type __UNUSED__, void *mem)
4447 {
4448    Eina_Model **tmem = mem;
4449    *tmem = NULL;
4450    return EINA_TRUE;
4451 }
4452
4453 static Eina_Bool
4454 _eina_value_type_model_flush(const Eina_Value_Type *type __UNUSED__, void *mem)
4455 {
4456    Eina_Model **tmem = mem;
4457    if (*tmem)
4458      {
4459         eina_model_unref(*tmem);
4460         *tmem = NULL;
4461      }
4462    return EINA_TRUE;
4463 }
4464
4465 static Eina_Bool
4466 _eina_value_type_model_copy(const Eina_Value_Type *type __UNUSED__, const void *src, void *dst)
4467 {
4468    const Eina_Model * const *s = src;
4469    Eina_Model **d = dst;
4470    if (*s)
4471      *d = eina_model_copy(*s); // is it better to deep-copy?
4472    else
4473      *d = NULL;
4474    return EINA_TRUE;
4475 }
4476
4477 static int
4478 _eina_value_type_model_compare(const Eina_Value_Type *type __UNUSED__, const void *a, const void *b)
4479 {
4480    const Eina_Model * const *ta = a;
4481    const Eina_Model * const *tb = b;
4482
4483    if ((!*ta) && (!*tb)) return 0;
4484    else if (!*ta) return 1;
4485    else if (!*tb) return -1;
4486    else return eina_model_compare(*ta, *tb);
4487 }
4488
4489 static Eina_Bool
4490 _eina_value_type_model_convert_to(const Eina_Value_Type *type __UNUSED__, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
4491 {
4492    const Eina_Model *v = *(const Eina_Model **)type_mem;
4493
4494    eina_error_set(0);
4495
4496    if (convert == EINA_VALUE_TYPE_STRINGSHARE ||
4497        convert == EINA_VALUE_TYPE_STRING)
4498      {
4499         char *other_mem = v ? eina_model_to_string(v) : NULL;
4500         Eina_Bool ret = eina_value_type_pset(convert, convert_mem, &other_mem);
4501         free(other_mem);
4502         return ret;
4503      }
4504    else
4505      {
4506         eina_error_set(EINA_ERROR_VALUE_FAILED);
4507         return EINA_FALSE;
4508      }
4509
4510    return EINA_TRUE;
4511 }
4512
4513 static Eina_Bool
4514 _eina_value_type_model_vset(const Eina_Value_Type *type __UNUSED__, void *mem, va_list args)
4515 {
4516    Eina_Model **tmem = mem, *tmp;
4517
4518    tmp = va_arg(args, Eina_Model *);
4519
4520    if (tmp) eina_model_ref(tmp);
4521    if (*tmem) eina_model_unref(*tmem);
4522
4523    *tmem = tmp;
4524
4525    return EINA_TRUE;
4526 }
4527
4528 static Eina_Bool
4529 _eina_value_type_model_pset(const Eina_Value_Type *type __UNUSED__, void *mem, const void *ptr)
4530 {
4531    Eina_Model **tmem = mem;
4532    Eina_Model **p = (Eina_Model **)ptr;
4533
4534    eina_error_set(0);
4535    if (*tmem == *p) return EINA_TRUE;
4536
4537    if (*p) eina_model_ref(*p);
4538    if (*tmem) eina_model_unref(*tmem);
4539
4540    *tmem = *p;
4541
4542    return EINA_TRUE;
4543 }
4544
4545 static Eina_Bool
4546 _eina_value_type_model_pget(const Eina_Value_Type *type __UNUSED__, const void *mem, void *ptr)
4547 {
4548    Eina_Model **tmem = (Eina_Model **)mem;
4549    Eina_Model **p = ptr;
4550    *p = *tmem;
4551    return EINA_TRUE;
4552 }
4553
4554 static const Eina_Value_Type _EINA_VALUE_TYPE_MODEL = {
4555   EINA_VALUE_TYPE_VERSION,
4556   sizeof(Eina_Model *),
4557   "Eina_Model",
4558   _eina_value_type_model_setup,
4559   _eina_value_type_model_flush,
4560   _eina_value_type_model_copy,
4561   _eina_value_type_model_compare,
4562   _eina_value_type_model_convert_to,
4563   NULL, // no convert from
4564   _eina_value_type_model_vset,
4565   _eina_value_type_model_pset,
4566   _eina_value_type_model_pget
4567 };
4568 */
4569
4570 /* keep all basic types inlined in an array so we can compare if it's
4571  * a basic type using pointer arithmetic.
4572  *
4573  * NOTE-1: JUST BASIC TYPES, DO NOT ADD MORE TYPES HERE!!!
4574  * NOTE-2: KEEP ORDER, see eina_value_init()
4575  */
4576 static const Eina_Value_Type _EINA_VALUE_TYPE_BASICS[] = {
4577   {
4578     EINA_VALUE_TYPE_VERSION,
4579     sizeof(unsigned char),
4580     "unsigned char",
4581     _eina_value_type_uchar_setup,
4582     _eina_value_type_uchar_flush,
4583     _eina_value_type_uchar_copy,
4584     _eina_value_type_uchar_compare,
4585     _eina_value_type_uchar_convert_to,
4586     NULL, /* no convert from */
4587     _eina_value_type_uchar_vset,
4588     _eina_value_type_uchar_pset,
4589     _eina_value_type_uchar_pget
4590   },
4591   {
4592     EINA_VALUE_TYPE_VERSION,
4593     sizeof(unsigned short),
4594     "unsigned short",
4595     _eina_value_type_ushort_setup,
4596     _eina_value_type_ushort_flush,
4597     _eina_value_type_ushort_copy,
4598     _eina_value_type_ushort_compare,
4599     _eina_value_type_ushort_convert_to,
4600     NULL, /* no convert from */
4601     _eina_value_type_ushort_vset,
4602     _eina_value_type_ushort_pset,
4603     _eina_value_type_ushort_pget
4604   },
4605   {
4606     EINA_VALUE_TYPE_VERSION,
4607     sizeof(unsigned int),
4608     "unsigned int",
4609     _eina_value_type_uint_setup,
4610     _eina_value_type_uint_flush,
4611     _eina_value_type_uint_copy,
4612     _eina_value_type_uint_compare,
4613     _eina_value_type_uint_convert_to,
4614     NULL, /* no convert from */
4615     _eina_value_type_uint_vset,
4616     _eina_value_type_uint_pset,
4617     _eina_value_type_uint_pget
4618   },
4619   {
4620     EINA_VALUE_TYPE_VERSION,
4621     sizeof(unsigned long),
4622     "unsigned long",
4623     _eina_value_type_ulong_setup,
4624     _eina_value_type_ulong_flush,
4625     _eina_value_type_ulong_copy,
4626     _eina_value_type_ulong_compare,
4627     _eina_value_type_ulong_convert_to,
4628     NULL, /* no convert from */
4629     _eina_value_type_ulong_vset,
4630     _eina_value_type_ulong_pset,
4631     _eina_value_type_ulong_pget
4632   },
4633   {
4634     EINA_VALUE_TYPE_VERSION,
4635     sizeof(uint64_t),
4636     "uint64_t",
4637     _eina_value_type_uint64_setup,
4638     _eina_value_type_uint64_flush,
4639     _eina_value_type_uint64_copy,
4640     _eina_value_type_uint64_compare,
4641     _eina_value_type_uint64_convert_to,
4642     NULL, /* no convert from */
4643     _eina_value_type_uint64_vset,
4644     _eina_value_type_uint64_pset,
4645     _eina_value_type_uint64_pget
4646   },
4647   {
4648     EINA_VALUE_TYPE_VERSION,
4649     sizeof(char),
4650     "char",
4651     _eina_value_type_char_setup,
4652     _eina_value_type_char_flush,
4653     _eina_value_type_char_copy,
4654     _eina_value_type_char_compare,
4655     _eina_value_type_char_convert_to,
4656     NULL, /* no convert from */
4657     _eina_value_type_char_vset,
4658     _eina_value_type_char_pset,
4659     _eina_value_type_char_pget
4660   },
4661   {
4662     EINA_VALUE_TYPE_VERSION,
4663     sizeof(short),
4664     "short",
4665     _eina_value_type_short_setup,
4666     _eina_value_type_short_flush,
4667     _eina_value_type_short_copy,
4668     _eina_value_type_short_compare,
4669     _eina_value_type_short_convert_to,
4670     NULL, /* no convert from */
4671     _eina_value_type_short_vset,
4672     _eina_value_type_short_pset,
4673     _eina_value_type_short_pget
4674   },
4675   {
4676     EINA_VALUE_TYPE_VERSION,
4677     sizeof(int),
4678     "int",
4679     _eina_value_type_int_setup,
4680     _eina_value_type_int_flush,
4681     _eina_value_type_int_copy,
4682     _eina_value_type_int_compare,
4683     _eina_value_type_int_convert_to,
4684     NULL, /* no convert from */
4685     _eina_value_type_int_vset,
4686     _eina_value_type_int_pset,
4687     _eina_value_type_int_pget
4688   },
4689   {
4690     EINA_VALUE_TYPE_VERSION,
4691     sizeof(long),
4692     "long",
4693     _eina_value_type_long_setup,
4694     _eina_value_type_long_flush,
4695     _eina_value_type_long_copy,
4696     _eina_value_type_long_compare,
4697     _eina_value_type_long_convert_to,
4698     NULL, /* no convert from */
4699     _eina_value_type_long_vset,
4700     _eina_value_type_long_pset,
4701     _eina_value_type_long_pget
4702   },
4703   {
4704     EINA_VALUE_TYPE_VERSION,
4705     sizeof(int64_t),
4706     "int64_t",
4707     _eina_value_type_int64_setup,
4708     _eina_value_type_int64_flush,
4709     _eina_value_type_int64_copy,
4710     _eina_value_type_int64_compare,
4711     _eina_value_type_int64_convert_to,
4712     NULL, /* no convert from */
4713     _eina_value_type_int64_vset,
4714     _eina_value_type_int64_pset,
4715     _eina_value_type_int64_pget
4716   },
4717   {
4718     EINA_VALUE_TYPE_VERSION,
4719     sizeof(float),
4720     "float",
4721     _eina_value_type_float_setup,
4722     _eina_value_type_float_flush,
4723     _eina_value_type_float_copy,
4724     _eina_value_type_float_compare,
4725     _eina_value_type_float_convert_to,
4726     NULL, /* no convert from */
4727     _eina_value_type_float_vset,
4728     _eina_value_type_float_pset,
4729     _eina_value_type_float_pget
4730   },
4731   {
4732     EINA_VALUE_TYPE_VERSION,
4733     sizeof(double),
4734     "double",
4735     _eina_value_type_double_setup,
4736     _eina_value_type_double_flush,
4737     _eina_value_type_double_copy,
4738     _eina_value_type_double_compare,
4739     _eina_value_type_double_convert_to,
4740     NULL, /* no convert from */
4741     _eina_value_type_double_vset,
4742     _eina_value_type_double_pset,
4743     _eina_value_type_double_pget
4744   },
4745   {
4746     EINA_VALUE_TYPE_VERSION,
4747     sizeof(const char *),
4748     "stringshare",
4749     _eina_value_type_string_common_setup,
4750     _eina_value_type_stringshare_flush,
4751     _eina_value_type_stringshare_copy,
4752     _eina_value_type_string_common_compare,
4753     _eina_value_type_string_common_convert_to,
4754     NULL, /* no convert from */
4755     _eina_value_type_stringshare_vset,
4756     _eina_value_type_stringshare_pset,
4757     _eina_value_type_string_common_pget
4758   },
4759   {
4760     EINA_VALUE_TYPE_VERSION,
4761     sizeof(char *),
4762     "string",
4763     _eina_value_type_string_common_setup,
4764     _eina_value_type_string_flush,
4765     _eina_value_type_string_copy,
4766     _eina_value_type_string_common_compare,
4767     _eina_value_type_string_common_convert_to,
4768     NULL, /* no convert from */
4769     _eina_value_type_string_vset,
4770     _eina_value_type_string_pset,
4771     _eina_value_type_string_common_pget
4772   },
4773   {
4774     EINA_VALUE_TYPE_VERSION,
4775     sizeof(unsigned long),
4776     "timestamp",
4777     _eina_value_type_ulong_setup,
4778     _eina_value_type_ulong_flush,
4779     _eina_value_type_ulong_copy,
4780     _eina_value_type_ulong_compare,
4781     _eina_value_type_ulong_convert_to,
4782     NULL, /* no convert from */
4783     _eina_value_type_ulong_vset,
4784     _eina_value_type_ulong_pset,
4785     _eina_value_type_ulong_pget
4786   }
4787 };
4788
4789 static void
4790 _eina_value_blob_operations_malloc_free(const Eina_Value_Blob_Operations *ops __UNUSED__, void *memory, size_t size __UNUSED__)
4791 {
4792    free(memory);
4793 }
4794
4795 static void *
4796 _eina_value_blob_operations_malloc_copy(const Eina_Value_Blob_Operations *ops __UNUSED__, const void *memory, size_t size)
4797 {
4798    void *ret = malloc(size);
4799    if (!ret)
4800      {
4801         eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
4802         return NULL;
4803      }
4804    memcpy(ret, memory, size);
4805    return ret;
4806 }
4807
4808 static const Eina_Value_Blob_Operations _EINA_VALUE_BLOB_OPERATIONS_MALLOC = {
4809   EINA_VALUE_BLOB_OPERATIONS_VERSION,
4810   _eina_value_blob_operations_malloc_free,
4811   _eina_value_blob_operations_malloc_copy,
4812   NULL,
4813   NULL
4814 };
4815
4816 typedef struct _Eina_Value_Inner_Mp Eina_Value_Inner_Mp;
4817 struct _Eina_Value_Inner_Mp
4818 {
4819    Eina_Mempool *mempool;
4820    int references;
4821 };
4822
4823 /**
4824  * @endcond
4825  */
4826
4827 static const char EINA_ERROR_VALUE_FAILED_STR[] = "Value check failed.";
4828
4829 /**
4830  */
4831
4832 static inline void
4833 _eina_value_inner_mp_dispose(int size, Eina_Value_Inner_Mp *imp)
4834 {
4835    EINA_SAFETY_ON_FALSE_RETURN(imp->references == 0);
4836
4837    eina_hash_del_by_key(_eina_value_inner_mps, &size);
4838    eina_mempool_del(imp->mempool);
4839    free(imp);
4840 }
4841
4842 static inline Eina_Value_Inner_Mp *
4843 _eina_value_inner_mp_get(int size)
4844 {
4845    Eina_Value_Inner_Mp *imp = eina_hash_find(_eina_value_inner_mps, &size);
4846    if (imp) return imp;
4847
4848    imp = malloc(sizeof(Eina_Value_Inner_Mp));
4849    if (!imp)
4850      return NULL;
4851
4852    imp->references = 0;
4853
4854    imp->mempool = eina_mempool_add(_eina_value_mp_choice,
4855                                    "Eina_Value_Inner_Mp", NULL, size, 128);
4856    if (!imp->mempool)
4857      {
4858         free(imp);
4859         return NULL;
4860      }
4861
4862    if (!eina_hash_add(_eina_value_inner_mps, &size, imp))
4863      {
4864         eina_mempool_del(imp->mempool);
4865         free(imp);
4866         return NULL;
4867      }
4868
4869    return imp;
4870 }
4871
4872 static inline void *
4873 _eina_value_inner_alloc_internal(int size)
4874 {
4875    Eina_Value_Inner_Mp *imp;
4876    void *mem;
4877
4878    imp = _eina_value_inner_mp_get(size);
4879    if (!imp) return NULL;
4880
4881    mem = eina_mempool_malloc(imp->mempool, size);
4882    if (mem) imp->references++;
4883    else if (imp->references == 0) _eina_value_inner_mp_dispose(size, imp);
4884
4885    return mem;
4886 }
4887
4888 static inline void
4889 _eina_value_inner_free_internal(int size, void *mem)
4890 {
4891    Eina_Value_Inner_Mp *imp = eina_hash_find(_eina_value_inner_mps, &size);
4892    EINA_SAFETY_ON_NULL_RETURN(imp);
4893
4894    eina_mempool_free(imp->mempool, mem);
4895
4896    imp->references--;
4897    if (imp->references > 0) return;
4898    _eina_value_inner_mp_dispose(size, imp);
4899 }
4900
4901 EAPI void *
4902 eina_value_inner_alloc(size_t size)
4903 {
4904    void *mem;
4905
4906    if (size > 256) return malloc(size);
4907
4908    eina_lock_take(&_eina_value_inner_mps_lock);
4909    mem = _eina_value_inner_alloc_internal(size);
4910    eina_lock_release(&_eina_value_inner_mps_lock);
4911
4912    return mem;
4913 }
4914
4915 EAPI void
4916 eina_value_inner_free(size_t size, void *mem)
4917 {
4918    if (size > 256)
4919      {
4920         free(mem);
4921         return;
4922      }
4923
4924    eina_lock_take(&_eina_value_inner_mps_lock);
4925    _eina_value_inner_free_internal(size, mem);
4926    eina_lock_release(&_eina_value_inner_mps_lock);
4927 }
4928
4929 /**
4930  * @internal
4931  * @brief Initialize the value module.
4932  *
4933  * @return #EINA_TRUE on success, #EINA_FALSE on failure.
4934  *
4935  * This function sets up the value module of Eina. It is called
4936  * by eina_init().
4937  *
4938  * @see eina_init()
4939  */
4940 Eina_Bool
4941 eina_value_init(void)
4942 {
4943    const char *choice, *tmp;
4944
4945    _eina_value_log_dom = eina_log_domain_register("eina_value",
4946                                                   EINA_LOG_COLOR_DEFAULT);
4947    if (_eina_value_log_dom < 0)
4948      {
4949         EINA_LOG_ERR("Could not register log domain: eina_value");
4950         return EINA_FALSE;
4951      }
4952
4953 #ifdef EINA_DEFAULT_MEMPOOL
4954    choice = "pass_through";
4955 #else
4956    choice = "chained_mempool";
4957 #endif
4958    tmp = getenv("EINA_MEMPOOL");
4959    if (tmp && tmp[0])
4960      choice = tmp;
4961
4962    if (choice)
4963      _eina_value_mp_choice = strdup(choice);
4964
4965    _eina_value_mp = eina_mempool_add
4966       (_eina_value_mp_choice, "value", NULL, sizeof(Eina_Value), 320);
4967    if (!_eina_value_mp)
4968      {
4969         ERR("Mempool for value cannot be allocated in value init.");
4970         goto on_init_fail_mp;
4971      }
4972
4973    if (!eina_lock_new(&_eina_value_inner_mps_lock))
4974      {
4975         ERR("Cannot create lock in value init.");
4976         goto on_init_fail_lock;
4977      }
4978    _eina_value_inner_mps = eina_hash_int32_new(NULL);
4979    if (!_eina_value_inner_mps)
4980      {
4981         ERR("Cannot create hash for inner mempools in value init.");
4982         goto on_init_fail_hash;
4983      }
4984
4985    EINA_ERROR_VALUE_FAILED = eina_error_msg_static_register(
4986          EINA_ERROR_VALUE_FAILED_STR);
4987
4988    EINA_VALUE_TYPE_UCHAR       = _EINA_VALUE_TYPE_BASICS +  0;
4989    EINA_VALUE_TYPE_USHORT      = _EINA_VALUE_TYPE_BASICS +  1;
4990    EINA_VALUE_TYPE_UINT        = _EINA_VALUE_TYPE_BASICS +  2;
4991    EINA_VALUE_TYPE_ULONG       = _EINA_VALUE_TYPE_BASICS +  3;
4992    EINA_VALUE_TYPE_UINT64      = _EINA_VALUE_TYPE_BASICS +  4;
4993    EINA_VALUE_TYPE_CHAR        = _EINA_VALUE_TYPE_BASICS +  5;
4994    EINA_VALUE_TYPE_SHORT       = _EINA_VALUE_TYPE_BASICS +  6;
4995    EINA_VALUE_TYPE_INT         = _EINA_VALUE_TYPE_BASICS +  7;
4996    EINA_VALUE_TYPE_LONG        = _EINA_VALUE_TYPE_BASICS +  8;
4997    EINA_VALUE_TYPE_INT64       = _EINA_VALUE_TYPE_BASICS +  9;
4998    EINA_VALUE_TYPE_FLOAT       = _EINA_VALUE_TYPE_BASICS + 10;
4999    EINA_VALUE_TYPE_DOUBLE      = _EINA_VALUE_TYPE_BASICS + 11;
5000    EINA_VALUE_TYPE_STRINGSHARE = _EINA_VALUE_TYPE_BASICS + 12;
5001    EINA_VALUE_TYPE_STRING      = _EINA_VALUE_TYPE_BASICS + 13;
5002    EINA_VALUE_TYPE_TIMESTAMP   = _EINA_VALUE_TYPE_BASICS +  14;
5003
5004    _EINA_VALUE_TYPE_BASICS_START = _EINA_VALUE_TYPE_BASICS +  0;
5005    _EINA_VALUE_TYPE_BASICS_END   = _EINA_VALUE_TYPE_BASICS + 14;
5006
5007    EINA_SAFETY_ON_FALSE_RETURN_VAL((sizeof(_EINA_VALUE_TYPE_BASICS)/sizeof(_EINA_VALUE_TYPE_BASICS[0])) == 15, EINA_FALSE);
5008
5009
5010    EINA_VALUE_TYPE_ARRAY = &_EINA_VALUE_TYPE_ARRAY;
5011    EINA_VALUE_TYPE_LIST = &_EINA_VALUE_TYPE_LIST;
5012    EINA_VALUE_TYPE_HASH = &_EINA_VALUE_TYPE_HASH;
5013    EINA_VALUE_TYPE_TIMEVAL = &_EINA_VALUE_TYPE_TIMEVAL;
5014    EINA_VALUE_TYPE_BLOB = &_EINA_VALUE_TYPE_BLOB;
5015    EINA_VALUE_TYPE_STRUCT = &_EINA_VALUE_TYPE_STRUCT;
5016 /* no model for now
5017    EINA_VALUE_TYPE_MODEL = &_EINA_VALUE_TYPE_MODEL;
5018  */
5019    
5020    EINA_VALUE_BLOB_OPERATIONS_MALLOC = &_EINA_VALUE_BLOB_OPERATIONS_MALLOC;
5021
5022    EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH = &_EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH;
5023    EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE = &_EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE;
5024
5025    return EINA_TRUE;
5026
5027  on_init_fail_hash:
5028    eina_lock_free(&_eina_value_inner_mps_lock);
5029  on_init_fail_lock:
5030    eina_mempool_del(_eina_value_mp);
5031  on_init_fail_mp:
5032    free(_eina_value_mp_choice);
5033    _eina_value_mp_choice = NULL;
5034    eina_log_domain_unregister(_eina_value_log_dom);
5035    _eina_value_log_dom = -1;
5036    return EINA_FALSE;
5037 }
5038
5039 /**
5040  * @internal
5041  * @brief Shut down the value module.
5042  *
5043  * @return #EINA_TRUE on success, #EINA_FALSE on failure.
5044  *
5045  * This function shuts down the value module set up by
5046  * eina_value_init(). It is called by eina_shutdown().
5047  *
5048  * @see eina_shutdown()
5049  */
5050 Eina_Bool
5051 eina_value_shutdown(void)
5052 {
5053    eina_lock_take(&_eina_value_inner_mps_lock);
5054    if (eina_hash_population(_eina_value_inner_mps) != 0)
5055      ERR("Cannot free eina_value internal memory pools -- still in use!");
5056    else
5057      eina_hash_free(_eina_value_inner_mps);
5058    eina_lock_release(&_eina_value_inner_mps_lock);
5059    eina_lock_free(&_eina_value_inner_mps_lock);
5060
5061    free(_eina_value_mp_choice);
5062    _eina_value_mp_choice = NULL;
5063    eina_mempool_del(_eina_value_mp);
5064    eina_log_domain_unregister(_eina_value_log_dom);
5065    _eina_value_log_dom = -1;
5066    return EINA_TRUE;
5067 }
5068
5069 /*============================================================================*
5070 *                                 Global                                     *
5071 *============================================================================*/
5072
5073 /*============================================================================*
5074 *                                   API                                      *
5075 *============================================================================*/
5076
5077 EAPI const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_START = NULL;
5078 EAPI const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_END = NULL;
5079
5080 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UCHAR = NULL;
5081 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_USHORT = NULL;
5082 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT = NULL;
5083 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ULONG = NULL;
5084 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMESTAMP = NULL;
5085 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_UINT64 = NULL;
5086 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_CHAR = NULL;
5087 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_SHORT = NULL;
5088 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_INT = NULL;
5089 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_LONG = NULL;
5090 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_INT64 = NULL;
5091 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_FLOAT = NULL;
5092 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_DOUBLE = NULL;
5093 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRINGSHARE = NULL;
5094 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRING = NULL;
5095 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_ARRAY = NULL;
5096 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_LIST = NULL;
5097 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_HASH = NULL;
5098 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_TIMEVAL = NULL;
5099 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_BLOB = NULL;
5100 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_STRUCT = NULL;
5101 /* no model for now
5102 EAPI const Eina_Value_Type *EINA_VALUE_TYPE_MODEL = NULL;
5103  */
5104
5105 EAPI const Eina_Value_Blob_Operations *EINA_VALUE_BLOB_OPERATIONS_MALLOC = NULL;
5106
5107 EAPI const Eina_Value_Struct_Operations *EINA_VALUE_STRUCT_OPERATIONS_BINSEARCH = NULL;
5108 EAPI const Eina_Value_Struct_Operations *EINA_VALUE_STRUCT_OPERATIONS_STRINGSHARE = NULL;
5109
5110 EAPI Eina_Error EINA_ERROR_VALUE_FAILED = 0;
5111
5112 EAPI const unsigned int eina_prime_table[] =
5113 {
5114    17, 31, 61, 127, 257, 509, 1021,
5115    2053, 4093, 8191, 16381, 32771, 65537, 131071, 262147, 524287, 1048573,
5116    2097143, 4194301, 8388617, 16777213
5117 };
5118
5119 EAPI Eina_Value *
5120 eina_value_new(const Eina_Value_Type *type)
5121 {
5122    Eina_Value *value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));;
5123    if (!value)
5124      {
5125         eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
5126         return NULL;
5127      }
5128    if (!eina_value_setup(value, type))
5129      {
5130         free(value);
5131         return NULL;
5132      }
5133    return value;
5134 }
5135
5136 EAPI void
5137 eina_value_free(Eina_Value *value)
5138 {
5139    EINA_SAFETY_ON_NULL_RETURN(value);
5140    eina_value_flush(value);
5141    eina_mempool_free(_eina_value_mp, value);
5142 }
5143
5144
5145 EAPI Eina_Bool
5146 eina_value_copy(const Eina_Value *value, Eina_Value *copy)
5147 {
5148    const Eina_Value_Type *type;
5149    const void *src;
5150    void *dst;
5151    Eina_Bool ret;
5152
5153    EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
5154    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type),
5155                                    EINA_FALSE);
5156    EINA_SAFETY_ON_NULL_RETURN_VAL(copy, EINA_FALSE);
5157    EINA_SAFETY_ON_NULL_RETURN_VAL(value->type->copy, EINA_FALSE);
5158
5159    type = value->type;
5160    if (!eina_value_setup(copy, type))
5161      return EINA_FALSE;
5162
5163    src = eina_value_memory_get(value);
5164    dst = eina_value_memory_get(copy);
5165    ret = type->copy(type, src, dst);
5166    if (!ret)
5167      eina_value_flush(copy);
5168
5169    return ret;
5170 }
5171
5172 EAPI Eina_Bool
5173 eina_value_convert(const Eina_Value *value, Eina_Value *convert)
5174 {
5175    Eina_Bool ret = EINA_FALSE;
5176    const Eina_Value_Type *type, *convert_type;
5177    const void *type_mem;
5178    void *convert_mem;
5179
5180    EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
5181    EINA_SAFETY_ON_NULL_RETURN_VAL(convert, EINA_FALSE);
5182    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type),
5183                                    EINA_FALSE);
5184    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(convert->type),
5185                                    EINA_FALSE);
5186
5187    type = value->type;
5188    convert_type = convert->type;
5189
5190    type_mem = eina_value_memory_get(value);
5191    convert_mem = eina_value_memory_get(convert);
5192
5193    if (type->convert_to)
5194      ret = type->convert_to(type, convert_type, type_mem, convert_mem);
5195
5196    if ((!ret) && (convert_type->convert_from))
5197      ret = convert_type->convert_from(convert_type, type, convert_mem,
5198                                       type_mem);
5199
5200    return ret;
5201 }
5202
5203 EAPI char *
5204 eina_value_to_string(const Eina_Value *value)
5205 {
5206    Eina_Value tmp;
5207
5208    EINA_SAFETY_ON_NULL_RETURN_VAL(value, NULL);
5209    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), NULL);
5210
5211    if (!eina_value_setup(&tmp, EINA_VALUE_TYPE_STRING))
5212      return NULL;
5213    if (!eina_value_convert(value, &tmp))
5214      return NULL;
5215
5216    return tmp.value.ptr; /* steal value */
5217 }
5218
5219 EAPI Eina_Value *
5220 eina_value_array_new(const Eina_Value_Type *subtype, unsigned int step)
5221 {
5222    Eina_Value *value;
5223
5224    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(subtype), EINA_FALSE);
5225
5226    value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));;
5227    if (!value)
5228      return NULL;
5229
5230    if (!eina_value_array_setup(value, subtype, step))
5231      {
5232         eina_mempool_free(_eina_value_mp, value);
5233         return NULL;
5234      }
5235
5236    return value;
5237 }
5238
5239 EAPI Eina_Value *
5240 eina_value_list_new(const Eina_Value_Type *subtype)
5241 {
5242    Eina_Value *value;
5243
5244    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(subtype), EINA_FALSE);
5245
5246    value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));;
5247    if (!value)
5248      return NULL;
5249
5250    if (!eina_value_list_setup(value, subtype))
5251      {
5252         eina_mempool_free(_eina_value_mp, value);
5253         return NULL;
5254      }
5255
5256    return value;
5257 }
5258
5259 EAPI Eina_Value *
5260 eina_value_hash_new(const Eina_Value_Type *subtype, unsigned int buckets_power_size)
5261 {
5262    Eina_Value *value;
5263
5264    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(subtype), EINA_FALSE);
5265
5266    value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));;
5267    if (!value)
5268      return NULL;
5269
5270    if (!eina_value_hash_setup(value, subtype, buckets_power_size))
5271      {
5272         eina_mempool_free(_eina_value_mp, value);
5273         return NULL;
5274      }
5275
5276    return value;
5277 }
5278
5279 EAPI Eina_Value *
5280 eina_value_struct_new(const Eina_Value_Struct_Desc *desc)
5281 {
5282    Eina_Value *value;
5283
5284    value = eina_mempool_malloc(_eina_value_mp, sizeof(Eina_Value));;
5285    if (!value)
5286      return NULL;
5287
5288    if (!eina_value_struct_setup(value, desc))
5289      {
5290         eina_mempool_free(_eina_value_mp, value);
5291         return NULL;
5292      }
5293
5294    return value;
5295 }
5296
5297 EAPI Eina_Bool
5298 eina_value_type_check(const Eina_Value_Type *type)
5299 {
5300    EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE);
5301    return type->version == EINA_VALUE_TYPE_VERSION;
5302 }
5303
5304 EAPI const char *
5305 eina_value_type_name_get(const Eina_Value_Type *type)
5306 {
5307    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), NULL);
5308    return type->name;
5309 }