EFL 1.7 svn doobies
[profile/ivi/eina.git] / src / include / eina_inline_value.x
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 #ifndef EINA_INLINE_VALUE_X_
20 #define EINA_INLINE_VALUE_X_
21
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "eina_stringshare.h"
26
27 /* NOTE: most of value is implemented here for performance reasons */
28
29 //#define EINA_VALUE_NO_OPTIMIZE 1
30 #ifdef EINA_VALUE_NO_OPTIMIZE
31 #define EINA_VALUE_TYPE_DEFAULT(type) (0)
32 #else
33
34 /**
35  * @var _EINA_VALUE_TYPE_BASICS_START
36  * pointer to the first basic type.
37  * @since 1.2
38  * @private
39  */
40 EAPI extern const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_START;
41
42 /**
43  * @var _EINA_VALUE_TYPE_BASICS_END
44  * pointer to the last (inclusive) basic type.
45  * @since 1.2
46  * @private
47  */
48 EAPI extern const Eina_Value_Type *_EINA_VALUE_TYPE_BASICS_END;
49 #define EINA_VALUE_TYPE_DEFAULT(type)           \
50   ((_EINA_VALUE_TYPE_BASICS_START <= type) &&   \
51    (type <= _EINA_VALUE_TYPE_BASICS_END))
52 #endif
53
54 #define EINA_VALUE_TYPE_CHECK_RETURN(value)     \
55   EINA_SAFETY_ON_NULL_RETURN(value);            \
56   EINA_SAFETY_ON_FALSE_RETURN(eina_value_type_check(value->type))
57
58 #define EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, retval)                 \
59   EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval);                        \
60   EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(value->type), retval)
61
62 #define EINA_VALUE_TYPE_DISPATCH(type, method, no_method_err, ...)      \
63   do                                                                    \
64     {                                                                   \
65        if (type->method)                                                \
66          type->method(type, ##__VA_ARGS__);                             \
67        else                                                             \
68          eina_error_set(no_method_err);                                 \
69     }                                                                   \
70   while (0)
71
72 #define EINA_VALUE_TYPE_DISPATCH_RETURN(value, method, no_method_err, def_ret, ...) \
73   do                                                                    \
74     {                                                                   \
75        if (type->method)                                                \
76          return type->method(type, ##__VA_ARGS__);                      \
77        eina_error_set(no_method_err);                                   \
78        return def_ret;                                                  \
79     }                                                                   \
80   while (0)
81
82 /**
83  * @brief Get memory for given value (inline or allocated buffer).
84  * @since 1.2
85  * @private
86  */
87 static inline void *
88 eina_value_memory_get(const Eina_Value *value)
89 {
90    if (value->type->value_size <= 8)
91      return (void *)value->value.buf;
92    return value->value.ptr;
93 }
94
95 /**
96  * @brief Allocate memory for internal value types.
97  * @since 1.2
98  * @private
99  */
100 EAPI void *eina_value_inner_alloc(size_t size);
101 /**
102  * @brief Releases memory for internal value types.
103  * @since 1.2
104  * @private
105  */
106 EAPI void eina_value_inner_free(size_t size, void *mem);
107
108 static inline Eina_Bool
109 eina_value_setup(Eina_Value *value, const Eina_Value_Type *type)
110 {
111    void *mem;
112
113    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
114    EINA_SAFETY_ON_FALSE_RETURN_VAL(type->value_size > 0, EINA_FALSE);
115
116    value->type = type;
117
118    if (type->value_size <= 8) mem = &value->value;
119    else
120      {
121         mem = value->value.ptr = eina_value_inner_alloc(type->value_size);
122         EINA_SAFETY_ON_NULL_RETURN_VAL(mem, EINA_FALSE);
123      }
124
125    memset(mem, 0, type->value_size);
126
127    if (EINA_VALUE_TYPE_DEFAULT(type))
128      {
129         eina_error_set(0);
130         return EINA_TRUE;
131      }
132
133    EINA_VALUE_TYPE_DISPATCH_RETURN(type, setup,
134                                    EINA_ERROR_VALUE_FAILED, EINA_FALSE, mem);
135 }
136
137 static inline void
138 eina_value_flush(Eina_Value *value)
139 {
140    const Eina_Value_Type *type;
141    void *mem;
142
143    EINA_VALUE_TYPE_CHECK_RETURN(value);
144
145    type = value->type;
146    mem = eina_value_memory_get(value);
147
148    if (EINA_VALUE_TYPE_DEFAULT(type))
149      {
150         if (type == EINA_VALUE_TYPE_STRINGSHARE)
151           {
152              if (value->value.ptr) eina_stringshare_del((const char*) value->value.ptr);
153           }
154         else if (type == EINA_VALUE_TYPE_STRING)
155           {
156              if (value->value.ptr) free(value->value.ptr);
157           }
158         else if (type->value_size > 8)
159           eina_value_inner_free(type->value_size, mem);
160         eina_error_set(0);
161         return;
162      }
163
164    EINA_VALUE_TYPE_DISPATCH(type, flush, EINA_ERROR_VALUE_FAILED, mem);
165    if (type->value_size > 8)
166      eina_value_inner_free(type->value_size, mem);
167    value->type = NULL;
168 }
169
170 static inline int
171 eina_value_compare(const Eina_Value *a, const Eina_Value *b)
172 {
173    const Eina_Value_Type *type;
174    void *pa, *pb;
175
176    EINA_VALUE_TYPE_CHECK_RETURN_VAL(a, -1);
177    EINA_SAFETY_ON_NULL_RETURN_VAL(b, -1);
178    EINA_SAFETY_ON_FALSE_RETURN_VAL(a->type == b->type, -1);
179
180    eina_error_set(0);
181    type = a->type;
182    pa = eina_value_memory_get(a);
183    pb = eina_value_memory_get(b);
184
185 #ifndef EINA_VALUE_NO_OPTIMIZE
186    if (type == EINA_VALUE_TYPE_UCHAR)
187      {
188         unsigned char *ta = (unsigned char *) pa, *tb = (unsigned char *) pb;
189         if (*ta < *tb)
190           return -1;
191         else if (*ta > *tb)
192           return 1;
193         return 0;
194      }
195    else if (type == EINA_VALUE_TYPE_USHORT)
196      {
197         unsigned short *ta = (unsigned short *) pa, *tb = (unsigned short *) pb;
198         if (*ta < *tb)
199           return -1;
200         else if (*ta > *tb)
201           return 1;
202         return 0;
203      }
204    else if (type == EINA_VALUE_TYPE_UINT)
205      {
206         unsigned int *ta = (unsigned int *) pa, *tb = (unsigned int *) pb;
207         if (*ta < *tb)
208           return -1;
209         else if (*ta > *tb)
210           return 1;
211         return 0;
212      }
213    else if ((type == EINA_VALUE_TYPE_ULONG) || (type == EINA_VALUE_TYPE_TIMESTAMP))
214      {
215         unsigned long *ta = (unsigned long *) pa, *tb = (unsigned long *) pb;
216         if (*ta < *tb)
217           return -1;
218         else if (*ta > *tb)
219           return 1;
220         return 0;
221      }
222    else if (type == EINA_VALUE_TYPE_UINT64)
223      {
224         uint64_t *ta = (uint64_t *) pa, *tb = (uint64_t *) pb;
225         if (*ta < *tb)
226           return -1;
227         else if (*ta > *tb)
228           return 1;
229         return 0;
230      }
231    else if (type == EINA_VALUE_TYPE_CHAR)
232      {
233         signed char *ta = (signed char *) pa, *tb = (signed char *) pb;
234         if (*ta < *tb)
235           return -1;
236         else if (*ta > *tb)
237           return 1;
238         return 0;
239      }
240    else if (type == EINA_VALUE_TYPE_SHORT)
241      {
242         short *ta = (short *) pa, *tb = (short *) pb;
243         if (*ta < *tb)
244           return -1;
245         else if (*ta > *tb)
246           return 1;
247         return 0;
248      }
249    else if (type == EINA_VALUE_TYPE_INT)
250      {
251         int *ta = (int *) pa, *tb = (int *) pb;
252         if (*ta < *tb)
253           return -1;
254         else if (*ta > *tb)
255           return 1;
256         return 0;
257      }
258    else if (type == EINA_VALUE_TYPE_LONG)
259      {
260         long *ta = (long *) pa, *tb = (long *) pb;
261         if (*ta < *tb)
262           return -1;
263         else if (*ta > *tb)
264           return 1;
265         return 0;
266      }
267    else if (type == EINA_VALUE_TYPE_INT64)
268      {
269         int64_t *ta = (int64_t *) pa, *tb = (int64_t *) pb;
270         if (*ta < *tb)
271           return -1;
272         else if (*ta > *tb)
273           return 1;
274         return 0;
275      }
276    else if (type == EINA_VALUE_TYPE_FLOAT)
277      {
278         float *ta = (float *) pa, *tb = (float *) pb;
279         if (*ta < *tb)
280           return -1;
281         else if (*ta > *tb)
282           return 1;
283         return 0;
284      }
285    else if (type == EINA_VALUE_TYPE_DOUBLE)
286      {
287         double *ta = (double *) pa, *tb = (double *) pb;
288         if (*ta < *tb)
289           return -1;
290         else if (*ta > *tb)
291           return 1;
292         return 0;
293      }
294    else if (type == EINA_VALUE_TYPE_STRINGSHARE ||
295             type == EINA_VALUE_TYPE_STRING)
296      {
297         const char *sa = *(const char **)pa;
298         const char *sb = *(const char **)pb;
299         if (sa == sb)
300           return 0;
301         if (sa == NULL)
302           return -1;
303         if (sb == NULL)
304           return 1;
305         return strcmp(sa, sb);
306      }
307 #endif
308
309    EINA_VALUE_TYPE_DISPATCH_RETURN(type, compare, EINA_ERROR_VALUE_FAILED,
310                                    EINA_FALSE, pa, pb);
311 }
312
313 static inline Eina_Bool
314 eina_value_set(Eina_Value *value, ...)
315 {
316    va_list args;
317    Eina_Bool ret;
318    va_start(args, value);
319    ret = eina_value_vset(value, args);
320    va_end(args);
321    return ret;
322 }
323
324 static inline Eina_Bool
325 eina_value_get(const Eina_Value *value, ...)
326 {
327    va_list args;
328    Eina_Bool ret;
329    va_start(args, value);
330    ret = eina_value_vget(value, args);
331    va_end(args);
332    return ret;
333 }
334
335 static inline Eina_Bool
336 eina_value_vset(Eina_Value *value, va_list args)
337 {
338    const Eina_Value_Type *type;
339    void *mem;
340
341    EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
342
343    type = value->type;
344    mem = eina_value_memory_get(value);
345    eina_error_set(0);
346 #ifndef EINA_VALUE_NO_OPTIMIZE
347    if (type == EINA_VALUE_TYPE_UCHAR)
348      {
349         unsigned char *tmem = (unsigned char *) mem;
350         *tmem = va_arg(args, unsigned int); /* promoted by va_arg */
351         return EINA_TRUE;
352      }
353    else if (type == EINA_VALUE_TYPE_USHORT)
354      {
355         unsigned short *tmem = (unsigned short *) mem;
356         *tmem = va_arg(args, unsigned int); /* promoted by va_arg */
357         return EINA_TRUE;
358      }
359    else if (type == EINA_VALUE_TYPE_UINT)
360      {
361         unsigned int *tmem = (unsigned int *) mem;
362         *tmem = va_arg(args, unsigned int);
363         return EINA_TRUE;
364      }
365    else if ((type == EINA_VALUE_TYPE_ULONG) || (type == EINA_VALUE_TYPE_TIMESTAMP))
366      {
367         unsigned long *tmem = (unsigned long *) mem;
368         *tmem = va_arg(args, unsigned long);
369         return EINA_TRUE;
370      }
371    else if (type == EINA_VALUE_TYPE_UINT64)
372      {
373         uint64_t *tmem = (uint64_t *) mem;
374         *tmem = va_arg(args, uint64_t);
375         return EINA_TRUE;
376      }
377    else if (type == EINA_VALUE_TYPE_CHAR)
378      {
379         signed char *tmem = (signed char *) mem;
380         *tmem = va_arg(args, int); /* promoted by va_arg */
381         return EINA_TRUE;
382      }
383    else if (type == EINA_VALUE_TYPE_SHORT)
384      {
385         short *tmem = (short *) mem;
386         *tmem = va_arg(args, int); /* promoted by va_arg */
387         return EINA_TRUE;
388      }
389    else if (type == EINA_VALUE_TYPE_INT)
390      {
391         int *tmem = (int *) mem;
392         *tmem = va_arg(args, int);
393         return EINA_TRUE;
394      }
395    else if (type == EINA_VALUE_TYPE_LONG)
396      {
397         long *tmem = (long *) mem;
398         *tmem = va_arg(args, long);
399         return EINA_TRUE;
400      }
401    else if (type == EINA_VALUE_TYPE_INT64)
402      {
403         int64_t *tmem = (int64_t *) mem;
404         *tmem = va_arg(args, int64_t);
405         return EINA_TRUE;
406      }
407    else if (type == EINA_VALUE_TYPE_FLOAT)
408      {
409         float *tmem = (float *) mem;
410         *tmem = va_arg(args, double); /* promoted by va_arg */
411         return EINA_TRUE;
412      }
413    else if (type == EINA_VALUE_TYPE_DOUBLE)
414      {
415         double *tmem = (double *) mem;
416         *tmem = va_arg(args, double);
417         return EINA_TRUE;
418      }
419    else if (type == EINA_VALUE_TYPE_STRINGSHARE)
420      {
421         const char *str = (const char *) va_arg(args, const char *);
422         return eina_stringshare_replace((const char **)&value->value.ptr, str);
423      }
424    else if (type == EINA_VALUE_TYPE_STRING)
425      {
426         const char *str = (const char *) va_arg(args, const char *);
427         if (value->value.ptr == str) return EINA_TRUE;
428         if (!str)
429           {
430              free(value->value.ptr);
431              value->value.ptr = NULL;
432           }
433         else
434           {
435              char *tmp = strdup(str);
436              if (!tmp)
437                {
438                   eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
439                   return EINA_FALSE;
440                }
441              free(value->value.ptr);
442              value->value.ptr = tmp;
443           }
444         return EINA_TRUE;
445      }
446 #endif
447
448    EINA_VALUE_TYPE_DISPATCH_RETURN(value, vset, EINA_ERROR_VALUE_FAILED,
449                                    EINA_FALSE, mem, args);
450 }
451
452 static inline Eina_Bool
453 eina_value_vget(const Eina_Value *value, va_list args)
454 {
455    const Eina_Value_Type *type;
456    const void *mem;
457    void *ptr;
458
459    EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
460
461    type = value->type;
462    mem = eina_value_memory_get(value);
463    ptr = va_arg(args, void *);
464    eina_error_set(0);
465    if (EINA_VALUE_TYPE_DEFAULT(type))
466      {
467         memcpy(ptr, mem, type->value_size);
468         return EINA_TRUE;
469      }
470
471    EINA_VALUE_TYPE_DISPATCH_RETURN(value, pget, EINA_ERROR_VALUE_FAILED,
472                                    EINA_FALSE, mem, ptr);
473 }
474
475 static inline Eina_Bool
476 eina_value_pset(Eina_Value *value, const void *ptr)
477 {
478    const Eina_Value_Type *type;
479    void *mem;
480
481    EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
482    EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
483
484    type = value->type;
485    mem = eina_value_memory_get(value);
486    eina_error_set(0);
487
488    if (EINA_VALUE_TYPE_DEFAULT(type))
489      {
490         if (type == EINA_VALUE_TYPE_STRINGSHARE)
491           {
492              const char *str = *((const char * const *) ptr);
493
494              return eina_stringshare_replace((const char **)&value->value.ptr,
495                                              str);
496           }
497         else if (type == EINA_VALUE_TYPE_STRING)
498           {
499              const char *str = *((const char * const *) ptr);
500              if (value->value.ptr == str) return EINA_TRUE;
501              if (!str)
502                {
503                   free(value->value.ptr);
504                   value->value.ptr = NULL;
505                }
506              else
507                {
508                   char *tmp = strdup(str);
509                   if (!tmp)
510                     {
511                        eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
512                        return EINA_FALSE;
513                     }
514                   free(value->value.ptr);
515                   value->value.ptr = tmp;
516                }
517              return EINA_TRUE;
518           }
519         else
520           memcpy(mem, ptr, type->value_size);
521         return EINA_TRUE;
522      }
523
524    EINA_VALUE_TYPE_DISPATCH_RETURN(value, pset, EINA_ERROR_VALUE_FAILED,
525                                    EINA_FALSE, mem, ptr);
526 }
527
528 static inline Eina_Bool
529 eina_value_pget(const Eina_Value *value, void *ptr)
530 {
531    const Eina_Value_Type *type;
532    const void *mem;
533
534    EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
535    EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
536
537    type = value->type;
538    mem = eina_value_memory_get(value);
539    eina_error_set(0);
540    if (EINA_VALUE_TYPE_DEFAULT(type))
541      {
542         memcpy(ptr, mem, type->value_size);
543         return EINA_TRUE;
544      }
545
546    EINA_VALUE_TYPE_DISPATCH_RETURN(value, pget, EINA_ERROR_VALUE_FAILED,
547                                    EINA_FALSE, mem, ptr);
548 }
549
550 static inline const Eina_Value_Type *
551 eina_value_type_get(const Eina_Value *value)
552 {
553    EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, NULL);
554    return value->type;
555 }
556
557 #define EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, retval)   \
558   EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval);                \
559   EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_ARRAY, retval)
560
561 static inline Eina_Bool
562 eina_value_array_setup(Eina_Value *value, const Eina_Value_Type *subtype, unsigned int step)
563 {
564    Eina_Value_Array desc = { subtype, step, NULL };
565    if (!eina_value_setup(value, EINA_VALUE_TYPE_ARRAY))
566      return EINA_FALSE;
567    if (!eina_value_pset(value, &desc))
568      {
569         eina_value_flush(value);
570         return EINA_FALSE;
571      }
572    return EINA_TRUE;
573 }
574
575 static inline unsigned int
576 eina_value_array_count(const Eina_Value *value)
577 {
578    Eina_Value_Array desc;
579    EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
580    if (!eina_value_pget(value, &desc))
581      return 0;
582    return eina_inarray_count(desc.array);
583 }
584
585 static inline Eina_Bool
586 eina_value_array_remove(Eina_Value *value, unsigned int position)
587 {
588    Eina_Value_Array desc;
589    void *mem;
590
591    EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
592    if (!eina_value_pget(value, &desc))
593      return EINA_FALSE;
594
595    mem = eina_inarray_nth(desc.array, position);
596    if (!mem)
597      return EINA_FALSE;
598
599    eina_value_type_flush(desc.subtype, mem);
600    return eina_inarray_remove_at(desc.array, position);
601 }
602
603 static inline Eina_Bool
604 eina_value_array_vset(Eina_Value *value, unsigned int position, va_list args)
605 {
606    Eina_Value_Array desc;
607    void *mem;
608
609    EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
610    if (!eina_value_pget(value, &desc))
611      return EINA_FALSE;
612
613    mem = eina_inarray_nth(desc.array, position);
614    if (!mem)
615      return EINA_FALSE;
616
617    return eina_value_type_vset(desc.subtype, mem, args);
618 }
619
620 static inline Eina_Bool
621 eina_value_array_vget(const Eina_Value *value, unsigned int position, va_list args)
622 {
623    Eina_Value_Array desc;
624    const void *mem;
625    void *ptr;
626    Eina_Bool ret;
627
628    EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
629    if (!eina_value_pget(value, &desc))
630      return EINA_FALSE;
631
632    mem = eina_inarray_nth(desc.array, position);
633    if (!mem)
634      return EINA_FALSE;
635
636    ptr = va_arg(args, void *);
637    ret = eina_value_type_pget(desc.subtype, mem, ptr);
638    return ret;
639 }
640
641 static inline Eina_Bool
642 eina_value_array_vinsert(Eina_Value *value, unsigned int position, va_list args)
643 {
644    Eina_Value_Array desc;
645    void *mem;
646
647    EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
648    if (!eina_value_pget(value, &desc))
649      return EINA_FALSE;
650
651    mem = eina_inarray_alloc_at(desc.array, position, 1);
652    if (!mem)
653      return EINA_FALSE;
654
655    if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
656    if (!eina_value_type_vset(desc.subtype, mem, args)) goto error_set;
657    return EINA_TRUE;
658
659  error_set:
660    eina_value_type_flush(desc.subtype, mem);
661  error_setup:
662    eina_inarray_remove_at(desc.array, position);
663    return EINA_FALSE;
664 }
665
666 static inline Eina_Bool
667 eina_value_array_vappend(Eina_Value *value, va_list args)
668 {
669    Eina_Value_Array desc;
670    void *mem;
671    int position;
672
673    EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
674    if (!eina_value_pget(value, &desc))
675      return EINA_FALSE;
676
677    position = eina_inarray_count(desc.array);
678    mem = eina_inarray_alloc_at(desc.array, position, 1);
679    if (!mem)
680      return EINA_FALSE;
681
682    if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
683    if (!eina_value_type_vset(desc.subtype, mem, args)) goto error_set;
684    return EINA_TRUE;
685
686  error_set:
687    eina_value_type_flush(desc.subtype, mem);
688  error_setup:
689    eina_inarray_remove_at(desc.array, position);
690    return EINA_FALSE;
691 }
692
693 static inline Eina_Bool
694 eina_value_array_set(Eina_Value *value, unsigned int position, ...)
695 {
696    va_list args;
697    Eina_Bool ret;
698    va_start(args, position);
699    ret = eina_value_array_vset(value, position, args);
700    va_end(args);
701    return ret;
702 }
703
704 static inline Eina_Bool
705 eina_value_array_get(const Eina_Value *value, unsigned int position, ...)
706 {
707    va_list args;
708    Eina_Bool ret;
709    va_start(args, position);
710    ret = eina_value_array_vget(value, position, args);
711    va_end(args);
712    return ret;
713 }
714
715 static inline Eina_Bool
716 eina_value_array_insert(Eina_Value *value, unsigned int position, ...)
717 {
718    va_list args;
719    Eina_Bool ret;
720    va_start(args, position);
721    ret = eina_value_array_vinsert(value, position, args);
722    va_end(args);
723    return ret;
724 }
725
726 static inline Eina_Bool eina_value_array_append(Eina_Value *value, ...)
727 {
728    va_list args;
729    Eina_Bool ret;
730    va_start(args, value);
731    ret = eina_value_array_vappend(value, args);
732    va_end(args);
733    return ret;
734 }
735
736 static inline Eina_Bool
737 eina_value_array_pset(Eina_Value *value, unsigned int position, const void *ptr)
738 {
739    Eina_Value_Array desc;
740    void *mem;
741
742    EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
743    if (!eina_value_pget(value, &desc))
744      return EINA_FALSE;
745
746    mem = eina_inarray_nth(desc.array, position);
747    if (!mem)
748      return EINA_FALSE;
749
750    return eina_value_type_pset(desc.subtype, mem, ptr);
751 }
752
753 static inline Eina_Bool
754 eina_value_array_pget(const Eina_Value *value, unsigned int position, void *ptr)
755 {
756    Eina_Value_Array desc;
757    const void *mem;
758    Eina_Bool ret;
759
760    EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
761    if (!eina_value_pget(value, &desc))
762      return EINA_FALSE;
763
764    mem = eina_inarray_nth(desc.array, position);
765    if (!mem)
766      return EINA_FALSE;
767
768    ret = eina_value_type_pget(desc.subtype, mem, ptr);
769    return ret;
770 }
771
772 static inline Eina_Bool
773 eina_value_array_pinsert(Eina_Value *value, unsigned int position, const void *ptr)
774 {
775    Eina_Value_Array desc;
776    void *mem;
777
778    EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
779    if (!eina_value_pget(value, &desc))
780      return EINA_FALSE;
781
782    mem = eina_inarray_alloc_at(desc.array, position, 1);
783    if (!mem)
784      return EINA_FALSE;
785
786    if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
787    if (!eina_value_type_pset(desc.subtype, mem, ptr)) goto error_set;
788    return EINA_TRUE;
789
790  error_set:
791    eina_value_type_flush(desc.subtype, mem);
792  error_setup:
793    eina_inarray_remove_at(desc.array, position);
794    return EINA_FALSE;
795 }
796
797 static inline Eina_Bool
798 eina_value_array_pappend(Eina_Value *value, const void *ptr)
799 {
800    Eina_Value_Array desc;
801    void *mem;
802    int position;
803
804    EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
805    if (!eina_value_pget(value, &desc))
806      return EINA_FALSE;
807
808    position = eina_inarray_count(desc.array);
809    mem = eina_inarray_alloc_at(desc.array, position, 1);
810    if (!mem)
811      return EINA_FALSE;
812
813    if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
814    if (!eina_value_type_pset(desc.subtype, mem, ptr)) goto error_set;
815    return EINA_TRUE;
816
817  error_set:
818    eina_value_type_flush(desc.subtype, mem);
819  error_setup:
820    eina_inarray_remove_at(desc.array, position);
821    return EINA_FALSE;
822 }
823
824 static inline Eina_Bool
825 eina_value_array_value_get(const Eina_Value *src, unsigned int position, Eina_Value *dst)
826 {
827    Eina_Value_Array desc;
828
829    EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(src, EINA_FALSE);
830    EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
831
832    if (!eina_value_pget(src, &desc))
833      return EINA_FALSE;
834    if (position >= eina_inarray_count(desc.array))
835      return EINA_FALSE;
836    if (!eina_value_setup(dst, desc.subtype))
837      return EINA_FALSE;
838    if (!eina_value_pset(dst, eina_inarray_nth(desc.array, position)))
839      {
840         eina_value_flush(dst);
841         return EINA_FALSE;
842      }
843
844    return EINA_TRUE;
845 }
846
847 #undef EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL
848
849 #define EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, retval)   \
850   EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval);                \
851   EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_LIST, retval)
852
853 static inline void *
854 eina_value_list_node_memory_get(const Eina_Value_Type *type, const Eina_List *node)
855 {
856    if (node == NULL) return NULL;
857    if (type->value_size <= sizeof(void*))
858      return (void *)&(node->data);
859    return node->data;
860 }
861
862 static inline void *
863 eina_value_list_node_memory_setup(const Eina_Value_Type *type, Eina_List *node)
864 {
865    if (type->value_size <= sizeof(void*))
866      return (void *)&(node->data);
867    node->data = malloc(type->value_size);
868    return node->data;
869 }
870
871 static inline void
872 eina_value_list_node_memory_flush(const Eina_Value_Type *type, Eina_List *node)
873 {
874    if (type->value_size <= sizeof(void*))
875      return;
876    free(node->data);
877 }
878
879 static inline Eina_Bool
880 eina_value_list_setup(Eina_Value *value, const Eina_Value_Type *subtype)
881 {
882    Eina_Value_List desc = { subtype, NULL };
883    if (!eina_value_setup(value, EINA_VALUE_TYPE_LIST))
884      return EINA_FALSE;
885    if (!eina_value_pset(value, &desc))
886      {
887         eina_value_flush(value);
888         return EINA_FALSE;
889      }
890    return EINA_TRUE;
891 }
892
893 static inline unsigned int
894 eina_value_list_count(const Eina_Value *value)
895 {
896    Eina_Value_List *desc;
897    EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
898    desc = (Eina_Value_List *)eina_value_memory_get(value);
899    if (!desc)
900      return 0;
901    return eina_list_count(desc->list);
902 }
903
904 static inline Eina_Bool
905 eina_value_list_remove(Eina_Value *value, unsigned int position)
906 {
907    Eina_Value_List *desc;
908    Eina_List *node;
909    void *mem;
910
911    EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
912    desc = (Eina_Value_List *)eina_value_memory_get(value);
913    if (!desc)
914      return EINA_FALSE;
915
916    node = eina_list_nth_list(desc->list, position);
917    mem = eina_value_list_node_memory_get(desc->subtype, node);
918    if (!mem)
919      return EINA_FALSE;
920
921    eina_value_type_flush(desc->subtype, mem);
922    eina_value_list_node_memory_flush(desc->subtype, node);
923    desc->list = eina_list_remove_list(desc->list, node);
924    return EINA_TRUE;
925 }
926
927 static inline Eina_Bool
928 eina_value_list_vset(Eina_Value *value, unsigned int position, va_list args)
929 {
930    Eina_Value_List *desc;
931    Eina_List *node;
932    void *mem;
933
934    EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
935    desc = (Eina_Value_List *)eina_value_memory_get(value);
936    if (!desc)
937      return EINA_FALSE;
938
939    node = eina_list_nth_list(desc->list, position);
940    mem = eina_value_list_node_memory_get(desc->subtype, node);
941    if (!mem)
942      return EINA_FALSE;
943
944    return eina_value_type_vset(desc->subtype, mem, args);
945 }
946
947 static inline Eina_Bool
948 eina_value_list_vget(const Eina_Value *value, unsigned int position, va_list args)
949 {
950    const Eina_Value_List *desc;
951    const Eina_List *node;
952    const void *mem;
953    void *ptr;
954    Eina_Bool ret;
955
956    EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
957    desc = (const Eina_Value_List *)eina_value_memory_get(value);
958    if (!desc)
959      return EINA_FALSE;
960
961    node = eina_list_nth_list(desc->list, position);
962    mem = eina_value_list_node_memory_get(desc->subtype, node);
963    if (!mem)
964      return EINA_FALSE;
965
966    ptr = va_arg(args, void *);
967    ret = eina_value_type_pget(desc->subtype, mem, ptr);
968    return ret;
969 }
970
971 static inline Eina_Bool
972 eina_value_list_vinsert(Eina_Value *value, unsigned int position, va_list args)
973 {
974    Eina_Value_List *desc;
975    Eina_List *node;
976    void *mem;
977
978    EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
979    desc = (Eina_Value_List *)eina_value_memory_get(value);
980    if (!desc)
981      return EINA_FALSE;
982
983    if (!desc->list)
984      node = desc->list = eina_list_append(NULL, (void*)1L);
985    else if (position == 0)
986      node = desc->list = eina_list_prepend(desc->list, (void*)1L);
987    else
988      {
989         Eina_List *rel = eina_list_nth_list(desc->list, position - 1);
990         desc->list = eina_list_append_relative_list(desc->list, (void*)1L, rel);
991         node = rel->next;
992      }
993    EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
994    EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
995
996    mem = eina_value_list_node_memory_setup(desc->subtype, node);
997    if (!mem)
998      {
999         desc->list = eina_list_remove_list(desc->list, node);
1000         return EINA_FALSE;
1001      }
1002
1003    if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1004    if (!eina_value_type_vset(desc->subtype, mem, args)) goto error_set;
1005    return EINA_TRUE;
1006
1007  error_set:
1008    eina_value_type_flush(desc->subtype, mem);
1009  error_setup:
1010    eina_value_list_node_memory_flush(desc->subtype, node);
1011    desc->list = eina_list_remove_list(desc->list, node);
1012    return EINA_FALSE;
1013 }
1014
1015 static inline Eina_Bool
1016 eina_value_list_vappend(Eina_Value *value, va_list args)
1017 {
1018    Eina_Value_List *desc;
1019    Eina_List *node;
1020    void *mem;
1021
1022    EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1023    desc = (Eina_Value_List *)eina_value_memory_get(value);
1024    if (!desc)
1025      return EINA_FALSE;
1026
1027    desc->list = eina_list_append(desc->list, (void*)1L);
1028    node = eina_list_last(desc->list);
1029    EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
1030    EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
1031
1032    mem = eina_value_list_node_memory_setup(desc->subtype, node);
1033    if (!mem)
1034      {
1035         desc->list = eina_list_remove_list(desc->list, node);
1036         return EINA_FALSE;
1037      }
1038
1039    if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1040    if (!eina_value_type_vset(desc->subtype, mem, args)) goto error_set;
1041    return EINA_TRUE;
1042
1043  error_set:
1044    eina_value_type_flush(desc->subtype, mem);
1045  error_setup:
1046    eina_value_list_node_memory_flush(desc->subtype, node);
1047    desc->list = eina_list_remove_list(desc->list, node);
1048    return EINA_FALSE;
1049 }
1050
1051 static inline Eina_Bool
1052 eina_value_list_set(Eina_Value *value, unsigned int position, ...)
1053 {
1054    va_list args;
1055    Eina_Bool ret;
1056    va_start(args, position);
1057    ret = eina_value_list_vset(value, position, args);
1058    va_end(args);
1059    return ret;
1060 }
1061
1062 static inline Eina_Bool
1063 eina_value_list_get(const Eina_Value *value, unsigned int position, ...)
1064 {
1065    va_list args;
1066    Eina_Bool ret;
1067    va_start(args, position);
1068    ret = eina_value_list_vget(value, position, args);
1069    va_end(args);
1070    return ret;
1071 }
1072
1073 static inline Eina_Bool
1074 eina_value_list_insert(Eina_Value *value, unsigned int position, ...)
1075 {
1076    va_list args;
1077    Eina_Bool ret;
1078    va_start(args, position);
1079    ret = eina_value_list_vinsert(value, position, args);
1080    va_end(args);
1081    return ret;
1082 }
1083
1084 static inline Eina_Bool eina_value_list_append(Eina_Value *value, ...)
1085 {
1086    va_list args;
1087    Eina_Bool ret;
1088    va_start(args, value);
1089    ret = eina_value_list_vappend(value, args);
1090    va_end(args);
1091    return ret;
1092 }
1093
1094 static inline Eina_Bool
1095 eina_value_list_pset(Eina_Value *value, unsigned int position, const void *ptr)
1096 {
1097    Eina_Value_List *desc;
1098    Eina_List *node;
1099    void *mem;
1100
1101    EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1102    desc = (Eina_Value_List *)eina_value_memory_get(value);
1103    if (!desc)
1104      return EINA_FALSE;
1105
1106    node = eina_list_nth_list(desc->list, position);
1107    mem = eina_value_list_node_memory_get(desc->subtype, node);
1108    if (!mem)
1109      return EINA_FALSE;
1110
1111    return eina_value_type_pset(desc->subtype, mem, ptr);
1112 }
1113
1114 static inline Eina_Bool
1115 eina_value_list_pget(const Eina_Value *value, unsigned int position, void *ptr)
1116 {
1117    const Eina_Value_List *desc;
1118    const Eina_List *node;
1119    const void *mem;
1120    Eina_Bool ret;
1121
1122    EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1123    desc = (const Eina_Value_List *)eina_value_memory_get(value);
1124    if (!desc)
1125      return EINA_FALSE;
1126
1127    node = eina_list_nth_list(desc->list, position);
1128    mem = eina_value_list_node_memory_get(desc->subtype, node);
1129    if (!mem)
1130      return EINA_FALSE;
1131
1132    ret = eina_value_type_pget(desc->subtype, mem, ptr);
1133    return ret;
1134 }
1135
1136 static inline Eina_Bool
1137 eina_value_list_pinsert(Eina_Value *value, unsigned int position, const void *ptr)
1138 {
1139    Eina_Value_List *desc;
1140    Eina_List *node;
1141    void *mem;
1142
1143    EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1144    desc = (Eina_Value_List *)eina_value_memory_get(value);
1145    if (!desc)
1146      return EINA_FALSE;
1147
1148    if (!desc->list)
1149      node = desc->list = eina_list_append(NULL, (void*)1L);
1150    else if (position == 0)
1151      node = desc->list = eina_list_prepend(desc->list, (void*)1L);
1152    else
1153      {
1154         Eina_List *rel = eina_list_nth_list(desc->list, position - 1);
1155         desc->list = eina_list_append_relative_list(desc->list, (void*)1L, rel);
1156         node = rel->next;
1157      }
1158    EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
1159    EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
1160
1161    mem = eina_value_list_node_memory_setup(desc->subtype, node);
1162    if (!mem)
1163      {
1164         desc->list = eina_list_remove_list(desc->list, node);
1165         return EINA_FALSE;
1166      }
1167
1168    if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1169    if (!eina_value_type_pset(desc->subtype, mem, ptr)) goto error_set;
1170    return EINA_TRUE;
1171
1172  error_set:
1173    eina_value_type_flush(desc->subtype, mem);
1174  error_setup:
1175    eina_value_list_node_memory_flush(desc->subtype, node);
1176    desc->list = eina_list_remove_list(desc->list, node);
1177    return EINA_FALSE;
1178 }
1179
1180 static inline Eina_Bool
1181 eina_value_list_pappend(Eina_Value *value, const void *ptr)
1182 {
1183    Eina_Value_List *desc;
1184    Eina_List *node;
1185    void *mem;
1186
1187    EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1188    desc = (Eina_Value_List *)eina_value_memory_get(value);
1189    if (!desc)
1190      return EINA_FALSE;
1191
1192    desc->list = eina_list_append(desc->list, (void*)1L);
1193    node = eina_list_last(desc->list);
1194    EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
1195    EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
1196
1197    mem = eina_value_list_node_memory_setup(desc->subtype, node);
1198    if (!mem)
1199      {
1200         desc->list = eina_list_remove_list(desc->list, node);
1201         return EINA_FALSE;
1202      }
1203
1204    if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1205    if (!eina_value_type_pset(desc->subtype, mem, ptr)) goto error_set;
1206    return EINA_TRUE;
1207
1208  error_set:
1209    eina_value_type_flush(desc->subtype, mem);
1210  error_setup:
1211    eina_value_list_node_memory_flush(desc->subtype, node);
1212    desc->list = eina_list_remove_list(desc->list, node);
1213    return EINA_FALSE;
1214 }
1215 #undef EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL
1216
1217 #define EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, retval)   \
1218   EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval);                \
1219   EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_HASH, retval)
1220
1221 static inline Eina_Bool
1222 eina_value_hash_setup(Eina_Value *value, const Eina_Value_Type *subtype, unsigned int buckets_power_size)
1223 {
1224    Eina_Value_Hash desc = { subtype, buckets_power_size, NULL };
1225    if (!eina_value_setup(value, EINA_VALUE_TYPE_HASH))
1226      return EINA_FALSE;
1227    if (!eina_value_pset(value, &desc))
1228      {
1229         eina_value_flush(value);
1230         return EINA_FALSE;
1231      }
1232    return EINA_TRUE;
1233 }
1234
1235 static inline unsigned int
1236 eina_value_hash_population(const Eina_Value *value)
1237 {
1238    Eina_Value_Hash *desc;
1239    EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0);
1240    desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1241    if (!desc)
1242      return 0;
1243    return eina_hash_population(desc->hash);
1244 }
1245
1246 static inline Eina_Bool
1247 eina_value_hash_del(Eina_Value *value, const char *key)
1248 {
1249    Eina_Value_Hash *desc;
1250    void *mem;
1251
1252    EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE);
1253    EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1254    desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1255    if (!desc)
1256      return EINA_FALSE;
1257
1258    mem = eina_hash_find(desc->hash, key);
1259    if (!mem)
1260      return EINA_FALSE;
1261
1262    eina_value_type_flush(desc->subtype, mem);
1263    free(mem);
1264    eina_hash_del_by_key(desc->hash, key);
1265    return EINA_TRUE;
1266 }
1267
1268 static inline Eina_Bool
1269 eina_value_hash_vset(Eina_Value *value, const char *key, va_list args)
1270 {
1271    Eina_Value_Hash *desc;
1272    void *mem;
1273
1274    EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE);
1275    EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1276    desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1277    if (!desc)
1278      return EINA_FALSE;
1279
1280    mem = eina_hash_find(desc->hash, key);
1281    if (!mem)
1282      {
1283         mem = malloc(desc->subtype->value_size);
1284         if (!mem)
1285           {
1286              eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
1287              return EINA_FALSE;
1288           }
1289         if (!eina_hash_add(desc->hash, key, mem))
1290           {
1291              free(mem);
1292              return EINA_FALSE;
1293           }
1294         if (!eina_value_type_setup(desc->subtype, mem))
1295           {
1296              eina_value_type_flush(desc->subtype, mem);
1297              eina_hash_del_by_key(desc->hash, key);
1298              free(mem);
1299           }
1300      }
1301
1302    return eina_value_type_vset(desc->subtype, mem, args);
1303 }
1304
1305 static inline Eina_Bool
1306 eina_value_hash_vget(const Eina_Value *value, const char *key, va_list args)
1307 {
1308    const Eina_Value_Hash *desc;
1309    const void *mem;
1310    void *ptr;
1311    Eina_Bool ret;
1312
1313    EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE);
1314    EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1315    desc = (const Eina_Value_Hash *)eina_value_memory_get(value);
1316    if (!desc)
1317      return EINA_FALSE;
1318
1319    mem = eina_hash_find(desc->hash, key);
1320    if (!mem)
1321      return EINA_FALSE;
1322
1323    ptr = va_arg(args, void *);
1324    ret = eina_value_type_pget(desc->subtype, mem, ptr);
1325    return ret;
1326 }
1327
1328 static inline Eina_Bool
1329 eina_value_hash_set(Eina_Value *value, const char *key, ...)
1330 {
1331    va_list args;
1332    Eina_Bool ret;
1333    va_start(args, key);
1334    ret = eina_value_hash_vset(value, key, args);
1335    va_end(args);
1336    return ret;
1337 }
1338
1339 static inline Eina_Bool
1340 eina_value_hash_get(const Eina_Value *value, const char *key, ...)
1341 {
1342    va_list args;
1343    Eina_Bool ret;
1344    va_start(args, key);
1345    ret = eina_value_hash_vget(value, key, args);
1346    va_end(args);
1347    return ret;
1348 }
1349
1350 static inline Eina_Bool
1351 eina_value_hash_pset(Eina_Value *value, const char *key, const void *ptr)
1352 {
1353    Eina_Value_Hash *desc;
1354    void *mem;
1355
1356    EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0);
1357    EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1358    desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1359    if (!desc)
1360      return EINA_FALSE;
1361
1362    mem = eina_hash_find(desc->hash, key);
1363    if (!mem)
1364      {
1365         mem = malloc(desc->subtype->value_size);
1366         if (!mem)
1367           {
1368              eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
1369              return EINA_FALSE;
1370           }
1371         if (!eina_hash_add(desc->hash, key, mem))
1372           {
1373              free(mem);
1374              return EINA_FALSE;
1375           }
1376         if (!eina_value_type_setup(desc->subtype, mem))
1377           {
1378              eina_value_type_flush(desc->subtype, mem);
1379              eina_hash_del_by_key(desc->hash, key);
1380              free(mem);
1381           }
1382      }
1383
1384    return eina_value_type_pset(desc->subtype, mem, ptr);
1385 }
1386
1387 static inline Eina_Bool
1388 eina_value_hash_pget(const Eina_Value *value, const char *key, void *ptr)
1389 {
1390    const Eina_Value_Hash *desc;
1391    const void *mem;
1392    Eina_Bool ret;
1393
1394    EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0);
1395    EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1396    desc = (const Eina_Value_Hash *)eina_value_memory_get(value);
1397    if (!desc)
1398      return EINA_FALSE;
1399
1400    mem = eina_hash_find(desc->hash, key);
1401    if (!mem)
1402      return EINA_FALSE;
1403
1404    ret = eina_value_type_pget(desc->subtype, mem, ptr);
1405    return ret;
1406 }
1407 #undef EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL
1408
1409 #define EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, retval)          \
1410   EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval);                        \
1411   EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_STRUCT, retval)
1412
1413 /**
1414  * @brief Find member of struct
1415  * @since 1.2
1416  * @internal
1417  */
1418 EAPI const Eina_Value_Struct_Member *eina_value_struct_member_find(const Eina_Value_Struct *st, const char *name) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
1419
1420 static inline Eina_Bool
1421 eina_value_struct_setup(Eina_Value *value, const Eina_Value_Struct_Desc *sdesc)
1422 {
1423    Eina_Value_Struct desc = {sdesc, NULL};
1424    if (!eina_value_setup(value, EINA_VALUE_TYPE_STRUCT))
1425      return EINA_FALSE;
1426    if (!eina_value_pset(value, &desc))
1427      {
1428         eina_value_flush(value);
1429         return EINA_FALSE;
1430      }
1431    return EINA_TRUE;
1432 }
1433
1434 static inline void *
1435 eina_value_struct_member_memory_get(const Eina_Value_Struct *st, const Eina_Value_Struct_Member *member)
1436 {
1437    unsigned char *base = (unsigned char *)st->memory;
1438    if (!base) return NULL;
1439    return base + member->offset;
1440 }
1441
1442 static inline Eina_Bool
1443 eina_value_struct_vset(Eina_Value *value, const char *name, va_list args)
1444 {
1445    const Eina_Value_Struct_Member *member;
1446    Eina_Value_Struct *st;
1447    void *mem;
1448
1449    EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1450    EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1451    st = (Eina_Value_Struct *)eina_value_memory_get(value);
1452    if (!st)
1453      return EINA_FALSE;
1454    member = eina_value_struct_member_find(st, name);
1455    if (!member)
1456      return EINA_FALSE;
1457    mem = eina_value_struct_member_memory_get(st, member);
1458    if (!mem)
1459      return EINA_FALSE;
1460
1461    return eina_value_type_vset(member->type, mem, args);
1462 }
1463
1464 static inline Eina_Bool
1465 eina_value_struct_vget(const Eina_Value *value, const char *name, va_list args)
1466 {
1467    const Eina_Value_Struct_Member *member;
1468    const Eina_Value_Struct *st;
1469    const void *mem;
1470    void *ptr;
1471    Eina_Bool ret;
1472
1473    EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1474    EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1475    st = (const Eina_Value_Struct *)eina_value_memory_get(value);
1476    if (!st)
1477      return EINA_FALSE;
1478    member = eina_value_struct_member_find(st, name);
1479    if (!member)
1480      return EINA_FALSE;
1481    mem = eina_value_struct_member_memory_get(st, member);
1482    if (!mem)
1483      return EINA_FALSE;
1484
1485    ptr = va_arg(args, void *);
1486    ret = eina_value_type_pget(member->type, mem, ptr);
1487    return ret;
1488 }
1489
1490 static inline Eina_Bool
1491 eina_value_struct_set(Eina_Value *value, const char *name, ...)
1492 {
1493    va_list args;
1494    Eina_Bool ret;
1495    va_start(args, name);
1496    ret = eina_value_struct_vset(value, name, args);
1497    va_end(args);
1498    return ret;
1499 }
1500
1501 static inline Eina_Bool
1502 eina_value_struct_get(const Eina_Value *value, const char *name, ...)
1503 {
1504    va_list args;
1505    Eina_Bool ret;
1506    va_start(args, name);
1507    ret = eina_value_struct_vget(value, name, args);
1508    va_end(args);
1509    return ret;
1510 }
1511
1512 static inline Eina_Bool
1513 eina_value_struct_pset(Eina_Value *value, const char *name, const void *ptr)
1514 {
1515    const Eina_Value_Struct_Member *member;
1516    Eina_Value_Struct *st;
1517    void *mem;
1518
1519    EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1520    EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1521    EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
1522    st = (Eina_Value_Struct *)eina_value_memory_get(value);
1523    if (!st)
1524      return EINA_FALSE;
1525    member = eina_value_struct_member_find(st, name);
1526    if (!member)
1527      return EINA_FALSE;
1528    mem = eina_value_struct_member_memory_get(st, member);
1529    if (!mem)
1530      return EINA_FALSE;
1531
1532    return eina_value_type_pset(member->type, mem, ptr);
1533 }
1534
1535 static inline Eina_Bool
1536 eina_value_struct_pget(const Eina_Value *value, const char *name, void *ptr)
1537 {
1538    const Eina_Value_Struct_Member *member;
1539    const Eina_Value_Struct *st;
1540    const void *mem;
1541    Eina_Bool ret;
1542
1543    EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1544    EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1545    EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
1546    st = (const Eina_Value_Struct *)eina_value_memory_get(value);
1547    if (!st)
1548      return EINA_FALSE;
1549    member = eina_value_struct_member_find(st, name);
1550    if (!member)
1551      return EINA_FALSE;
1552    mem = eina_value_struct_member_memory_get(st, member);
1553    if (!mem)
1554      return EINA_FALSE;
1555
1556    ret = eina_value_type_pget(member->type, mem, ptr);
1557    return ret;
1558 }
1559
1560 static inline Eina_Bool
1561 eina_value_struct_value_get(const Eina_Value *src, const char *name, Eina_Value *dst)
1562 {
1563    const Eina_Value_Struct_Member *member;
1564    const Eina_Value_Struct *st;
1565    const void *mem;
1566
1567    EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(src, EINA_FALSE);
1568    EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1569    EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
1570    st = (const Eina_Value_Struct *)eina_value_memory_get(src);
1571    if (!st)
1572      return EINA_FALSE;
1573    member = eina_value_struct_member_find(st, name);
1574    if (!member)
1575      return EINA_FALSE;
1576    mem = eina_value_struct_member_memory_get(st, member);
1577    if (!mem)
1578      return EINA_FALSE;
1579    if (!eina_value_setup(dst, member->type))
1580      return EINA_FALSE;
1581    if (!eina_value_pset(dst, mem))
1582      {
1583         eina_value_flush(dst);
1584         return EINA_FALSE;
1585      }
1586    return EINA_TRUE;
1587 }
1588
1589 static inline Eina_Bool
1590 eina_value_struct_value_set(Eina_Value *dst, const char *name, const Eina_Value *src)
1591 {
1592    const Eina_Value_Struct_Member *member;
1593    Eina_Value_Struct *st;
1594    void *mem;
1595    const void *ptr;
1596
1597    EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(dst, EINA_FALSE);
1598    EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1599    EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
1600
1601    st = (Eina_Value_Struct *)eina_value_memory_get(dst);
1602    if (!st)
1603      return EINA_FALSE;
1604    member = eina_value_struct_member_find(st, name);
1605    if (!member)
1606      return EINA_FALSE;
1607    EINA_SAFETY_ON_FALSE_RETURN_VAL(src->type == member->type, EINA_FALSE);
1608
1609    mem = eina_value_struct_member_memory_get(st, member);
1610    if (!mem)
1611      return EINA_FALSE;
1612
1613    ptr = eina_value_memory_get(src);
1614    if (!ptr)
1615      return EINA_FALSE;
1616
1617    return eina_value_type_pset(member->type, mem, ptr);
1618 }
1619
1620 static inline Eina_Bool
1621 eina_value_struct_member_value_get(const Eina_Value *src, const Eina_Value_Struct_Member *member, Eina_Value *dst)
1622 {
1623    const Eina_Value_Struct *st;
1624    const void *mem;
1625
1626    EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(src, EINA_FALSE);
1627    EINA_SAFETY_ON_NULL_RETURN_VAL(member, EINA_FALSE);
1628    EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
1629    st = (const Eina_Value_Struct *)eina_value_memory_get(src);
1630    if (!st)
1631      return EINA_FALSE;
1632    mem = eina_value_struct_member_memory_get(st, member);
1633    if (!mem)
1634      return EINA_FALSE;
1635    if (!eina_value_setup(dst, member->type))
1636      return EINA_FALSE;
1637    if (!eina_value_pset(dst, mem))
1638      {
1639         eina_value_flush(dst);
1640         return EINA_FALSE;
1641      }
1642    return EINA_TRUE;
1643 }
1644
1645 static inline Eina_Bool
1646 eina_value_struct_member_value_set(Eina_Value *dst, const Eina_Value_Struct_Member *member, const Eina_Value *src)
1647 {
1648    Eina_Value_Struct *st;
1649    void *mem;
1650    const void *ptr;
1651
1652    EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(dst, EINA_FALSE);
1653    EINA_SAFETY_ON_NULL_RETURN_VAL(member, EINA_FALSE);
1654    EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
1655
1656    st = (Eina_Value_Struct *)eina_value_memory_get(dst);
1657    if (!st)
1658      return EINA_FALSE;
1659    EINA_SAFETY_ON_FALSE_RETURN_VAL(src->type == member->type, EINA_FALSE);
1660
1661    mem = eina_value_struct_member_memory_get(st, member);
1662    if (!mem)
1663      return EINA_FALSE;
1664
1665    ptr = eina_value_memory_get(src);
1666    if (!ptr)
1667      return EINA_FALSE;
1668
1669    return eina_value_type_pset(member->type, mem, ptr);
1670 }
1671
1672 #undef EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL
1673
1674
1675 static inline Eina_Bool
1676 eina_value_type_setup(const Eina_Value_Type *type, void *mem)
1677 {
1678    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1679    if (!type->setup)
1680      {
1681         eina_error_set(EINA_ERROR_VALUE_FAILED);
1682         return EINA_FALSE;
1683      }
1684    return type->setup(type, mem);
1685 }
1686
1687 static inline Eina_Bool
1688 eina_value_type_flush(const Eina_Value_Type *type, void *mem)
1689 {
1690    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1691    if (!type->flush)
1692      {
1693         eina_error_set(EINA_ERROR_VALUE_FAILED);
1694         return EINA_FALSE;
1695      }
1696    return type->flush(type, mem);
1697 }
1698
1699 static inline Eina_Bool
1700 eina_value_type_copy(const Eina_Value_Type *type, const void *src, void *dst)
1701 {
1702    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1703    if (!type->copy)
1704      {
1705         eina_error_set(EINA_ERROR_VALUE_FAILED);
1706         return EINA_FALSE;
1707      }
1708    return type->copy(type, src, dst);
1709 }
1710
1711 static inline int
1712 eina_value_type_compare(const Eina_Value_Type *type, const void *a, const void *b)
1713 {
1714    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1715    if (!type->compare)
1716      {
1717         eina_error_set(EINA_ERROR_VALUE_FAILED);
1718         return EINA_FALSE;
1719      }
1720    return type->compare(type, a, b);
1721 }
1722
1723 static inline Eina_Bool
1724 eina_value_type_convert_to(const Eina_Value_Type *type, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
1725 {
1726    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1727    if (!type->convert_to)
1728      {
1729         eina_error_set(EINA_ERROR_VALUE_FAILED);
1730         return EINA_FALSE;
1731      }
1732    return type->convert_to(type, convert, type_mem, convert_mem);
1733 }
1734
1735 static inline Eina_Bool
1736 eina_value_type_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem)
1737 {
1738    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1739    if (!type->convert_from)
1740      {
1741         eina_error_set(EINA_ERROR_VALUE_FAILED);
1742         return EINA_FALSE;
1743      }
1744    return type->convert_from(type, convert, type_mem, convert_mem);
1745 }
1746
1747 static inline Eina_Bool
1748 eina_value_type_vset(const Eina_Value_Type *type, void *mem, va_list args)
1749 {
1750    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1751    if (!type->vset)
1752      {
1753         eina_error_set(EINA_ERROR_VALUE_FAILED);
1754         return EINA_FALSE;
1755      }
1756    return type->vset(type, mem, args);
1757 }
1758
1759 static inline Eina_Bool
1760 eina_value_type_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
1761 {
1762    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1763    if (!type->pset)
1764      {
1765         eina_error_set(EINA_ERROR_VALUE_FAILED);
1766         return EINA_FALSE;
1767      }
1768    return type->pset(type, mem, ptr);
1769 }
1770
1771 static inline Eina_Bool
1772 eina_value_type_pget(const Eina_Value_Type *type, const void *mem, void *ptr)
1773 {
1774    EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1775    if (!type->pget)
1776      {
1777         eina_error_set(EINA_ERROR_VALUE_FAILED);
1778         return EINA_FALSE;
1779      }
1780    return type->pget(type, mem, ptr);
1781 }
1782
1783 #undef EINA_VALUE_TYPE_DEFAULT
1784 #undef EINA_VALUE_TYPE_CHECK_RETURN
1785 #undef EINA_VALUE_TYPE_CHECK_RETURN_VAL
1786 #undef EINA_VALUE_TYPE_DISPATCH
1787 #undef EINA_VALUE_TYPE_DISPATCH_RETURN
1788 #endif