aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eet/src/lib/eet_data.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eet/src/lib/eet_data.c')
-rw-r--r--libraries/eet/src/lib/eet_data.c4999
1 files changed, 4999 insertions, 0 deletions
diff --git a/libraries/eet/src/lib/eet_data.c b/libraries/eet/src/lib/eet_data.c
new file mode 100644
index 0000000..23b0b97
--- /dev/null
+++ b/libraries/eet/src/lib/eet_data.c
@@ -0,0 +1,4999 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif /* ifdef HAVE_CONFIG_H */
4
5#include <stdio.h>
6#include <string.h>
7#include <math.h>
8#include <ctype.h>
9#include <limits.h>
10
11#ifdef HAVE_NETINET_IN_H
12# include <netinet/in.h>
13#endif /* ifdef HAVE_NETINET_IN_H */
14
15#ifdef _WIN32
16# include <winsock2.h>
17#endif /* ifdef _WIN32 */
18
19#include <Eina.h>
20
21#include "Eet.h"
22#include "Eet_private.h"
23
24#ifdef _WIN32
25# define FMT_CHAR "%c"
26# define FMT_UCHAR "%c"
27# define FMT_LONG_LONG "%I64i"
28# define FMT_ULONG_LONG "%I64u"
29#else
30# define FMT_CHAR "%hhi"
31# define FMT_UCHAR "%hhu"
32# define FMT_LONG_LONG "%lli"
33# define FMT_ULONG_LONG "%llu"
34#endif
35
36/*
37 * routines for doing data -> struct and struct -> data conversion
38 *
39 * types:
40 *
41 * basic types:
42 * a sequence of...
43 *
44 * char
45 * short
46 * int
47 * long long
48 * float
49 * double
50 * unsigned char
51 * unsigned short
52 * unsigned int
53 * unsgined long long
54 * string
55 *
56 * groupings:
57 * multiple entries ordered as...
58 *
59 * fixed size array [ of basic types ]
60 * variable size array [ of basic types ]
61 * linked list [ of basic types ]
62 * hash table [ of basic types ]
63 *
64 * need to provide builder/accessor funcs for:
65 *
66 * list_next
67 * list_append
68 *
69 * hash_foreach
70 * hash_add
71 *
72 */
73
74/*---*/
75
76typedef struct _Eet_Data_Element Eet_Data_Element;
77typedef struct _Eet_Data_Basic_Type_Codec Eet_Data_Basic_Type_Codec;
78typedef struct _Eet_Data_Group_Type_Codec Eet_Data_Group_Type_Codec;
79typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
80typedef struct _Eet_Data_Stream Eet_Data_Stream;
81typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash;
82typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info;
83typedef struct _Eet_Free Eet_Free;
84typedef struct _Eet_Free_Context Eet_Free_Context;
85typedef struct _Eet_Variant_Unknow Eet_Variant_Unknow;
86
87/*---*/
88
89/* TODO:
90 * Eet_Data_Basic_Type_Codec (Coder, Decoder)
91 * Eet_Data_Group_Type_Codec (Coder, Decoder)
92 */
93struct _Eet_Data_Basic_Type_Codec
94{
95 int size;
96 const char *name;
97 int (*get)(const Eet_Dictionary *ed,
98 const void *src,
99 const void *src_end,
100 void *dest);
101 void * (*put)(Eet_Dictionary *ed, const void *src, int *size_ret);
102};
103
104struct _Eet_Data_Group_Type_Codec
105{
106 int (*get)(Eet_Free_Context *context,
107 const Eet_Dictionary *ed,
108 Eet_Data_Descriptor *edd,
109 Eet_Data_Element *ede,
110 Eet_Data_Chunk *echnk,
111 int type,
112 int group_type,
113 void *data_in,
114 char **p,
115 int *size);
116 void (*put)(Eet_Dictionary *ed,
117 Eet_Data_Descriptor *edd,
118 Eet_Data_Element *ede,
119 Eet_Data_Stream *ds,
120 void *data_in);
121};
122
123struct _Eet_Data_Chunk
124{
125 char *name;
126 int len;
127 int size;
128 int hash;
129 void *data;
130 unsigned char type;
131 unsigned char group_type;
132};
133
134struct _Eet_Data_Stream
135{
136 void *data;
137 int size;
138 int pos;
139};
140
141struct _Eet_Data_Descriptor_Hash
142{
143 Eet_Data_Element *element;
144 Eet_Data_Descriptor_Hash *next;
145};
146
147struct _Eet_Data_Descriptor
148{
149 const char *name;
150 const Eet_Dictionary *ed;
151 int size;
152 struct
153 {
154 void * (*mem_alloc)(size_t size);
155 void (*mem_free)(void *mem);
156 char * (*str_alloc)(const char *str);
157 char * (*str_direct_alloc)(const char *str);
158 void (*str_free)(const char *str);
159 void (*str_direct_free)(const char *str);
160 void * (*list_next)(void *l);
161 void * (*list_append)(void *l, void *d);
162 void * (*list_data)(void *l);
163 void * (*list_free)(void *l);
164 void (*hash_foreach)(void *h,
165 int (*func)(void *h,
166 const char *k,
167 void *dt,
168 void *fdt),
169 void *fdt);
170 void * (*hash_add)(void *h, const char *k, void *d);
171 void (*hash_free)(void *h);
172 const char *(*type_get)(const void *data, Eina_Bool *unknow);
173 Eina_Bool (*type_set)(const char *type,
174 void *data,
175 Eina_Bool unknow);
176 void * (*array_alloc)(size_t size);
177 void (*array_free)(void *mem);
178 } func;
179 struct
180 {
181 int num;
182 Eet_Data_Element *set;
183 struct
184 {
185 int size;
186 Eet_Data_Descriptor_Hash *buckets;
187 } hash;
188 } elements;
189
190 Eina_Bool unified_type : 1;
191// char *strings;
192// int strings_len;
193};
194
195struct _Eet_Data_Element
196{
197 const char *name;
198 const char *counter_name;
199 const char *directory_name_ptr;
200 Eet_Data_Descriptor *subtype;
201 int offset; /* offset in bytes from the base element */
202 int count; /* number of elements for a fixed array */
203 int counter_offset; /* for a variable array we need the offset of the count variable */
204 unsigned char type; /* EET_T_XXX */
205 unsigned char group_type; /* EET_G_XXX */
206};
207
208struct _Eet_Data_Encode_Hash_Info
209{
210 Eet_Data_Stream *ds;
211 Eet_Data_Element *ede;
212 Eet_Dictionary *ed;
213};
214
215#define EET_FREE_COUNT 256
216struct _Eet_Free
217{
218 int ref;
219 Eina_Array list[EET_FREE_COUNT];
220};
221
222struct _Eet_Free_Context
223{
224 Eet_Free freelist;
225 Eet_Free freelist_array;
226 Eet_Free freelist_list;
227 Eet_Free freelist_hash;
228 Eet_Free freelist_str;
229 Eet_Free freelist_direct_str;
230};
231
232struct _Eet_Variant_Unknow
233{
234 EINA_MAGIC
235
236 int size;
237 char data[1];
238};
239
240/*---*/
241
242static void
243 eet_free_context_init(Eet_Free_Context *context);
244static void
245 eet_free_context_shutdown(Eet_Free_Context *context);
246
247static int
248eet_data_get_char(const Eet_Dictionary *ed,
249 const void *src,
250 const void *src_end,
251 void *dest);
252static void *
253eet_data_put_char(Eet_Dictionary *ed,
254 const void *src,
255 int *size_ret);
256static int
257eet_data_get_short(const Eet_Dictionary *ed,
258 const void *src,
259 const void *src_end,
260 void *dest);
261static void *
262eet_data_put_short(Eet_Dictionary *ed,
263 const void *src,
264 int *size_ret);
265static inline int
266eet_data_get_int(const Eet_Dictionary *ed,
267 const void *src,
268 const void *src_end,
269 void *dest);
270static void *
271eet_data_put_int(Eet_Dictionary *ed,
272 const void *src,
273 int *size_ret);
274static int
275eet_data_get_long_long(const Eet_Dictionary *ed,
276 const void *src,
277 const void *src_end,
278 void *dest);
279static void *
280eet_data_put_long_long(Eet_Dictionary *ed,
281 const void *src,
282 int *size_ret);
283static int
284eet_data_get_float(const Eet_Dictionary *ed,
285 const void *src,
286 const void *src_end,
287 void *dest);
288static void *
289eet_data_put_float(Eet_Dictionary *ed,
290 const void *src,
291 int *size_ret);
292static int
293eet_data_get_double(const Eet_Dictionary *ed,
294 const void *src,
295 const void *src_end,
296 void *dest);
297static void *
298eet_data_put_double(Eet_Dictionary *ed,
299 const void *src,
300 int *size_ret);
301static int
302eet_data_get_f32p32(const Eet_Dictionary *ed,
303 const void *src,
304 const void *src_end,
305 void *dest);
306static void *
307eet_data_put_f32p32(Eet_Dictionary *ed,
308 const void *src,
309 int *size_ret);
310static int
311eet_data_get_f16p16(const Eet_Dictionary *ed,
312 const void *src,
313 const void *src_end,
314 void *dest);
315static void *
316eet_data_put_f16p16(Eet_Dictionary *ed,
317 const void *src,
318 int *size_ret);
319static int
320eet_data_get_f8p24(const Eet_Dictionary *ed,
321 const void *src,
322 const void *src_end,
323 void *dest);
324static void *
325eet_data_put_f8p24(Eet_Dictionary *ed,
326 const void *src,
327 int *size_ret);
328static inline int
329eet_data_get_string(const Eet_Dictionary *ed,
330 const void *src,
331 const void *src_end,
332 void *dest);
333static void *
334eet_data_put_string(Eet_Dictionary *ed,
335 const void *src,
336 int *size_ret);
337static int
338eet_data_get_istring(const Eet_Dictionary *ed,
339 const void *src,
340 const void *src_end,
341 void *dest);
342static void *
343eet_data_put_istring(Eet_Dictionary *ed,
344 const void *src,
345 int *size_ret);
346static int
347eet_data_get_null(const Eet_Dictionary *ed,
348 const void *src,
349 const void *src_end,
350 void *dest);
351static void *
352eet_data_put_null(Eet_Dictionary *ed,
353 const void *src,
354 int *size_ret);
355
356static int
357eet_data_get_type(const Eet_Dictionary *ed,
358 int type,
359 const void *src,
360 const void *src_end,
361 void *dest);
362static void *
363eet_data_put_type(Eet_Dictionary *ed,
364 int type,
365 const void *src,
366 int *size_ret);
367
368static Eet_Node *
369eet_data_node_simple_type(int type,
370 const char *name,
371 void *dd);
372
373static int
374eet_data_get_unknown(Eet_Free_Context *context,
375 const Eet_Dictionary *ed,
376 Eet_Data_Descriptor *edd,
377 Eet_Data_Element *ede,
378 Eet_Data_Chunk *echnk,
379 int type,
380 int group_type,
381 void *data_in,
382 char **p,
383 int *size);
384static void
385eet_data_put_unknown(Eet_Dictionary *ed,
386 Eet_Data_Descriptor *edd,
387 Eet_Data_Element *ede,
388 Eet_Data_Stream *ds,
389 void *data_in);
390static void
391eet_data_put_array(Eet_Dictionary *ed,
392 Eet_Data_Descriptor *edd,
393 Eet_Data_Element *ede,
394 Eet_Data_Stream *ds,
395 void *data_in);
396static int
397eet_data_get_array(Eet_Free_Context *context,
398 const Eet_Dictionary *ed,
399 Eet_Data_Descriptor *edd,
400 Eet_Data_Element *ede,
401 Eet_Data_Chunk *echnk,
402 int type,
403 int group_type,
404 void *data,
405 char **p,
406 int *size);
407static int
408eet_data_get_list(Eet_Free_Context *context,
409 const Eet_Dictionary *ed,
410 Eet_Data_Descriptor *edd,
411 Eet_Data_Element *ede,
412 Eet_Data_Chunk *echnk,
413 int type,
414 int group_type,
415 void *data_in,
416 char **p,
417 int *size);
418static void
419eet_data_put_list(Eet_Dictionary *ed,
420 Eet_Data_Descriptor *edd,
421 Eet_Data_Element *ede,
422 Eet_Data_Stream *ds,
423 void *data_in);
424static void
425eet_data_put_hash(Eet_Dictionary *ed,
426 Eet_Data_Descriptor *edd,
427 Eet_Data_Element *ede,
428 Eet_Data_Stream *ds,
429 void *data_in);
430static int
431eet_data_get_hash(Eet_Free_Context *context,
432 const Eet_Dictionary *ed,
433 Eet_Data_Descriptor *edd,
434 Eet_Data_Element *ede,
435 Eet_Data_Chunk *echnk,
436 int type,
437 int group_type,
438 void *data,
439 char **p,
440 int *size);
441static void
442eet_data_put_union(Eet_Dictionary *ed,
443 Eet_Data_Descriptor *edd,
444 Eet_Data_Element *ede,
445 Eet_Data_Stream *ds,
446 void *data_in);
447static int
448eet_data_get_union(Eet_Free_Context *context,
449 const Eet_Dictionary *ed,
450 Eet_Data_Descriptor *edd,
451 Eet_Data_Element *ede,
452 Eet_Data_Chunk *echnk,
453 int type,
454 int group_type,
455 void *data,
456 char **p,
457 int *size);
458static void
459eet_data_put_variant(Eet_Dictionary *ed,
460 Eet_Data_Descriptor *edd,
461 Eet_Data_Element *ede,
462 Eet_Data_Stream *ds,
463 void *data_in);
464static int
465eet_data_get_variant(Eet_Free_Context *context,
466 const Eet_Dictionary *ed,
467 Eet_Data_Descriptor *edd,
468 Eet_Data_Element *ede,
469 Eet_Data_Chunk *echnk,
470 int type,
471 int group_type,
472 void *data,
473 char **p,
474 int *size);
475
476static void
477eet_data_chunk_get(const Eet_Dictionary *ed,
478 Eet_Data_Chunk *chnk,
479 const void *src,
480 int size);
481static Eet_Data_Chunk *
482eet_data_chunk_new(void *data,
483 int size,
484 const char *name,
485 int type,
486 int group_type);
487static void
488eet_data_chunk_free(Eet_Data_Chunk *chnk);
489
490static Eet_Data_Stream *
491 eet_data_stream_new(void);
492static void
493 eet_data_stream_write(Eet_Data_Stream *ds,
494 const void *data,
495 int size);
496static void
497eet_data_stream_free(Eet_Data_Stream *ds);
498
499static void
500eet_data_chunk_put(Eet_Dictionary *ed,
501 Eet_Data_Chunk *chnk,
502 Eet_Data_Stream *ds);
503
504static int
505eet_data_descriptor_encode_hash_cb(void *hash,
506 const char *key,
507 void *hdata,
508 void *fdata);
509static void *_eet_data_descriptor_encode(Eet_Dictionary *ed,
510 Eet_Data_Descriptor *edd,
511 const void *data_in,
512 int *size_ret);
513static void *_eet_data_descriptor_decode(Eet_Free_Context *context,
514 const Eet_Dictionary *ed,
515 Eet_Data_Descriptor *edd,
516 const void *data_in,
517 int size_in,
518 void *data_out,
519 int size_out);
520
521/*---*/
522
523static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
524{
525 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
526 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
527 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
528 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
529 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
530 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
531 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
532 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
533 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
534 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
535 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
536 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
537 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
538 {sizeof(Eina_F32p32), "f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
539 {sizeof(Eina_F16p16), "f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
540 {sizeof(Eina_F8p24), "f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
541};
542
543static const Eet_Data_Group_Type_Codec eet_group_codec[] =
544{
545 { eet_data_get_unknown, eet_data_put_unknown },
546 { eet_data_get_array, eet_data_put_array },
547 { eet_data_get_array, eet_data_put_array },
548 { eet_data_get_list, eet_data_put_list },
549 { eet_data_get_hash, eet_data_put_hash },
550 { eet_data_get_union, eet_data_put_union },
551 { eet_data_get_variant, eet_data_put_variant }
552};
553
554static int _eet_data_words_bigendian = -1;
555
556/*---*/
557
558#define SWAP64(x) (x) = \
559 ((((unsigned long long)(x) & 0x00000000000000ffULL) << 56) | \
560 (((unsigned long long)(x) & 0x000000000000ff00ULL) << 40) | \
561 (((unsigned long long)(x) & 0x0000000000ff0000ULL) << 24) | \
562 (((unsigned long long)(x) & 0x00000000ff000000ULL) << 8) | \
563 (((unsigned long long)(x) & 0x000000ff00000000ULL) >> 8) | \
564 (((unsigned long long)(x) & 0x0000ff0000000000ULL) >> 24) | \
565 (((unsigned long long)(x) & 0x00ff000000000000ULL) >> 40) | \
566 (((unsigned long long)(x) & 0xff00000000000000ULL) >> 56))
567#define SWAP32(x) (x) = \
568 ((((int)(x) & 0x000000ff) << 24) | \
569 (((int)(x) & 0x0000ff00) << 8) | \
570 (((int)(x) & 0x00ff0000) >> 8) | \
571 (((int)(x) & 0xff000000) >> 24))
572#define SWAP16(x) (x) = \
573 ((((short)(x) & 0x00ff) << 8) | \
574 (((short)(x) & 0xff00) >> 8))
575
576#ifdef CONV8
577# undef CONV8
578#endif /* ifdef CONV8 */
579#ifdef CONV16
580# undef CONV16
581#endif /* ifdef CONV16 */
582#ifdef CONV32
583# undef CONV32
584#endif /* ifdef CONV32 */
585#ifdef CONV64
586# undef CONV64
587#endif /* ifdef CONV64 */
588
589#define CONV8(x)
590#define CONV16(x) {if (_eet_data_words_bigendian) {SWAP16(x); }}
591#define CONV32(x) {if (_eet_data_words_bigendian) {SWAP32(x); }}
592#define CONV64(x) {if (_eet_data_words_bigendian) {SWAP64(x); }}
593
594#define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
595#define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL)
596
597#define POINTER_TYPE_DECODE(Context, \
598 Ed, \
599 Edd, \
600 Ede, \
601 Echnk, \
602 Type, \
603 Data, \
604 P, \
605 Size, \
606 Label) \
607 do { \
608 int ___r; \
609 ___r = eet_data_get_unknown(Context, \
610 Ed, \
611 Edd, Ede, \
612 Echnk, \
613 Type, EET_G_UNKNOWN, \
614 Data, P, Size); \
615 if (!___r) { goto Label; } \
616 } while (0)
617
618#define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, SubSize, Label) \
619 do { \
620 Data_Ret = _eet_data_descriptor_decode(Context, \
621 Ed, \
622 Ede, \
623 Data, \
624 Size, \
625 SubSize > 0 ? Data_Ret : NULL, \
626 SubSize); \
627 if (!Data_Ret) { goto Label; } \
628 } while (0)
629
630#define EET_I_STRING 1 << 4
631#define EET_I_INLINED_STRING 2 << 4
632#define EET_I_NULL 3 << 4
633
634#define EET_MAGIC_VARIANT 0xF1234BC
635/*---*/
636
637/* CHAR TYPE */
638static int
639eet_data_get_char(const Eet_Dictionary *ed __UNUSED__,
640 const void *src,
641 const void *src_end,
642 void *dst)
643{
644 char *s, *d;
645
646 if (((char *)src + sizeof(char)) > (char *)src_end)
647 return -1;
648
649 s = (char *)src;
650 d = (char *)dst;
651 *d = *s;
652 CONV8(*d);
653 return sizeof(char);
654} /* eet_data_get_char */
655
656static void *
657eet_data_put_char(Eet_Dictionary *ed __UNUSED__,
658 const void *src,
659 int *size_ret)
660{
661 char *s, *d;
662
663 d = (char *)malloc(sizeof(char));
664 if (!d)
665 return NULL;
666
667 s = (char *)src;
668 *d = *s;
669 CONV8(*d);
670 *size_ret = sizeof(char);
671 return d;
672} /* eet_data_put_char */
673
674/* SHORT TYPE */
675static int
676eet_data_get_short(const Eet_Dictionary *ed __UNUSED__,
677 const void *src,
678 const void *src_end,
679 void *dst)
680{
681 short *d;
682
683 if (((char *)src + sizeof(short)) > (char *)src_end)
684 return -1;
685
686 memcpy(dst, src, sizeof(short));
687 d = (short *)dst;
688 CONV16(*d);
689 return sizeof(short);
690} /* eet_data_get_short */
691
692static void *
693eet_data_put_short(Eet_Dictionary *ed __UNUSED__,
694 const void *src,
695 int *size_ret)
696{
697 short *s, *d;
698
699 d = (short *)malloc(sizeof(short));
700 if (!d)
701 return NULL;
702
703 s = (short *)src;
704 *d = *s;
705 CONV16(*d);
706 *size_ret = sizeof(short);
707 return d;
708} /* eet_data_put_short */
709
710/* INT TYPE */
711static inline int
712eet_data_get_int(const Eet_Dictionary *ed __UNUSED__,
713 const void *src,
714 const void *src_end,
715 void *dst)
716{
717 int *d;
718
719 if (((char *)src + sizeof(int)) > (char *)src_end)
720 return -1;
721
722 memcpy(dst, src, sizeof(int));
723 d = (int *)dst;
724 CONV32(*d);
725 return sizeof(int);
726} /* eet_data_get_int */
727
728static void *
729eet_data_put_int(Eet_Dictionary *ed __UNUSED__,
730 const void *src,
731 int *size_ret)
732{
733 int *s, *d;
734
735 d = (int *)malloc(sizeof(int));
736 if (!d)
737 return NULL;
738
739 s = (int *)src;
740 *d = *s;
741 CONV32(*d);
742 *size_ret = sizeof(int);
743 return d;
744} /* eet_data_put_int */
745
746/* LONG LONG TYPE */
747static int
748eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__,
749 const void *src,
750 const void *src_end,
751 void *dst)
752{
753 unsigned long long *d;
754
755 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end)
756 return -1;
757
758 memcpy(dst, src, sizeof(unsigned long long));
759 d = (unsigned long long *)dst;
760 CONV64(*d);
761 return sizeof(unsigned long long);
762} /* eet_data_get_long_long */
763
764static void *
765eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__,
766 const void *src,
767 int *size_ret)
768{
769 unsigned long long *s, *d;
770
771 d = (unsigned long long *)malloc(sizeof(unsigned long long));
772 if (!d)
773 return NULL;
774
775 s = (unsigned long long *)src;
776 *d = *s;
777 CONV64(*d);
778 *size_ret = sizeof(unsigned long long);
779 return d;
780} /* eet_data_put_long_long */
781
782/* STRING TYPE */
783static inline int
784eet_data_get_string_hash(const Eet_Dictionary *ed,
785 const void *src,
786 const void *src_end)
787{
788 if (ed)
789 {
790 int idx;
791
792 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
793 return -1;
794
795 return eet_dictionary_string_get_hash(ed, idx);
796 }
797
798 return -1;
799} /* eet_data_get_string_hash */
800
801static inline int
802eet_data_get_string(const Eet_Dictionary *ed,
803 const void *src,
804 const void *src_end,
805 void *dst)
806{
807 char *s, **d;
808
809 d = (char **)dst;
810
811 if (ed)
812 {
813 const char *str;
814 int idx;
815
816 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
817 return -1;
818
819 str = eet_dictionary_string_get_char(ed, idx);
820 if (!str)
821 return -1;
822
823 *d = (char *)str;
824 return eet_dictionary_string_get_size(ed, idx);
825 }
826
827 s = (char *)src;
828 if (!s)
829 {
830 *d = NULL;
831 return 0;
832 }
833
834 *d = s;
835 return strlen(s) + 1;
836} /* eet_data_get_string */
837
838static void *
839eet_data_put_string(Eet_Dictionary *ed,
840 const void *src,
841 int *size_ret)
842{
843 char *s, *d;
844 int len;
845
846 if (ed)
847 {
848 const char *str;
849 int idx;
850
851 str = *((const char **)src);
852 if (!str)
853 return NULL;
854
855 idx = eet_dictionary_string_add(ed, str);
856 if (idx == -1)
857 return NULL;
858
859 return eet_data_put_int(ed, &idx, size_ret);
860 }
861
862 s = (char *)(*((char **)src));
863 if (!s)
864 return NULL;
865
866 len = strlen(s);
867 d = malloc(len + 1);
868 if (!d)
869 return NULL;
870
871 memcpy(d, s, len + 1);
872 *size_ret = len + 1;
873 return d;
874} /* eet_data_put_string */
875
876/* ALWAYS INLINED STRING TYPE */
877static int
878eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__,
879 const void *src,
880 const void *src_end,
881 void *dst)
882{
883 return eet_data_get_string(NULL, src, src_end, dst);
884} /* eet_data_get_istring */
885
886static void *
887eet_data_put_istring(Eet_Dictionary *ed __UNUSED__,
888 const void *src,
889 int *size_ret)
890{
891 return eet_data_put_string(NULL, src, size_ret);
892} /* eet_data_put_istring */
893
894/* ALWAYS NULL TYPE */
895static int
896eet_data_get_null(const Eet_Dictionary *ed __UNUSED__,
897 const void *src __UNUSED__,
898 const void *src_end __UNUSED__,
899 void *dst)
900{
901 char **d;
902
903 d = (char **)dst;
904
905 *d = NULL;
906 return 1;
907} /* eet_data_get_null */
908
909static void *
910eet_data_put_null(Eet_Dictionary *ed __UNUSED__,
911 const void *src __UNUSED__,
912 int *size_ret)
913{
914 *size_ret = 0;
915 return NULL;
916} /* eet_data_put_null */
917
918/**
919 * Fast lookups of simple doubles/floats.
920 *
921 * These aren't properly a cache because they don't store pre-calculated
922 * values, but have a so simple math that is almost as fast.
923 */
924static inline int
925_eet_data_float_cache_get(const char *s,
926 int len,
927 float *d)
928{
929 /* fast handle of simple case 0xMp+E*/
930 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
931 {
932 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
933 int exponent = (s[5] - '0');
934
935 if (s[4] == '+')
936 *d = (float)(mantisse << exponent);
937 else
938 *d = (float)mantisse / (float)(1 << exponent);
939
940 return 1;
941 }
942
943 return 0;
944} /* _eet_data_float_cache_get */
945
946static inline int
947_eet_data_double_cache_get(const char *s,
948 int len,
949 double *d)
950{
951 /* fast handle of simple case 0xMp+E*/
952 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
953 {
954 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
955 int exponent = (s[5] - '0');
956
957 if (s[4] == '+')
958 *d = (double)(mantisse << exponent);
959 else
960 *d = (double)mantisse / (double)(1 << exponent);
961
962 return 1;
963 }
964
965 return 0;
966} /* _eet_data_double_cache_get */
967
968/* FLOAT TYPE */
969static int
970eet_data_get_float(const Eet_Dictionary *ed,
971 const void *src,
972 const void *src_end,
973 void *dst)
974{
975 float *d;
976 int idx;
977
978 d = (float *)dst;
979 if (!ed)
980 {
981 const char *s, *p;
982 long long mantisse;
983 long exponent;
984 int len;
985
986 s = (const char *)src;
987 p = s;
988 len = 0;
989 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
990
991 if (_eet_data_float_cache_get(s, len, d) != 0)
992 return len + 1;
993
994 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
995 return -1;
996
997 *d = (float)ldexp((double)mantisse, exponent);
998
999 return len + 1;
1000 }
1001
1002 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1003 return -1;
1004
1005 if (!eet_dictionary_string_get_float(ed, idx, d))
1006 return -1;
1007
1008 return 1;
1009} /* eet_data_get_float */
1010
1011static void *
1012eet_data_put_float(Eet_Dictionary *ed,
1013 const void *src,
1014 int *size_ret)
1015{
1016 char buf[128];
1017 int idx;
1018
1019 eina_convert_dtoa((double)(*(float *)src), buf);
1020
1021 if (!ed)
1022 {
1023 char *d;
1024 int len;
1025
1026 len = strlen(buf);
1027 d = malloc(len + 1);
1028 if (!d)
1029 return NULL;
1030
1031 memcpy(d, buf, len + 1);
1032 *size_ret = len + 1;
1033 return d;
1034 }
1035
1036 idx = eet_dictionary_string_add(ed, buf);
1037 if (idx == -1)
1038 return NULL;
1039
1040 return eet_data_put_int(ed, &idx, size_ret);
1041} /* eet_data_put_float */
1042
1043/* DOUBLE TYPE */
1044static int
1045eet_data_get_double(const Eet_Dictionary *ed,
1046 const void *src,
1047 const void *src_end,
1048 void *dst)
1049{
1050 double *d;
1051 int idx;
1052
1053 d = (double *)dst;
1054
1055 if (!ed)
1056 {
1057 const char *s, *p;
1058 long long mantisse = 0;
1059 long exponent = 0;
1060 int len;
1061
1062 s = (const char *)src;
1063 p = s;
1064 len = 0;
1065 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
1066
1067 if (_eet_data_double_cache_get(s, len, d) != 0)
1068 return len + 1;
1069
1070 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
1071 return -1;
1072
1073 *d = ldexp((double)mantisse, exponent);
1074
1075 return len + 1;
1076 }
1077
1078 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1079 return -1;
1080
1081 if (!eet_dictionary_string_get_double(ed, idx, d))
1082 return -1;
1083
1084 return 1;
1085} /* eet_data_get_double */
1086
1087static void *
1088eet_data_put_double(Eet_Dictionary *ed,
1089 const void *src,
1090 int *size_ret)
1091{
1092 char buf[128];
1093 int idx;
1094
1095 eina_convert_dtoa((double)(*(double *)src), buf);
1096
1097 if (!ed)
1098 {
1099 char *d;
1100 int len;
1101
1102 len = strlen(buf);
1103 d = malloc(len + 1);
1104 if (!d)
1105 return NULL;
1106
1107 memcpy(d, buf, len + 1);
1108 *size_ret = len + 1;
1109
1110 return d;
1111 }
1112
1113 idx = eet_dictionary_string_add(ed, buf);
1114 if (idx == -1)
1115 return NULL;
1116
1117 return eet_data_put_int(ed, &idx, size_ret);
1118} /* eet_data_put_double */
1119
1120static int
1121eet_data_get_f32p32(const Eet_Dictionary *ed,
1122 const void *src,
1123 const void *src_end,
1124 void *dst)
1125{
1126 Eina_F32p32 *fp;
1127 int idx;
1128
1129 fp = (Eina_F32p32 *)dst;
1130
1131 if (!ed)
1132 {
1133 const char *s, *p;
1134 int len;
1135
1136 s = (const char *)src;
1137 p = s;
1138 len = 0;
1139 while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; }
1140
1141 if (!(eina_convert_atofp(s, len, fp)))
1142 return -1;
1143
1144 return 1;
1145 }
1146
1147 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1148 return -1;
1149
1150 if (!eet_dictionary_string_get_fp(ed, idx, fp))
1151 return -1;
1152
1153 return 1;
1154} /* eet_data_get_f32p32 */
1155
1156static void *
1157eet_data_put_f32p32(Eet_Dictionary *ed,
1158 const void *src,
1159 int *size_ret)
1160{
1161 char buf[128];
1162 int idx;
1163
1164 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
1165
1166 if (!ed)
1167 {
1168 char *d;
1169 int len;
1170
1171 len = strlen(buf);
1172 d = malloc(len + 1);
1173 if (!d)
1174 return NULL;
1175
1176 memcpy(d, buf, len + 1);
1177 *size_ret = len + 1;
1178
1179 return d;
1180 }
1181
1182 idx = eet_dictionary_string_add(ed, buf);
1183 if (idx == -1)
1184 return NULL;
1185
1186 return eet_data_put_int(ed, &idx, size_ret);
1187} /* eet_data_put_f32p32 */
1188
1189static int
1190eet_data_get_f16p16(const Eet_Dictionary *ed,
1191 const void *src,
1192 const void *src_end,
1193 void *dst)
1194{
1195 Eina_F32p32 tmp;
1196 Eina_F16p16 *fp;
1197
1198 fp = (Eina_F16p16 *)dst;
1199
1200 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1201 return -1;
1202
1203 *fp = eina_f32p32_to_f16p16(tmp);
1204 return 1;
1205} /* eet_data_get_f16p16 */
1206
1207static void *
1208eet_data_put_f16p16(Eet_Dictionary *ed,
1209 const void *src,
1210 int *size_ret)
1211{
1212 Eina_F32p32 tmp;
1213
1214 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
1215 return eet_data_put_f32p32(ed, &tmp, size_ret);
1216} /* eet_data_put_f16p16 */
1217
1218static int
1219eet_data_get_f8p24(const Eet_Dictionary *ed,
1220 const void *src,
1221 const void *src_end,
1222 void *dst)
1223{
1224 Eina_F32p32 tmp;
1225 Eina_F8p24 *fp;
1226
1227 fp = (Eina_F8p24 *)dst;
1228
1229 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1230 return -1;
1231
1232 *fp = eina_f32p32_to_f8p24(tmp);
1233 return 1;
1234} /* eet_data_get_f8p24 */
1235
1236static void *
1237eet_data_put_f8p24(Eet_Dictionary *ed,
1238 const void *src,
1239 int *size_ret)
1240{
1241 Eina_F32p32 tmp;
1242
1243 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
1244 return eet_data_put_f32p32(ed, &tmp, size_ret);
1245} /* eet_data_put_f8p24 */
1246
1247static inline int
1248eet_data_get_type(const Eet_Dictionary *ed,
1249 int type,
1250 const void *src,
1251 const void *src_end,
1252 void *dest)
1253{
1254 int ret;
1255
1256 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
1257 return ret;
1258} /* eet_data_get_type */
1259
1260static inline void *
1261eet_data_put_type(Eet_Dictionary *ed,
1262 int type,
1263 const void *src,
1264 int *size_ret)
1265{
1266 void *ret;
1267
1268 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
1269 return ret;
1270} /* eet_data_put_type */
1271
1272static inline Eina_Bool
1273eet_data_type_match(int type1,
1274 int type2)
1275{
1276 if (type1 == type2)
1277 return EINA_TRUE;
1278
1279 /* Note: All floating point type are equivalent and could be read
1280 without problem by any other floating point getter. */
1281 switch (type1)
1282 {
1283 case EET_T_FLOAT:
1284 case EET_T_DOUBLE:
1285 case EET_T_F32P32:
1286 case EET_T_F16P16:
1287 case EET_T_F8P24:
1288 switch (type2)
1289 {
1290 case EET_T_FLOAT:
1291 case EET_T_DOUBLE:
1292 case EET_T_F32P32:
1293 case EET_T_F16P16:
1294 case EET_T_F8P24:
1295 return EINA_TRUE;
1296
1297 default:
1298 break;
1299 } /* switch */
1300 break;
1301
1302 default:
1303 break;
1304 } /* switch */
1305
1306 return EINA_FALSE;
1307} /* eet_data_type_match */
1308
1309/* chunk format...
1310 *
1311 * char[4] = "CHnK"; // untyped data ... or
1312 * char[4] = "CHKx"; // typed data - x == type
1313 *
1314 * int = chunk size (including magic string);
1315 * char[] = chunk magic/name string (0 byte terminated);
1316 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
1317 * or
1318 * ... payload data ...
1319 *
1320 */
1321
1322static inline void
1323eet_data_chunk_get(const Eet_Dictionary *ed,
1324 Eet_Data_Chunk *chnk,
1325 const void *src,
1326 int size)
1327{
1328 const char *s;
1329 int ret1, ret2;
1330
1331 if (!src)
1332 return;
1333
1334 if (size <= 8)
1335 return;
1336
1337 if (!chnk)
1338 return;
1339
1340 s = src;
1341 if (s[2] == 'K')
1342 {
1343 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
1344 return;
1345
1346 chnk->type = (unsigned char)(s[3]);
1347 if (chnk->type >= EET_I_LIMIT)
1348 {
1349 chnk->group_type =
1350 ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
1351 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
1352 {
1353#define EET_UNMATCH_TYPE(Type) \
1354case EET_I_ ## Type: chnk->type = EET_T_ ## Type; break;
1355
1356 EET_UNMATCH_TYPE(STRING);
1357 EET_UNMATCH_TYPE(INLINED_STRING);
1358 EET_UNMATCH_TYPE(NULL);
1359
1360 default:
1361 return;
1362 } /* switch */
1363 }
1364 else if (chnk->type > EET_T_LAST)
1365 {
1366 chnk->group_type = chnk->type;
1367 chnk->type = EET_T_UNKNOW;
1368 }
1369 else
1370 chnk->group_type = EET_G_UNKNOWN;
1371 if ((chnk->type >= EET_T_LAST) ||
1372 (chnk->group_type >=
1373 EET_G_LAST))
1374 {
1375 chnk->type = 0;
1376 chnk->group_type = 0;
1377 }
1378 }
1379 else if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
1380 return;
1381
1382 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
1383
1384 if (ret1 <= 0)
1385 return;
1386
1387 if ((chnk->size < 0) || ((chnk->size + 8) > size))
1388 return;
1389
1390 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
1391
1392 if (ret2 <= 0)
1393 return;
1394
1395 chnk->len = ret2;
1396
1397 /* Precalc hash */
1398 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
1399
1400 if (ed)
1401 {
1402 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
1403 chnk->size -= sizeof(int);
1404 }
1405 else
1406 {
1407 chnk->data = (char *)src + 4 + ret1 + chnk->len;
1408 chnk->size -= chnk->len;
1409 }
1410
1411 return;
1412} /* eet_data_chunk_get */
1413
1414static inline Eet_Data_Chunk *
1415eet_data_chunk_new(void *data,
1416 int size,
1417 const char *name,
1418 int type,
1419 int group_type)
1420{
1421 Eet_Data_Chunk *chnk;
1422
1423 if (!name)
1424 return NULL;
1425
1426 chnk = calloc(1, sizeof(Eet_Data_Chunk));
1427 if (!chnk)
1428 return NULL;
1429
1430 /* Note: Another security, so older eet library could read file
1431 saved with fixed point value. */
1432 if (type == EET_T_F32P32
1433 || type == EET_T_F16P16
1434 || type == EET_T_F8P24)
1435 type = EET_T_DOUBLE;
1436
1437 chnk->name = strdup(name);
1438 chnk->len = strlen(name) + 1;
1439 chnk->size = size;
1440 chnk->data = data;
1441 chnk->type = type;
1442 chnk->group_type = group_type;
1443 return chnk;
1444} /* eet_data_chunk_new */
1445
1446static inline void
1447eet_data_chunk_free(Eet_Data_Chunk *chnk)
1448{
1449 if (chnk->name)
1450 free(chnk->name);
1451
1452 free(chnk);
1453} /* eet_data_chunk_free */
1454
1455static inline Eet_Data_Stream *
1456eet_data_stream_new(void)
1457{
1458 Eet_Data_Stream *ds;
1459
1460 ds = calloc(1, sizeof(Eet_Data_Stream));
1461 if (!ds)
1462 return NULL;
1463
1464 return ds;
1465} /* eet_data_stream_new */
1466
1467static inline void
1468eet_data_stream_free(Eet_Data_Stream *ds)
1469{
1470 if (ds->data)
1471 free(ds->data);
1472
1473 free(ds);
1474} /* eet_data_stream_free */
1475
1476static inline void
1477eet_data_stream_flush(Eet_Data_Stream *ds)
1478{
1479 free(ds);
1480} /* eet_data_stream_flush */
1481
1482static inline void
1483eet_data_stream_write(Eet_Data_Stream *ds,
1484 const void *data,
1485 int size)
1486{
1487 char *p;
1488
1489 if ((ds->pos + size) > ds->size)
1490 {
1491 ds->data = realloc(ds->data, ds->size + size + 512);
1492 if (!ds->data)
1493 {
1494 ds->pos = 0;
1495 ds->size = 0;
1496 return;
1497 }
1498
1499 ds->size = ds->size + size + 512;
1500 }
1501
1502 p = ds->data;
1503 memcpy(p + ds->pos, data, size);
1504 ds->pos += size;
1505} /* eet_data_stream_write */
1506
1507static void
1508eet_data_chunk_put(Eet_Dictionary *ed,
1509 Eet_Data_Chunk *chnk,
1510 Eet_Data_Stream *ds)
1511{
1512 int *size;
1513 void *string;
1514 int s;
1515 int size_ret = 0;
1516 int string_ret = 0;
1517 unsigned char buf[4] = "CHK";
1518
1519 /* disable this check - it will allow empty chunks to be written. this is
1520 * right for corner-cases when y have a struct with empty fields (empty
1521 * strings or empty list ptrs etc.) */
1522 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1523 /* chunk head */
1524
1525/* eet_data_stream_write(ds, "CHnK", 4);*/
1526 if (chnk->type != EET_T_UNKNOW)
1527 {
1528 if (chnk->group_type != EET_G_UNKNOWN)
1529 {
1530 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1531
1532 switch (chnk->type)
1533 {
1534 /* Only make sense with pointer type. */
1535#define EET_MATCH_TYPE(Type) \
1536case EET_T_ ## Type: type += EET_I_ ## Type; break;
1537
1538 EET_MATCH_TYPE(STRING);
1539 EET_MATCH_TYPE(INLINED_STRING);
1540 EET_MATCH_TYPE(NULL);
1541
1542 default:
1543 return;
1544 } /* switch */
1545
1546 buf[3] = type;
1547 }
1548 else
1549 buf[3] = chnk->type;
1550 }
1551 else
1552 buf[3] = chnk->group_type;
1553
1554 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1555 if (!string)
1556 return;
1557
1558 /* size of chunk payload data + name */
1559 s = chnk->size + string_ret;
1560 size = eet_data_put_int(ed, &s, &size_ret);
1561
1562 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1563 if (!size)
1564 goto on_error;
1565
1566 eet_data_stream_write(ds, buf, 4);
1567
1568 /* write chunk length */
1569 eet_data_stream_write(ds, size, size_ret);
1570
1571 /* write chunk name */
1572 eet_data_stream_write(ds, string, string_ret);
1573
1574 /* write payload */
1575 if (chnk->data)
1576 eet_data_stream_write(ds, chnk->data, chnk->size);
1577
1578 free(string);
1579on_error:
1580 free(size);
1581} /* eet_data_chunk_put */
1582
1583/*---*/
1584
1585static void
1586_eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1587{
1588 int i;
1589
1590 edd->elements.hash.size = 1 << 6;
1591 edd->elements.hash.buckets = calloc(
1592 1,
1593 sizeof(Eet_Data_Descriptor_Hash) *
1594 edd->elements.hash.size);
1595 for (i = 0; i < edd->elements.num; i++)
1596 {
1597 Eet_Data_Element *ede;
1598 int hash;
1599
1600 ede = &(edd->elements.set[i]);
1601 hash = _eet_hash_gen((char *)ede->name, 6);
1602 if (!edd->elements.hash.buckets[hash].element)
1603 edd->elements.hash.buckets[hash].element = ede;
1604 else
1605 {
1606 Eet_Data_Descriptor_Hash *bucket;
1607
1608 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1609 bucket->element = ede;
1610 bucket->next = edd->elements.hash.buckets[hash].next;
1611 edd->elements.hash.buckets[hash].next = bucket;
1612 }
1613 }
1614} /* _eet_descriptor_hash_new */
1615
1616static void
1617_eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1618{
1619 int i;
1620
1621 for (i = 0; i < edd->elements.hash.size; i++)
1622 {
1623 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1624
1625 bucket = edd->elements.hash.buckets[i].next;
1626 while (bucket)
1627 {
1628 pbucket = bucket;
1629 bucket = bucket->next;
1630 free(pbucket);
1631 }
1632 }
1633 if (edd->elements.hash.buckets)
1634 free(edd->elements.hash.buckets);
1635} /* _eet_descriptor_hash_free */
1636
1637static Eet_Data_Element *
1638_eet_descriptor_hash_find(Eet_Data_Descriptor *edd,
1639 char *name,
1640 int hash)
1641{
1642 Eet_Data_Descriptor_Hash *bucket;
1643
1644 if (hash < 0)
1645 hash = _eet_hash_gen(name, 6);
1646 else
1647 hash &= 0x3f;
1648
1649 if (!edd->elements.hash.buckets[hash].element)
1650 return NULL; /*
1651 When we use the dictionary as a source for chunk name, we will always
1652 have the same pointer in name. It's a good idea to just compare pointer
1653 instead of running strcmp on both string.
1654 */
1655
1656 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1657 return edd->elements.hash.buckets[hash].element;
1658
1659 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1660 {
1661 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1662 return edd->elements.hash.buckets[hash].element;
1663 }
1664
1665 bucket = edd->elements.hash.buckets[hash].next;
1666 while (bucket)
1667 {
1668 if (bucket->element->directory_name_ptr == name)
1669 return bucket->element;
1670
1671 if (!strcmp(bucket->element->name, name))
1672 {
1673 bucket->element->directory_name_ptr = name;
1674 return bucket->element;
1675 }
1676
1677 bucket = bucket->next;
1678 }
1679 return NULL;
1680} /* _eet_descriptor_hash_find */
1681
1682static void *
1683_eet_mem_alloc(size_t size)
1684{
1685 return calloc(1, size);
1686} /* _eet_mem_alloc */
1687
1688static void
1689_eet_mem_free(void *mem)
1690{
1691 free(mem);
1692} /* _eet_mem_free */
1693
1694static char *
1695_eet_str_alloc(const char *str)
1696{
1697 return strdup(str);
1698} /* _eet_str_alloc */
1699
1700static void
1701_eet_str_free(const char *str)
1702{
1703 free((char *)str);
1704} /* _eet_str_free */
1705
1706static Eina_Hash *
1707_eet_eina_hash_add_alloc(Eina_Hash *hash,
1708 const char *key,
1709 void *data)
1710{
1711 if (!hash)
1712 hash = eina_hash_string_small_new(NULL);
1713
1714 if (!hash)
1715 return NULL;
1716
1717 eina_hash_add(hash, key, data);
1718 return hash;
1719} /* _eet_eina_hash_add_alloc */
1720
1721static Eina_Hash *
1722_eet_eina_hash_direct_add_alloc(Eina_Hash *hash,
1723 const char *key,
1724 void *data)
1725{
1726 if (!hash)
1727 hash = eina_hash_string_small_new(NULL);
1728
1729 if (!hash)
1730 return NULL;
1731
1732 eina_hash_direct_add(hash, key, data);
1733 return hash;
1734} /* _eet_eina_hash_direct_add_alloc */
1735
1736static char *
1737_eet_str_direct_alloc(const char *str)
1738{
1739 return (char *)str;
1740} /* _eet_str_direct_alloc */
1741
1742static void
1743_eet_str_direct_free(const char *str __UNUSED__)
1744{
1745} /* _eet_str_direct_free */
1746
1747static void
1748_eet_eina_hash_foreach(void *hash,
1749 Eina_Hash_Foreach cb,
1750 void *fdata)
1751{
1752 if (hash)
1753 eina_hash_foreach(hash, cb, fdata);
1754} /* _eet_eina_hash_foreach */
1755
1756static void
1757_eet_eina_hash_free(void *hash)
1758{
1759 if (hash)
1760 eina_hash_free(hash);
1761} /* _eet_eina_hash_free */
1762
1763/*---*/
1764EAPI Eina_Bool
1765eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1766 /* When we change the structure content in the future, we need to handle old structure type too */
1767 unsigned int eddc_size,
1768 const char *name,
1769 int size)
1770{
1771 if (!eddc || !name || eddc_size != sizeof (Eet_Data_Descriptor_Class))
1772 return EINA_FALSE;
1773
1774 eddc->name = name;
1775 eddc->size = size;
1776 eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
1777
1778 eddc->func.mem_alloc = _eet_mem_alloc;
1779 eddc->func.mem_free = _eet_mem_free;
1780 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1781 eddc->func.str_free = eina_stringshare_del;
1782 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1783 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1784 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1785 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1786 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach;
1787 eddc->func.hash_add = (void *(*)(void *, const char *, void *))_eet_eina_hash_add_alloc;
1788 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1789
1790 /* This will cause an ABI incompatibility */
1791 eddc->func.array_alloc = _eet_mem_alloc;
1792 eddc->func.array_free = _eet_mem_free;
1793
1794 return EINA_TRUE;
1795} /* eet_eina_stream_data_descriptor_class_set */
1796
1797EAPI Eina_Bool
1798eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1799 /* When we change the structure content in the future, we need to handle old structure type too */
1800 unsigned int eddc_size,
1801 const char *name,
1802 int size)
1803{
1804 if (!eet_eina_stream_data_descriptor_class_set(eddc, eddc_size, name, size))
1805 return EINA_FALSE;
1806
1807 eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
1808
1809 eddc->func.hash_add = (void *(*)(void *, const char *, void *))_eet_eina_hash_direct_add_alloc;
1810 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1811 eddc->func.str_direct_free = _eet_str_direct_free;
1812
1813 return EINA_TRUE;
1814} /* eet_eina_file_data_descriptor_class_set */
1815
1816static Eet_Data_Descriptor *
1817_eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc,
1818 int version)
1819{
1820 Eet_Data_Descriptor *edd;
1821
1822 if (!eddc)
1823 return NULL;
1824
1825 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1826 if (!edd)
1827 return NULL;
1828
1829 edd->name = eddc->name;
1830 edd->ed = NULL;
1831 edd->size = eddc->size;
1832 edd->func.mem_alloc = _eet_mem_alloc;
1833 edd->func.mem_free = _eet_mem_free;
1834 edd->func.str_alloc = _eet_str_alloc;
1835 edd->func.str_free = _eet_str_free;
1836 if (eddc->func.mem_alloc)
1837 edd->func.mem_alloc = eddc->func.mem_alloc;
1838
1839 if (eddc->func.mem_free)
1840 edd->func.mem_free = eddc->func.mem_free;
1841
1842 if (eddc->func.str_alloc)
1843 edd->func.str_alloc = eddc->func.str_alloc;
1844
1845 if (eddc->func.str_free)
1846 edd->func.str_free = eddc->func.str_free;
1847
1848 edd->func.list_next = eddc->func.list_next;
1849 edd->func.list_append = eddc->func.list_append;
1850 edd->func.list_data = eddc->func.list_data;
1851 edd->func.list_free = eddc->func.list_free;
1852 edd->func.hash_foreach = eddc->func.hash_foreach;
1853 edd->func.hash_add = eddc->func.hash_add;
1854 edd->func.hash_free = eddc->func.hash_free;
1855
1856 if (eddc->version > 1 && version > 1)
1857 {
1858 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1859 edd->func.str_direct_free = eddc->func.str_direct_free;
1860 }
1861
1862 if (eddc->version > 2)
1863 {
1864 edd->func.type_get = eddc->func.type_get;
1865 edd->func.type_set = eddc->func.type_set;
1866 }
1867
1868 if (eddc->version > 3)
1869 {
1870 edd->func.array_alloc = eddc->func.array_alloc;
1871 edd->func.array_free = eddc->func.array_free;
1872 }
1873
1874 return edd;
1875} /* _eet_data_descriptor_new */
1876
1877EAPI Eet_Data_Descriptor *
1878eet_data_descriptor_new(const char *name,
1879 int size,
1880 Eet_Descriptor_List_Next_Callback func_list_next,
1881 Eet_Descriptor_List_Append_Callback func_list_append,
1882 Eet_Descriptor_List_Data_Callback func_list_data,
1883 Eet_Descriptor_List_Free_Callback func_list_free,
1884 Eet_Descriptor_Hash_Foreach_Callback func_hash_foreach,
1885 Eet_Descriptor_Hash_Add_Callback func_hash_add,
1886 Eet_Descriptor_Hash_Free_Callback func_hash_free)
1887{
1888 Eet_Data_Descriptor_Class eddc;
1889
1890 if (!name)
1891 return NULL;
1892
1893 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1894
1895 eddc.name = name;
1896 eddc.size = size;
1897 eddc.version = 0;
1898
1899 eddc.func.list_next = func_list_next;
1900 eddc.func.list_append = func_list_append;
1901 eddc.func.list_data = func_list_data;
1902 eddc.func.list_free = func_list_free;
1903 eddc.func.hash_foreach = func_hash_foreach;
1904 eddc.func.hash_add = func_hash_add;
1905 eddc.func.hash_free = func_hash_free;
1906
1907 return _eet_data_descriptor_new(&eddc, 0);
1908} /* eet_data_descriptor_new */
1909
1910EAPI Eet_Data_Descriptor *
1911eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1912{
1913 return _eet_data_descriptor_new(eddc, 1);
1914} /* eet_data_descriptor2_new */
1915
1916EAPI Eet_Data_Descriptor *
1917eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1918{
1919 return _eet_data_descriptor_new(eddc, 2);
1920} /* eet_data_descriptor3_new */
1921
1922EAPI Eet_Data_Descriptor *
1923eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1924{
1925 return _eet_data_descriptor_new(eddc, 1);
1926} /* eet_data_descriptor_stream_new */
1927
1928EAPI Eet_Data_Descriptor *
1929eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1930{
1931 return _eet_data_descriptor_new(eddc, 2);
1932} /* eet_data_descriptor_file_new */
1933
1934EAPI void
1935eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1936{
1937 if (!edd)
1938 return;
1939
1940 _eet_descriptor_hash_free(edd);
1941 if (edd->elements.set)
1942 free(edd->elements.set);
1943
1944 free(edd);
1945} /* eet_data_descriptor_free */
1946
1947EAPI void
1948eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1949 const char *name,
1950 int type,
1951 int group_type,
1952 int offset,
1953 int count,
1954/* int counter_offset, */
1955 const char *counter_name /* FIXME: Useless should go on a major release */,
1956 Eet_Data_Descriptor *subtype)
1957{
1958 Eet_Data_Element *ede;
1959 Eet_Data_Element *tmp;
1960
1961 /* UNION, VARIANT type would not work with simple type, we need a way to map the type. */
1962 if ((group_type == EET_G_UNION
1963 || group_type == EET_G_VARIANT)
1964 &&
1965 (type != EET_T_UNKNOW
1966 || !subtype
1967 || !subtype->func.type_get
1968 || !subtype->func.type_set))
1969 return;
1970
1971 /* VARIANT type will only work if the map only contains EET_G_*, but not UNION, VARIANT and ARRAY. */
1972 if (group_type == EET_G_VARIANT)
1973 {
1974 int i;
1975
1976 for (i = 0; i < subtype->elements.num; ++i)
1977 if (subtype->elements.set[i].type != EET_T_UNKNOW
1978 && subtype->elements.set[i].group_type > EET_G_VAR_ARRAY
1979 && subtype->elements.set[i].group_type < EET_G_UNION)
1980 return;
1981
1982 subtype->unified_type = EINA_TRUE;
1983 }
1984
1985 if (subtype
1986 && subtype->unified_type
1987 && (type != EET_T_UNKNOW
1988 || group_type < EET_G_UNION))
1989 return;
1990
1991 /* Sanity check done, let allocate ! */
1992 edd->elements.num++;
1993 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1994 if (!tmp)
1995 return;
1996
1997 edd->elements.set = tmp;
1998 ede = &(edd->elements.set[edd->elements.num - 1]);
1999 ede->name = name;
2000 ede->directory_name_ptr = NULL;
2001
2002 /*
2003 * We do a special case when we do list,hash or whatever group of simple type.
2004 * Instead of handling it in encode/decode/dump/undump, we create an
2005 * implicit structure with only the simple type.
2006 */
2007 if ((group_type > EET_G_UNKNOWN)
2008 && (group_type < EET_G_LAST)
2009 && (((type > EET_T_UNKNOW) && (type < EET_T_STRING))
2010 || ((type > EET_T_NULL) && (type < EET_T_LAST)))
2011 && (!subtype))
2012 {
2013 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
2014 if (!subtype)
2015 return;
2016
2017 subtype->name = "implicit";
2018 subtype->size = eet_basic_codec[type - 1].size;
2019 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
2020
2021 eet_data_descriptor_element_add(subtype,
2022 eet_basic_codec[type - 1].name,
2023 type,
2024 EET_G_UNKNOWN,
2025 0,
2026 0,
2027 /* 0, */ NULL,
2028 NULL);
2029 type = EET_T_UNKNOW;
2030 }
2031
2032 ede->type = type;
2033 ede->group_type = group_type;
2034 ede->offset = offset;
2035 ede->count = count;
2036 /* FIXME: For the time being, VAR_ARRAY, UNION and VARIANT will put the counter_offset in count. */
2037 ede->counter_offset = count;
2038/* ede->counter_offset = counter_offset; */
2039 ede->counter_name = counter_name;
2040
2041 ede->subtype = subtype;
2042} /* eet_data_descriptor_element_add */
2043
2044EAPI void *
2045eet_data_read_cipher(Eet_File *ef,
2046 Eet_Data_Descriptor *edd,
2047 const char *name,
2048 const char *cipher_key)
2049{
2050 const Eet_Dictionary *ed = NULL;
2051 const void *data = NULL;
2052 void *data_dec;
2053 Eet_Free_Context context;
2054 int required_free = 0;
2055 int size;
2056
2057 ed = eet_dictionary_get(ef);
2058
2059 if (!cipher_key)
2060 data = eet_read_direct(ef, name, &size);
2061
2062 if (!data)
2063 {
2064 required_free = 1;
2065 data = eet_read_cipher(ef, name, &size, cipher_key);
2066 if (!data)
2067 return NULL;
2068 }
2069
2070 eet_free_context_init(&context);
2071 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, NULL, 0);
2072 eet_free_context_shutdown(&context);
2073
2074 if (required_free)
2075 free((void *)data);
2076
2077 return data_dec;
2078} /* eet_data_read_cipher */
2079
2080EAPI Eet_Node *
2081eet_data_node_read_cipher(Eet_File *ef,
2082 const char *name,
2083 const char *cipher_key)
2084{
2085 const Eet_Dictionary *ed = NULL;
2086 const void *data = NULL;
2087 Eet_Node *result;
2088 Eet_Free_Context context;
2089 int required_free = 0;
2090 int size;
2091
2092 ed = eet_dictionary_get(ef);
2093
2094 if (!cipher_key)
2095 data = eet_read_direct(ef, name, &size);
2096
2097 if (!data)
2098 {
2099 required_free = 1;
2100 data = eet_read_cipher(ef, name, &size, cipher_key);
2101 if (!data)
2102 return NULL;
2103 }
2104
2105 eet_free_context_init(&context);
2106 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0);
2107 eet_free_context_shutdown(&context);
2108
2109 if (required_free)
2110 free((void *)data);
2111
2112 return result;
2113} /* eet_data_node_read_cipher */
2114
2115EAPI void *
2116eet_data_read(Eet_File *ef,
2117 Eet_Data_Descriptor *edd,
2118 const char *name)
2119{
2120 return eet_data_read_cipher(ef, edd, name, NULL);
2121} /* eet_data_read */
2122
2123EAPI int
2124eet_data_write_cipher(Eet_File *ef,
2125 Eet_Data_Descriptor *edd,
2126 const char *name,
2127 const char *cipher_key,
2128 const void *data,
2129 int compress)
2130{
2131 Eet_Dictionary *ed;
2132 void *data_enc;
2133 int size;
2134 int val;
2135
2136 ed = eet_dictionary_get(ef);
2137
2138 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
2139 if (!data_enc)
2140 return 0;
2141
2142 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
2143 free(data_enc);
2144 return val;
2145} /* eet_data_write_cipher */
2146
2147EAPI int
2148eet_data_write(Eet_File *ef,
2149 Eet_Data_Descriptor *edd,
2150 const char *name,
2151 const void *data,
2152 int compress)
2153{
2154 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
2155} /* eet_data_write */
2156
2157static void
2158eet_free_context_init(Eet_Free_Context *context)
2159{
2160 unsigned int i = 0;
2161
2162 memset(context, 0, sizeof (Eet_Free_Context));
2163 for (i = 0; i < EET_FREE_COUNT; ++i)
2164 {
2165 eina_array_step_set(&context->freelist.list[i],
2166 sizeof (context->freelist.list[i]),
2167 32);
2168 eina_array_step_set(&context->freelist_array.list[i],
2169 sizeof (context->freelist.list[i]),
2170 32);
2171 eina_array_step_set(&context->freelist_list.list[i],
2172 sizeof (context->freelist.list[i]),
2173 32);
2174 eina_array_step_set(&context->freelist_hash.list[i],
2175 sizeof (context->freelist.list[i]),
2176 32);
2177 eina_array_step_set(&context->freelist_str.list[i],
2178 sizeof (context->freelist.list[i]),
2179 32);
2180 eina_array_step_set(&context->freelist_direct_str.list[i],
2181 sizeof (context->freelist.list[i]),
2182 32);
2183 }
2184}
2185
2186static void
2187eet_free_context_shutdown(Eet_Free_Context *context)
2188{
2189 unsigned int i = 0;
2190
2191 for (i = 0; i < EET_FREE_COUNT; ++i)
2192 {
2193 eina_array_flush(&context->freelist.list[i]);
2194 eina_array_flush(&context->freelist_array.list[i]);
2195 eina_array_flush(&context->freelist_list.list[i]);
2196 eina_array_flush(&context->freelist_hash.list[i]);
2197 eina_array_flush(&context->freelist_str.list[i]);
2198 eina_array_flush(&context->freelist_direct_str.list[i]);
2199 }
2200}
2201
2202static int
2203_eet_free_hash(void *data)
2204{
2205#ifdef _WIN64
2206 __int64 ptr = (UINT_PTR)data;
2207#else /* ifdef _WIN64 */
2208 unsigned long ptr = (unsigned long)(data);
2209#endif /* ifdef _WIN64 */
2210 int hash;
2211
2212 hash = ptr;
2213 hash ^= ptr >> 8;
2214 hash ^= ptr >> 16;
2215 hash ^= ptr >> 24;
2216
2217#if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32))
2218 hash ^= ptr >> 32;
2219 hash ^= ptr >> 40;
2220 hash ^= ptr >> 48;
2221 hash ^= ptr >> 56;
2222#endif /* if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32)) */
2223
2224 return hash & 0xFF;
2225} /* _eet_free_hash */
2226
2227static void
2228_eet_free_add(Eet_Free *ef,
2229 void *data)
2230{
2231 void *track;
2232 Eina_Array_Iterator it;
2233 unsigned int i;
2234 int hash;
2235
2236 hash = _eet_free_hash(data);
2237
2238 EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it)
2239 if (track == data)
2240 return;
2241
2242 eina_array_push(&ef->list[hash], data);
2243} /* _eet_free_add */
2244
2245#if 0
2246static void
2247_eet_free_del(Eet_Free *ef,
2248 void *data)
2249{
2250 void *track;
2251 Eina_Array_Iterator it;
2252 unsigned int i;
2253 int hash;
2254
2255 hash = _eet_free_hash(data);
2256
2257 EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it)
2258 if (track == data)
2259 {
2260 eina_array_data_set(&ef->list[hash], i, NULL);
2261 return;
2262 }
2263}
2264
2265#endif
2266
2267static void
2268_eet_free_reset(Eet_Free *ef)
2269{
2270 unsigned int i;
2271
2272 if (ef->ref > 0)
2273 return;
2274
2275 for (i = 0; i < EET_FREE_COUNT; ++i)
2276 eina_array_clean(&ef->list[i]);
2277} /* _eet_free_reset */
2278
2279static void
2280_eet_free_ref(Eet_Free *ef)
2281{
2282 ef->ref++;
2283} /* _eet_free_ref */
2284
2285static void
2286_eet_free_unref(Eet_Free *ef)
2287{
2288 ef->ref--;
2289} /* _eet_free_unref */
2290
2291#define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
2292#define _eet_freelist_del(Ctx, Data) _eet_free_del(&Ctx->freelist, Data);
2293#define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
2294#define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
2295#define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
2296
2297static void
2298_eet_freelist_free(Eet_Free_Context *context,
2299 Eet_Data_Descriptor *edd)
2300{
2301 void *track;
2302 Eina_Array_Iterator it;
2303 unsigned int j;
2304 unsigned int i;
2305
2306 if (context->freelist.ref > 0)
2307 return;
2308
2309 for (j = 0; j < EET_FREE_COUNT; ++j)
2310 EINA_ARRAY_ITER_NEXT(&context->freelist.list[j], i, track, it)
2311 if (track)
2312 {
2313 if (edd)
2314 edd->func.mem_free(track);
2315 else
2316 free(track);
2317 }
2318 _eet_free_reset(&context->freelist);
2319} /* _eet_freelist_free */
2320
2321#define _eet_freelist_array_add(Ctx, Data) _eet_free_add(&Ctx->freelist_array, Data);
2322#define _eet_freelist_array_del(Ctx, Data) _eet_free_del(&Ctx->freelist_array, Data);
2323#define _eet_freelist_array_reset(Ctx) _eet_free_reset(&Ctx->freelist_array);
2324#define _eet_freelist_array_ref(Ctx) _eet_free_ref(&Ctx->freelist_array);
2325#define _eet_freelist_array_unref(Ctx) _eet_free_unref(&Ctx->freelist_array);
2326
2327static void
2328_eet_freelist_array_free(Eet_Free_Context *context,
2329 Eet_Data_Descriptor *edd)
2330{
2331 void *track;
2332 Eina_Array_Iterator it;
2333 unsigned int j;
2334 unsigned int i;
2335
2336 if (context->freelist_array.ref > 0)
2337 return;
2338
2339 for (j = 0; j < EET_FREE_COUNT; ++j)
2340 EINA_ARRAY_ITER_NEXT(&context->freelist_array.list[j], i, track, it)
2341 if (track)
2342 {
2343 if (edd)
2344 {
2345 if (edd->func.array_free)
2346 edd->func.array_free(track);
2347 else
2348 edd->func.mem_free(track);
2349 }
2350 else
2351 free(track);
2352 }
2353 _eet_free_reset(&context->freelist_array);
2354} /* _eet_freelist_array_free */
2355
2356#define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
2357#define _eet_freelist_list_del(Ctx, Data) _eet_free_del(&Ctx->freelist_list, Data);
2358#define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
2359#define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
2360#define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
2361
2362static void
2363_eet_freelist_list_free(Eet_Free_Context *context,
2364 Eet_Data_Descriptor *edd)
2365{
2366 void *track;
2367 Eina_Array_Iterator it;
2368 unsigned int j;
2369 unsigned int i;
2370
2371 if (context->freelist_list.ref > 0)
2372 return;
2373
2374 for (j = 0; j < EET_FREE_COUNT; ++j)
2375 EINA_ARRAY_ITER_NEXT(&context->freelist_list.list[j], i, track, it)
2376 if (track)
2377 {
2378 if (edd)
2379 edd->func.list_free(*((void **)(track)));
2380 }
2381 _eet_free_reset(&context->freelist_list);
2382} /* _eet_freelist_list_free */
2383
2384#define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
2385#define _eet_freelist_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_str, Data);
2386#define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
2387#define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
2388#define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
2389
2390static void
2391_eet_freelist_str_free(Eet_Free_Context *context,
2392 Eet_Data_Descriptor *edd)
2393{
2394 void *track;
2395 Eina_Array_Iterator it;
2396 unsigned int j;
2397 unsigned int i;
2398
2399 if (context->freelist_str.ref > 0)
2400 return;
2401
2402 for (j = 0; j < EET_FREE_COUNT; ++j)
2403 EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it)
2404 if (track)
2405 {
2406 if (edd)
2407 edd->func.str_free(track);
2408 else
2409 free(track);
2410 }
2411 _eet_free_reset(&context->freelist_str);
2412} /* _eet_freelist_str_free */
2413
2414#define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
2415#define _eet_freelist_direct_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_direct_str, Data);
2416#define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
2417#define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
2418#define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
2419
2420static void
2421_eet_freelist_direct_str_free(Eet_Free_Context *context,
2422 Eet_Data_Descriptor *edd)
2423{
2424 void *track;
2425 Eina_Array_Iterator it;
2426 unsigned int j;
2427 unsigned int i;
2428
2429 if (context->freelist_direct_str.ref > 0)
2430 return;
2431
2432 for (j = 0; j < EET_FREE_COUNT; ++j)
2433 EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it)
2434 if (track)
2435 {
2436 if (edd)
2437 edd->func.str_direct_free(track);
2438 else
2439 free(track);
2440 }
2441 _eet_free_reset(&context->freelist_direct_str);
2442} /* _eet_freelist_direct_str_free */
2443
2444#define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
2445#define _eet_freelist_hash_del(Ctx, Data) _eet_free_del(&Ctx->freelist_hash, Data);
2446#define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
2447#define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
2448#define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
2449
2450static void
2451_eet_freelist_hash_free(Eet_Free_Context *context,
2452 Eet_Data_Descriptor *edd)
2453{
2454 void *track;
2455 Eina_Array_Iterator it;
2456 unsigned int j;
2457 unsigned int i;
2458
2459 if (context->freelist_hash.ref > 0)
2460 return;
2461
2462 for (j = 0; j < EET_FREE_COUNT; ++j)
2463 EINA_ARRAY_ITER_NEXT(&context->freelist_hash.list[j], i, track, it)
2464 if (track)
2465 {
2466 if (edd)
2467 edd->func.hash_free(track);
2468 else
2469 free(track);
2470 }
2471 _eet_free_reset(&context->freelist_hash);
2472} /* _eet_freelist_hash_free */
2473
2474static void
2475_eet_freelist_all_ref(Eet_Free_Context *freelist_context)
2476{
2477 _eet_freelist_ref(freelist_context);
2478 _eet_freelist_str_ref(freelist_context);
2479 _eet_freelist_list_ref(freelist_context);
2480 _eet_freelist_hash_ref(freelist_context);
2481 _eet_freelist_direct_str_ref(freelist_context);
2482} /* _eet_freelist_all_ref */
2483
2484static void
2485_eet_freelist_all_unref(Eet_Free_Context *freelist_context)
2486{
2487 _eet_freelist_unref(freelist_context);
2488 _eet_freelist_str_unref(freelist_context);
2489 _eet_freelist_list_unref(freelist_context);
2490 _eet_freelist_hash_unref(freelist_context);
2491 _eet_freelist_direct_str_unref(freelist_context);
2492} /* _eet_freelist_all_unref */
2493
2494static int
2495eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__,
2496 const char *cipher_key,
2497 void *hdata,
2498 void *fdata)
2499{
2500 Eet_Dictionary *ed;
2501 Eet_Data_Encode_Hash_Info *edehi;
2502 Eet_Data_Stream *ds;
2503 Eet_Data_Element *ede;
2504 Eet_Data_Chunk *echnk;
2505 void *data = NULL;
2506 int size;
2507
2508 edehi = fdata;
2509 ede = edehi->ede;
2510 ds = edehi->ds;
2511 ed = edehi->ed;
2512
2513 /* Store key */
2514 data = eet_data_put_type(ed,
2515 EET_T_STRING,
2516 &cipher_key,
2517 &size);
2518 if (data)
2519 {
2520 echnk = eet_data_chunk_new(data,
2521 size,
2522 ede->name,
2523 ede->type,
2524 ede->group_type);
2525 eet_data_chunk_put(ed, echnk, ds);
2526 eet_data_chunk_free(echnk);
2527 free(data);
2528 data = NULL;
2529 }
2530
2531 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2532
2533 /* Store data */
2534 if (ede->type >= EET_T_STRING)
2535 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
2536 else
2537 {
2538 if (ede->subtype)
2539 data = _eet_data_descriptor_encode(ed,
2540 ede->subtype,
2541 hdata,
2542 &size);
2543
2544 if (data)
2545 {
2546 echnk = eet_data_chunk_new(data,
2547 size,
2548 ede->name,
2549 ede->type,
2550 ede->group_type);
2551 eet_data_chunk_put(ed, echnk, ds);
2552 eet_data_chunk_free(echnk);
2553 free(data);
2554 data = NULL;
2555 }
2556 }
2557
2558 return 1;
2559} /* eet_data_descriptor_encode_hash_cb */
2560
2561static char *
2562_eet_data_dump_token_get(const char *src,
2563 int *len)
2564{
2565 const char *p;
2566 char *tok = NULL;
2567 int in_token = 0;
2568 int in_quote = 0;
2569 int tlen = 0, tsize = 0;
2570
2571#define TOK_ADD(x) \
2572 do { \
2573 tlen++; \
2574 if (tlen >= tsize) \
2575 { \
2576 tsize += 32; \
2577 tok = realloc(tok, tsize); \
2578 } \
2579 tok[tlen - 1] = x; \
2580 } while (0)
2581
2582 for (p = src; *len > 0; p++, (*len)--)
2583 {
2584 if (in_token)
2585 {
2586 if (in_quote)
2587 {
2588 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
2589 in_quote = 0;
2590 else if ((p[0] == '\\') && (*len > 1) &&
2591 (p[1] == '\"'))
2592 {
2593/* skip */
2594 }
2595 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
2596 {
2597/* skip */
2598 }
2599 else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n'))
2600 {
2601/* skip */
2602 }
2603 else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\'))
2604 TOK_ADD('\n');
2605 else
2606 TOK_ADD(p[0]);
2607 }
2608 else
2609 {
2610 if (p[0] == '\"')
2611 in_quote = 1;
2612 else
2613 {
2614 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
2615 {
2616 TOK_ADD(0);
2617 (*len)--;
2618 return tok;
2619 }
2620 else
2621 TOK_ADD(p[0]);
2622 }
2623 }
2624 }
2625 else if (!((isspace(p[0])) || (p[0] == ';')))
2626 {
2627 in_token = 1;
2628 (*len)++;
2629 p--;
2630 }
2631 }
2632 if (in_token)
2633 {
2634 TOK_ADD(0);
2635 return tok;
2636 }
2637
2638 if (tok)
2639 free(tok);
2640
2641 return NULL;
2642} /* _eet_data_dump_token_get */
2643
2644static void
2645eet_data_encode(Eet_Dictionary *ed,
2646 Eet_Data_Stream *ds,
2647 void *data,
2648 const char *name,
2649 int size,
2650 int type,
2651 int group_type)
2652{
2653 Eet_Data_Chunk *echnk;
2654
2655 if (!data)
2656 type = EET_T_NULL;
2657
2658 if (group_type != EET_G_UNKNOWN)
2659 if (type >= EET_T_LAST)
2660 type = EET_T_UNKNOW;
2661
2662 echnk = eet_data_chunk_new(data, size, name, type, group_type);
2663 eet_data_chunk_put(ed, echnk, ds);
2664 eet_data_chunk_free(echnk);
2665 free(data);
2666} /* eet_data_encode */
2667
2668static void *
2669_eet_data_dump_encode(int parent_type,
2670 Eet_Dictionary *ed,
2671 Eet_Node *node,
2672 int *size_ret)
2673{
2674 Eet_Data_Chunk *chnk = NULL;
2675 Eet_Data_Stream *ds;
2676 void *cdata, *data;
2677 int csize, size;
2678 int count;
2679 int child_type;
2680 Eet_Node *n;
2681
2682 if (_eet_data_words_bigendian == -1)
2683 {
2684 unsigned long int v;
2685
2686 v = htonl(0x12345678);
2687 if (v == 0x12345678)
2688 _eet_data_words_bigendian = 1;
2689 else
2690 _eet_data_words_bigendian = 0;
2691 }
2692
2693 if (!node)
2694 return NULL;
2695
2696 ds = eet_data_stream_new();
2697 if (!ds)
2698 return NULL;
2699
2700 switch (node->type)
2701 {
2702 case EET_G_UNKNOWN:
2703 for (n = node->values; n; n = n->next)
2704 {
2705 data = _eet_data_dump_encode(node->type, ed, n, &size);
2706 if (data)
2707 {
2708 eet_data_stream_write(ds, data, size);
2709 free(data);
2710 }
2711 }
2712 break;
2713
2714 case EET_G_ARRAY:
2715 case EET_G_VAR_ARRAY:
2716 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
2717 {
2718 if (n->type != EET_T_NULL)
2719 {
2720 child_type = n->type;
2721 break;
2722 }
2723 }
2724
2725 data = eet_data_put_type(ed,
2726 EET_T_INT,
2727 &node->count,
2728 &size);
2729 eet_data_encode(ed,
2730 ds,
2731 data,
2732 node->name,
2733 size,
2734 child_type,
2735 node->type);
2736
2737 count = node->count;
2738
2739 for (n = node->values; n; n = n->next)
2740 {
2741 int pos = ds->pos;
2742
2743 switch (n->type)
2744 {
2745 case EET_T_STRING:
2746 case EET_T_INLINED_STRING:
2747 data = eet_data_put_type(ed,
2748 n->type,
2749 &(n->data.value.str),
2750 &size);
2751 if (data)
2752 eet_data_encode(ed,
2753 ds,
2754 data,
2755 node->name,
2756 size,
2757 n->type,
2758 node->type);
2759
2760 break;
2761
2762 case EET_T_NULL:
2763 continue;
2764
2765 default:
2766 data = _eet_data_dump_encode(n->type, ed, n, &size);
2767 eet_data_encode(ed,
2768 ds,
2769 data,
2770 node->name,
2771 size,
2772 n->type,
2773 node->type);
2774 break;
2775 } /* switch */
2776 if (ds->pos != pos)
2777 count--;
2778 }
2779
2780 for (; count; count--)
2781 {
2782 eet_data_encode(ed,
2783 ds,
2784 NULL,
2785 node->name,
2786 0,
2787 EET_T_NULL,
2788 node->type);
2789 }
2790
2791 /* Array is somekind of special case, so we should embed it inside another chunk. */
2792 *size_ret = ds->pos;
2793 cdata = ds->data;
2794
2795 ds->data = NULL;
2796 ds->size = 0;
2797 eet_data_stream_free(ds);
2798
2799 return cdata;
2800 break;
2801
2802 case EET_G_LIST:
2803 for (n = node->values; n; n = n->next)
2804 {
2805 switch (n->type)
2806 {
2807 case EET_T_STRING:
2808 case EET_T_INLINED_STRING:
2809 data = eet_data_put_type(ed,
2810 n->type,
2811 &(n->data.value.str),
2812 &size);
2813 if (data)
2814 eet_data_encode(ed,
2815 ds,
2816 data,
2817 node->name,
2818 size,
2819 n->type,
2820 node->type);
2821
2822 break;
2823
2824 case EET_T_NULL:
2825 continue;
2826
2827 default:
2828 data = _eet_data_dump_encode(node->type, ed, n, &size);
2829 eet_data_encode(ed,
2830 ds,
2831 data,
2832 node->name,
2833 size,
2834 n->type,
2835 node->type);
2836 } /* switch */
2837 }
2838
2839 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
2840 *size_ret = ds->pos;
2841 cdata = ds->data;
2842
2843 ds->data = NULL;
2844 ds->size = 0;
2845 eet_data_stream_free(ds);
2846
2847 return cdata;
2848 break;
2849
2850 case EET_G_HASH:
2851 if (node->key)
2852 {
2853 data = eet_data_put_type(ed,
2854 EET_T_STRING,
2855 &node->key,
2856 &size);
2857 eet_data_encode(ed,
2858 ds,
2859 data,
2860 node->name,
2861 size,
2862 node->type,
2863 node->type);
2864 }
2865 else
2866 /* A Hash without key will not decode correctly. */
2867 return NULL;
2868
2869 for (n = node->values; n; n = n->next)
2870 {
2871 switch (n->type)
2872 {
2873 case EET_T_STRING:
2874 case EET_T_INLINED_STRING:
2875 data = eet_data_put_type(ed,
2876 n->type,
2877 &(n->data.value.str),
2878 &size);
2879 if (data)
2880 eet_data_encode(ed,
2881 ds,
2882 data,
2883 node->name,
2884 size,
2885 n->type,
2886 node->type);
2887
2888 break;
2889
2890 case EET_T_NULL:
2891 continue;
2892
2893 default:
2894 data = _eet_data_dump_encode(node->type, ed, n, &size);
2895 eet_data_encode(ed,
2896 ds,
2897 data,
2898 node->name,
2899 size,
2900 n->type,
2901 node->type);
2902 } /* switch */
2903 }
2904
2905 /* Hash is somekind of special case, so we should embed it inside another chunk. */
2906 *size_ret = ds->pos;
2907 cdata = ds->data;
2908
2909 eet_data_stream_flush(ds);
2910
2911 return cdata;
2912
2913 case EET_T_NULL:
2914 break;
2915
2916#define EET_DATA_NODE_ENCODE(Eet_Type, Type) \
2917case Eet_Type: \
2918 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size); \
2919 if (data) \
2920 { \
2921 eet_data_encode(ed, \
2922 ds, \
2923 data, \
2924 node->name, \
2925 size, \
2926 node->type, \
2927 parent_type); \
2928 cdata = ds->data; \
2929 *size_ret = ds->pos; \
2930 eet_data_stream_flush(ds); \
2931 return cdata; \
2932 } /* switch */ \
2933 break;
2934
2935 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
2936 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
2937 EET_DATA_NODE_ENCODE(EET_T_INT, i);
2938 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
2939 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
2940 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
2941 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
2942 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
2943 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
2944 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
2945 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
2946 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
2947
2948 default:
2949 break;
2950 }
2951
2952 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2953 chnk = eet_data_chunk_new(ds->data,
2954 ds->pos,
2955 node->name,
2956 EET_T_UNKNOW,
2957 node->type);
2958 else
2959 chnk = eet_data_chunk_new(ds->data,
2960 ds->pos,
2961 node->name,
2962 node->type,
2963 EET_G_UNKNOWN);
2964
2965 eet_data_stream_flush(ds);
2966
2967 ds = eet_data_stream_new();
2968 eet_data_chunk_put(ed, chnk, ds);
2969 cdata = ds->data;
2970 csize = ds->pos;
2971
2972 eet_data_stream_flush(ds);
2973 *size_ret = csize;
2974
2975 free(chnk->data);
2976 eet_data_chunk_free(chnk);
2977
2978 return cdata;
2979} /* _eet_data_dump_encode */
2980
2981static void *
2982_eet_data_dump_parse(Eet_Dictionary *ed,
2983 int *size_ret,
2984 const char *src,
2985 int size)
2986{
2987 void *cdata = NULL;
2988 const char *p = NULL;
2989#define M_NONE 0
2990#define M_STRUCT 1
2991#define M_ 2
2992 int left, jump;
2993 Eet_Node *node_base = NULL;
2994 Eet_Node *node = NULL;
2995 Eet_Node *n = NULL, *nn = NULL;
2996
2997 /* FIXME; handle parse errors */
2998#define TOK_GET(t) \
2999 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
3000 left = size;
3001 for (p = src; p < (src + size); )
3002 {
3003 char *tok1, *tok2, *tok3, *tok4;
3004
3005 TOK_GET(tok1);
3006 if (tok1)
3007 {
3008 if (!strcmp(tok1, "group"))
3009 {
3010 TOK_GET(tok2);
3011 if (tok2)
3012 {
3013 TOK_GET(tok3);
3014 if (tok3)
3015 {
3016 TOK_GET(tok4);
3017 if (tok4)
3018 {
3019 if (!strcmp(tok4, "{"))
3020 {
3021/* we have 'group NAM TYP {' */
3022 n = eet_node_new();
3023 if (n)
3024 {
3025 n->parent = node;
3026 if (!node_base)
3027 node_base = n;
3028
3029 if (node)
3030 {
3031/* append node */
3032 if (!node->values)
3033 node->values = n;
3034 else
3035 for (nn = node->values; nn;
3036 nn = nn->next)
3037 {
3038 if (!nn->next)
3039 {
3040 nn->next = n;
3041 break;
3042 }
3043 }
3044 }
3045
3046 n->name = eina_stringshare_add(tok2);
3047 if (!strcmp(tok3, "struct"))
3048 n->type = EET_G_UNKNOWN;
3049 else if (!strcmp(tok3, "array"))
3050 n->type = EET_G_ARRAY;
3051 else if (!strcmp(tok3, "var_array"))
3052 n->type = EET_G_VAR_ARRAY;
3053 else if (!strcmp(tok3, "list"))
3054 n->type = EET_G_LIST;
3055 else if (!strcmp(tok3, "hash"))
3056 n->type = EET_G_HASH;
3057 else
3058 ERR(
3059 "ERROR: group type '%s' invalid.",
3060 tok3);
3061
3062 node = n;
3063 }
3064 }
3065
3066 free(tok4);
3067 }
3068
3069 free(tok3);
3070 }
3071
3072 free(tok2);
3073 }
3074 }
3075 else if (!strcmp(tok1, "value"))
3076 {
3077 TOK_GET(tok2);
3078 if (tok2)
3079 {
3080 TOK_GET(tok3);
3081 if (tok3)
3082 {
3083 TOK_GET(tok4);
3084 if (tok4)
3085 {
3086/* we have 'value NAME TYP XXX' */
3087 if (node_base)
3088 {
3089 n = eet_node_new();
3090 if (n)
3091 {
3092 n->parent = node;
3093/* append node */
3094 if (!node->values)
3095 node->values = n;
3096 else
3097 for (nn = node->values; nn;
3098 nn = nn->next)
3099 {
3100 if (!nn->next)
3101 {
3102 nn->next = n;
3103 break;
3104 }
3105 }
3106
3107 n->name = eina_stringshare_add(tok2);
3108 if (!strcmp(tok3, "char:"))
3109 {
3110 n->type = EET_T_CHAR;
3111 sscanf(tok4, FMT_CHAR,
3112 &(n->data.value.c));
3113 }
3114 else if (!strcmp(tok3, "short:"))
3115 {
3116 n->type = EET_T_SHORT;
3117 sscanf(tok4, "%hi",
3118 &(n->data.value.s));
3119 }
3120 else if (!strcmp(tok3, "int:"))
3121 {
3122 n->type = EET_T_INT;
3123 sscanf(tok4, "%i",
3124 &(n->data.value.i));
3125 }
3126 else if (!strcmp(tok3, "long_long:"))
3127 {
3128 n->type = EET_T_LONG_LONG;
3129 sscanf(tok4, FMT_LONG_LONG,
3130 &(n->data.value.l));
3131 }
3132 else if (!strcmp(tok3, "float:"))
3133 {
3134 n->type = EET_T_FLOAT;
3135 sscanf(tok4, "%f",
3136 &(n->data.value.f));
3137 }
3138 else if (!strcmp(tok3, "double:"))
3139 {
3140 n->type = EET_T_DOUBLE;
3141 sscanf(tok4, "%lf",
3142 &(n->data.value.d));
3143 }
3144 else if (!strcmp(tok3, "uchar:"))
3145 {
3146 n->type = EET_T_UCHAR;
3147 sscanf(tok4, FMT_UCHAR,
3148 &(n->data.value.uc));
3149 }
3150 else if (!strcmp(tok3, "ushort:"))
3151 {
3152 n->type = EET_T_USHORT;
3153 sscanf(tok4, "%hu",
3154 &(n->data.value.us));
3155 }
3156 else if (!strcmp(tok3, "uint:"))
3157 {
3158 n->type = EET_T_UINT;
3159 sscanf(tok4, "%u",
3160 &(n->data.value.ui));
3161 }
3162 else if (!strcmp(tok3, "ulong_long:"))
3163 {
3164 n->type = EET_T_ULONG_LONG;
3165 sscanf(tok4, FMT_ULONG_LONG,
3166 &(n->data.value.ul));
3167 }
3168 else if (!strcmp(tok3, "string:"))
3169 {
3170 n->type = EET_T_STRING;
3171 n->data.value.str =
3172 eina_stringshare_add(tok4);
3173 }
3174 else if (!strcmp(tok3, "inlined:"))
3175 {
3176 n->type = EET_T_INLINED_STRING;
3177 n->data.value.str =
3178 eina_stringshare_add(tok4);
3179 }
3180 else if (!strcmp(tok3, "null"))
3181 {
3182 n->type = EET_T_NULL;
3183 n->data.value.str = NULL;
3184 }
3185 else
3186 ERR(
3187 "ERROR: value type '%s' invalid.",
3188 tok4);
3189 }
3190 }
3191
3192 free(tok4);
3193 }
3194
3195 free(tok3);
3196 }
3197
3198 free(tok2);
3199 }
3200 }
3201 else if (!strcmp(tok1, "key"))
3202 {
3203 TOK_GET(tok2);
3204 if (tok2)
3205 {
3206/* we have 'key NAME' */
3207 if (node)
3208 node->key = eina_stringshare_add(tok2);
3209
3210 free(tok2);
3211 }
3212 }
3213 else if (!strcmp(tok1, "count"))
3214 {
3215 TOK_GET(tok2);
3216 if (tok2)
3217 {
3218/* we have a 'count COUNT' */
3219 if (node)
3220 sscanf(tok2, "%i", &(node->count));
3221
3222 free(tok2);
3223 }
3224 }
3225 else if (!strcmp(tok1, "}"))
3226 /* we have an end of the group */
3227 if (node)
3228 node = node->parent;
3229
3230 free(tok1);
3231 }
3232 }
3233
3234 if (node_base)
3235 {
3236 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
3237 eet_node_del(node_base);
3238 }
3239
3240 return cdata;
3241} /* _eet_data_dump_parse */
3242
3243#define NEXT_CHUNK(P, Size, Echnk, Ed) \
3244 { \
3245 int __tmp; \
3246 __tmp = Ed ? (int)(sizeof(int) * 2) : Echnk.len + 4; \
3247 P += (4 + Echnk.size + __tmp); \
3248 Size -= (4 + Echnk.size + __tmp); \
3249 }
3250
3251static void *
3252_eet_data_descriptor_decode(Eet_Free_Context *context,
3253 const Eet_Dictionary *ed,
3254 Eet_Data_Descriptor *edd,
3255 const void *data_in,
3256 int size_in,
3257 void *data_out,
3258 int size_out)
3259{
3260 Eet_Node *result = NULL;
3261 void *data = NULL;
3262 char *p;
3263 int size, i;
3264 Eet_Data_Chunk chnk;
3265
3266 if (_eet_data_words_bigendian == -1)
3267 {
3268 unsigned long int v;
3269
3270 v = htonl(0x12345678);
3271 if (v == 0x12345678)
3272 _eet_data_words_bigendian = 1;
3273 else
3274 _eet_data_words_bigendian = 0;
3275 }
3276
3277 if (edd)
3278 {
3279 if (data_out)
3280 {
3281 if (size_out <= edd->size)
3282 data = data_out;
3283 }
3284 else
3285 {
3286 data = edd->func.mem_alloc(edd->size);
3287 }
3288
3289 if (!data)
3290 return NULL;
3291
3292 if (edd->ed != ed)
3293 {
3294 for (i = 0; i < edd->elements.num; i++)
3295 edd->elements.set[i].directory_name_ptr = NULL;
3296 edd->ed = ed;
3297 }
3298 }
3299
3300 _eet_freelist_all_ref(context);
3301 if (data && !data_out)
3302 _eet_freelist_add(context, data);
3303
3304 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3305 eet_data_chunk_get(ed, &chnk, data_in, size_in);
3306 if (!chnk.name)
3307 goto error;
3308
3309 if (edd)
3310 if (strcmp(chnk.name, edd->name))
3311 goto error;
3312
3313 p = chnk.data;
3314 if (ed)
3315 size = size_in - (4 + sizeof(int) * 2);
3316 else
3317 size = size_in - (4 + 4 + chnk.len);
3318
3319 if (edd)
3320 {
3321 if (!edd->elements.hash.buckets)
3322 _eet_descriptor_hash_new(edd);
3323 }
3324 else
3325 {
3326 switch (chnk.group_type)
3327 {
3328 case EET_G_UNKNOWN:
3329 switch (chnk.type)
3330 {
3331 case EET_T_STRING:
3332 return eet_node_string_new(chnk.name, chnk.data);
3333
3334 case EET_T_INLINED_STRING:
3335 return eet_node_inlined_string_new(chnk.name, chnk.data);
3336
3337 case EET_T_NULL:
3338 return eet_node_null_new(chnk.name);
3339
3340 default:
3341 result = eet_node_struct_new(chnk.name, NULL);
3342 } /* switch */
3343 break;
3344
3345 case EET_G_VAR_ARRAY:
3346 return eet_node_var_array_new(chnk.name, NULL);
3347
3348 case EET_G_LIST:
3349 case EET_G_HASH:
3350 case EET_G_ARRAY:
3351 case EET_G_UNION:
3352 case EET_G_VARIANT:
3353 default:
3354 goto error;
3355 } /* switch */
3356 }
3357
3358 while (size > 0)
3359 {
3360 Eet_Data_Chunk echnk;
3361 Eet_Data_Element *ede = NULL;
3362 Eet_Node *child = NULL;
3363 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
3364 int ret = 0;
3365
3366 /* get next data chunk */
3367 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
3368 eet_data_chunk_get(ed, &echnk, p, size);
3369 if (!echnk.name)
3370 goto error; /* FIXME: don't REPLY on edd - work without */
3371
3372 if (edd)
3373 {
3374 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
3375 if (ede)
3376 {
3377 group_type = ede->group_type;
3378 type = ede->type;
3379 if ((echnk.type == 0) && (echnk.group_type == 0))
3380 {
3381 type = ede->type;
3382 group_type = ede->group_type;
3383 }
3384 else
3385 {
3386 if (IS_SIMPLE_TYPE(echnk.type) &&
3387 eet_data_type_match(echnk.type, ede->type))
3388/* Needed when converting on the fly from FP to Float */
3389 type = ede->type;
3390 else if ((echnk.group_type > EET_G_UNKNOWN) &&
3391 (echnk.group_type < EET_G_LAST) &&
3392 (echnk.group_type == ede->group_type))
3393 group_type = echnk.group_type;
3394 }
3395 }
3396 }
3397 /*...... dump to node */
3398 else
3399 {
3400 type = echnk.type;
3401 group_type = echnk.group_type;
3402 }
3403
3404 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
3405 {
3406 unsigned char dd[128];
3407
3408 ret = eet_data_get_type(ed,
3409 type,
3410 echnk.data,
3411 ((char *)echnk.data) + echnk.size,
3412 dd);
3413 if (ret <= 0)
3414 goto error;
3415
3416 child = eet_data_node_simple_type(type, echnk.name, dd);
3417
3418 eet_node_struct_append(result, echnk.name, child);
3419 }
3420 else
3421 {
3422 ret = eet_group_codec[group_type - 100].get(
3423 context,
3424 ed,
3425 edd,
3426 ede,
3427 &echnk,
3428 type,
3429 group_type,
3430 ede ? (void *)(((char *)data) + ede->offset) : (void **)&result,
3431 &p,
3432 &size);
3433
3434 if (ret <= 0)
3435 goto error;
3436 }
3437
3438 /* advance to next chunk */
3439 NEXT_CHUNK(p, size, echnk, ed);
3440 }
3441
3442 _eet_freelist_all_unref(context);
3443 if (!edd)
3444 {
3445 _eet_freelist_str_free(context, edd);
3446 _eet_freelist_direct_str_free(context, edd);
3447 _eet_freelist_list_free(context, edd);
3448 _eet_freelist_hash_free(context, edd);
3449 _eet_freelist_array_free(context, edd);
3450 _eet_freelist_free(context, edd);
3451 }
3452 else
3453 {
3454 _eet_freelist_reset(context);
3455 _eet_freelist_str_reset(context);
3456 _eet_freelist_list_reset(context);
3457 _eet_freelist_hash_reset(context);
3458 _eet_freelist_direct_str_reset(context);
3459 _eet_freelist_array_reset(context);
3460 }
3461
3462 if (!edd)
3463 return result;
3464
3465 return data;
3466
3467error:
3468 eet_node_del(result);
3469
3470 _eet_freelist_all_unref(context);
3471 _eet_freelist_str_free(context, edd);
3472 _eet_freelist_direct_str_free(context, edd);
3473 _eet_freelist_list_free(context, edd);
3474 _eet_freelist_hash_free(context, edd);
3475 _eet_freelist_array_free(context, edd);
3476 _eet_freelist_free(context, edd);
3477
3478 /* FIXME: Warn that something goes wrong here. */
3479 return NULL;
3480} /* _eet_data_descriptor_decode */
3481
3482static int
3483eet_data_get_list(Eet_Free_Context *context,
3484 const Eet_Dictionary *ed,
3485 Eet_Data_Descriptor *edd,
3486 Eet_Data_Element *ede,
3487 Eet_Data_Chunk *echnk,
3488 int type,
3489 int group_type __UNUSED__,
3490 void *data,
3491 char **p,
3492 int *size)
3493{
3494 Eet_Data_Descriptor *subtype = NULL;
3495 void *list = NULL;
3496 void **ptr;
3497 void *data_ret;
3498
3499 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3500
3501 if (ede)
3502 {
3503 subtype = ede->subtype;
3504
3505 if (type != ede->type)
3506 return 0;
3507 }
3508
3509 ptr = (void **)data;
3510 list = *ptr;
3511 data_ret = NULL;
3512
3513 if (IS_POINTER_TYPE(type))
3514 POINTER_TYPE_DECODE(context,
3515 ed,
3516 edd,
3517 ede,
3518 echnk,
3519 type,
3520 &data_ret,
3521 p,
3522 size,
3523 on_error);
3524 else
3525 STRUCT_TYPE_DECODE(data_ret,
3526 context,
3527 ed,
3528 subtype,
3529 echnk->data,
3530 echnk->size,
3531 -1,
3532 on_error);
3533
3534 if (edd)
3535 {
3536 list = edd->func.list_append(list, data_ret);
3537 *ptr = list;
3538 _eet_freelist_list_add(context, ptr);
3539 }
3540 else
3541 eet_node_list_append(*((Eet_Node **)data), echnk->name, data_ret);
3542
3543 return 1;
3544
3545on_error:
3546 return 0;
3547} /* eet_data_get_list */
3548
3549static int
3550eet_data_get_hash(Eet_Free_Context *context,
3551 const Eet_Dictionary *ed,
3552 Eet_Data_Descriptor *edd,
3553 Eet_Data_Element *ede,
3554 Eet_Data_Chunk *echnk,
3555 int type,
3556 int group_type __UNUSED__,
3557 void *data,
3558 char **p,
3559 int *size)
3560{
3561 void **ptr;
3562 void *hash = NULL;
3563 char *key = NULL;
3564 void *data_ret = NULL;
3565 int ret = 0;
3566
3567 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3568
3569 ptr = (void **)data;
3570 hash = *ptr;
3571
3572 /* Read key */
3573 ret = eet_data_get_type(ed,
3574 EET_T_STRING,
3575 echnk->data,
3576 ((char *)echnk->data) + echnk->size,
3577 &key);
3578 if (ret <= 0)
3579 goto on_error;
3580
3581 if (!key)
3582 goto on_error;
3583
3584 /* Advance to next chunk */
3585 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3586 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3587
3588 /* Read value */
3589 eet_data_chunk_get(ed, echnk, *p, *size);
3590 if (!echnk->name)
3591 goto on_error;
3592
3593 if (ede)
3594 if ((ede->group_type != echnk->group_type)
3595 || (ede->type != echnk->type))
3596 goto on_error;
3597
3598 if (IS_POINTER_TYPE(echnk->type))
3599 POINTER_TYPE_DECODE(context,
3600 ed,
3601 edd,
3602 ede,
3603 echnk,
3604 echnk->type,
3605 &data_ret,
3606 p,
3607 size,
3608 on_error);
3609 else
3610 STRUCT_TYPE_DECODE(data_ret,
3611 context,
3612 ed,
3613 ede ? ede->subtype : NULL,
3614 echnk->data,
3615 echnk->size,
3616 -1,
3617 on_error);
3618
3619 if (edd)
3620 {
3621 hash = edd->func.hash_add(hash, key, data_ret);
3622 *ptr = hash;
3623 _eet_freelist_hash_add(context, hash);
3624 }
3625 else
3626 eet_node_hash_add(*((Eet_Node **)data), echnk->name, key, data_ret);
3627
3628 return 1;
3629
3630on_error:
3631 return 0;
3632} /* eet_data_get_hash */
3633
3634/* var arrays and fixed arrays have to
3635 * get all chunks at once. for fixed arrays
3636 * we can get each chunk and increment a
3637 * counter stored on the element itself but
3638 * it wont be thread safe. for var arrays
3639 * we still need a way to get the number of
3640 * elements from the data, so storing the
3641 * number of elements and the element data on
3642 * each chunk is pointless.
3643 */
3644static int
3645eet_data_get_array(Eet_Free_Context *context,
3646 const Eet_Dictionary *ed,
3647 Eet_Data_Descriptor *edd,
3648 Eet_Data_Element *ede,
3649 Eet_Data_Chunk *echnk,
3650 int type,
3651 int group_type,
3652 void *data,
3653 char **p,
3654 int *size)
3655{
3656 Eina_List *childs = NULL;
3657 const char *name;
3658 Eet_Node *tmp;
3659 void *ptr;
3660 int count;
3661 int ret;
3662 int subsize = 0;
3663 int i;
3664
3665 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3666
3667 ptr = data;
3668 /* read the number of elements */
3669 ret = eet_data_get_type(ed,
3670 EET_T_INT,
3671 echnk->data,
3672 ((char *)echnk->data) + echnk->size,
3673 &count);
3674 if (ret <= 0)
3675 return ret;
3676
3677 name = echnk->name;
3678
3679 if (ede)
3680 {
3681 if (IS_POINTER_TYPE(type))
3682 subsize = eet_basic_codec[ede->type].size;
3683 else
3684 subsize = ede->subtype->size;
3685
3686 if (group_type == EET_G_VAR_ARRAY)
3687 {
3688 /* store the number of elements
3689 * on the counter offset */
3690 *(int *)(((char *)data) + ede->count - ede->offset) = count;
3691 /* allocate space for the array of elements */
3692 if (edd->func.array_alloc)
3693 *(void **)ptr = edd->func.array_alloc(count * subsize);
3694 else
3695 *(void **)ptr = edd->func.mem_alloc(count * subsize);
3696
3697 if (!*(void **)ptr)
3698 return 0;
3699
3700 memset(*(void **)ptr, 0, count * subsize);
3701
3702 _eet_freelist_array_add(context, *(void **)ptr);
3703 }
3704 }
3705
3706 /* get all array elements */
3707 for (i = 0; i < count; i++)
3708 {
3709 void *dst = NULL;
3710
3711 /* Advance to next chunk */
3712 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3713 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3714
3715 eet_data_chunk_get(ed, echnk, *p, *size);
3716 if (!echnk->name || strcmp(echnk->name, name) != 0)
3717 goto on_error; /* get the data */
3718
3719 if ((echnk->group_type != group_type)
3720 || ((echnk->type != type) && (echnk->type != EET_T_NULL)))
3721 goto on_error;
3722
3723 if (ede)
3724 if ((ede->group_type != echnk->group_type)
3725 || ((echnk->type != ede->type) && (echnk->type != EET_T_NULL)))
3726 goto on_error;
3727
3728 /* get the destination pointer */
3729 if (ede)
3730 {
3731 if (group_type == EET_G_ARRAY)
3732 dst = (char *)ptr + (subsize * i);
3733 else
3734 dst = *(char **)ptr + (subsize * i);
3735 }
3736
3737 if (IS_POINTER_TYPE(echnk->type))
3738 {
3739 void *data_ret = NULL;
3740
3741 POINTER_TYPE_DECODE(context,
3742 ed,
3743 edd,
3744 ede,
3745 echnk,
3746 echnk->type,
3747 &data_ret,
3748 p,
3749 size,
3750 on_error);
3751 if (dst)
3752 memcpy(dst, &data_ret, subsize);
3753
3754 if (!edd)
3755 childs = eina_list_append(childs, data_ret);
3756 }
3757 else
3758 {
3759 STRUCT_TYPE_DECODE(dst,
3760 context,
3761 ed,
3762 ede ? ede->subtype : NULL,
3763 echnk->data,
3764 echnk->size,
3765 subsize,
3766 on_error);
3767
3768 if (!edd)
3769 childs = eina_list_append(childs, dst);
3770 }
3771 }
3772
3773 if (!edd)
3774 {
3775 Eet_Node *parent = *((Eet_Node **)data);
3776 Eet_Node *array;
3777
3778 if (group_type == EET_G_ARRAY)
3779 array = eet_node_array_new(name, count, childs);
3780 else
3781 array = eet_node_var_array_new(name, childs);
3782
3783 if (!array)
3784 goto on_error;
3785
3786 eet_node_struct_append(parent, name, array);
3787 }
3788
3789 return 1;
3790
3791on_error:
3792 EINA_LIST_FREE(childs, tmp)
3793 eet_node_del(tmp);
3794
3795 return 0;
3796} /* eet_data_get_array */
3797
3798static void
3799eet_data_put_union(Eet_Dictionary *ed,
3800 Eet_Data_Descriptor *edd __UNUSED__,
3801 Eet_Data_Element *ede,
3802 Eet_Data_Stream *ds,
3803 void *data_in)
3804{
3805 const char *union_type;
3806 int i;
3807
3808 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3809
3810 union_type = ede->subtype->func.type_get(
3811 ((char *)data_in) + ede->count - ede->offset,
3812 NULL);
3813
3814 if (!union_type)
3815 return;
3816
3817 /* Search the structure of the union to encode. */
3818 for (i = 0; i < ede->subtype->elements.num; ++i)
3819 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3820 {
3821 Eet_Data_Element *sede;
3822 void *data;
3823 int size;
3824
3825 /* Yeah we found it ! */
3826 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3827 if (data)
3828 eet_data_encode(ed,
3829 ds,
3830 data,
3831 ede->name,
3832 size,
3833 ede->type,
3834 ede->group_type);
3835
3836 sede = &(ede->subtype->elements.set[i]);
3837 data = _eet_data_descriptor_encode(ed,
3838 sede->subtype,
3839 data_in,
3840 &size);
3841 if (data)
3842 eet_data_encode(ed,
3843 ds,
3844 data,
3845 ede->name,
3846 size,
3847 ede->type,
3848 ede->group_type);
3849
3850 break;
3851 }
3852} /* eet_data_put_union */
3853
3854static int
3855eet_data_get_union(Eet_Free_Context *context,
3856 const Eet_Dictionary *ed,
3857 Eet_Data_Descriptor *edd __UNUSED__,
3858 Eet_Data_Element *ede,
3859 Eet_Data_Chunk *echnk,
3860 int type,
3861 int group_type,
3862 void *data,
3863 char **p,
3864 int *size)
3865{
3866 const char *union_type;
3867 void *data_ret = NULL;
3868 int ret = 0;
3869 int i;
3870
3871 /* Read type */
3872 ret = eet_data_get_type(ed,
3873 EET_T_STRING,
3874 echnk->data,
3875 ((char *)echnk->data) + echnk->size,
3876 &union_type);
3877 if (ret <= 0)
3878 goto on_error;
3879
3880 /* Advance to next chunk */
3881 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3882 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3883
3884 /* Read value */
3885 eet_data_chunk_get(ed, echnk, *p, *size);
3886 if (!echnk->name)
3887 goto on_error;
3888
3889 if (ede)
3890 {
3891 EET_ASSERT(!(ede->group_type != group_type || ede->type != type),
3892 goto on_error);
3893
3894 /* Search the structure of the union to decode */
3895 for (i = 0; i < ede->subtype->elements.num; ++i)
3896 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3897 {
3898 Eet_Data_Element *sede;
3899 char *ut;
3900
3901 /* Yeah we found it ! */
3902 sede = &(ede->subtype->elements.set[i]);
3903 EET_ASSERT(sede->subtype, goto on_error);
3904
3905 data_ret = _eet_data_descriptor_decode(context,
3906 ed,
3907 sede->subtype,
3908 echnk->data,
3909 echnk->size,
3910 data,
3911 sede->subtype->size);
3912 if (!data_ret)
3913 goto on_error;
3914
3915 /* Set union type. */
3916 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3917 {
3918 ut = ede->subtype->func.str_alloc(union_type);
3919 _eet_freelist_str_add(context, ut);
3920 }
3921 else
3922 {
3923 ut = ede->subtype->func.str_direct_alloc(union_type);
3924 _eet_freelist_direct_str_add(context, ut);
3925 }
3926
3927 ede->subtype->func.type_set(
3928 ut,
3929 ((char *)data) + ede->count -
3930 ede->offset,
3931 EINA_FALSE);
3932
3933 break;
3934 }
3935 }
3936 else
3937 {
3938 /* FIXME: generate node structure. */
3939 data_ret = _eet_data_descriptor_decode(context,
3940 ed, NULL,
3941 echnk->data, echnk->size,
3942 NULL, 0);
3943 goto on_error;
3944 }
3945
3946 return 1;
3947
3948on_error:
3949 return 0;
3950} /* eet_data_get_union */
3951
3952static void
3953eet_data_put_variant(Eet_Dictionary *ed,
3954 Eet_Data_Descriptor *edd __UNUSED__,
3955 Eet_Data_Element *ede,
3956 Eet_Data_Stream *ds,
3957 void *data_in)
3958{
3959 const char *union_type;
3960 void *data;
3961 Eina_Bool unknow = EINA_FALSE;
3962 int size;
3963 int i;
3964
3965 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3966
3967 union_type = ede->subtype->func.type_get(
3968 ((char *)data_in) + ede->count - ede->offset,
3969 &unknow);
3970
3971 if (!union_type && unknow == EINA_FALSE)
3972 return;
3973
3974 if (unknow)
3975 {
3976 /* Handle opaque internal representation */
3977 Eet_Variant_Unknow *evu;
3978
3979 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3980 if (data)
3981 eet_data_encode(ed,
3982 ds,
3983 data,
3984 ede->name,
3985 size,
3986 ede->type,
3987 ede->group_type);
3988
3989 evu = (Eet_Variant_Unknow *)data_in;
3990 if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT))
3991 eet_data_encode(ed,
3992 ds,
3993 evu->data,
3994 ede->name,
3995 evu->size,
3996 ede->type,
3997 ede->group_type);
3998 }
3999 else
4000 /* Search the structure of the union to encode. */
4001 for (i = 0; i < ede->subtype->elements.num; ++i)
4002 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
4003 {
4004 Eet_Data_Element *sede;
4005
4006 /* Yeah we found it ! */
4007 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
4008 if (data)
4009 eet_data_encode(ed,
4010 ds,
4011 data,
4012 ede->name,
4013 size,
4014 ede->type,
4015 ede->group_type);
4016
4017 sede = &(ede->subtype->elements.set[i]);
4018
4019 if (sede->group_type != EET_G_UNKNOWN)
4020 {
4021 Eet_Data_Stream *lds;
4022
4023 lds = eet_data_stream_new();
4024 eet_group_codec[sede->group_type - 100].put(ed,
4025 sede->subtype,
4026 sede,
4027 lds,
4028 data_in);
4029 if (lds->size != 0)
4030 {
4031 eet_data_encode(ed, ds, lds->data, ede->name, lds->pos,
4032 ede->type, ede->group_type);
4033
4034 lds->data = NULL;
4035 lds->size = 0;
4036 }
4037 else
4038 eet_data_encode(ed, ds, NULL, ede->name, 0,
4039 EET_T_NULL, ede->group_type);
4040
4041 eet_data_stream_free(lds);
4042 }
4043 else
4044 {
4045 data = _eet_data_descriptor_encode(ed,
4046 sede->subtype,
4047 *(void **)data_in,
4048 &size);
4049 if (data)
4050 eet_data_encode(ed,
4051 ds,
4052 data,
4053 ede->name,
4054 size,
4055 ede->type,
4056 ede->group_type);
4057 }
4058
4059 break;
4060 }
4061} /* eet_data_put_variant */
4062
4063static int
4064eet_data_get_variant(Eet_Free_Context *context,
4065 const Eet_Dictionary *ed,
4066 Eet_Data_Descriptor *edd __UNUSED__,
4067 Eet_Data_Element *ede,
4068 Eet_Data_Chunk *echnk,
4069 int type __UNUSED__,
4070 int group_type __UNUSED__,
4071 void *data,
4072 char **p,
4073 int *size)
4074{
4075 const char *union_type;
4076 void *data_ret = NULL;
4077 int ret = 0;
4078 int i;
4079
4080 /* Read type */
4081 ret = eet_data_get_type(ed,
4082 EET_T_STRING,
4083 echnk->data,
4084 ((char *)echnk->data) + echnk->size,
4085 &union_type);
4086 if (ret <= 0)
4087 goto on_error;
4088
4089 /* Advance to next chunk */
4090 NEXT_CHUNK((*p), (*size), (*echnk), ed);
4091 memset(echnk, 0, sizeof(Eet_Data_Chunk));
4092
4093 /* Read value */
4094 eet_data_chunk_get(ed, echnk, *p, *size);
4095 if (!echnk->name)
4096 goto on_error;
4097
4098 if (ede)
4099 {
4100 char *ut;
4101
4102 EET_ASSERT(ede->subtype, goto on_error);
4103
4104 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
4105 {
4106 ut = ede->subtype->func.str_alloc(union_type);
4107 _eet_freelist_str_add(context, ut);
4108 }
4109 else
4110 {
4111 ut = ede->subtype->func.str_direct_alloc(union_type);
4112 _eet_freelist_direct_str_add(context, ut);
4113 }
4114
4115 /* Search the structure of the union to decode */
4116 for (i = 0; i < ede->subtype->elements.num; ++i)
4117 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
4118 {
4119 Eet_Data_Element *sede;
4120
4121 /* Yeah we found it ! */
4122 sede = &(ede->subtype->elements.set[i]);
4123
4124 if (sede->group_type != EET_G_UNKNOWN)
4125 {
4126 Eet_Data_Chunk chnk;
4127 char *p2;
4128 int size2;
4129
4130 p2 = echnk->data;
4131 size2 = echnk->size;
4132
4133 /* Didn't find a proper way to provide this
4134 without duplicating code */
4135 while (size2 > 0)
4136 {
4137 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
4138 eet_data_chunk_get(ed, &chnk, p2, size2);
4139
4140 if (!chnk.name)
4141 goto on_error;
4142
4143 ret = eet_group_codec[sede->group_type - 100].get
4144 (context, ed, sede->subtype, sede, &chnk, sede->type,
4145 sede->group_type, data, &p2, &size2);
4146
4147 if (ret <= 0)
4148 goto on_error;
4149
4150/* advance to next chunk */
4151 NEXT_CHUNK(p2, size2, chnk, ed);
4152 }
4153
4154 /* Put garbage so that we will not put eet_variant_unknow in it */
4155 data_ret = (void *)data;
4156
4157 /* Set variant type. */
4158 ede->subtype->func.type_set
4159 (ut, ((char *)data) + ede->count - ede->offset,
4160 EINA_FALSE);
4161 break;
4162 }
4163
4164 data_ret = _eet_data_descriptor_decode(context,
4165 ed,
4166 sede->subtype,
4167 echnk->data,
4168 echnk->size,
4169 NULL, 0);
4170 if (!data_ret)
4171 break;
4172
4173 /* And point to the variant data. */
4174 *(void **)data = data_ret;
4175
4176 /* Set variant type. */
4177 ede->subtype->func.type_set
4178 (ut, ((char *)data) + ede->count - ede->offset, EINA_FALSE);
4179 break;
4180 }
4181
4182 if (!data_ret)
4183 {
4184 Eet_Variant_Unknow *evu;
4185
4186 evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1);
4187 if (!evu)
4188 goto on_error;
4189
4190 evu->size = echnk->size;
4191 memcpy(evu->data, echnk->data, evu->size);
4192 EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT);
4193
4194 /* And point to the opaque internal data scructure */
4195 *(void **)data = evu;
4196
4197 /* Set variant type. */
4198 ede->subtype->func.type_set
4199 (ut, ((char *)data) + ede->count - ede->offset, EINA_TRUE);
4200 }
4201 }
4202 else
4203 {
4204 /* FIXME: dump node structure. */
4205 data_ret = _eet_data_descriptor_decode(context,
4206 ed, NULL,
4207 echnk->data, echnk->size,
4208 NULL, 0);
4209 goto on_error;
4210 }
4211
4212 return 1;
4213
4214on_error:
4215 return 0;
4216} /* eet_data_get_variant */
4217
4218static Eet_Node *
4219eet_data_node_simple_type(int type,
4220 const char *name,
4221 void *dd)
4222{
4223#ifdef EET_T_TYPE
4224# undef EET_T_TYPE
4225#endif /* ifdef EET_T_TYPE */
4226
4227#define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type) \
4228case Eet_Type: \
4229 return eet_node_ ## Eet_Node_Type ## _new(name, *((Type *)dd)); \
4230
4231 switch (type)
4232 {
4233 EET_T_TYPE(EET_T_CHAR, char, char);
4234 EET_T_TYPE(EET_T_SHORT, short, short);
4235 EET_T_TYPE(EET_T_INT, int, int);
4236 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
4237 EET_T_TYPE(EET_T_FLOAT, float, float);
4238 EET_T_TYPE(EET_T_DOUBLE, double, double);
4239 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
4240 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
4241 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
4242 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
4243 EET_T_TYPE(EET_T_STRING, string, char *);
4244 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char *);
4245
4246 case EET_T_NULL:
4247 return eet_node_null_new(name);
4248
4249 default:
4250 ERR("Unknow type passed to eet_data_node_simple_type");
4251 return NULL;
4252 } /* switch */
4253} /* eet_data_node_simple_type */
4254
4255static int
4256eet_data_get_unknown(Eet_Free_Context *context,
4257 const Eet_Dictionary *ed,
4258 Eet_Data_Descriptor *edd,
4259 Eet_Data_Element *ede,
4260 Eet_Data_Chunk *echnk,
4261 int type,
4262 int group_type __UNUSED__,
4263 void *data,
4264 char **p __UNUSED__,
4265 int *size __UNUSED__)
4266{
4267 int ret;
4268 void *data_ret;
4269
4270 if (IS_SIMPLE_TYPE(type))
4271 {
4272 unsigned char dd[128];
4273
4274 ret = eet_data_get_type(ed,
4275 type,
4276 echnk->data,
4277 ((char *)echnk->data) + echnk->size,
4278 edd ? (char *)data : (char *)dd);
4279 if (ret <= 0)
4280 return ret;
4281
4282 if (!edd)
4283 {
4284 Eet_Node **parent = data;
4285 Eet_Node *node;
4286
4287 node = eet_data_node_simple_type(type, echnk->name, dd);
4288
4289 if (*parent)
4290 eet_node_struct_append(*parent, echnk->name, node);
4291 else
4292 *parent = node;
4293 }
4294 else
4295 {
4296 if (type == EET_T_STRING)
4297 {
4298 char **str;
4299
4300 str = (char **)(((char *)data));
4301 if (*str)
4302 {
4303 if ((!ed) || (!edd->func.str_direct_alloc))
4304 {
4305 *str = edd->func.str_alloc(*str);
4306 _eet_freelist_str_add(context, *str);
4307 }
4308 else
4309 {
4310 *str = edd->func.str_direct_alloc(*str);
4311 _eet_freelist_direct_str_add(context, *str);
4312 }
4313 }
4314 }
4315 else if (edd && type == EET_T_INLINED_STRING)
4316 {
4317 char **str;
4318
4319 str = (char **)(((char *)data));
4320 if (*str)
4321 {
4322 *str = edd->func.str_alloc(*str);
4323 _eet_freelist_str_add(context, *str);
4324 }
4325 }
4326 }
4327 }
4328 else
4329 {
4330 Eet_Data_Descriptor *subtype;
4331
4332 subtype = ede ? ede->subtype : NULL;
4333
4334 if (subtype || !edd)
4335 {
4336 Eet_Node **parent = data;
4337 void **ptr;
4338
4339 data_ret = _eet_data_descriptor_decode(context,
4340 ed,
4341 subtype,
4342 echnk->data,
4343 echnk->size,
4344 NULL, 0);
4345 if (!data_ret)
4346 return 0;
4347
4348 if (edd)
4349 {
4350 ptr = (void **)(((char *)data));
4351 *ptr = (void *)data_ret;
4352 }
4353 else
4354 {
4355 Eet_Node *node = data_ret;
4356
4357 if (*parent)
4358 {
4359 node = eet_node_struct_child_new(echnk->name, node);
4360 eet_node_struct_append(*parent, echnk->name, node);
4361 }
4362 else
4363 *parent = node;
4364 }
4365 }
4366 }
4367
4368 return 1;
4369} /* eet_data_get_unknown */
4370
4371static void
4372eet_data_put_array(Eet_Dictionary *ed,
4373 Eet_Data_Descriptor *edd __UNUSED__,
4374 Eet_Data_Element *ede,
4375 Eet_Data_Stream *ds,
4376 void *data_in)
4377{
4378 void *data;
4379 int offset = 0;
4380 int subsize;
4381 int count;
4382 int size;
4383 int j;
4384
4385 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)),
4386 return );
4387
4388 if (ede->group_type == EET_G_ARRAY)
4389 count = ede->counter_offset;
4390 else
4391 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
4392
4393 if (count <= 0)
4394 return; /* Store number of elements */
4395
4396 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
4397 if (data)
4398 eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
4399
4400 if (IS_POINTER_TYPE(ede->type))
4401 subsize = eet_basic_codec[ede->type].size;
4402 else
4403 subsize = ede->subtype->size;
4404
4405 for (j = 0; j < count; j++)
4406 {
4407 void *d;
4408 int pos = ds->pos;
4409
4410 if (ede->group_type == EET_G_ARRAY)
4411 d = (void *)(((char *)data_in) + offset);
4412 else
4413 d = *(((char **)data_in)) + offset;
4414
4415 if (IS_POINTER_TYPE(ede->type))
4416 {
4417 if (*(char **)d)
4418 eet_data_put_unknown(ed, NULL, ede, ds, d);
4419 }
4420 else
4421 {
4422 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
4423 if (data)
4424 eet_data_encode(ed,
4425 ds,
4426 data,
4427 ede->name,
4428 size,
4429 ede->type,
4430 ede->group_type);
4431 }
4432
4433 if (pos == ds->pos)
4434 /* Add a NULL element just to have the correct array layout. */
4435 eet_data_encode(ed,
4436 ds,
4437 NULL,
4438 ede->name,
4439 0,
4440 EET_T_NULL,
4441 ede->group_type);
4442
4443 offset += subsize;
4444 }
4445} /* eet_data_put_array */
4446
4447static void
4448eet_data_put_unknown(Eet_Dictionary *ed,
4449 Eet_Data_Descriptor *edd __UNUSED__,
4450 Eet_Data_Element *ede,
4451 Eet_Data_Stream *ds,
4452 void *data_in)
4453{
4454 void *data = NULL;
4455 int size;
4456
4457 if (IS_SIMPLE_TYPE(ede->type))
4458 data = eet_data_put_type(ed, ede->type, data_in, &size);
4459 else if (ede->subtype)
4460 if (*((char **)data_in))
4461 data = _eet_data_descriptor_encode(ed,
4462 ede->subtype,
4463 *((char **)((char *)(data_in))),
4464 &size);
4465
4466 if (data)
4467 eet_data_encode(ed,
4468 ds,
4469 data,
4470 ede->name,
4471 size,
4472 ede->type,
4473 ede->group_type);
4474} /* eet_data_put_unknown */
4475
4476static void
4477eet_data_put_list(Eet_Dictionary *ed,
4478 Eet_Data_Descriptor *edd,
4479 Eet_Data_Element *ede,
4480 Eet_Data_Stream *ds,
4481 void *data_in)
4482{
4483 void *data;
4484 void *l;
4485 int size;
4486
4487 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
4488 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
4489 return );
4490
4491 l = *((void **)(((char *)data_in)));
4492 for (; l; l = edd->func.list_next(l))
4493 {
4494 if (IS_POINTER_TYPE(ede->type))
4495 {
4496 const void *str = edd->func.list_data(l);
4497 eet_data_put_unknown(ed, NULL, ede, ds, &str);
4498 }
4499 else
4500 {
4501 data = _eet_data_descriptor_encode(ed,
4502 ede->subtype,
4503 edd->func.list_data(l),
4504 &size);
4505 if (data)
4506 eet_data_encode(ed,
4507 ds,
4508 data,
4509 ede->name,
4510 size,
4511 ede->type,
4512 ede->group_type);
4513 }
4514 }
4515} /* eet_data_put_list */
4516
4517static void
4518eet_data_put_hash(Eet_Dictionary *ed,
4519 Eet_Data_Descriptor *edd,
4520 Eet_Data_Element *ede,
4521 Eet_Data_Stream *ds,
4522 void *data_in)
4523{
4524 Eet_Data_Encode_Hash_Info fdata;
4525 void *l;
4526
4527 l = *((void **)(((char *)data_in)));
4528 fdata.ds = ds;
4529 fdata.ede = ede;
4530 fdata.ed = ed;
4531 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
4532} /* eet_data_put_hash */
4533
4534EAPI int
4535eet_data_dump_cipher(Eet_File *ef,
4536 const char *name,
4537 const char *cipher_key,
4538 Eet_Dump_Callback dumpfunc,
4539 void *dumpdata)
4540{
4541 const Eet_Dictionary *ed = NULL;
4542 const void *data = NULL;
4543 Eet_Node *result;
4544 Eet_Free_Context context;
4545 int required_free = 0;
4546 int size;
4547
4548 ed = eet_dictionary_get(ef);
4549
4550 if (!cipher_key)
4551 data = eet_read_direct(ef, name, &size);
4552
4553 if (!data)
4554 {
4555 required_free = 1;
4556 data = eet_read_cipher(ef, name, &size, cipher_key);
4557 if (!data)
4558 return 0;
4559 }
4560
4561 eet_free_context_init(&context);
4562 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0);
4563 eet_free_context_shutdown(&context);
4564
4565 eet_node_dump(result, 0, dumpfunc, dumpdata);
4566
4567 eet_node_del(result);
4568
4569 if (required_free)
4570 free((void *)data);
4571
4572 return result ? 1 : 0;
4573} /* eet_data_dump_cipher */
4574
4575EAPI int
4576eet_data_dump(Eet_File *ef,
4577 const char *name,
4578 Eet_Dump_Callback dumpfunc,
4579 void *dumpdata)
4580{
4581 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
4582} /* eet_data_dump */
4583
4584EAPI int
4585eet_data_text_dump_cipher(const void *data_in,
4586 const char *cipher_key,
4587 int size_in,
4588 Eet_Dump_Callback dumpfunc,
4589 void *dumpdata)
4590{
4591 void *ret = NULL;
4592 Eet_Node *result;
4593 Eet_Free_Context context;
4594 unsigned int ret_len = 0;
4595
4596 if (!data_in)
4597 return 0;
4598
4599 if (cipher_key)
4600 {
4601 if (eet_decipher(data_in, size_in, cipher_key,
4602 strlen(cipher_key), &ret, &ret_len))
4603 {
4604 if (ret)
4605 free(ret);
4606
4607 return 0;
4608 }
4609 }
4610 else
4611 {
4612 ret = (void *)data_in;
4613 ret_len = size_in;
4614 }
4615
4616 eet_free_context_init(&context);
4617 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len, NULL, 0);
4618 eet_free_context_shutdown(&context);
4619
4620 eet_node_dump(result, 0, dumpfunc, dumpdata);
4621
4622 eet_node_del(result);
4623 if (cipher_key)
4624 free(ret);
4625
4626 return result ? 1 : 0;
4627} /* eet_data_text_dump_cipher */
4628
4629EAPI int
4630eet_data_text_dump(const void *data_in,
4631 int size_in,
4632 Eet_Dump_Callback dumpfunc,
4633 void *dumpdata)
4634{
4635 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
4636} /* eet_data_text_dump */
4637
4638EAPI void *
4639eet_data_text_undump_cipher(const char *text,
4640 const char *cipher_key,
4641 int textlen,
4642 int *size_ret)
4643{
4644 void *ret = NULL;
4645
4646 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
4647 if (ret && cipher_key)
4648 {
4649 void *ciphered = NULL;
4650 unsigned int ciphered_len;
4651
4652 if (eet_cipher(ret, *size_ret, cipher_key,
4653 strlen(cipher_key), &ciphered, &ciphered_len))
4654 {
4655 if (ciphered)
4656 free(ciphered);
4657
4658 size_ret = 0;
4659 free(ret);
4660 return NULL;
4661 }
4662
4663 free(ret);
4664 *size_ret = ciphered_len;
4665 ret = ciphered;
4666 }
4667
4668 return ret;
4669} /* eet_data_text_undump_cipher */
4670
4671EAPI void *
4672eet_data_text_undump(const char *text,
4673 int textlen,
4674 int *size_ret)
4675{
4676 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
4677} /* eet_data_text_undump */
4678
4679EAPI int
4680eet_data_undump_cipher(Eet_File *ef,
4681 const char *name,
4682 const char *cipher_key,
4683 const char *text,
4684 int textlen,
4685 int compress)
4686{
4687 Eet_Dictionary *ed;
4688 void *data_enc;
4689 int size;
4690 int val;
4691
4692 ed = eet_dictionary_get(ef);
4693
4694 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
4695 if (!data_enc)
4696 return 0;
4697
4698 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4699 free(data_enc);
4700 return val;
4701} /* eet_data_undump_cipher */
4702
4703EAPI int
4704eet_data_undump(Eet_File *ef,
4705 const char *name,
4706 const char *text,
4707 int textlen,
4708 int compress)
4709{
4710 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
4711} /* eet_data_undump */
4712
4713EAPI void *
4714eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
4715 const void *data_in,
4716 const char *cipher_key,
4717 int size_in)
4718{
4719 void *deciphered = (void *)data_in;
4720 void *ret;
4721 Eet_Free_Context context;
4722 unsigned int deciphered_len = size_in;
4723
4724 if (cipher_key && data_in)
4725 if (eet_decipher(data_in, size_in, cipher_key,
4726 strlen(cipher_key), &deciphered, &deciphered_len))
4727 {
4728 if (deciphered)
4729 free(deciphered);
4730
4731 return NULL;
4732 }
4733
4734 eet_free_context_init(&context);
4735 ret = _eet_data_descriptor_decode(&context,
4736 NULL,
4737 edd,
4738 deciphered,
4739 deciphered_len,
4740 NULL, 0);
4741 eet_free_context_shutdown(&context);
4742
4743 if (data_in != deciphered)
4744 free(deciphered);
4745
4746 return ret;
4747} /* eet_data_descriptor_decode_cipher */
4748
4749EAPI void *
4750eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
4751 const void *data_in,
4752 int size_in)
4753{
4754 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
4755} /* eet_data_descriptor_decode */
4756
4757EAPI Eet_Node *
4758eet_data_node_decode_cipher(const void *data_in,
4759 const char *cipher_key,
4760 int size_in)
4761{
4762 void *deciphered = (void *)data_in;
4763 Eet_Node *ret;
4764 Eet_Free_Context context;
4765 unsigned int deciphered_len = size_in;
4766
4767 if (cipher_key && data_in)
4768 if (eet_decipher(data_in, size_in, cipher_key,
4769 strlen(cipher_key), &deciphered, &deciphered_len))
4770 {
4771 if (deciphered)
4772 free(deciphered);
4773
4774 return NULL;
4775 }
4776
4777 eet_free_context_init(&context);
4778 ret = _eet_data_descriptor_decode(&context,
4779 NULL,
4780 NULL,
4781 deciphered,
4782 deciphered_len,
4783 NULL, 0);
4784 eet_free_context_shutdown(&context);
4785
4786 if (data_in != deciphered)
4787 free(deciphered);
4788
4789 return ret;
4790} /* eet_data_node_decode_cipher */
4791
4792static void *
4793_eet_data_descriptor_encode(Eet_Dictionary *ed,
4794 Eet_Data_Descriptor *edd,
4795 const void *data_in,
4796 int *size_ret)
4797{
4798 Eet_Data_Stream *ds;
4799 Eet_Data_Chunk *chnk;
4800 void *cdata;
4801 int csize;
4802 int i;
4803
4804 if (_eet_data_words_bigendian == -1)
4805 {
4806 unsigned long int v;
4807
4808 v = htonl(0x12345678);
4809 if (v == 0x12345678)
4810 _eet_data_words_bigendian = 1;
4811 else
4812 _eet_data_words_bigendian = 0;
4813 }
4814
4815 ds = eet_data_stream_new();
4816 for (i = 0; i < edd->elements.num; i++)
4817 {
4818 Eet_Data_Element *ede;
4819
4820 ede = &(edd->elements.set[i]);
4821 eet_group_codec[ede->group_type - 100].put(
4822 ed,
4823 edd,
4824 ede,
4825 ds,
4826 ((char *)data_in) +
4827 ede->offset);
4828 }
4829 chnk = eet_data_chunk_new(ds->data,
4830 ds->pos,
4831 edd->name,
4832 EET_T_UNKNOW,
4833 EET_G_UNKNOWN);
4834 ds->data = NULL;
4835 ds->size = 0;
4836 eet_data_stream_free(ds);
4837
4838 ds = eet_data_stream_new();
4839 eet_data_chunk_put(ed, chnk, ds);
4840 cdata = ds->data;
4841 csize = ds->pos;
4842
4843 ds->data = NULL;
4844 ds->size = 0;
4845 eet_data_stream_free(ds);
4846 *size_ret = csize;
4847
4848 free(chnk->data);
4849 eet_data_chunk_free(chnk);
4850
4851 return cdata;
4852} /* _eet_data_descriptor_encode */
4853
4854EAPI int
4855eet_data_node_write_cipher(Eet_File *ef,
4856 const char *name,
4857 const char *cipher_key,
4858 Eet_Node *node,
4859 int compress)
4860{
4861 Eet_Dictionary *ed;
4862 void *data_enc;
4863 int size;
4864 int val;
4865
4866 ed = eet_dictionary_get(ef);
4867
4868 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
4869 if (!data_enc)
4870 return 0;
4871
4872 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4873 free(data_enc);
4874 return val;
4875} /* eet_data_node_write_cipher */
4876
4877EAPI void *
4878eet_data_node_encode_cipher(Eet_Node *node,
4879 const char *cipher_key,
4880 int *size_ret)
4881{
4882 void *ret = NULL;
4883 void *ciphered = NULL;
4884 unsigned int ciphered_len = 0;
4885 int size;
4886
4887 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
4888 if (cipher_key && ret)
4889 {
4890 if (eet_cipher(ret, size, cipher_key,
4891 strlen(cipher_key), &ciphered, &ciphered_len))
4892 {
4893 if (ciphered)
4894 free(ciphered);
4895
4896 if (size_ret)
4897 *size_ret = 0;
4898
4899 free(ret);
4900 return NULL;
4901 }
4902
4903 free(ret);
4904 size = (int)ciphered_len;
4905 ret = ciphered;
4906 }
4907
4908 if (size_ret)
4909 *size_ret = size;
4910
4911 return ret;
4912} /* eet_data_node_encode_cipher */
4913
4914EAPI void *
4915eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
4916 const void *data_in,
4917 const char *cipher_key,
4918 int *size_ret)
4919{
4920 void *ret = NULL;
4921 void *ciphered = NULL;
4922 unsigned int ciphered_len = 0;
4923 int size;
4924
4925 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
4926 if (cipher_key && ret)
4927 {
4928 if (eet_cipher(ret, size, cipher_key,
4929 strlen(cipher_key), &ciphered, &ciphered_len))
4930 {
4931 if (ciphered)
4932 free(ciphered);
4933
4934 if (size_ret)
4935 *size_ret = 0;
4936
4937 free(ret);
4938 return NULL;
4939 }
4940
4941 free(ret);
4942 size = ciphered_len;
4943 ret = ciphered;
4944 }
4945
4946 if (size_ret)
4947 *size_ret = size;
4948
4949 return ret;
4950} /* eet_data_descriptor_encode_cipher */
4951
4952EAPI void *
4953eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
4954 const void *data_in,
4955 int *size_ret)
4956{
4957 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);
4958} /* eet_data_descriptor_encode */
4959
4960EAPI void *
4961eet_data_xattr_cipher_get(const char *filename,
4962 const char *attribute,
4963 Eet_Data_Descriptor *edd,
4964 const char *cipher_key)
4965{
4966 void *blob;
4967 void *ret;
4968 ssize_t size;
4969
4970 blob = eina_xattr_get(filename, attribute, &size);
4971 if (!blob) return NULL;
4972
4973 ret = eet_data_descriptor_decode_cipher(edd, blob, cipher_key, size);
4974 free(blob);
4975
4976 return ret;
4977}
4978
4979EAPI Eina_Bool
4980eet_data_xattr_cipher_set(const char *filename,
4981 const char *attribute,
4982 Eet_Data_Descriptor *edd,
4983 const char *cipher_key,
4984 const void *data,
4985 Eina_Xattr_Flags flags)
4986{
4987 void *blob;
4988 int size;
4989 Eina_Bool ret;
4990
4991 blob = eet_data_descriptor_encode_cipher(edd, data, cipher_key, &size);
4992 if (!blob) return EINA_FALSE;
4993
4994 ret = eina_xattr_set(filename, attribute, blob, size, flags);
4995 free(blob);
4996
4997 return ret;
4998}
4999