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