aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/include/eina_inline_value.x
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/include/eina_inline_value.x')
-rw-r--r--libraries/eina/src/include/eina_inline_value.x1790
1 files changed, 0 insertions, 1790 deletions
diff --git a/libraries/eina/src/include/eina_inline_value.x b/libraries/eina/src/include/eina_inline_value.x
deleted file mode 100644
index 33c83f5..0000000
--- a/libraries/eina/src/include/eina_inline_value.x
+++ /dev/null
@@ -1,1790 +0,0 @@
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 */
40EAPI 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 */
48EAPI 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 */
87static inline void *
88eina_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 */
100EAPI void *eina_value_inner_alloc(size_t size);
101/**
102 * @brief Releases memory for internal value types.
103 * @since 1.2
104 * @private
105 */
106EAPI void eina_value_inner_free(size_t size, void *mem);
107
108static inline Eina_Bool
109eina_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
137static inline void
138eina_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
170static inline int
171eina_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 char *ta = (char *) pa, *tb = (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
313static inline Eina_Bool
314eina_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
324static inline Eina_Bool
325eina_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
335static inline Eina_Bool
336eina_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 char *tmem = (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
452static inline Eina_Bool
453eina_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
475static inline Eina_Bool
476eina_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 * const *pstr = (const char * const *) ptr;
493 const char *str = *pstr;
494
495 return eina_stringshare_replace((const char **)&value->value.ptr,
496 str);
497 }
498 else if (type == EINA_VALUE_TYPE_STRING)
499 {
500 const char * const * pstr = (const char * const *) ptr;
501 const char *str = *pstr;
502 if (value->value.ptr == str) return EINA_TRUE;
503 if (!str)
504 {
505 free(value->value.ptr);
506 value->value.ptr = NULL;
507 }
508 else
509 {
510 char *tmp = strdup(str);
511 if (!tmp)
512 {
513 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
514 return EINA_FALSE;
515 }
516 free(value->value.ptr);
517 value->value.ptr = tmp;
518 }
519 return EINA_TRUE;
520 }
521 else
522 memcpy(mem, ptr, type->value_size);
523 return EINA_TRUE;
524 }
525
526 EINA_VALUE_TYPE_DISPATCH_RETURN(value, pset, EINA_ERROR_VALUE_FAILED,
527 EINA_FALSE, mem, ptr);
528}
529
530static inline Eina_Bool
531eina_value_pget(const Eina_Value *value, void *ptr)
532{
533 const Eina_Value_Type *type;
534 const void *mem;
535
536 EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
537 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
538
539 type = value->type;
540 mem = eina_value_memory_get(value);
541 eina_error_set(0);
542 if (EINA_VALUE_TYPE_DEFAULT(type))
543 {
544 memcpy(ptr, mem, type->value_size);
545 return EINA_TRUE;
546 }
547
548 EINA_VALUE_TYPE_DISPATCH_RETURN(value, pget, EINA_ERROR_VALUE_FAILED,
549 EINA_FALSE, mem, ptr);
550}
551
552static inline const Eina_Value_Type *
553eina_value_type_get(const Eina_Value *value)
554{
555 EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, NULL);
556 return value->type;
557}
558
559#define EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, retval) \
560 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
561 EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_ARRAY, retval)
562
563static inline Eina_Bool
564eina_value_array_setup(Eina_Value *value, const Eina_Value_Type *subtype, unsigned int step)
565{
566 Eina_Value_Array desc = { subtype, step, NULL };
567 if (!eina_value_setup(value, EINA_VALUE_TYPE_ARRAY))
568 return EINA_FALSE;
569 if (!eina_value_pset(value, &desc))
570 {
571 eina_value_flush(value);
572 return EINA_FALSE;
573 }
574 return EINA_TRUE;
575}
576
577static inline unsigned int
578eina_value_array_count(const Eina_Value *value)
579{
580 Eina_Value_Array desc;
581 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
582 if (!eina_value_pget(value, &desc))
583 return 0;
584 return eina_inarray_count(desc.array);
585}
586
587static inline Eina_Bool
588eina_value_array_remove(Eina_Value *value, unsigned int position)
589{
590 Eina_Value_Array desc;
591 void *mem;
592
593 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
594 if (!eina_value_pget(value, &desc))
595 return EINA_FALSE;
596
597 mem = eina_inarray_nth(desc.array, position);
598 if (!mem)
599 return EINA_FALSE;
600
601 eina_value_type_flush(desc.subtype, mem);
602 return eina_inarray_remove_at(desc.array, position);
603}
604
605static inline Eina_Bool
606eina_value_array_vset(Eina_Value *value, unsigned int position, va_list args)
607{
608 Eina_Value_Array desc;
609 void *mem;
610
611 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
612 if (!eina_value_pget(value, &desc))
613 return EINA_FALSE;
614
615 mem = eina_inarray_nth(desc.array, position);
616 if (!mem)
617 return EINA_FALSE;
618
619 return eina_value_type_vset(desc.subtype, mem, args);
620}
621
622static inline Eina_Bool
623eina_value_array_vget(const Eina_Value *value, unsigned int position, va_list args)
624{
625 Eina_Value_Array desc;
626 const void *mem;
627 void *ptr;
628 Eina_Bool ret;
629
630 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
631 if (!eina_value_pget(value, &desc))
632 return EINA_FALSE;
633
634 mem = eina_inarray_nth(desc.array, position);
635 if (!mem)
636 return EINA_FALSE;
637
638 ptr = va_arg(args, void *);
639 ret = eina_value_type_pget(desc.subtype, mem, ptr);
640 return ret;
641}
642
643static inline Eina_Bool
644eina_value_array_vinsert(Eina_Value *value, unsigned int position, va_list args)
645{
646 Eina_Value_Array desc;
647 void *mem;
648
649 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
650 if (!eina_value_pget(value, &desc))
651 return EINA_FALSE;
652
653 mem = eina_inarray_alloc_at(desc.array, position, 1);
654 if (!mem)
655 return EINA_FALSE;
656
657 if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
658 if (!eina_value_type_vset(desc.subtype, mem, args)) goto error_set;
659 return EINA_TRUE;
660
661 error_set:
662 eina_value_type_flush(desc.subtype, mem);
663 error_setup:
664 eina_inarray_remove_at(desc.array, position);
665 return EINA_FALSE;
666}
667
668static inline Eina_Bool
669eina_value_array_vappend(Eina_Value *value, va_list args)
670{
671 Eina_Value_Array desc;
672 void *mem;
673 int position;
674
675 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
676 if (!eina_value_pget(value, &desc))
677 return EINA_FALSE;
678
679 position = eina_inarray_count(desc.array);
680 mem = eina_inarray_alloc_at(desc.array, position, 1);
681 if (!mem)
682 return EINA_FALSE;
683
684 if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
685 if (!eina_value_type_vset(desc.subtype, mem, args)) goto error_set;
686 return EINA_TRUE;
687
688 error_set:
689 eina_value_type_flush(desc.subtype, mem);
690 error_setup:
691 eina_inarray_remove_at(desc.array, position);
692 return EINA_FALSE;
693}
694
695static inline Eina_Bool
696eina_value_array_set(Eina_Value *value, unsigned int position, ...)
697{
698 va_list args;
699 Eina_Bool ret;
700 va_start(args, position);
701 ret = eina_value_array_vset(value, position, args);
702 va_end(args);
703 return ret;
704}
705
706static inline Eina_Bool
707eina_value_array_get(const Eina_Value *value, unsigned int position, ...)
708{
709 va_list args;
710 Eina_Bool ret;
711 va_start(args, position);
712 ret = eina_value_array_vget(value, position, args);
713 va_end(args);
714 return ret;
715}
716
717static inline Eina_Bool
718eina_value_array_insert(Eina_Value *value, unsigned int position, ...)
719{
720 va_list args;
721 Eina_Bool ret;
722 va_start(args, position);
723 ret = eina_value_array_vinsert(value, position, args);
724 va_end(args);
725 return ret;
726}
727
728static inline Eina_Bool eina_value_array_append(Eina_Value *value, ...)
729{
730 va_list args;
731 Eina_Bool ret;
732 va_start(args, value);
733 ret = eina_value_array_vappend(value, args);
734 va_end(args);
735 return ret;
736}
737
738static inline Eina_Bool
739eina_value_array_pset(Eina_Value *value, unsigned int position, const void *ptr)
740{
741 Eina_Value_Array desc;
742 void *mem;
743
744 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
745 if (!eina_value_pget(value, &desc))
746 return EINA_FALSE;
747
748 mem = eina_inarray_nth(desc.array, position);
749 if (!mem)
750 return EINA_FALSE;
751
752 return eina_value_type_pset(desc.subtype, mem, ptr);
753}
754
755static inline Eina_Bool
756eina_value_array_pget(const Eina_Value *value, unsigned int position, void *ptr)
757{
758 Eina_Value_Array desc;
759 const void *mem;
760 Eina_Bool ret;
761
762 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
763 if (!eina_value_pget(value, &desc))
764 return EINA_FALSE;
765
766 mem = eina_inarray_nth(desc.array, position);
767 if (!mem)
768 return EINA_FALSE;
769
770 ret = eina_value_type_pget(desc.subtype, mem, ptr);
771 return ret;
772}
773
774static inline Eina_Bool
775eina_value_array_pinsert(Eina_Value *value, unsigned int position, const void *ptr)
776{
777 Eina_Value_Array desc;
778 void *mem;
779
780 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
781 if (!eina_value_pget(value, &desc))
782 return EINA_FALSE;
783
784 mem = eina_inarray_alloc_at(desc.array, position, 1);
785 if (!mem)
786 return EINA_FALSE;
787
788 if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
789 if (!eina_value_type_pset(desc.subtype, mem, ptr)) goto error_set;
790 return EINA_TRUE;
791
792 error_set:
793 eina_value_type_flush(desc.subtype, mem);
794 error_setup:
795 eina_inarray_remove_at(desc.array, position);
796 return EINA_FALSE;
797}
798
799static inline Eina_Bool
800eina_value_array_pappend(Eina_Value *value, const void *ptr)
801{
802 Eina_Value_Array desc;
803 void *mem;
804 int position;
805
806 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
807 if (!eina_value_pget(value, &desc))
808 return EINA_FALSE;
809
810 position = eina_inarray_count(desc.array);
811 mem = eina_inarray_alloc_at(desc.array, position, 1);
812 if (!mem)
813 return EINA_FALSE;
814
815 if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
816 if (!eina_value_type_pset(desc.subtype, mem, ptr)) goto error_set;
817 return EINA_TRUE;
818
819 error_set:
820 eina_value_type_flush(desc.subtype, mem);
821 error_setup:
822 eina_inarray_remove_at(desc.array, position);
823 return EINA_FALSE;
824}
825
826static inline Eina_Bool
827eina_value_array_value_get(const Eina_Value *src, unsigned int position, Eina_Value *dst)
828{
829 Eina_Value_Array desc;
830
831 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(src, EINA_FALSE);
832 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
833
834 if (!eina_value_pget(src, &desc))
835 return EINA_FALSE;
836 if (position >= eina_inarray_count(desc.array))
837 return EINA_FALSE;
838 if (!eina_value_setup(dst, desc.subtype))
839 return EINA_FALSE;
840 if (!eina_value_pset(dst, eina_inarray_nth(desc.array, position)))
841 {
842 eina_value_flush(dst);
843 return EINA_FALSE;
844 }
845
846 return EINA_TRUE;
847}
848
849#undef EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL
850
851#define EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, retval) \
852 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
853 EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_LIST, retval)
854
855static inline void *
856eina_value_list_node_memory_get(const Eina_Value_Type *type, const Eina_List *node)
857{
858 if (node == NULL) return NULL;
859 if (type->value_size <= sizeof(void*))
860 return (void *)&(node->data);
861 return node->data;
862}
863
864static inline void *
865eina_value_list_node_memory_setup(const Eina_Value_Type *type, Eina_List *node)
866{
867 if (type->value_size <= sizeof(void*))
868 return (void *)&(node->data);
869 node->data = malloc(type->value_size);
870 return node->data;
871}
872
873static inline void
874eina_value_list_node_memory_flush(const Eina_Value_Type *type, Eina_List *node)
875{
876 if (type->value_size <= sizeof(void*))
877 return;
878 free(node->data);
879}
880
881static inline Eina_Bool
882eina_value_list_setup(Eina_Value *value, const Eina_Value_Type *subtype)
883{
884 Eina_Value_List desc = { subtype, NULL };
885 if (!eina_value_setup(value, EINA_VALUE_TYPE_LIST))
886 return EINA_FALSE;
887 if (!eina_value_pset(value, &desc))
888 {
889 eina_value_flush(value);
890 return EINA_FALSE;
891 }
892 return EINA_TRUE;
893}
894
895static inline unsigned int
896eina_value_list_count(const Eina_Value *value)
897{
898 Eina_Value_List *desc;
899 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
900 desc = (Eina_Value_List *)eina_value_memory_get(value);
901 if (!desc)
902 return 0;
903 return eina_list_count(desc->list);
904}
905
906static inline Eina_Bool
907eina_value_list_remove(Eina_Value *value, unsigned int position)
908{
909 Eina_Value_List *desc;
910 Eina_List *node;
911 void *mem;
912
913 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
914 desc = (Eina_Value_List *)eina_value_memory_get(value);
915 if (!desc)
916 return EINA_FALSE;
917
918 node = eina_list_nth_list(desc->list, position);
919 mem = eina_value_list_node_memory_get(desc->subtype, node);
920 if (!mem)
921 return EINA_FALSE;
922
923 eina_value_type_flush(desc->subtype, mem);
924 eina_value_list_node_memory_flush(desc->subtype, node);
925 desc->list = eina_list_remove_list(desc->list, node);
926 return EINA_TRUE;
927}
928
929static inline Eina_Bool
930eina_value_list_vset(Eina_Value *value, unsigned int position, va_list args)
931{
932 Eina_Value_List *desc;
933 Eina_List *node;
934 void *mem;
935
936 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
937 desc = (Eina_Value_List *)eina_value_memory_get(value);
938 if (!desc)
939 return EINA_FALSE;
940
941 node = eina_list_nth_list(desc->list, position);
942 mem = eina_value_list_node_memory_get(desc->subtype, node);
943 if (!mem)
944 return EINA_FALSE;
945
946 return eina_value_type_vset(desc->subtype, mem, args);
947}
948
949static inline Eina_Bool
950eina_value_list_vget(const Eina_Value *value, unsigned int position, va_list args)
951{
952 const Eina_Value_List *desc;
953 const Eina_List *node;
954 const void *mem;
955 void *ptr;
956 Eina_Bool ret;
957
958 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
959 desc = (const Eina_Value_List *)eina_value_memory_get(value);
960 if (!desc)
961 return EINA_FALSE;
962
963 node = eina_list_nth_list(desc->list, position);
964 mem = eina_value_list_node_memory_get(desc->subtype, node);
965 if (!mem)
966 return EINA_FALSE;
967
968 ptr = va_arg(args, void *);
969 ret = eina_value_type_pget(desc->subtype, mem, ptr);
970 return ret;
971}
972
973static inline Eina_Bool
974eina_value_list_vinsert(Eina_Value *value, unsigned int position, va_list args)
975{
976 Eina_Value_List *desc;
977 Eina_List *node;
978 void *mem;
979
980 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
981 desc = (Eina_Value_List *)eina_value_memory_get(value);
982 if (!desc)
983 return EINA_FALSE;
984
985 if (!desc->list)
986 node = desc->list = eina_list_append(NULL, (void*)1L);
987 else if (position == 0)
988 node = desc->list = eina_list_prepend(desc->list, (void*)1L);
989 else
990 {
991 Eina_List *rel = eina_list_nth_list(desc->list, position - 1);
992 desc->list = eina_list_append_relative_list(desc->list, (void*)1L, rel);
993 node = rel->next;
994 }
995 EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
996 EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
997
998 mem = eina_value_list_node_memory_setup(desc->subtype, node);
999 if (!mem)
1000 {
1001 desc->list = eina_list_remove_list(desc->list, node);
1002 return EINA_FALSE;
1003 }
1004
1005 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1006 if (!eina_value_type_vset(desc->subtype, mem, args)) goto error_set;
1007 return EINA_TRUE;
1008
1009 error_set:
1010 eina_value_type_flush(desc->subtype, mem);
1011 error_setup:
1012 eina_value_list_node_memory_flush(desc->subtype, node);
1013 desc->list = eina_list_remove_list(desc->list, node);
1014 return EINA_FALSE;
1015}
1016
1017static inline Eina_Bool
1018eina_value_list_vappend(Eina_Value *value, va_list args)
1019{
1020 Eina_Value_List *desc;
1021 Eina_List *node;
1022 void *mem;
1023
1024 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1025 desc = (Eina_Value_List *)eina_value_memory_get(value);
1026 if (!desc)
1027 return EINA_FALSE;
1028
1029 desc->list = eina_list_append(desc->list, (void*)1L);
1030 node = eina_list_last(desc->list);
1031 EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
1032 EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
1033
1034 mem = eina_value_list_node_memory_setup(desc->subtype, node);
1035 if (!mem)
1036 {
1037 desc->list = eina_list_remove_list(desc->list, node);
1038 return EINA_FALSE;
1039 }
1040
1041 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1042 if (!eina_value_type_vset(desc->subtype, mem, args)) goto error_set;
1043 return EINA_TRUE;
1044
1045 error_set:
1046 eina_value_type_flush(desc->subtype, mem);
1047 error_setup:
1048 eina_value_list_node_memory_flush(desc->subtype, node);
1049 desc->list = eina_list_remove_list(desc->list, node);
1050 return EINA_FALSE;
1051}
1052
1053static inline Eina_Bool
1054eina_value_list_set(Eina_Value *value, unsigned int position, ...)
1055{
1056 va_list args;
1057 Eina_Bool ret;
1058 va_start(args, position);
1059 ret = eina_value_list_vset(value, position, args);
1060 va_end(args);
1061 return ret;
1062}
1063
1064static inline Eina_Bool
1065eina_value_list_get(const Eina_Value *value, unsigned int position, ...)
1066{
1067 va_list args;
1068 Eina_Bool ret;
1069 va_start(args, position);
1070 ret = eina_value_list_vget(value, position, args);
1071 va_end(args);
1072 return ret;
1073}
1074
1075static inline Eina_Bool
1076eina_value_list_insert(Eina_Value *value, unsigned int position, ...)
1077{
1078 va_list args;
1079 Eina_Bool ret;
1080 va_start(args, position);
1081 ret = eina_value_list_vinsert(value, position, args);
1082 va_end(args);
1083 return ret;
1084}
1085
1086static inline Eina_Bool eina_value_list_append(Eina_Value *value, ...)
1087{
1088 va_list args;
1089 Eina_Bool ret;
1090 va_start(args, value);
1091 ret = eina_value_list_vappend(value, args);
1092 va_end(args);
1093 return ret;
1094}
1095
1096static inline Eina_Bool
1097eina_value_list_pset(Eina_Value *value, unsigned int position, const void *ptr)
1098{
1099 Eina_Value_List *desc;
1100 Eina_List *node;
1101 void *mem;
1102
1103 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1104 desc = (Eina_Value_List *)eina_value_memory_get(value);
1105 if (!desc)
1106 return EINA_FALSE;
1107
1108 node = eina_list_nth_list(desc->list, position);
1109 mem = eina_value_list_node_memory_get(desc->subtype, node);
1110 if (!mem)
1111 return EINA_FALSE;
1112
1113 return eina_value_type_pset(desc->subtype, mem, ptr);
1114}
1115
1116static inline Eina_Bool
1117eina_value_list_pget(const Eina_Value *value, unsigned int position, void *ptr)
1118{
1119 const Eina_Value_List *desc;
1120 const Eina_List *node;
1121 const void *mem;
1122 Eina_Bool ret;
1123
1124 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1125 desc = (const Eina_Value_List *)eina_value_memory_get(value);
1126 if (!desc)
1127 return EINA_FALSE;
1128
1129 node = eina_list_nth_list(desc->list, position);
1130 mem = eina_value_list_node_memory_get(desc->subtype, node);
1131 if (!mem)
1132 return EINA_FALSE;
1133
1134 ret = eina_value_type_pget(desc->subtype, mem, ptr);
1135 return ret;
1136}
1137
1138static inline Eina_Bool
1139eina_value_list_pinsert(Eina_Value *value, unsigned int position, const void *ptr)
1140{
1141 Eina_Value_List *desc;
1142 Eina_List *node;
1143 void *mem;
1144
1145 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1146 desc = (Eina_Value_List *)eina_value_memory_get(value);
1147 if (!desc)
1148 return EINA_FALSE;
1149
1150 if (!desc->list)
1151 node = desc->list = eina_list_append(NULL, (void*)1L);
1152 else if (position == 0)
1153 node = desc->list = eina_list_prepend(desc->list, (void*)1L);
1154 else
1155 {
1156 Eina_List *rel = eina_list_nth_list(desc->list, position - 1);
1157 desc->list = eina_list_append_relative_list(desc->list, (void*)1L, rel);
1158 node = rel->next;
1159 }
1160 EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
1161 EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
1162
1163 mem = eina_value_list_node_memory_setup(desc->subtype, node);
1164 if (!mem)
1165 {
1166 desc->list = eina_list_remove_list(desc->list, node);
1167 return EINA_FALSE;
1168 }
1169
1170 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1171 if (!eina_value_type_pset(desc->subtype, mem, ptr)) goto error_set;
1172 return EINA_TRUE;
1173
1174 error_set:
1175 eina_value_type_flush(desc->subtype, mem);
1176 error_setup:
1177 eina_value_list_node_memory_flush(desc->subtype, node);
1178 desc->list = eina_list_remove_list(desc->list, node);
1179 return EINA_FALSE;
1180}
1181
1182static inline Eina_Bool
1183eina_value_list_pappend(Eina_Value *value, const void *ptr)
1184{
1185 Eina_Value_List *desc;
1186 Eina_List *node;
1187 void *mem;
1188
1189 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1190 desc = (Eina_Value_List *)eina_value_memory_get(value);
1191 if (!desc)
1192 return EINA_FALSE;
1193
1194 desc->list = eina_list_append(desc->list, (void*)1L);
1195 node = eina_list_last(desc->list);
1196 EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
1197 EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
1198
1199 mem = eina_value_list_node_memory_setup(desc->subtype, node);
1200 if (!mem)
1201 {
1202 desc->list = eina_list_remove_list(desc->list, node);
1203 return EINA_FALSE;
1204 }
1205
1206 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1207 if (!eina_value_type_pset(desc->subtype, mem, ptr)) goto error_set;
1208 return EINA_TRUE;
1209
1210 error_set:
1211 eina_value_type_flush(desc->subtype, mem);
1212 error_setup:
1213 eina_value_list_node_memory_flush(desc->subtype, node);
1214 desc->list = eina_list_remove_list(desc->list, node);
1215 return EINA_FALSE;
1216}
1217#undef EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL
1218
1219#define EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, retval) \
1220 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
1221 EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_HASH, retval)
1222
1223static inline Eina_Bool
1224eina_value_hash_setup(Eina_Value *value, const Eina_Value_Type *subtype, unsigned int buckets_power_size)
1225{
1226 Eina_Value_Hash desc = { subtype, buckets_power_size, NULL };
1227 if (!eina_value_setup(value, EINA_VALUE_TYPE_HASH))
1228 return EINA_FALSE;
1229 if (!eina_value_pset(value, &desc))
1230 {
1231 eina_value_flush(value);
1232 return EINA_FALSE;
1233 }
1234 return EINA_TRUE;
1235}
1236
1237static inline unsigned int
1238eina_value_hash_population(const Eina_Value *value)
1239{
1240 Eina_Value_Hash *desc;
1241 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0);
1242 desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1243 if (!desc)
1244 return 0;
1245 return eina_hash_population(desc->hash);
1246}
1247
1248static inline Eina_Bool
1249eina_value_hash_del(Eina_Value *value, const char *key)
1250{
1251 Eina_Value_Hash *desc;
1252 void *mem;
1253
1254 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE);
1255 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1256 desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1257 if (!desc)
1258 return EINA_FALSE;
1259
1260 mem = eina_hash_find(desc->hash, key);
1261 if (!mem)
1262 return EINA_FALSE;
1263
1264 eina_value_type_flush(desc->subtype, mem);
1265 free(mem);
1266 eina_hash_del_by_key(desc->hash, key);
1267 return EINA_TRUE;
1268}
1269
1270static inline Eina_Bool
1271eina_value_hash_vset(Eina_Value *value, const char *key, va_list args)
1272{
1273 Eina_Value_Hash *desc;
1274 void *mem;
1275
1276 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE);
1277 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1278 desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1279 if (!desc)
1280 return EINA_FALSE;
1281
1282 mem = eina_hash_find(desc->hash, key);
1283 if (!mem)
1284 {
1285 mem = malloc(desc->subtype->value_size);
1286 if (!mem)
1287 {
1288 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
1289 return EINA_FALSE;
1290 }
1291 if (!eina_hash_add(desc->hash, key, mem))
1292 {
1293 free(mem);
1294 return EINA_FALSE;
1295 }
1296 if (!eina_value_type_setup(desc->subtype, mem))
1297 {
1298 eina_value_type_flush(desc->subtype, mem);
1299 eina_hash_del_by_key(desc->hash, key);
1300 free(mem);
1301 }
1302 }
1303
1304 return eina_value_type_vset(desc->subtype, mem, args);
1305}
1306
1307static inline Eina_Bool
1308eina_value_hash_vget(const Eina_Value *value, const char *key, va_list args)
1309{
1310 const Eina_Value_Hash *desc;
1311 const void *mem;
1312 void *ptr;
1313 Eina_Bool ret;
1314
1315 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE);
1316 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1317 desc = (const Eina_Value_Hash *)eina_value_memory_get(value);
1318 if (!desc)
1319 return EINA_FALSE;
1320
1321 mem = eina_hash_find(desc->hash, key);
1322 if (!mem)
1323 return EINA_FALSE;
1324
1325 ptr = va_arg(args, void *);
1326 ret = eina_value_type_pget(desc->subtype, mem, ptr);
1327 return ret;
1328}
1329
1330static inline Eina_Bool
1331eina_value_hash_set(Eina_Value *value, const char *key, ...)
1332{
1333 va_list args;
1334 Eina_Bool ret;
1335 va_start(args, key);
1336 ret = eina_value_hash_vset(value, key, args);
1337 va_end(args);
1338 return ret;
1339}
1340
1341static inline Eina_Bool
1342eina_value_hash_get(const Eina_Value *value, const char *key, ...)
1343{
1344 va_list args;
1345 Eina_Bool ret;
1346 va_start(args, key);
1347 ret = eina_value_hash_vget(value, key, args);
1348 va_end(args);
1349 return ret;
1350}
1351
1352static inline Eina_Bool
1353eina_value_hash_pset(Eina_Value *value, const char *key, const void *ptr)
1354{
1355 Eina_Value_Hash *desc;
1356 void *mem;
1357
1358 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0);
1359 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1360 desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1361 if (!desc)
1362 return EINA_FALSE;
1363
1364 mem = eina_hash_find(desc->hash, key);
1365 if (!mem)
1366 {
1367 mem = malloc(desc->subtype->value_size);
1368 if (!mem)
1369 {
1370 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
1371 return EINA_FALSE;
1372 }
1373 if (!eina_hash_add(desc->hash, key, mem))
1374 {
1375 free(mem);
1376 return EINA_FALSE;
1377 }
1378 if (!eina_value_type_setup(desc->subtype, mem))
1379 {
1380 eina_value_type_flush(desc->subtype, mem);
1381 eina_hash_del_by_key(desc->hash, key);
1382 free(mem);
1383 }
1384 }
1385
1386 return eina_value_type_pset(desc->subtype, mem, ptr);
1387}
1388
1389static inline Eina_Bool
1390eina_value_hash_pget(const Eina_Value *value, const char *key, void *ptr)
1391{
1392 const Eina_Value_Hash *desc;
1393 const void *mem;
1394 Eina_Bool ret;
1395
1396 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0);
1397 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1398 desc = (const Eina_Value_Hash *)eina_value_memory_get(value);
1399 if (!desc)
1400 return EINA_FALSE;
1401
1402 mem = eina_hash_find(desc->hash, key);
1403 if (!mem)
1404 return EINA_FALSE;
1405
1406 ret = eina_value_type_pget(desc->subtype, mem, ptr);
1407 return ret;
1408}
1409#undef EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL
1410
1411#define EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, retval) \
1412 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
1413 EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_STRUCT, retval)
1414
1415/**
1416 * @brief Find member of struct
1417 * @since 1.2
1418 * @internal
1419 */
1420EAPI 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;
1421
1422static inline Eina_Bool
1423eina_value_struct_setup(Eina_Value *value, const Eina_Value_Struct_Desc *sdesc)
1424{
1425 Eina_Value_Struct desc = {sdesc, NULL};
1426 if (!eina_value_setup(value, EINA_VALUE_TYPE_STRUCT))
1427 return EINA_FALSE;
1428 if (!eina_value_pset(value, &desc))
1429 {
1430 eina_value_flush(value);
1431 return EINA_FALSE;
1432 }
1433 return EINA_TRUE;
1434}
1435
1436static inline void *
1437eina_value_struct_member_memory_get(const Eina_Value_Struct *st, const Eina_Value_Struct_Member *member)
1438{
1439 unsigned char *base = (unsigned char *)st->memory;
1440 if (!base) return NULL;
1441 return base + member->offset;
1442}
1443
1444static inline Eina_Bool
1445eina_value_struct_vset(Eina_Value *value, const char *name, va_list args)
1446{
1447 const Eina_Value_Struct_Member *member;
1448 Eina_Value_Struct *st;
1449 void *mem;
1450
1451 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1452 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1453 st = (Eina_Value_Struct *)eina_value_memory_get(value);
1454 if (!st)
1455 return EINA_FALSE;
1456 member = eina_value_struct_member_find(st, name);
1457 if (!member)
1458 return EINA_FALSE;
1459 mem = eina_value_struct_member_memory_get(st, member);
1460 if (!mem)
1461 return EINA_FALSE;
1462
1463 return eina_value_type_vset(member->type, mem, args);
1464}
1465
1466static inline Eina_Bool
1467eina_value_struct_vget(const Eina_Value *value, const char *name, va_list args)
1468{
1469 const Eina_Value_Struct_Member *member;
1470 const Eina_Value_Struct *st;
1471 const void *mem;
1472 void *ptr;
1473 Eina_Bool ret;
1474
1475 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1476 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1477 st = (const Eina_Value_Struct *)eina_value_memory_get(value);
1478 if (!st)
1479 return EINA_FALSE;
1480 member = eina_value_struct_member_find(st, name);
1481 if (!member)
1482 return EINA_FALSE;
1483 mem = eina_value_struct_member_memory_get(st, member);
1484 if (!mem)
1485 return EINA_FALSE;
1486
1487 ptr = va_arg(args, void *);
1488 ret = eina_value_type_pget(member->type, mem, ptr);
1489 return ret;
1490}
1491
1492static inline Eina_Bool
1493eina_value_struct_set(Eina_Value *value, const char *name, ...)
1494{
1495 va_list args;
1496 Eina_Bool ret;
1497 va_start(args, name);
1498 ret = eina_value_struct_vset(value, name, args);
1499 va_end(args);
1500 return ret;
1501}
1502
1503static inline Eina_Bool
1504eina_value_struct_get(const Eina_Value *value, const char *name, ...)
1505{
1506 va_list args;
1507 Eina_Bool ret;
1508 va_start(args, name);
1509 ret = eina_value_struct_vget(value, name, args);
1510 va_end(args);
1511 return ret;
1512}
1513
1514static inline Eina_Bool
1515eina_value_struct_pset(Eina_Value *value, const char *name, const void *ptr)
1516{
1517 const Eina_Value_Struct_Member *member;
1518 Eina_Value_Struct *st;
1519 void *mem;
1520
1521 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1522 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1523 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
1524 st = (Eina_Value_Struct *)eina_value_memory_get(value);
1525 if (!st)
1526 return EINA_FALSE;
1527 member = eina_value_struct_member_find(st, name);
1528 if (!member)
1529 return EINA_FALSE;
1530 mem = eina_value_struct_member_memory_get(st, member);
1531 if (!mem)
1532 return EINA_FALSE;
1533
1534 return eina_value_type_pset(member->type, mem, ptr);
1535}
1536
1537static inline Eina_Bool
1538eina_value_struct_pget(const Eina_Value *value, const char *name, void *ptr)
1539{
1540 const Eina_Value_Struct_Member *member;
1541 const Eina_Value_Struct *st;
1542 const void *mem;
1543 Eina_Bool ret;
1544
1545 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1546 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1547 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
1548 st = (const Eina_Value_Struct *)eina_value_memory_get(value);
1549 if (!st)
1550 return EINA_FALSE;
1551 member = eina_value_struct_member_find(st, name);
1552 if (!member)
1553 return EINA_FALSE;
1554 mem = eina_value_struct_member_memory_get(st, member);
1555 if (!mem)
1556 return EINA_FALSE;
1557
1558 ret = eina_value_type_pget(member->type, mem, ptr);
1559 return ret;
1560}
1561
1562static inline Eina_Bool
1563eina_value_struct_value_get(const Eina_Value *src, const char *name, Eina_Value *dst)
1564{
1565 const Eina_Value_Struct_Member *member;
1566 const Eina_Value_Struct *st;
1567 const void *mem;
1568
1569 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(src, EINA_FALSE);
1570 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1571 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
1572 st = (const Eina_Value_Struct *)eina_value_memory_get(src);
1573 if (!st)
1574 return EINA_FALSE;
1575 member = eina_value_struct_member_find(st, name);
1576 if (!member)
1577 return EINA_FALSE;
1578 mem = eina_value_struct_member_memory_get(st, member);
1579 if (!mem)
1580 return EINA_FALSE;
1581 if (!eina_value_setup(dst, member->type))
1582 return EINA_FALSE;
1583 if (!eina_value_pset(dst, mem))
1584 {
1585 eina_value_flush(dst);
1586 return EINA_FALSE;
1587 }
1588 return EINA_TRUE;
1589}
1590
1591static inline Eina_Bool
1592eina_value_struct_value_set(Eina_Value *dst, const char *name, const Eina_Value *src)
1593{
1594 const Eina_Value_Struct_Member *member;
1595 Eina_Value_Struct *st;
1596 void *mem;
1597 const void *ptr;
1598
1599 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(dst, EINA_FALSE);
1600 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1601 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
1602
1603 st = (Eina_Value_Struct *)eina_value_memory_get(dst);
1604 if (!st)
1605 return EINA_FALSE;
1606 member = eina_value_struct_member_find(st, name);
1607 if (!member)
1608 return EINA_FALSE;
1609 EINA_SAFETY_ON_FALSE_RETURN_VAL(src->type == member->type, EINA_FALSE);
1610
1611 mem = eina_value_struct_member_memory_get(st, member);
1612 if (!mem)
1613 return EINA_FALSE;
1614
1615 ptr = eina_value_memory_get(src);
1616 if (!ptr)
1617 return EINA_FALSE;
1618
1619 return eina_value_type_pset(member->type, mem, ptr);
1620}
1621
1622static inline Eina_Bool
1623eina_value_struct_member_value_get(const Eina_Value *src, const Eina_Value_Struct_Member *member, Eina_Value *dst)
1624{
1625 const Eina_Value_Struct *st;
1626 const void *mem;
1627
1628 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(src, EINA_FALSE);
1629 EINA_SAFETY_ON_NULL_RETURN_VAL(member, EINA_FALSE);
1630 EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
1631 st = (const Eina_Value_Struct *)eina_value_memory_get(src);
1632 if (!st)
1633 return EINA_FALSE;
1634 mem = eina_value_struct_member_memory_get(st, member);
1635 if (!mem)
1636 return EINA_FALSE;
1637 if (!eina_value_setup(dst, member->type))
1638 return EINA_FALSE;
1639 if (!eina_value_pset(dst, mem))
1640 {
1641 eina_value_flush(dst);
1642 return EINA_FALSE;
1643 }
1644 return EINA_TRUE;
1645}
1646
1647static inline Eina_Bool
1648eina_value_struct_member_value_set(Eina_Value *dst, const Eina_Value_Struct_Member *member, const Eina_Value *src)
1649{
1650 Eina_Value_Struct *st;
1651 void *mem;
1652 const void *ptr;
1653
1654 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(dst, EINA_FALSE);
1655 EINA_SAFETY_ON_NULL_RETURN_VAL(member, EINA_FALSE);
1656 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
1657
1658 st = (Eina_Value_Struct *)eina_value_memory_get(dst);
1659 if (!st)
1660 return EINA_FALSE;
1661 EINA_SAFETY_ON_FALSE_RETURN_VAL(src->type == member->type, EINA_FALSE);
1662
1663 mem = eina_value_struct_member_memory_get(st, member);
1664 if (!mem)
1665 return EINA_FALSE;
1666
1667 ptr = eina_value_memory_get(src);
1668 if (!ptr)
1669 return EINA_FALSE;
1670
1671 return eina_value_type_pset(member->type, mem, ptr);
1672}
1673
1674#undef EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL
1675
1676
1677static inline Eina_Bool
1678eina_value_type_setup(const Eina_Value_Type *type, void *mem)
1679{
1680 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1681 if (!type->setup)
1682 {
1683 eina_error_set(EINA_ERROR_VALUE_FAILED);
1684 return EINA_FALSE;
1685 }
1686 return type->setup(type, mem);
1687}
1688
1689static inline Eina_Bool
1690eina_value_type_flush(const Eina_Value_Type *type, void *mem)
1691{
1692 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1693 if (!type->flush)
1694 {
1695 eina_error_set(EINA_ERROR_VALUE_FAILED);
1696 return EINA_FALSE;
1697 }
1698 return type->flush(type, mem);
1699}
1700
1701static inline Eina_Bool
1702eina_value_type_copy(const Eina_Value_Type *type, const void *src, void *dst)
1703{
1704 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1705 if (!type->copy)
1706 {
1707 eina_error_set(EINA_ERROR_VALUE_FAILED);
1708 return EINA_FALSE;
1709 }
1710 return type->copy(type, src, dst);
1711}
1712
1713static inline int
1714eina_value_type_compare(const Eina_Value_Type *type, const void *a, const void *b)
1715{
1716 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1717 if (!type->compare)
1718 {
1719 eina_error_set(EINA_ERROR_VALUE_FAILED);
1720 return EINA_FALSE;
1721 }
1722 return type->compare(type, a, b);
1723}
1724
1725static inline Eina_Bool
1726eina_value_type_convert_to(const Eina_Value_Type *type, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
1727{
1728 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1729 if (!type->convert_to)
1730 {
1731 eina_error_set(EINA_ERROR_VALUE_FAILED);
1732 return EINA_FALSE;
1733 }
1734 return type->convert_to(type, convert, type_mem, convert_mem);
1735}
1736
1737static inline Eina_Bool
1738eina_value_type_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem)
1739{
1740 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1741 if (!type->convert_from)
1742 {
1743 eina_error_set(EINA_ERROR_VALUE_FAILED);
1744 return EINA_FALSE;
1745 }
1746 return type->convert_from(type, convert, type_mem, convert_mem);
1747}
1748
1749static inline Eina_Bool
1750eina_value_type_vset(const Eina_Value_Type *type, void *mem, va_list args)
1751{
1752 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1753 if (!type->vset)
1754 {
1755 eina_error_set(EINA_ERROR_VALUE_FAILED);
1756 return EINA_FALSE;
1757 }
1758 return type->vset(type, mem, args);
1759}
1760
1761static inline Eina_Bool
1762eina_value_type_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
1763{
1764 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1765 if (!type->pset)
1766 {
1767 eina_error_set(EINA_ERROR_VALUE_FAILED);
1768 return EINA_FALSE;
1769 }
1770 return type->pset(type, mem, ptr);
1771}
1772
1773static inline Eina_Bool
1774eina_value_type_pget(const Eina_Value_Type *type, const void *mem, void *ptr)
1775{
1776 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1777 if (!type->pget)
1778 {
1779 eina_error_set(EINA_ERROR_VALUE_FAILED);
1780 return EINA_FALSE;
1781 }
1782 return type->pget(type, mem, ptr);
1783}
1784
1785#undef EINA_VALUE_TYPE_DEFAULT
1786#undef EINA_VALUE_TYPE_CHECK_RETURN
1787#undef EINA_VALUE_TYPE_CHECK_RETURN_VAL
1788#undef EINA_VALUE_TYPE_DISPATCH
1789#undef EINA_VALUE_TYPE_DISPATCH_RETURN
1790#endif