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