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.x1705
1 files changed, 1705 insertions, 0 deletions
diff --git a/libraries/eina/src/include/eina_inline_value.x b/libraries/eina/src/include/eina_inline_value.x
new file mode 100644
index 0000000..59ec315
--- /dev/null
+++ b/libraries/eina/src/include/eina_inline_value.x
@@ -0,0 +1,1705 @@
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 <string.h>
23#include <alloca.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)
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)
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 free(value->value.ptr);
428 if (!str)
429 value->value.ptr = NULL;
430 else
431 {
432 value->value.ptr = strdup(str);
433 if (!value->value.ptr)
434 {
435 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
436 return EINA_FALSE;
437 }
438 }
439 return EINA_TRUE;
440 }
441#endif
442
443 EINA_VALUE_TYPE_DISPATCH_RETURN(value, vset, EINA_ERROR_VALUE_FAILED,
444 EINA_FALSE, mem, args);
445}
446
447static inline Eina_Bool
448eina_value_vget(const Eina_Value *value, va_list args)
449{
450 const Eina_Value_Type *type;
451 const void *mem;
452 void *ptr;
453
454 EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
455
456 type = value->type;
457 mem = eina_value_memory_get(value);
458 ptr = va_arg(args, void *);
459 eina_error_set(0);
460 if (EINA_VALUE_TYPE_DEFAULT(type))
461 {
462 memcpy(ptr, mem, type->value_size);
463 return EINA_TRUE;
464 }
465
466 EINA_VALUE_TYPE_DISPATCH_RETURN(value, pget, EINA_ERROR_VALUE_FAILED,
467 EINA_FALSE, mem, ptr);
468}
469
470static inline Eina_Bool
471eina_value_pset(Eina_Value *value, const void *ptr)
472{
473 const Eina_Value_Type *type;
474 void *mem;
475
476 EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
477 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
478
479 type = value->type;
480 mem = eina_value_memory_get(value);
481 eina_error_set(0);
482
483 if (EINA_VALUE_TYPE_DEFAULT(type))
484 {
485 if (type == EINA_VALUE_TYPE_STRINGSHARE)
486 {
487 const char * const *pstr = (const char * const *) ptr;
488 const char *str = *pstr;
489
490 return eina_stringshare_replace((const char **)&value->value.ptr,
491 str);
492 }
493 else if (type == EINA_VALUE_TYPE_STRING)
494 {
495 const char * const * pstr = (const char * const *) ptr;
496 const char *str = *pstr;
497
498 free(value->value.ptr);
499 if (!str)
500 value->value.ptr = NULL;
501 else
502 {
503 value->value.ptr = strdup(str);
504 if (!value->value.ptr)
505 {
506 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
507 return EINA_FALSE;
508 }
509 }
510 return EINA_TRUE;
511 }
512 else
513 memcpy(mem, ptr, type->value_size);
514 return EINA_TRUE;
515 }
516
517 EINA_VALUE_TYPE_DISPATCH_RETURN(value, pset, EINA_ERROR_VALUE_FAILED,
518 EINA_FALSE, mem, ptr);
519}
520
521static inline Eina_Bool
522eina_value_pget(const Eina_Value *value, void *ptr)
523{
524 const Eina_Value_Type *type;
525 const void *mem;
526
527 EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, EINA_FALSE);
528 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, EINA_FALSE);
529
530 type = value->type;
531 mem = eina_value_memory_get(value);
532 eina_error_set(0);
533 if (EINA_VALUE_TYPE_DEFAULT(type))
534 {
535 memcpy(ptr, mem, type->value_size);
536 return EINA_TRUE;
537 }
538
539 EINA_VALUE_TYPE_DISPATCH_RETURN(value, pget, EINA_ERROR_VALUE_FAILED,
540 EINA_FALSE, mem, ptr);
541}
542
543static inline const Eina_Value_Type *
544eina_value_type_get(const Eina_Value *value)
545{
546 EINA_VALUE_TYPE_CHECK_RETURN_VAL(value, NULL);
547 return value->type;
548}
549
550#define EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, retval) \
551 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
552 EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_ARRAY, retval)
553
554static inline Eina_Bool
555eina_value_array_setup(Eina_Value *value, const Eina_Value_Type *subtype, unsigned int step)
556{
557 Eina_Value_Array desc = { subtype, step, NULL };
558 if (!eina_value_setup(value, EINA_VALUE_TYPE_ARRAY))
559 return EINA_FALSE;
560 if (!eina_value_pset(value, &desc))
561 {
562 eina_value_flush(value);
563 return EINA_FALSE;
564 }
565 return EINA_TRUE;
566}
567
568static inline unsigned int
569eina_value_array_count(const Eina_Value *value)
570{
571 Eina_Value_Array desc;
572 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
573 if (!eina_value_pget(value, &desc))
574 return 0;
575 return eina_inarray_count(desc.array);
576}
577
578static inline Eina_Bool
579eina_value_array_remove(Eina_Value *value, unsigned int position)
580{
581 Eina_Value_Array desc;
582 void *mem;
583
584 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
585 if (!eina_value_pget(value, &desc))
586 return EINA_FALSE;
587
588 mem = eina_inarray_nth(desc.array, position);
589 if (!mem)
590 return EINA_FALSE;
591
592 eina_value_type_flush(desc.subtype, mem);
593 return eina_inarray_remove_at(desc.array, position);
594}
595
596static inline Eina_Bool
597eina_value_array_vset(Eina_Value *value, unsigned int position, va_list args)
598{
599 Eina_Value_Array desc;
600 void *mem;
601
602 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
603 if (!eina_value_pget(value, &desc))
604 return EINA_FALSE;
605
606 mem = eina_inarray_nth(desc.array, position);
607 if (!mem)
608 return EINA_FALSE;
609
610 eina_value_type_flush(desc.subtype, mem);
611
612 if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
613 if (!eina_value_type_vset(desc.subtype, mem, args)) goto error_set;
614 return EINA_TRUE;
615
616 error_set:
617 eina_value_type_flush(desc.subtype, mem);
618 error_setup:
619 return EINA_FALSE;
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 eina_value_type_flush(desc.subtype, mem);
753
754 if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
755 if (!eina_value_type_pset(desc.subtype, mem, ptr)) goto error_set;
756 return EINA_TRUE;
757
758 error_set:
759 eina_value_type_flush(desc.subtype, mem);
760 error_setup:
761 return EINA_FALSE;
762}
763
764static inline Eina_Bool
765eina_value_array_pget(const Eina_Value *value, unsigned int position, void *ptr)
766{
767 Eina_Value_Array desc;
768 const void *mem;
769 Eina_Bool ret;
770
771 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
772 if (!eina_value_pget(value, &desc))
773 return EINA_FALSE;
774
775 mem = eina_inarray_nth(desc.array, position);
776 if (!mem)
777 return EINA_FALSE;
778
779 ret = eina_value_type_pget(desc.subtype, mem, ptr);
780 return ret;
781}
782
783static inline Eina_Bool
784eina_value_array_pinsert(Eina_Value *value, unsigned int position, const void *ptr)
785{
786 Eina_Value_Array desc;
787 void *mem;
788
789 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
790 if (!eina_value_pget(value, &desc))
791 return EINA_FALSE;
792
793 mem = eina_inarray_alloc_at(desc.array, position, 1);
794 if (!mem)
795 return EINA_FALSE;
796
797 if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
798 if (!eina_value_type_pset(desc.subtype, mem, ptr)) goto error_set;
799 return EINA_TRUE;
800
801 error_set:
802 eina_value_type_flush(desc.subtype, mem);
803 error_setup:
804 eina_inarray_remove_at(desc.array, position);
805 return EINA_FALSE;
806}
807
808static inline Eina_Bool
809eina_value_array_pappend(Eina_Value *value, const void *ptr)
810{
811 Eina_Value_Array desc;
812 void *mem;
813 int position;
814
815 EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL(value, 0);
816 if (!eina_value_pget(value, &desc))
817 return EINA_FALSE;
818
819 position = eina_inarray_count(desc.array);
820 mem = eina_inarray_alloc_at(desc.array, position, 1);
821 if (!mem)
822 return EINA_FALSE;
823
824 if (!eina_value_type_setup(desc.subtype, mem)) goto error_setup;
825 if (!eina_value_type_pset(desc.subtype, mem, ptr)) goto error_set;
826 return EINA_TRUE;
827
828 error_set:
829 eina_value_type_flush(desc.subtype, mem);
830 error_setup:
831 eina_inarray_remove_at(desc.array, position);
832 return EINA_FALSE;
833}
834
835#undef EINA_VALUE_TYPE_ARRAY_CHECK_RETURN_VAL
836
837#define EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, retval) \
838 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
839 EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_LIST, retval)
840
841static inline void *
842eina_value_list_node_memory_get(const Eina_Value_Type *type, const Eina_List *node)
843{
844 if (node == NULL) return NULL;
845 if (type->value_size <= sizeof(void*))
846 return (void *)&(node->data);
847 return node->data;
848}
849
850static inline void *
851eina_value_list_node_memory_setup(const Eina_Value_Type *type, Eina_List *node)
852{
853 if (type->value_size <= sizeof(void*))
854 return (void *)&(node->data);
855 node->data = malloc(type->value_size);
856 return node->data;
857}
858
859static inline void
860eina_value_list_node_memory_flush(const Eina_Value_Type *type, Eina_List *node)
861{
862 if (type->value_size <= sizeof(void*))
863 return;
864 free(node->data);
865}
866
867static inline Eina_Bool
868eina_value_list_setup(Eina_Value *value, const Eina_Value_Type *subtype)
869{
870 Eina_Value_List desc = { subtype, NULL };
871 if (!eina_value_setup(value, EINA_VALUE_TYPE_LIST))
872 return EINA_FALSE;
873 if (!eina_value_pset(value, &desc))
874 {
875 eina_value_flush(value);
876 return EINA_FALSE;
877 }
878 return EINA_TRUE;
879}
880
881static inline unsigned int
882eina_value_list_count(const Eina_Value *value)
883{
884 Eina_Value_List *desc;
885 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
886 desc = (Eina_Value_List *)eina_value_memory_get(value);
887 if (!desc)
888 return 0;
889 return eina_list_count(desc->list);
890}
891
892static inline Eina_Bool
893eina_value_list_remove(Eina_Value *value, unsigned int position)
894{
895 Eina_Value_List *desc;
896 Eina_List *node;
897 void *mem;
898
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 EINA_FALSE;
903
904 node = eina_list_nth_list(desc->list, position);
905 mem = eina_value_list_node_memory_get(desc->subtype, node);
906 if (!mem)
907 return EINA_FALSE;
908
909 eina_value_type_flush(desc->subtype, mem);
910 eina_value_list_node_memory_flush(desc->subtype, node);
911 desc->list = eina_list_remove_list(desc->list, node);
912 return EINA_TRUE;
913}
914
915static inline Eina_Bool
916eina_value_list_vset(Eina_Value *value, unsigned int position, va_list args)
917{
918 Eina_Value_List *desc;
919 Eina_List *node;
920 void *mem;
921
922 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
923 desc = (Eina_Value_List *)eina_value_memory_get(value);
924 if (!desc)
925 return EINA_FALSE;
926
927 node = eina_list_nth_list(desc->list, position);
928 mem = eina_value_list_node_memory_get(desc->subtype, node);
929 if (!mem)
930 return EINA_FALSE;
931
932 eina_value_type_flush(desc->subtype, mem);
933
934 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
935 if (!eina_value_type_vset(desc->subtype, mem, args)) goto error_set;
936 return EINA_TRUE;
937
938 error_set:
939 eina_value_type_flush(desc->subtype, mem);
940 error_setup:
941 return EINA_FALSE;
942}
943
944static inline Eina_Bool
945eina_value_list_vget(const Eina_Value *value, unsigned int position, va_list args)
946{
947 const Eina_Value_List *desc;
948 const Eina_List *node;
949 const void *mem;
950 void *ptr;
951 Eina_Bool ret;
952
953 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
954 desc = (const Eina_Value_List *)eina_value_memory_get(value);
955 if (!desc)
956 return EINA_FALSE;
957
958 node = eina_list_nth_list(desc->list, position);
959 mem = eina_value_list_node_memory_get(desc->subtype, node);
960 if (!mem)
961 return EINA_FALSE;
962
963 ptr = va_arg(args, void *);
964 ret = eina_value_type_pget(desc->subtype, mem, ptr);
965 return ret;
966}
967
968static inline Eina_Bool
969eina_value_list_vinsert(Eina_Value *value, unsigned int position, va_list args)
970{
971 Eina_Value_List *desc;
972 Eina_List *node;
973 void *mem;
974
975 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
976 desc = (Eina_Value_List *)eina_value_memory_get(value);
977 if (!desc)
978 return EINA_FALSE;
979
980 if (!desc->list)
981 node = desc->list = eina_list_append(NULL, (void*)1L);
982 else if (position == 0)
983 node = desc->list = eina_list_prepend(desc->list, (void*)1L);
984 else
985 {
986 Eina_List *rel = eina_list_nth_list(desc->list, position - 1);
987 desc->list = eina_list_append_relative_list(desc->list, (void*)1L, rel);
988 node = rel->next;
989 }
990 EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
991 EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
992
993 mem = eina_value_list_node_memory_setup(desc->subtype, node);
994 if (!mem)
995 {
996 desc->list = eina_list_remove_list(desc->list, node);
997 return EINA_FALSE;
998 }
999
1000 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1001 if (!eina_value_type_vset(desc->subtype, mem, args)) goto error_set;
1002 return EINA_TRUE;
1003
1004 error_set:
1005 eina_value_type_flush(desc->subtype, mem);
1006 error_setup:
1007 eina_value_list_node_memory_flush(desc->subtype, node);
1008 desc->list = eina_list_remove_list(desc->list, node);
1009 return EINA_FALSE;
1010}
1011
1012static inline Eina_Bool
1013eina_value_list_vappend(Eina_Value *value, va_list args)
1014{
1015 Eina_Value_List *desc;
1016 Eina_List *node;
1017 void *mem;
1018
1019 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1020 desc = (Eina_Value_List *)eina_value_memory_get(value);
1021 if (!desc)
1022 return EINA_FALSE;
1023
1024 desc->list = eina_list_append(desc->list, (void*)1L);
1025 node = eina_list_last(desc->list);
1026 EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
1027 EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
1028
1029 mem = eina_value_list_node_memory_setup(desc->subtype, node);
1030 if (!mem)
1031 {
1032 desc->list = eina_list_remove_list(desc->list, node);
1033 return EINA_FALSE;
1034 }
1035
1036 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1037 if (!eina_value_type_vset(desc->subtype, mem, args)) goto error_set;
1038 return EINA_TRUE;
1039
1040 error_set:
1041 eina_value_type_flush(desc->subtype, mem);
1042 error_setup:
1043 eina_value_list_node_memory_flush(desc->subtype, node);
1044 desc->list = eina_list_remove_list(desc->list, node);
1045 return EINA_FALSE;
1046}
1047
1048static inline Eina_Bool
1049eina_value_list_set(Eina_Value *value, unsigned int position, ...)
1050{
1051 va_list args;
1052 Eina_Bool ret;
1053 va_start(args, position);
1054 ret = eina_value_list_vset(value, position, args);
1055 va_end(args);
1056 return ret;
1057}
1058
1059static inline Eina_Bool
1060eina_value_list_get(const Eina_Value *value, unsigned int position, ...)
1061{
1062 va_list args;
1063 Eina_Bool ret;
1064 va_start(args, position);
1065 ret = eina_value_list_vget(value, position, args);
1066 va_end(args);
1067 return ret;
1068}
1069
1070static inline Eina_Bool
1071eina_value_list_insert(Eina_Value *value, unsigned int position, ...)
1072{
1073 va_list args;
1074 Eina_Bool ret;
1075 va_start(args, position);
1076 ret = eina_value_list_vinsert(value, position, args);
1077 va_end(args);
1078 return ret;
1079}
1080
1081static inline Eina_Bool eina_value_list_append(Eina_Value *value, ...)
1082{
1083 va_list args;
1084 Eina_Bool ret;
1085 va_start(args, value);
1086 ret = eina_value_list_vappend(value, args);
1087 va_end(args);
1088 return ret;
1089}
1090
1091static inline Eina_Bool
1092eina_value_list_pset(Eina_Value *value, unsigned int position, const void *ptr)
1093{
1094 Eina_Value_List *desc;
1095 Eina_List *node;
1096 void *mem;
1097
1098 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1099 desc = (Eina_Value_List *)eina_value_memory_get(value);
1100 if (!desc)
1101 return EINA_FALSE;
1102
1103 node = eina_list_nth_list(desc->list, position);
1104 mem = eina_value_list_node_memory_get(desc->subtype, node);
1105 if (!mem)
1106 return EINA_FALSE;
1107
1108 eina_value_type_flush(desc->subtype, mem);
1109
1110 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1111 if (!eina_value_type_pset(desc->subtype, mem, ptr)) goto error_set;
1112 return EINA_TRUE;
1113
1114 error_set:
1115 eina_value_type_flush(desc->subtype, mem);
1116 error_setup:
1117 return EINA_FALSE;
1118}
1119
1120static inline Eina_Bool
1121eina_value_list_pget(const Eina_Value *value, unsigned int position, void *ptr)
1122{
1123 const Eina_Value_List *desc;
1124 const Eina_List *node;
1125 const void *mem;
1126 Eina_Bool ret;
1127
1128 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1129 desc = (const Eina_Value_List *)eina_value_memory_get(value);
1130 if (!desc)
1131 return EINA_FALSE;
1132
1133 node = eina_list_nth_list(desc->list, position);
1134 mem = eina_value_list_node_memory_get(desc->subtype, node);
1135 if (!mem)
1136 return EINA_FALSE;
1137
1138 ret = eina_value_type_pget(desc->subtype, mem, ptr);
1139 return ret;
1140}
1141
1142static inline Eina_Bool
1143eina_value_list_pinsert(Eina_Value *value, unsigned int position, const void *ptr)
1144{
1145 Eina_Value_List *desc;
1146 Eina_List *node;
1147 void *mem;
1148
1149 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1150 desc = (Eina_Value_List *)eina_value_memory_get(value);
1151 if (!desc)
1152 return EINA_FALSE;
1153
1154 if (!desc->list)
1155 node = desc->list = eina_list_append(NULL, (void*)1L);
1156 else if (position == 0)
1157 node = desc->list = eina_list_prepend(desc->list, (void*)1L);
1158 else
1159 {
1160 Eina_List *rel = eina_list_nth_list(desc->list, position - 1);
1161 desc->list = eina_list_append_relative_list(desc->list, (void*)1L, rel);
1162 node = rel->next;
1163 }
1164 EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
1165 EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
1166
1167 mem = eina_value_list_node_memory_setup(desc->subtype, node);
1168 if (!mem)
1169 {
1170 desc->list = eina_list_remove_list(desc->list, node);
1171 return EINA_FALSE;
1172 }
1173
1174 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1175 if (!eina_value_type_pset(desc->subtype, mem, ptr)) goto error_set;
1176 return EINA_TRUE;
1177
1178 error_set:
1179 eina_value_type_flush(desc->subtype, mem);
1180 error_setup:
1181 eina_value_list_node_memory_flush(desc->subtype, node);
1182 desc->list = eina_list_remove_list(desc->list, node);
1183 return EINA_FALSE;
1184}
1185
1186static inline Eina_Bool
1187eina_value_list_pappend(Eina_Value *value, const void *ptr)
1188{
1189 Eina_Value_List *desc;
1190 Eina_List *node;
1191 void *mem;
1192
1193 EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL(value, 0);
1194 desc = (Eina_Value_List *)eina_value_memory_get(value);
1195 if (!desc)
1196 return EINA_FALSE;
1197
1198 desc->list = eina_list_append(desc->list, (void*)1L);
1199 node = eina_list_last(desc->list);
1200 EINA_SAFETY_ON_NULL_RETURN_VAL(node, EINA_FALSE);
1201 EINA_SAFETY_ON_FALSE_RETURN_VAL(node->data == (void*)1L, EINA_FALSE);
1202
1203 mem = eina_value_list_node_memory_setup(desc->subtype, node);
1204 if (!mem)
1205 {
1206 desc->list = eina_list_remove_list(desc->list, node);
1207 return EINA_FALSE;
1208 }
1209
1210 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1211 if (!eina_value_type_pset(desc->subtype, mem, ptr)) goto error_set;
1212 return EINA_TRUE;
1213
1214 error_set:
1215 eina_value_type_flush(desc->subtype, mem);
1216 error_setup:
1217 eina_value_list_node_memory_flush(desc->subtype, node);
1218 desc->list = eina_list_remove_list(desc->list, node);
1219 return EINA_FALSE;
1220}
1221#undef EINA_VALUE_TYPE_LIST_CHECK_RETURN_VAL
1222
1223#define EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, retval) \
1224 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
1225 EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_HASH, retval)
1226
1227static inline Eina_Bool
1228eina_value_hash_setup(Eina_Value *value, const Eina_Value_Type *subtype, unsigned int buckets_power_size)
1229{
1230 Eina_Value_Hash desc = { subtype, buckets_power_size, NULL };
1231 if (!eina_value_setup(value, EINA_VALUE_TYPE_HASH))
1232 return EINA_FALSE;
1233 if (!eina_value_pset(value, &desc))
1234 {
1235 eina_value_flush(value);
1236 return EINA_FALSE;
1237 }
1238 return EINA_TRUE;
1239}
1240
1241static inline unsigned int
1242eina_value_hash_population(const Eina_Value *value)
1243{
1244 Eina_Value_Hash *desc;
1245 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0);
1246 desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1247 if (!desc)
1248 return 0;
1249 return eina_hash_population(desc->hash);
1250}
1251
1252static inline Eina_Bool
1253eina_value_hash_del(Eina_Value *value, const char *key)
1254{
1255 Eina_Value_Hash *desc;
1256 void *mem;
1257
1258 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE);
1259 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1260 desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1261 if (!desc)
1262 return EINA_FALSE;
1263
1264 mem = eina_hash_find(desc->hash, key);
1265 if (!mem)
1266 return EINA_FALSE;
1267
1268 eina_value_type_flush(desc->subtype, mem);
1269 free(mem);
1270 eina_hash_del_by_key(desc->hash, key);
1271 return EINA_TRUE;
1272}
1273
1274static inline Eina_Bool
1275eina_value_hash_vset(Eina_Value *value, const char *key, va_list args)
1276{
1277 Eina_Value_Hash *desc;
1278 void *mem;
1279
1280 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE);
1281 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1282 desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1283 if (!desc)
1284 return EINA_FALSE;
1285
1286 mem = eina_hash_find(desc->hash, key);
1287 if (mem)
1288 eina_value_type_flush(desc->subtype, mem);
1289 else
1290 {
1291 mem = malloc(desc->subtype->value_size);
1292 if (!mem)
1293 {
1294 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
1295 return EINA_FALSE;
1296 }
1297 if (!eina_hash_add(desc->hash, key, mem))
1298 {
1299 free(mem);
1300 return EINA_FALSE;
1301 }
1302 }
1303
1304 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1305 if (!eina_value_type_vset(desc->subtype, mem, args)) goto error_set;
1306 return EINA_TRUE;
1307
1308 error_set:
1309 eina_value_type_flush(desc->subtype, mem);
1310 error_setup:
1311 eina_hash_del_by_key(desc->hash, key);
1312 free(mem);
1313 return EINA_FALSE;
1314}
1315
1316static inline Eina_Bool
1317eina_value_hash_vget(const Eina_Value *value, const char *key, va_list args)
1318{
1319 const Eina_Value_Hash *desc;
1320 const void *mem;
1321 void *ptr;
1322 Eina_Bool ret;
1323
1324 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, EINA_FALSE);
1325 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1326 desc = (const Eina_Value_Hash *)eina_value_memory_get(value);
1327 if (!desc)
1328 return EINA_FALSE;
1329
1330 mem = eina_hash_find(desc->hash, key);
1331 if (!mem)
1332 return EINA_FALSE;
1333
1334 ptr = va_arg(args, void *);
1335 ret = eina_value_type_pget(desc->subtype, mem, ptr);
1336 return ret;
1337}
1338
1339static inline Eina_Bool
1340eina_value_hash_set(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_vset(value, key, args);
1346 va_end(args);
1347 return ret;
1348}
1349
1350static inline Eina_Bool
1351eina_value_hash_get(const Eina_Value *value, const char *key, ...)
1352{
1353 va_list args;
1354 Eina_Bool ret;
1355 va_start(args, key);
1356 ret = eina_value_hash_vget(value, key, args);
1357 va_end(args);
1358 return ret;
1359}
1360
1361static inline Eina_Bool
1362eina_value_hash_pset(Eina_Value *value, const char *key, const void *ptr)
1363{
1364 Eina_Value_Hash *desc;
1365 void *mem;
1366
1367 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0);
1368 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1369 desc = (Eina_Value_Hash *)eina_value_memory_get(value);
1370 if (!desc)
1371 return EINA_FALSE;
1372
1373 mem = eina_hash_find(desc->hash, key);
1374 if (mem)
1375 eina_value_type_flush(desc->subtype, mem);
1376 else
1377 {
1378 mem = malloc(desc->subtype->value_size);
1379 if (!mem)
1380 {
1381 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
1382 return EINA_FALSE;
1383 }
1384 if (!eina_hash_add(desc->hash, key, mem))
1385 {
1386 free(mem);
1387 return EINA_FALSE;
1388 }
1389 }
1390
1391 if (!eina_value_type_setup(desc->subtype, mem)) goto error_setup;
1392 if (!eina_value_type_pset(desc->subtype, mem, ptr)) goto error_set;
1393 return EINA_TRUE;
1394
1395 error_set:
1396 eina_value_type_flush(desc->subtype, mem);
1397 error_setup:
1398 eina_hash_del_by_key(desc->hash, key);
1399 free(mem);
1400 return EINA_FALSE;
1401}
1402
1403static inline Eina_Bool
1404eina_value_hash_pget(const Eina_Value *value, const char *key, void *ptr)
1405{
1406 const Eina_Value_Hash *desc;
1407 const void *mem;
1408 Eina_Bool ret;
1409
1410 EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL(value, 0);
1411 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EINA_FALSE);
1412 desc = (const Eina_Value_Hash *)eina_value_memory_get(value);
1413 if (!desc)
1414 return EINA_FALSE;
1415
1416 mem = eina_hash_find(desc->hash, key);
1417 if (!mem)
1418 return EINA_FALSE;
1419
1420 ret = eina_value_type_pget(desc->subtype, mem, ptr);
1421 return ret;
1422}
1423#undef EINA_VALUE_TYPE_HASH_CHECK_RETURN_VAL
1424
1425#define EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, retval) \
1426 EINA_SAFETY_ON_NULL_RETURN_VAL(value, retval); \
1427 EINA_SAFETY_ON_FALSE_RETURN_VAL(value->type == EINA_VALUE_TYPE_STRUCT, retval)
1428
1429/**
1430 * @brief Find member of struct
1431 * @since 1.2
1432 * @internal
1433 */
1434EAPI 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;
1435
1436static inline Eina_Bool
1437eina_value_struct_setup(Eina_Value *value, const Eina_Value_Struct_Desc *sdesc)
1438{
1439 Eina_Value_Struct desc = {sdesc, NULL};
1440 if (!eina_value_setup(value, EINA_VALUE_TYPE_STRUCT))
1441 return EINA_FALSE;
1442 if (!eina_value_pset(value, &desc))
1443 {
1444 eina_value_flush(value);
1445 return EINA_FALSE;
1446 }
1447 return EINA_TRUE;
1448}
1449
1450static inline void *
1451eina_value_struct_member_memory_get(const Eina_Value_Struct *st, const Eina_Value_Struct_Member *member)
1452{
1453 unsigned char *base = (unsigned char *)st->memory;
1454 if (!base) return NULL;
1455 return base + member->offset;
1456}
1457
1458static inline Eina_Bool
1459eina_value_struct_vset(Eina_Value *value, const char *name, va_list args)
1460{
1461 const Eina_Value_Struct_Member *member;
1462 Eina_Value_Struct *st;
1463 void *mem;
1464
1465 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1466 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1467 st = (Eina_Value_Struct *)eina_value_memory_get(value);
1468 if (!st)
1469 return EINA_FALSE;
1470 member = eina_value_struct_member_find(st, name);
1471 if (!member)
1472 return EINA_FALSE;
1473 mem = eina_value_struct_member_memory_get(st, member);
1474 if (!mem)
1475 return EINA_FALSE;
1476
1477 eina_value_type_flush(member->type, mem);
1478 if (!eina_value_type_setup(member->type, mem)) goto error_setup;
1479 if (!eina_value_type_vset(member->type, mem, args)) goto error_set;
1480 return EINA_TRUE;
1481
1482 error_set:
1483 eina_value_type_flush(member->type, mem);
1484 error_setup:
1485 return EINA_FALSE;
1486}
1487
1488static inline Eina_Bool
1489eina_value_struct_vget(const Eina_Value *value, const char *name, va_list args)
1490{
1491 const Eina_Value_Struct_Member *member;
1492 const Eina_Value_Struct *st;
1493 const void *mem;
1494 void *ptr;
1495 Eina_Bool ret;
1496
1497 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, EINA_FALSE);
1498 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1499 st = (const Eina_Value_Struct *)eina_value_memory_get(value);
1500 if (!st)
1501 return EINA_FALSE;
1502 member = eina_value_struct_member_find(st, name);
1503 if (!member)
1504 return EINA_FALSE;
1505 mem = eina_value_struct_member_memory_get(st, member);
1506 if (!mem)
1507 return EINA_FALSE;
1508
1509 ptr = va_arg(args, void *);
1510 ret = eina_value_type_pget(member->type, mem, ptr);
1511 return ret;
1512}
1513
1514static inline Eina_Bool
1515eina_value_struct_set(Eina_Value *value, const char *name, ...)
1516{
1517 va_list args;
1518 Eina_Bool ret;
1519 va_start(args, name);
1520 ret = eina_value_struct_vset(value, name, args);
1521 va_end(args);
1522 return ret;
1523}
1524
1525static inline Eina_Bool
1526eina_value_struct_get(const Eina_Value *value, const char *name, ...)
1527{
1528 va_list args;
1529 Eina_Bool ret;
1530 va_start(args, name);
1531 ret = eina_value_struct_vget(value, name, args);
1532 va_end(args);
1533 return ret;
1534}
1535
1536static inline Eina_Bool
1537eina_value_struct_pset(Eina_Value *value, const char *name, const void *ptr)
1538{
1539 const Eina_Value_Struct_Member *member;
1540 Eina_Value_Struct *st;
1541 void *mem;
1542
1543 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, 0);
1544 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1545 st = (Eina_Value_Struct *)eina_value_memory_get(value);
1546 if (!st)
1547 return EINA_FALSE;
1548 member = eina_value_struct_member_find(st, name);
1549 if (!member)
1550 return EINA_FALSE;
1551 mem = eina_value_struct_member_memory_get(st, member);
1552 if (!mem)
1553 return EINA_FALSE;
1554
1555 eina_value_type_flush(member->type, mem);
1556 if (!eina_value_type_setup(member->type, mem)) goto error_setup;
1557 if (!eina_value_type_pset(member->type, mem, ptr)) goto error_set;
1558 return EINA_TRUE;
1559
1560 error_set:
1561 eina_value_type_flush(member->type, mem);
1562 error_setup:
1563 return EINA_FALSE;
1564}
1565
1566static inline Eina_Bool
1567eina_value_struct_pget(const Eina_Value *value, const char *name, void *ptr)
1568{
1569 const Eina_Value_Struct_Member *member;
1570 const Eina_Value_Struct *st;
1571 const void *mem;
1572 Eina_Bool ret;
1573
1574 EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL(value, 0);
1575 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1576 st = (const Eina_Value_Struct *)eina_value_memory_get(value);
1577 if (!st)
1578 return EINA_FALSE;
1579 member = eina_value_struct_member_find(st, name);
1580 if (!member)
1581 return EINA_FALSE;
1582 mem = eina_value_struct_member_memory_get(st, member);
1583 if (!mem)
1584 return EINA_FALSE;
1585
1586 ret = eina_value_type_pget(member->type, mem, ptr);
1587 return ret;
1588}
1589#undef EINA_VALUE_TYPE_STRUCT_CHECK_RETURN_VAL
1590
1591
1592static inline Eina_Bool
1593eina_value_type_setup(const Eina_Value_Type *type, void *mem)
1594{
1595 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1596 if (!type->setup)
1597 {
1598 eina_error_set(EINA_ERROR_VALUE_FAILED);
1599 return EINA_FALSE;
1600 }
1601 return type->setup(type, mem);
1602}
1603
1604static inline Eina_Bool
1605eina_value_type_flush(const Eina_Value_Type *type, void *mem)
1606{
1607 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1608 if (!type->flush)
1609 {
1610 eina_error_set(EINA_ERROR_VALUE_FAILED);
1611 return EINA_FALSE;
1612 }
1613 return type->flush(type, mem);
1614}
1615
1616static inline Eina_Bool
1617eina_value_type_copy(const Eina_Value_Type *type, const void *src, void *dst)
1618{
1619 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1620 if (!type->copy)
1621 {
1622 eina_error_set(EINA_ERROR_VALUE_FAILED);
1623 return EINA_FALSE;
1624 }
1625 return type->copy(type, src, dst);
1626}
1627
1628static inline int
1629eina_value_type_compare(const Eina_Value_Type *type, const void *a, const void *b)
1630{
1631 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1632 if (!type->compare)
1633 {
1634 eina_error_set(EINA_ERROR_VALUE_FAILED);
1635 return EINA_FALSE;
1636 }
1637 return type->compare(type, a, b);
1638}
1639
1640static inline Eina_Bool
1641eina_value_type_convert_to(const Eina_Value_Type *type, const Eina_Value_Type *convert, const void *type_mem, void *convert_mem)
1642{
1643 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1644 if (!type->convert_to)
1645 {
1646 eina_error_set(EINA_ERROR_VALUE_FAILED);
1647 return EINA_FALSE;
1648 }
1649 return type->convert_to(type, convert, type_mem, convert_mem);
1650}
1651
1652static inline Eina_Bool
1653eina_value_type_convert_from(const Eina_Value_Type *type, const Eina_Value_Type *convert, void *type_mem, const void *convert_mem)
1654{
1655 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1656 if (!type->convert_from)
1657 {
1658 eina_error_set(EINA_ERROR_VALUE_FAILED);
1659 return EINA_FALSE;
1660 }
1661 return type->convert_from(type, convert, type_mem, convert_mem);
1662}
1663
1664static inline Eina_Bool
1665eina_value_type_vset(const Eina_Value_Type *type, void *mem, va_list args)
1666{
1667 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1668 if (!type->vset)
1669 {
1670 eina_error_set(EINA_ERROR_VALUE_FAILED);
1671 return EINA_FALSE;
1672 }
1673 return type->vset(type, mem, args);
1674}
1675
1676static inline Eina_Bool
1677eina_value_type_pset(const Eina_Value_Type *type, void *mem, const void *ptr)
1678{
1679 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1680 if (!type->pset)
1681 {
1682 eina_error_set(EINA_ERROR_VALUE_FAILED);
1683 return EINA_FALSE;
1684 }
1685 return type->pset(type, mem, ptr);
1686}
1687
1688static inline Eina_Bool
1689eina_value_type_pget(const Eina_Value_Type *type, const void *mem, void *ptr)
1690{
1691 EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_type_check(type), EINA_FALSE);
1692 if (!type->pget)
1693 {
1694 eina_error_set(EINA_ERROR_VALUE_FAILED);
1695 return EINA_FALSE;
1696 }
1697 return type->pget(type, mem, ptr);
1698}
1699
1700#undef EINA_VALUE_TYPE_DEFAULT
1701#undef EINA_VALUE_TYPE_CHECK_RETURN
1702#undef EINA_VALUE_TYPE_CHECK_RETURN_VAL
1703#undef EINA_VALUE_TYPE_DISPATCH
1704#undef EINA_VALUE_TYPE_DISPATCH_RETURN
1705#endif