2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
10 #define __UNUSED__ __attribute__((unused))
21 #ifdef HAVE_NETINET_IN_H
22 # include <netinet/in.h>
25 #if defined(_WIN32) && ! defined(__CEGCC__)
26 # include <winsock2.h>
32 #include "Eet_private.h"
35 * routines for doing data -> struct and struct -> data conversion
55 * multiple entries ordered as...
57 * fixed size array [ of basic types ]
58 * variable size array [ of basic types ]
59 * linked list [ of basic types ]
60 * hash table [ of basic types ]
62 * need to provide builder/accessor funcs for:
74 typedef struct _Eet_Data_Element Eet_Data_Element;
75 typedef struct _Eet_Data_Basic_Type_Codec Eet_Data_Basic_Type_Codec;
76 typedef struct _Eet_Data_Group_Type_Codec Eet_Data_Group_Type_Codec;
77 typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
78 typedef struct _Eet_Data_Stream Eet_Data_Stream;
79 typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash;
80 typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info;
81 typedef struct _Eet_Free Eet_Free;
82 typedef struct _Eet_Free_Context Eet_Free_Context;
87 * Eet_Data_Basic_Type_Codec (Coder, Decoder)
88 * Eet_Data_Group_Type_Codec (Coder, Decoder)
90 struct _Eet_Data_Basic_Type_Codec
94 int (*get) (const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
95 void *(*put) (Eet_Dictionary *ed, const void *src, int *size_ret);
98 struct _Eet_Data_Group_Type_Codec
100 int (*get) (Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data_in, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
101 void (*put) (Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
104 struct _Eet_Data_Chunk
112 unsigned char group_type;
115 struct _Eet_Data_Stream
122 struct _Eet_Data_Descriptor_Hash
124 Eet_Data_Element *element;
125 Eet_Data_Descriptor_Hash *next;
128 struct _Eet_Data_Descriptor
131 const Eet_Dictionary *ed;
134 void *(*mem_alloc) (size_t size);
135 void (*mem_free) (void *mem);
136 char *(*str_alloc) (const char *str);
137 char *(*str_direct_alloc) (const char *str);
138 void (*str_free) (const char *str);
139 void (*str_direct_free) (const char *str);
140 void *(*list_next) (void *l);
141 void *(*list_append) (void *l, void *d);
142 void *(*list_data) (void *l);
143 void *(*list_free) (void *l);
144 void (*hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt);
145 void *(*hash_add) (void *h, const char *k, void *d);
146 void (*hash_free) (void *h);
150 Eet_Data_Element *set;
153 Eet_Data_Descriptor_Hash *buckets;
160 struct _Eet_Data_Element
163 const char *counter_name;
164 const char *directory_name_ptr;
165 Eet_Data_Descriptor *subtype;
166 int offset; /* offset in bytes from the base element */
167 int count; /* number of elements for a fixed array */
168 int counter_offset; /* for a variable array we need the offset of the count variable */
169 unsigned char type; /* EET_T_XXX */
170 unsigned char group_type; /* EET_G_XXX */
173 struct _Eet_Data_Encode_Hash_Info
176 Eet_Data_Element *ede;
188 struct _Eet_Free_Context
192 Eet_Free freelist_list;
193 Eet_Free freelist_hash;
194 Eet_Free freelist_str;
195 Eet_Free freelist_direct_str;
200 static int eet_data_get_char(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
201 static void *eet_data_put_char(Eet_Dictionary *ed, const void *src, int *size_ret);
202 static int eet_data_get_short(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
203 static void *eet_data_put_short(Eet_Dictionary *ed, const void *src, int *size_ret);
204 static inline int eet_data_get_int(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
205 static void *eet_data_put_int(Eet_Dictionary *ed, const void *src, int *size_ret);
206 static int eet_data_get_long_long(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
207 static void *eet_data_put_long_long(Eet_Dictionary *ed, const void *src, int *size_ret);
208 static int eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
209 static void *eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret);
210 static int eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
211 static void *eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret);
212 static inline int eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
213 static void *eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret);
214 static int eet_data_get_istring(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
215 static void *eet_data_put_istring(Eet_Dictionary *ed, const void *src, int *size_ret);
216 static int eet_data_get_null(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
217 static void *eet_data_put_null(Eet_Dictionary *ed, const void *src, int *size_ret);
219 static int eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest);
220 static void *eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret);
222 static int eet_data_get_unknown(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data_in, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
223 static void eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
224 static void eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
225 static int eet_data_get_array(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
226 static int eet_data_get_list(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data_in, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
227 static void eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
228 static void eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
229 static int eet_data_get_hash(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data, int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata, char **p, int *size);
231 static void eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk, const void *src, int size);
232 static Eet_Data_Chunk *eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type);
233 static void eet_data_chunk_free(Eet_Data_Chunk *chnk);
235 static Eet_Data_Stream *eet_data_stream_new(void);
236 static void eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size);
237 static void eet_data_stream_free(Eet_Data_Stream *ds);
239 static void eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds);
241 static int eet_data_descriptor_encode_hash_cb(void *hash, const char *key, void *hdata, void *fdata);
242 static void *_eet_data_descriptor_encode(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, const void *data_in, int *size_ret);
243 static void *_eet_data_descriptor_decode(Eet_Free_Context *context,
244 const Eet_Dictionary *ed,
245 Eet_Data_Descriptor *edd,
249 void (*dumpfunc) (void *data, const char *str),
254 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
256 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
257 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
258 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
259 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
260 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
261 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
262 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
263 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
264 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
265 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
266 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
267 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
268 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null }
271 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
273 { eet_data_get_unknown, eet_data_put_unknown },
274 { eet_data_get_array, eet_data_put_array },
275 { eet_data_get_array, eet_data_put_array },
276 { eet_data_get_list, eet_data_put_list },
277 { eet_data_get_hash, eet_data_put_hash }
280 static int words_bigendian = -1;
284 #define SWAP64(x) (x) = \
285 ((((unsigned long long)(x) & 0x00000000000000ffULL ) << 56) |\
286 (((unsigned long long)(x) & 0x000000000000ff00ULL ) << 40) |\
287 (((unsigned long long)(x) & 0x0000000000ff0000ULL ) << 24) |\
288 (((unsigned long long)(x) & 0x00000000ff000000ULL ) << 8) |\
289 (((unsigned long long)(x) & 0x000000ff00000000ULL ) >> 8) |\
290 (((unsigned long long)(x) & 0x0000ff0000000000ULL ) >> 24) |\
291 (((unsigned long long)(x) & 0x00ff000000000000ULL ) >> 40) |\
292 (((unsigned long long)(x) & 0xff00000000000000ULL ) >> 56))
293 #define SWAP32(x) (x) = \
294 ((((int)(x) & 0x000000ff ) << 24) |\
295 (((int)(x) & 0x0000ff00 ) << 8) |\
296 (((int)(x) & 0x00ff0000 ) >> 8) |\
297 (((int)(x) & 0xff000000 ) >> 24))
298 #define SWAP16(x) (x) = \
299 ((((short)(x) & 0x00ff ) << 8) |\
300 (((short)(x) & 0xff00 ) >> 8))
303 #define CONV16(x) {if (words_bigendian) SWAP16(x);}
304 #define CONV32(x) {if (words_bigendian) SWAP32(x);}
305 #define CONV64(x) {if (words_bigendian) SWAP64(x);}
307 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
313 eet_data_get_char(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
317 if (((char *)src + sizeof(char)) > (char *)src_end) return -1;
326 eet_data_put_char(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
330 d = (char *)malloc(sizeof(char));
335 *size_ret = sizeof(char);
341 eet_data_get_short(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
345 if (((char *)src + sizeof(short)) > (char *)src_end) return -1;
346 memcpy(dst, src, sizeof(short));
349 return sizeof(short);
353 eet_data_put_short(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
357 d = (short *)malloc(sizeof(short));
362 *size_ret = sizeof(short);
368 eet_data_get_int(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
372 if (((char *)src + sizeof(int)) > (char *)src_end) return -1;
373 memcpy(dst, src, sizeof(int));
380 eet_data_put_int(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
384 d = (int *)malloc(sizeof(int));
389 *size_ret = sizeof(int);
395 eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
397 unsigned long long *d;
399 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end) return -1;
400 memcpy(dst, src, sizeof(unsigned long long));
401 d = (unsigned long long *)dst;
403 return sizeof(unsigned long long);
407 eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
409 unsigned long long *s, *d;
411 d = (unsigned long long *)malloc(sizeof(unsigned long long));
413 s = (unsigned long long *)src;
416 *size_ret = sizeof(unsigned long long);
422 eet_data_get_string_hash(const Eet_Dictionary *ed, const void *src, const void *src_end)
428 if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
430 return eet_dictionary_string_get_hash(ed, index);
437 eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
448 if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
450 str = eet_dictionary_string_get_char(ed, index);
455 return eet_dictionary_string_get_size(ed, index);
466 return strlen(s) + 1;
470 eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret)
480 str = *((const char **) src);
481 if (!str) return NULL;
483 index = eet_dictionary_string_add(ed, str);
484 if (index == -1) return NULL;
486 return eet_data_put_int(ed, &index, size_ret);
489 s = (char *)(*((char **)src));
494 memcpy(d, s, len + 1);
499 /* ALWAYS INLINED STRING TYPE */
501 eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
503 return eet_data_get_string(NULL, src, src_end, dst);
507 eet_data_put_istring(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
509 return eet_data_put_string(NULL, src, size_ret);
512 /* ALWAYS NULL TYPE */
514 eet_data_get_null(const Eet_Dictionary *ed __UNUSED__, const void *src __UNUSED__, const void *src_end __UNUSED__, void *dst)
525 eet_data_put_null(Eet_Dictionary *ed __UNUSED__, const void *src __UNUSED__, int *size_ret)
532 * Fast lookups of simple doubles/floats.
534 * These aren't properly a cache because they don't store pre-calculated
535 * values, but have a so simple math that is almost as fast.
538 _eet_data_float_cache_get(const char *s, int len, float *d)
540 /* fast handle of simple case 0xMp+E*/
541 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
543 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
544 int exponent = (s[5] - '0');
546 if (s[4] == '+') *d = (float)(mantisse << exponent);
547 else *d = (float)mantisse / (float)(1 << exponent);
555 _eet_data_double_cache_get(const char *s, int len, double *d)
557 /* fast handle of simple case 0xMp+E*/
558 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
560 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
561 int exponent = (s[5] - '0');
563 if (s[4] == '+') *d = (double)(mantisse << exponent);
564 else *d = (double)mantisse / (double)(1 << exponent);
573 eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
586 s = (const char *)src;
589 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
591 if (_eet_data_float_cache_get(s, len, d) != 0) return len + 1;
593 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) return -1;
594 *d = (float)ldexp((double)mantisse, exponent);
599 if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
601 if (!eet_dictionary_string_get_float(ed, index, d))
607 eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret)
612 eina_convert_dtoa((double)(*(float *)src), buf);
622 memcpy(d, buf, len + 1);
627 index = eet_dictionary_string_add(ed, buf);
628 if (index == -1) return NULL;
630 return eet_data_put_int(ed, &index, size_ret);
635 eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
645 long long mantisse = 0;
649 s = (const char *) src;
652 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
654 if (_eet_data_double_cache_get(s, len, d) != 0) return len + 1;
656 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) return -1;
657 *d = ldexp((double) mantisse, exponent);
662 if (eet_data_get_int(ed, src, src_end, &index) < 0) return -1;
664 if (!eet_dictionary_string_get_double(ed, index, d))
670 eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret)
675 eina_convert_dtoa((double)(*(double *)src), buf);
685 memcpy(d, buf, len + 1);
691 index = eet_dictionary_string_add(ed, buf);
692 if (index == -1) return NULL;
694 return eet_data_put_int(ed, &index, size_ret);
698 eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest)
702 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
707 eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret)
711 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
717 * char[4] = "CHnK"; // untyped data ... or
718 * char[4] = "CHKx"; // typed data - x == type
720 * int = chunk size (including magic string);
721 * char[] = chunk magic/name string (0 byte terminated);
722 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
724 * ... payload data ...
729 eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk,
730 const void *src, int size)
737 fprintf(stderr, "stiouf -3\n");
742 fprintf(stderr, "stiouf -2 %i\n", size);
748 fprintf(stderr, "stiouf -1\n");
755 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
757 fprintf(stderr, "stiouf 0\n");
760 chnk->type = (unsigned char)(s[3]);
761 if (chnk->type > EET_T_LAST)
763 chnk->group_type = chnk->type;
764 chnk->type = EET_T_UNKNOW;
767 chnk->group_type = EET_G_UNKNOWN;
768 if ((chnk->type >= EET_T_LAST) ||
769 (chnk->group_type >= EET_G_LAST))
772 chnk->group_type = 0;
777 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
779 fprintf(stderr, "stiouf 1\n");
783 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
786 fprintf(stderr, "stiouf 2\n");
789 if ((chnk->size < 0) || ((chnk->size + 8) > size))
791 fprintf(stderr, "stiouf 3\n");
794 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
797 fprintf(stderr, "stiouf 4\n");
804 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
808 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
809 chnk->size -= sizeof(int);
813 chnk->data = (char *)src + 4 + ret1 + chnk->len;
814 chnk->size -= chnk->len;
820 static inline Eet_Data_Chunk *
821 eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type)
823 Eet_Data_Chunk *chnk;
825 if (!name) return NULL;
826 chnk = calloc(1, sizeof(Eet_Data_Chunk));
827 if (!chnk) return NULL;
829 chnk->name = strdup(name);
830 chnk->len = strlen(name) + 1;
834 chnk->group_type = group_type;
839 eet_data_chunk_free(Eet_Data_Chunk *chnk)
841 if (chnk->name) free(chnk->name);
845 static inline Eet_Data_Stream *
846 eet_data_stream_new(void)
850 ds = calloc(1, sizeof(Eet_Data_Stream));
851 if (!ds) return NULL;
856 eet_data_stream_free(Eet_Data_Stream *ds)
858 if (ds->data) free(ds->data);
863 eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size)
867 if ((ds->pos + size) > ds->size)
869 ds->data = realloc(ds->data, ds->size + size + 512);
876 ds->size = ds->size + size + 512;
879 memcpy(p + ds->pos, data, size);
884 eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds)
891 unsigned char buf[4] = "CHK";
893 if (!chnk->data && chnk->type != EET_T_NULL) return;
896 /* eet_data_stream_write(ds, "CHnK", 4);*/
897 if (chnk->type != EET_T_UNKNOW) buf[3] = chnk->type;
898 else buf[3] = chnk->group_type;
900 string = eet_data_put_string(ed, &chnk->name, &string_ret);
904 /* size of chunk payload data + name */
905 s = chnk->size + string_ret;
906 size = eet_data_put_int(ed, &s, &size_ret);
908 /* FIXME: If something goes wrong the resulting file will be corrupted. */
912 eet_data_stream_write(ds, buf, 4);
914 /* write chunk length */
915 eet_data_stream_write(ds, size, size_ret);
917 /* write chunk name */
918 eet_data_stream_write(ds, string, string_ret);
921 eet_data_stream_write(ds, chnk->data, chnk->size);
931 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
935 edd->elements.hash.size = 1 << 6;
936 edd->elements.hash.buckets = calloc(1, sizeof(Eet_Data_Descriptor_Hash) * edd->elements.hash.size);
937 for (i = 0; i < edd->elements.num; i++)
939 Eet_Data_Element *ede;
942 ede = &(edd->elements.set[i]);
943 hash = _eet_hash_gen((char *) ede->name, 6);
944 if (!edd->elements.hash.buckets[hash].element)
945 edd->elements.hash.buckets[hash].element = ede;
948 Eet_Data_Descriptor_Hash *bucket;
950 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
951 bucket->element = ede;
952 bucket->next = edd->elements.hash.buckets[hash].next;
953 edd->elements.hash.buckets[hash].next = bucket;
959 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
963 for (i = 0; i < edd->elements.hash.size; i++)
965 Eet_Data_Descriptor_Hash *bucket, *pbucket;
967 bucket = edd->elements.hash.buckets[i].next;
971 bucket = bucket->next;
975 if (edd->elements.hash.buckets) free(edd->elements.hash.buckets);
978 static Eet_Data_Element *
979 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd, char *name, int hash)
981 Eet_Data_Descriptor_Hash *bucket;
983 if (hash < 0) hash = _eet_hash_gen(name, 6);
985 if (!edd->elements.hash.buckets[hash].element) return NULL;
987 When we use the dictionnary as a source for chunk name, we will always
988 have the same pointer in name. It's a good idea to just compare pointer
989 instead of running strcmp on both string.
991 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
992 return edd->elements.hash.buckets[hash].element;
993 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
995 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
996 return edd->elements.hash.buckets[hash].element;
998 bucket = edd->elements.hash.buckets[hash].next;
1001 if (bucket->element->directory_name_ptr == name) return bucket->element;
1002 if (!strcmp(bucket->element->name, name))
1004 bucket->element->directory_name_ptr = name;
1005 return bucket->element;
1007 bucket = bucket->next;
1013 _eet_mem_alloc(size_t size)
1015 return calloc(1, size);
1019 _eet_mem_free(void *mem)
1025 _eet_str_alloc(const char *str)
1031 _eet_str_free(const char *str)
1038 EAPI Eet_Data_Descriptor *
1039 eet_data_descriptor_new(const char *name,
1041 void *(*func_list_next) (void *l),
1042 void *(*func_list_append) (void *l, void *d),
1043 void *(*func_list_data) (void *l),
1044 void *(*func_list_free) (void *l),
1045 void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt),
1046 void *(*func_hash_add) (void *h, const char *k, void *d),
1047 void (*func_hash_free) (void *h))
1049 Eet_Data_Descriptor *edd;
1051 if (!name) return NULL;
1052 edd = calloc(1, sizeof(Eet_Data_Descriptor));
1053 if (!edd) return NULL;
1058 edd->func.mem_alloc = _eet_mem_alloc;
1059 edd->func.mem_free = _eet_mem_free;
1060 edd->func.str_alloc = _eet_str_alloc;
1061 edd->func.str_direct_alloc = NULL;
1062 edd->func.str_direct_free = NULL;
1063 edd->func.str_free = _eet_str_free;
1064 edd->func.list_next = func_list_next;
1065 edd->func.list_append = func_list_append;
1066 edd->func.list_data = func_list_data;
1067 edd->func.list_free = func_list_free;
1068 edd->func.hash_foreach = func_hash_foreach;
1069 edd->func.hash_add = func_hash_add;
1070 edd->func.hash_free = func_hash_free;
1074 /* new replcement */
1075 EAPI Eet_Data_Descriptor *
1076 eet_data_descriptor2_new(Eet_Data_Descriptor_Class *eddc)
1078 Eet_Data_Descriptor *edd;
1080 if (!eddc) return NULL;
1081 if (eddc->version < 1) return NULL;
1082 edd = calloc(1, sizeof(Eet_Data_Descriptor));
1083 if (!edd) return NULL;
1085 edd->name = eddc->name;
1087 edd->size = eddc->size;
1088 edd->func.mem_alloc = _eet_mem_alloc;
1089 edd->func.mem_free = _eet_mem_free;
1090 edd->func.str_alloc = _eet_str_alloc;
1091 edd->func.str_free = _eet_str_free;
1092 if (eddc->func.mem_alloc)
1093 edd->func.mem_alloc = eddc->func.mem_alloc;
1094 if (eddc->func.mem_free)
1095 edd->func.mem_free = eddc->func.mem_free;
1096 if (eddc->func.str_alloc)
1097 edd->func.str_alloc = eddc->func.str_alloc;
1098 if (eddc->func.str_free)
1099 edd->func.str_free = eddc->func.str_free;
1100 edd->func.list_next = eddc->func.list_next;
1101 edd->func.list_append = eddc->func.list_append;
1102 edd->func.list_data = eddc->func.list_data;
1103 edd->func.list_free = eddc->func.list_free;
1104 edd->func.hash_foreach = eddc->func.hash_foreach;
1105 edd->func.hash_add = eddc->func.hash_add;
1106 edd->func.hash_free = eddc->func.hash_free;
1111 EAPI Eet_Data_Descriptor *
1112 eet_data_descriptor3_new(Eet_Data_Descriptor_Class *eddc)
1114 Eet_Data_Descriptor *edd;
1116 if (!eddc) return NULL;
1117 if (eddc->version < 2) return NULL;
1118 edd = calloc(1, sizeof(Eet_Data_Descriptor));
1119 if (!edd) return NULL;
1121 edd->name = eddc->name;
1123 edd->size = eddc->size;
1124 edd->func.mem_alloc = _eet_mem_alloc;
1125 edd->func.mem_free = _eet_mem_free;
1126 edd->func.str_alloc = _eet_str_alloc;
1127 edd->func.str_free = _eet_str_free;
1128 if (eddc->func.mem_alloc)
1129 edd->func.mem_alloc = eddc->func.mem_alloc;
1130 if (eddc->func.mem_free)
1131 edd->func.mem_free = eddc->func.mem_free;
1132 if (eddc->func.str_alloc)
1133 edd->func.str_alloc = eddc->func.str_alloc;
1134 if (eddc->func.str_free)
1135 edd->func.str_free = eddc->func.str_free;
1136 edd->func.list_next = eddc->func.list_next;
1137 edd->func.list_append = eddc->func.list_append;
1138 edd->func.list_data = eddc->func.list_data;
1139 edd->func.list_free = eddc->func.list_free;
1140 edd->func.hash_foreach = eddc->func.hash_foreach;
1141 edd->func.hash_add = eddc->func.hash_add;
1142 edd->func.hash_free = eddc->func.hash_free;
1143 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1144 edd->func.str_direct_free = eddc->func.str_direct_free;
1150 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1152 _eet_descriptor_hash_free(edd);
1153 if (edd->elements.set) free(edd->elements.set);
1158 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1164 /* int counter_offset, */
1165 const char *counter_name /* Useless should go on a major release */,
1166 Eet_Data_Descriptor *subtype)
1168 Eet_Data_Element *ede;
1169 /* int l1, l2, p1, p2, i;
1172 /* FIXME: Fail safely when realloc fail. */
1173 edd->elements.num++;
1174 edd->elements.set = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1175 if (!edd->elements.set) return;
1176 ede = &(edd->elements.set[edd->elements.num - 1]);
1178 ede->directory_name_ptr = NULL;
1181 * We do a special case when we do list,hash or whatever group of simple type.
1182 * Instead of handling it in encode/decode/dump/undump, we create an
1183 * implicit structure with only the simple type.
1185 if (group_type > EET_G_UNKNOWN
1186 && group_type < EET_G_LAST
1187 && type > EET_T_UNKNOW && type < EET_T_STRING
1190 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
1191 if (!subtype) return ;
1192 subtype->name = "implicit";
1193 subtype->size = eet_basic_codec[type - 1].size;
1194 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
1196 eet_data_descriptor_element_add(subtype, eet_basic_codec[type - 1].name, type,
1197 EET_G_UNKNOWN, 0, 0, /* 0, */NULL, NULL);
1198 type = EET_T_UNKNOW;
1202 ede->group_type = group_type;
1203 ede->offset = offset;
1205 /* FIXME: For the time being, EET_G_VAR_ARRAY will put the counter_offset in count. */
1206 ede->counter_offset = count;
1207 /* ede->counter_offset = counter_offset; */
1208 ede->counter_name = counter_name;
1210 ede->subtype = subtype;
1214 eet_data_read_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *key)
1216 const Eet_Dictionary *ed = NULL;
1217 const void *data = NULL;
1219 Eet_Free_Context context;
1220 int required_free = 0;
1223 ed = eet_dictionary_get(ef);
1226 data = eet_read_direct(ef, name, &size);
1230 data = eet_read_cipher(ef, name, &size, key);
1231 if (!data) return NULL;
1234 memset(&context, 0, sizeof (context));
1235 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, 0, NULL, NULL);
1243 eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
1245 return eet_data_read_cipher(ef, edd, name, NULL);
1249 eet_data_write_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *key, const void *data, int compress)
1256 ed = eet_dictionary_get(ef);
1258 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
1259 if (!data_enc) return 0;
1260 val = eet_write_cipher(ef, name, data_enc, size, compress, key);
1266 eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
1268 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
1272 _eet_free_hash(void *data)
1274 unsigned long ptr = (unsigned long)(data);
1293 _eet_free_add(Eet_Free *ef, void *data)
1298 hash = _eet_free_hash(data);
1300 for (i = 0; i < ef->num[hash]; ++i)
1301 if (ef->list[hash][i] == data) return;
1304 if (ef->num[hash] > ef->len[hash])
1308 tmp = realloc(ef->list[hash], (ef->len[hash] + 16) * sizeof(void*));
1311 ef->len[hash] += 16;
1312 ef->list[hash] = tmp;
1314 ef->list[hash][ef->num[hash] - 1] = data;
1317 _eet_free_reset(Eet_Free *ef)
1321 if (ef->ref > 0) return ;
1322 for (i = 0; i < 256; ++i)
1326 if (ef->list[i]) free(ef->list[i]);
1331 _eet_free_ref(Eet_Free *ef)
1336 _eet_free_unref(Eet_Free *ef)
1341 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
1342 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
1343 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
1344 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
1347 _eet_freelist_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1352 if (context->freelist.ref > 0) return;
1353 for (j = 0; j < 256; ++j)
1354 for (i = 0; i < context->freelist.num[j]; ++i)
1357 edd->func.mem_free(context->freelist.list[j][i]);
1359 free(context->freelist.list[j][i]);
1361 _eet_free_reset(&context->freelist);
1364 #define _eet_freeleak_add(Ctx, Data) _eet_free_add(&Ctx->freeleak, Data);
1365 #define _eet_freeleak_reset(Ctx) _eet_free_reset(&Ctx->freeleak);
1366 #define _eet_freeleak_ref(Ctx) _eet_free_ref(&Ctx->freeleak);
1367 #define _eet_freeleak_unref(Ctx) _eet_free_unref(&Ctx->freeleak);
1370 _eet_freeleak_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1375 if (context->freeleak.ref > 0) return;
1376 for (j = 0; j < 256; ++j)
1377 for (i = 0; i < context->freeleak.num[j]; ++i)
1380 edd->func.mem_free(context->freeleak.list[j][i]);
1382 free(context->freeleak.list[j][i]);
1384 _eet_free_reset(&context->freeleak);
1387 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
1388 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
1389 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
1390 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
1393 _eet_freelist_list_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1398 if (context->freelist_list.ref > 0) return;
1399 for (j = 0; j < 256; ++j)
1400 for (i = 0; i < context->freelist_list.num[j]; ++i)
1403 edd->func.list_free(*((void**)(context->freelist_list.list[j][i])));
1405 _eet_free_reset(&context->freelist_list);
1408 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
1409 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
1410 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
1411 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
1414 _eet_freelist_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1419 if (context->freelist_str.ref > 0) return;
1420 for (j = 0; j < 256; ++j)
1421 for (i = 0; i < context->freelist_str.num[j]; ++i)
1424 edd->func.str_free(context->freelist_str.list[j][i]);
1426 free(context->freelist_str.list[j][i]);
1428 _eet_free_reset(&context->freelist_str);
1431 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
1432 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
1433 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
1434 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
1437 _eet_freelist_direct_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1442 if (context->freelist_direct_str.ref > 0) return;
1443 for (j = 0; j < 256; ++j)
1444 for (i = 0; i < context->freelist_direct_str.num[j]; ++i)
1447 edd->func.str_direct_free(context->freelist_direct_str.list[j][i]);
1449 free(context->freelist_direct_str.list[j][i]);
1451 _eet_free_reset(&context->freelist_direct_str);
1454 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
1455 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
1456 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
1457 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
1460 _eet_freelist_hash_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1465 if (context->freelist_hash.ref > 0) return;
1466 for (j = 0; j < 256; ++j)
1467 for (i = 0; i < context->freelist_hash.num[j]; ++i)
1470 edd->func.hash_free(context->freelist_hash.list[j][i]);
1472 free(context->freelist_hash.list[j][i]);
1474 _eet_free_reset(&context->freelist_hash);
1478 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
1480 _eet_freelist_ref(freelist_context);
1481 _eet_freeleak_ref(freelist_context);
1482 _eet_freelist_str_ref(freelist_context);
1483 _eet_freelist_list_ref(freelist_context);
1484 _eet_freelist_hash_ref(freelist_context);
1485 _eet_freelist_direct_str_ref(freelist_context);
1489 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
1491 _eet_freelist_unref(freelist_context);
1492 _eet_freeleak_unref(freelist_context);
1493 _eet_freelist_str_unref(freelist_context);
1494 _eet_freelist_list_unref(freelist_context);
1495 _eet_freelist_hash_unref(freelist_context);
1496 _eet_freelist_direct_str_unref(freelist_context);
1500 eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__, const char *key, void *hdata, void *fdata)
1503 Eet_Data_Encode_Hash_Info *edehi;
1504 Eet_Data_Stream *ds;
1505 Eet_Data_Element *ede;
1506 Eet_Data_Chunk *echnk;
1516 data = eet_data_put_type(ed,
1522 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
1523 eet_data_chunk_put(ed, echnk, ds);
1524 eet_data_chunk_free(echnk);
1529 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
1532 if (ede->type >= EET_T_STRING)
1533 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
1537 data = _eet_data_descriptor_encode(ed,
1543 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
1544 eet_data_chunk_put(ed, echnk, ds);
1545 eet_data_chunk_free(echnk);
1555 _eet_data_string_escape(const char *str)
1561 for (strp = str; *strp; strp++)
1563 if (*strp == '\"') sz += 2;
1564 else if (*strp == '\\') sz += 2;
1568 if (!s) return NULL;
1569 for (strp = str, sp = s; *strp; strp++, sp++)
1576 else if (*strp == '\\')
1588 _eet_data_dump_string_escape(void *dumpdata, void dumpfunc(void *data, const char *str), const char *str)
1592 s = _eet_data_string_escape(str);
1595 dumpfunc(dumpdata, s);
1601 _eet_data_dump_token_get(const char *src, int *len)
1607 int tlen = 0, tsize = 0;
1609 #define TOK_ADD(x) \
1612 if (tlen >= tsize) \
1615 tok = realloc(tok, tsize); \
1617 tok[tlen - 1] = x; \
1620 for (p = src; *len > 0; p++, (*len)--)
1626 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
1630 else if ((p[0] == '\\') && (*len > 1) && (p[1] == '\"'))
1634 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
1643 if (p[0] == '\"') in_quote = 1;
1646 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
1659 if (!((isspace(p[0])) || (p[0] == ';')))
1677 _eet_data_dump_encode(Eet_Dictionary *ed,
1681 Eet_Data_Chunk *chnk = NULL, *echnk = NULL;
1682 Eet_Data_Stream *ds;
1687 if (words_bigendian == -1)
1689 unsigned long int v;
1691 v = htonl(0x12345678);
1692 if (v == 0x12345678) words_bigendian = 1;
1693 else words_bigendian = 0;
1696 ds = eet_data_stream_new();
1697 if (!ds) return NULL;
1702 for (n = node->values; n; n = n->next)
1704 data = _eet_data_dump_encode(ed, n, &size);
1707 eet_data_stream_write(ds, data, size);
1713 case EET_G_VAR_ARRAY:
1714 data = eet_data_put_type(ed,
1720 echnk = eet_data_chunk_new(data, size, node->name, node->type, node->type);
1721 eet_data_chunk_put(ed, echnk, ds);
1722 eet_data_chunk_free(echnk);
1725 for (n = node->values; n; n = n->next)
1727 data = _eet_data_dump_encode(ed, n, &size);
1730 echnk = eet_data_chunk_new(data, size, node->name, node->type, node->type);
1731 eet_data_chunk_put(ed, echnk, ds);
1732 eet_data_chunk_free(echnk);
1737 /* Array is somekind of special case, so we should embed it inside another chunk. */
1738 *size_ret = ds->pos;
1743 eet_data_stream_free(ds);
1747 for (n = node->values; n; n = n->next)
1749 data = _eet_data_dump_encode(ed, n, &size);
1752 eet_data_stream_write(ds, data, size);
1760 data = eet_data_put_type(ed,
1766 echnk = eet_data_chunk_new(data, size, node->name, node->type, node->type);
1767 eet_data_chunk_put(ed, echnk, ds);
1768 eet_data_chunk_free(echnk);
1772 for (n = node->values; n; n = n->next)
1774 data = _eet_data_dump_encode(ed, n, &size);
1777 echnk = eet_data_chunk_new(data, size, node->name, node->type, node->type);
1778 eet_data_chunk_put(ed, echnk, ds);
1779 eet_data_chunk_free(echnk);
1784 /* Hash is somekind of special case, so we should embed it inside another chunk. */
1785 *size_ret = ds->pos;
1790 eet_data_stream_free(ds);
1796 data = eet_data_put_type(ed, node->type, &(node->data.c), &size);
1799 eet_data_stream_write(ds, data, size);
1804 data = eet_data_put_type(ed, node->type, &(node->data.s), &size);
1807 eet_data_stream_write(ds, data, size);
1812 data = eet_data_put_type(ed, node->type, &(node->data.i), &size);
1815 eet_data_stream_write(ds, data, size);
1819 case EET_T_LONG_LONG:
1820 data = eet_data_put_type(ed, node->type, &(node->data.l), &size);
1823 eet_data_stream_write(ds, data, size);
1828 data = eet_data_put_type(ed, node->type, &(node->data.f), &size);
1831 eet_data_stream_write(ds, data, size);
1836 data = eet_data_put_type(ed, node->type, &(node->data.d), &size);
1839 eet_data_stream_write(ds, data, size);
1844 data = eet_data_put_type(ed, node->type, &(node->data.uc), &size);
1847 eet_data_stream_write(ds, data, size);
1852 data = eet_data_put_type(ed, node->type, &(node->data.us), &size);
1855 eet_data_stream_write(ds, data, size);
1860 data = eet_data_put_type(ed, node->type, &(node->data.ui), &size);
1863 eet_data_stream_write(ds, data, size);
1867 case EET_T_ULONG_LONG:
1868 data = eet_data_put_type(ed, node->type, &(node->data.ul), &size);
1871 eet_data_stream_write(ds, data, size);
1875 case EET_T_INLINED_STRING:
1876 data = eet_data_put_type(ed, node->type, &(node->data.str), &size);
1879 eet_data_stream_write(ds, data, size);
1884 data = eet_data_put_type(ed, node->type, &(node->data.str), &size);
1887 eet_data_stream_write(ds, data, size);
1895 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
1896 chnk = eet_data_chunk_new(ds->data, ds->pos, node->name, EET_T_UNKNOW, node->type);
1898 chnk = eet_data_chunk_new(ds->data, ds->pos, node->name, node->type, EET_G_UNKNOWN);
1901 eet_data_stream_free(ds);
1903 ds = eet_data_stream_new();
1904 eet_data_chunk_put(ed, chnk, ds);
1910 eet_data_stream_free(ds);
1914 eet_data_chunk_free(chnk);
1920 _eet_data_dump_parse(Eet_Dictionary *ed,
1931 Eet_Node *node_base = NULL;
1932 Eet_Node *node = NULL;
1935 /* FIXME; handle parse errors */
1936 #define TOK_GET(t) \
1937 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
1939 for (p = src; p < (src + size);)
1941 char *tok1, *tok2, *tok3, *tok4;
1946 if (!strcmp(tok1, "group"))
1957 if (!strcmp(tok4, "{"))
1959 /* we have 'group NAM TYP {' */
1960 n = calloc(1, sizeof(Eet_Node));
1975 for (nn = node->values; nn; nn = nn->next)
1985 n->name = eina_stringshare_add(tok2);
1986 if (!strcmp(tok3, "struct")) n->type = EET_G_UNKNOWN;
1987 else if (!strcmp(tok3, "array")) n->type = EET_G_ARRAY;
1988 else if (!strcmp(tok3, "var_array")) n->type = EET_G_VAR_ARRAY;
1989 else if (!strcmp(tok3, "list")) n->type = EET_G_LIST;
1990 else if (!strcmp(tok3, "hash")) n->type = EET_G_HASH;
1993 printf("ERROR: group type '%s' invalid.\n", tok3);
2005 else if (!strcmp(tok1, "value"))
2016 /* we have 'value NAME TYP XXX' */
2019 n = calloc(1, sizeof(Eet_Node));
2028 for (nn = node->values; nn; nn = nn->next)
2037 n->name = eina_stringshare_add(tok2);
2038 if (!strcmp(tok3, "char:"))
2040 n->type = EET_T_CHAR;
2041 sscanf(tok4, "%hhi", &(n->data.c));
2043 else if (!strcmp(tok3, "short:"))
2045 n->type = EET_T_SHORT;
2046 sscanf(tok4, "%hi", &(n->data.s));
2048 else if (!strcmp(tok3, "int:"))
2050 n->type = EET_T_INT;
2051 sscanf(tok4, "%i", &(n->data.i));
2053 else if (!strcmp(tok3, "long_long:"))
2055 n->type = EET_T_LONG_LONG;
2056 sscanf(tok4, "%lli", &(n->data.l));
2058 else if (!strcmp(tok3, "float:"))
2060 n->type = EET_T_FLOAT;
2061 sscanf(tok4, "%f", &(n->data.f));
2063 else if (!strcmp(tok3, "double:"))
2065 n->type = EET_T_DOUBLE;
2066 sscanf(tok4, "%lf", &(n->data.d));
2068 else if (!strcmp(tok3, "uchar:"))
2070 n->type = EET_T_UCHAR;
2071 sscanf(tok4, "%hhu", &(n->data.uc));
2073 else if (!strcmp(tok3, "ushort:"))
2075 n->type = EET_T_USHORT;
2076 sscanf(tok4, "%hu", &(n->data.us));
2078 else if (!strcmp(tok3, "uint:"))
2080 n->type = EET_T_UINT;
2081 sscanf(tok4, "%u", &(n->data.ui));
2083 else if (!strcmp(tok3, "ulong_long:"))
2085 n->type = EET_T_ULONG_LONG;
2086 sscanf(tok4, "%llu", &(n->data.ul));
2088 else if (!strcmp(tok3, "string:"))
2090 n->type = EET_T_STRING;
2091 n->data.str = eina_stringshare_add(tok4);
2093 else if (!strcmp(tok3, "inlined:"))
2095 n->type = EET_T_INLINED_STRING;
2096 n->data.str = eina_stringshare_add(tok4);
2098 else if (!strcmp(tok3, "null"))
2100 n->type = EET_T_NULL;
2105 printf("ERROR: value type '%s' invalid.\n", tok4);
2116 else if (!strcmp(tok1, "key"))
2121 /* we have 'key NAME' */
2124 node->key = eina_stringshare_add(tok2);
2129 else if (!strcmp(tok1, "count"))
2134 /* we have a 'count COUNT' */
2137 sscanf(tok2, "%i", &(node->count));
2142 else if (!strcmp(tok1, "}"))
2144 /* we have an end of the group */
2145 if (node) node = node->parent;
2153 cdata = _eet_data_dump_encode(ed, node_base, size_ret);
2154 eet_node_del(node_base);
2159 #define NEXT_CHUNK(P, Size, Echnk, Ed) \
2162 tmp = Ed ? (int) (sizeof(int) * 2) : Echnk.len + 4;\
2163 P += (4 + Echnk.size + tmp); \
2164 Size -= (4 + Echnk.size + tmp); \
2167 static const char *_dump_g_name[6] = {
2176 static const char *_dump_t_name[14][2] = {
2178 { "char: ", "%hhi" },
2179 { "short: ", "%hi" },
2181 { "long_long: ", "%lli" },
2182 { "float: ", "%1.25f" },
2183 { "double: ", "%1.25f" },
2184 { "uchar: ", "%hhu" },
2185 { "ushort: ", "%i" },
2187 { "ulong_long: ", "%llu" },
2192 _eet_data_descriptor_decode(Eet_Free_Context *context,
2193 const Eet_Dictionary *ed,
2194 Eet_Data_Descriptor *edd,
2195 const void *data_in,
2198 void (*dumpfunc) (void *data, const char *str),
2205 Eet_Data_Chunk chnk;
2207 if (words_bigendian == -1)
2209 unsigned long int v;
2211 v = htonl(0x12345678);
2212 if (v == 0x12345678) words_bigendian = 1;
2213 else words_bigendian = 0;
2218 data = edd->func.mem_alloc(edd->size);
2219 if (!data) return NULL;
2222 for (i = 0; i < edd->elements.num; i++)
2223 edd->elements.set[i].directory_name_ptr = NULL;
2227 _eet_freelist_all_ref(context);
2228 if (data) _eet_freelist_add(context, data);
2230 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
2231 eet_data_chunk_get(ed, &chnk, data_in, size_in);
2232 if (!chnk.name) goto error;
2235 if (strcmp(chnk.name, edd->name)) goto error;
2239 size = size_in - (4 + sizeof(int) * 2);
2241 size = size_in - (4 + 4 + chnk.len);
2244 if (!edd->elements.hash.buckets) _eet_descriptor_hash_new(edd);
2249 if (chnk.type == EET_T_UNKNOW)
2251 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
2252 dumpfunc(dumpdata, "group \"");
2253 _eet_data_dump_string_escape(dumpdata, dumpfunc, chnk.name);
2254 dumpfunc(dumpdata, "\" ");
2256 chnk_type = (chnk.group_type >= EET_G_UNKNOWN && chnk.group_type <= EET_G_HASH) ?
2257 chnk.group_type : EET_G_LAST;
2259 dumpfunc(dumpdata, _dump_g_name[chnk_type - EET_G_UNKNOWN]);
2260 dumpfunc(dumpdata, " {\n");
2265 Eet_Data_Chunk echnk;
2266 Eet_Data_Element *ede;
2268 /* get next data chunk */
2269 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
2270 eet_data_chunk_get(ed, &echnk, p, size);
2271 if (!echnk.name) goto error;
2272 /* FIXME: don't REPLY on edd - work without */
2273 if ((edd) && (!dumpfunc))
2275 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
2278 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
2281 group_type = ede->group_type;
2283 if ((echnk.type == 0) && (echnk.group_type == 0))
2286 group_type = ede->group_type;
2290 if (IS_SIMPLE_TYPE(echnk.type) &&
2291 (echnk.type == ede->type))
2293 else if ((echnk.group_type > EET_G_UNKNOWN) &&
2294 (echnk.group_type < EET_G_LAST) &&
2295 (echnk.group_type == ede->group_type))
2296 group_type = echnk.group_type;
2298 /* hashes doesnt fit well with the table */
2299 ret = eet_group_codec[group_type - 100].get(context, ed, edd, ede, &echnk, type, group_type, ((char *)data) + ede->offset, level, dumpfunc, dumpdata, &p, &size);
2300 if (ret <= 0) goto error;
2303 /*...... dump func */
2306 unsigned char dd[128];
2307 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
2309 if ((echnk.type > EET_T_UNKNOW) &&
2310 (echnk.type < EET_T_LAST))
2312 else if ((echnk.group_type > EET_G_UNKNOWN) &&
2313 (echnk.group_type < EET_G_LAST))
2314 group_type = echnk.group_type;
2315 if (group_type == EET_G_UNKNOWN)
2320 if (IS_SIMPLE_TYPE(type))
2322 const char *type_name = NULL;
2324 ret = eet_data_get_type(ed,
2327 ((char *)echnk.data) + echnk.size,
2329 if (ret <= 0) goto error;
2331 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
2332 dumpfunc(dumpdata, " value \"");
2333 _eet_data_dump_string_escape(dumpdata, dumpfunc, echnk.name);
2334 dumpfunc(dumpdata, "\" ");
2336 #define EET_T_TYPE(Eet_Type, Type) \
2339 dumpfunc(dumpdata, _dump_t_name[Eet_Type][0]); \
2340 snprintf(tbuf, sizeof (tbuf), _dump_t_name[Eet_Type][1], *((Type *)dd)); \
2341 dumpfunc(dumpdata, tbuf); \
2347 EET_T_TYPE(EET_T_CHAR, char);
2348 EET_T_TYPE(EET_T_SHORT, short);
2349 EET_T_TYPE(EET_T_INT, int);
2350 EET_T_TYPE(EET_T_LONG_LONG, long long);
2351 EET_T_TYPE(EET_T_FLOAT, float);
2352 EET_T_TYPE(EET_T_DOUBLE, double);
2353 EET_T_TYPE(EET_T_UCHAR, unsigned char);
2354 EET_T_TYPE(EET_T_USHORT, unsigned short);
2355 EET_T_TYPE(EET_T_UINT, unsigned int);
2356 EET_T_TYPE(EET_T_ULONG_LONG, unsigned long long);
2357 case EET_T_INLINED_STRING:
2358 type_name = "inlined: \"";
2360 if (!type_name) type_name = "string: \"";
2368 dumpfunc(dumpdata, type_name);
2369 _eet_data_dump_string_escape(dumpdata, dumpfunc, s);
2370 dumpfunc(dumpdata, "\"");
2375 dumpfunc(dumpdata, "null");
2378 dumpfunc(dumpdata, "???: ???"); break;
2381 dumpfunc(dumpdata, ";\n");
2385 data_ret = _eet_data_descriptor_decode(context,
2393 if (!data_ret) goto error;
2398 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
2399 dumpfunc(dumpdata, " group \"");
2400 _eet_data_dump_string_escape(dumpdata, dumpfunc, echnk.name);
2401 dumpfunc(dumpdata, "\" ");
2403 chnk_type = (echnk.group_type >= EET_G_UNKNOWN && echnk.group_type <= EET_G_HASH) ?
2404 echnk.group_type : EET_G_LAST;
2406 dumpfunc(dumpdata, _dump_g_name[chnk_type - EET_G_UNKNOWN]);
2407 dumpfunc(dumpdata, " {\n");
2411 case EET_G_VAR_ARRAY:
2417 EET_ASSERT(!IS_SIMPLE_TYPE(type), goto error);
2419 ret = eet_data_get_type(ed,
2422 ((char *)echnk.data) + echnk.size,
2424 if (ret <= 0) goto error;
2426 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
2427 dumpfunc(dumpdata, " count ");
2428 snprintf(tbuf, sizeof(tbuf), "%i", count);
2429 dumpfunc(dumpdata, tbuf);
2430 dumpfunc(dumpdata, ";\n");
2432 /* get all array elements */
2433 for (i = 0; i < count; i++)
2435 void *data_ret = NULL;
2437 /* Advance to next chunk */
2438 NEXT_CHUNK(p, size, echnk, ed);
2439 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
2441 eet_data_chunk_get(ed, &echnk, p, size);
2442 if (!echnk.name) goto error;
2444 data_ret = _eet_data_descriptor_decode(context,
2452 if (!data_ret) goto error;
2458 void *data_ret = NULL;
2460 EET_ASSERT(!IS_SIMPLE_TYPE(type), goto error);
2462 data_ret = _eet_data_descriptor_decode(context,
2470 if (!data_ret) goto error;
2477 void *data_ret = NULL;
2480 ret = eet_data_get_type(ed,
2483 ((char *)echnk.data) + echnk.size,
2485 if (ret <= 0) goto error;
2487 /* Advance to next chunk */
2488 NEXT_CHUNK(p, size, echnk, ed);
2489 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
2492 eet_data_chunk_get(ed, &echnk, p, size);
2493 if (!echnk.name) goto error;
2495 EET_ASSERT(!IS_SIMPLE_TYPE(type), goto error);
2503 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
2504 dumpfunc(dumpdata, " key \"");
2505 _eet_data_dump_string_escape(dumpdata, dumpfunc, s);
2506 dumpfunc(dumpdata, "\";\n");
2508 data_ret = _eet_data_descriptor_decode(context,
2528 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
2529 dumpfunc(dumpdata, " }\n");
2533 /* advance to next chunk */
2534 NEXT_CHUNK(p, size, echnk, ed);
2536 _eet_freelist_all_unref(context);
2539 _eet_freelist_str_free(context, edd);
2540 _eet_freelist_direct_str_free(context, edd);
2541 _eet_freelist_list_free(context, edd);
2542 _eet_freelist_hash_free(context, edd);
2543 _eet_freelist_free(context, edd);
2544 _eet_freeleak_reset(context);
2548 _eet_freelist_reset(context);
2549 _eet_freeleak_free(context, edd);
2550 _eet_freelist_str_reset(context);
2551 _eet_freelist_list_reset(context);
2552 _eet_freelist_hash_reset(context);
2553 _eet_freelist_direct_str_reset(context);
2559 if (chnk.type == EET_T_UNKNOW)
2561 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
2562 dumpfunc(dumpdata, "}\n");
2570 _eet_freelist_all_unref(context);
2571 _eet_freelist_str_free(context, edd);
2572 _eet_freelist_direct_str_free(context, edd);
2573 _eet_freelist_list_free(context, edd);
2574 _eet_freelist_hash_free(context, edd);
2575 _eet_freelist_free(context, edd);
2576 _eet_freeleak_reset(context);
2581 if (chnk.type == EET_T_UNKNOW)
2583 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
2584 dumpfunc(dumpdata, "}\n");
2592 eet_data_get_list(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2593 int type __UNUSED__, int group_type __UNUSED__, void *data,
2594 int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
2595 char **p __UNUSED__, int *size __UNUSED__)
2601 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2603 ptr = (void **)data;
2607 if (ede->type >= EET_T_STRING)
2611 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, ede->type, EET_G_UNKNOWN,
2612 &data_ret, level, dumpfunc, dumpdata, p, size);
2617 data_ret = _eet_data_descriptor_decode(context, ed, ede->subtype, echnk->data, echnk->size, level + 2, dumpfunc, dumpdata);
2618 if (!data_ret) return 0;
2621 list = edd->func.list_append(list, data_ret);
2623 _eet_freelist_list_add(context, ptr);
2629 eet_data_get_hash(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2630 int type, int group_type __UNUSED__, void *data,
2631 int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
2632 char **p, int *size)
2637 void *data_ret = NULL;
2640 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2642 ptr = (void **)data;
2646 ret = eet_data_get_type(ed,
2649 ((char *)echnk->data) + echnk->size,
2651 if (ret <= 0) goto on_error;
2653 /* Advance to next chunk */
2654 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2655 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2658 eet_data_chunk_get(ed, echnk, *p, *size);
2659 if (!echnk->name) goto on_error;
2661 if (type >= EET_T_STRING)
2665 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, ede->type, EET_G_UNKNOWN,
2666 &data_ret, level, dumpfunc, dumpdata, p, size);
2671 data_ret = _eet_data_descriptor_decode(context,
2679 if (!data_ret) goto on_error;
2682 hash = edd->func.hash_add(hash, key, data_ret);
2684 _eet_freelist_hash_add(context, ptr);
2691 /* var arrays and fixed arrays have to
2692 * get all chunks at once. for fixed arrays
2693 * we can get each chunk and increment a
2694 * counter stored on the element itself but
2695 * it wont be thread safe. for var arrays
2696 * we still need a way to get the number of
2697 * elements from the data, so storing the
2698 * number of elements and the element data on
2699 * each chunk is pointless.
2702 eet_data_get_array(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__,
2703 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2704 int type, int group_type, void *data,
2705 int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
2706 char **p, int *size)
2715 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2718 /* read the number of elements */
2719 ret = eet_data_get_type(ed,
2722 ((char *)echnk->data) + echnk->size,
2724 if (ret <= 0) return ret;
2726 if (type >= EET_T_STRING)
2727 subsize = eet_basic_codec[ede->type].size;
2729 subsize = ede->subtype->size;
2733 if (group_type == EET_G_VAR_ARRAY)
2735 /* store the number of elements
2736 * on the counter offset */
2737 *(int *)(((char *)data) + ede->count - ede->offset) = count;
2738 /* allocate space for the array of elements */
2739 *(void **)ptr = edd->func.mem_alloc(count * subsize);
2741 if (!*(void **)ptr) return 0;
2743 memset(*(void **)ptr, 0, count * subsize);
2745 _eet_freelist_add(context, *(void **)ptr);
2748 /* get all array elements */
2749 for (i = 0; i < count; i++)
2752 void *data_ret = NULL;
2754 /* Advance to next chunk */
2755 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2756 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2758 eet_data_chunk_get(ed, echnk, *p, *size);
2759 if (!echnk->name || strcmp(echnk->name, name) != 0) return 0;
2762 /* get the destination pointer */
2763 if (group_type == EET_G_ARRAY)
2764 dst = (char *)ptr + (subsize * i);
2766 dst = *(char **)ptr + (subsize * i);
2768 if (type >= EET_T_STRING)
2772 ret = eet_data_get_unknown(context,
2786 memcpy(dst, &data_ret, subsize);
2790 data_ret = _eet_data_descriptor_decode(context,
2798 if (!data_ret) return 0;
2799 memcpy(dst, data_ret, subsize);
2800 _eet_freelist_add(context, data_ret);
2807 eet_data_get_unknown(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2808 int type, int group_type __UNUSED__, void *data,
2809 int level, void (*dumpfunc) (void *data, const char *str), void *dumpdata,
2810 char **p __UNUSED__, int *size __UNUSED__)
2815 if (IS_SIMPLE_TYPE(type))
2817 ret = eet_data_get_type(ed, type, echnk->data, ((char *)echnk->data) + echnk->size, ((char *)data));
2818 if (ret <= 0) return ret;
2820 if (type == EET_T_STRING)
2824 str = (char **)(((char *)data));
2827 if ((ed == NULL) || (edd->func.str_direct_alloc == NULL))
2829 *str = edd->func.str_alloc(*str);
2830 _eet_freelist_str_add(context, *str);
2834 *str = edd->func.str_direct_alloc(*str);
2835 _eet_freelist_direct_str_add(context, *str);
2839 else if (type == EET_T_INLINED_STRING)
2843 str = (char **)(((char *)data));
2846 *str = edd->func.str_alloc(*str);
2847 _eet_freelist_str_add(context, *str);
2851 else if (ede->subtype)
2855 data_ret = _eet_data_descriptor_decode(context, ed, ede->subtype, echnk->data, echnk->size, level + 1, dumpfunc, dumpdata);
2856 if (!data_ret) return 0;
2858 ptr = (void **)(((char *)data));
2859 *ptr = (void *)data_ret;
2866 eet_data_encode(Eet_Dictionary *ed, Eet_Data_Stream *ds, void *data, const char *name, int size, int type, int group_type)
2868 Eet_Data_Chunk *echnk;
2870 echnk = eet_data_chunk_new(data, size, name, type, group_type);
2871 eet_data_chunk_put(ed, echnk, ds);
2872 eet_data_chunk_free(echnk);
2873 if (data) free(data);
2877 eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
2886 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2888 if (ede->group_type == EET_G_ARRAY)
2889 count = ede->counter_offset;
2891 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
2893 if (count <= 0) return;
2894 /* Store number of elements */
2895 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
2896 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2898 if (ede->type >= EET_T_STRING)
2899 subsize = eet_basic_codec[ede->type].size;
2901 subsize = ede->subtype->size;
2903 for (j = 0; j < count; j++)
2908 if (ede->group_type == EET_G_ARRAY)
2909 d = (void *)(((char *)data_in) + offset);
2911 d = *(((char **)data_in)) + offset;
2913 if (ede->type >= EET_T_STRING)
2914 eet_data_put_unknown(ed, NULL, ede, ds, d);
2917 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
2918 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2923 /* Add a NULL element just to have the correct array layout. */
2924 eet_data_encode(ed, ds, NULL, ede->name, 0, EET_T_NULL, ede->group_type);
2932 eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
2937 if (IS_SIMPLE_TYPE(ede->type))
2938 data = eet_data_put_type(ed, ede->type, data_in, &size);
2939 else if (ede->subtype)
2941 if (*((char **)data_in))
2942 data = _eet_data_descriptor_encode(ed,
2944 *((char **)((char *)(data_in))),
2947 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2951 eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
2957 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2959 l = *((void **)(((char *)data_in)));
2960 for (; l; l = edd->func.list_next(l))
2962 if (ede->type >= EET_T_STRING)
2964 const char *str = edd->func.list_data(l);
2965 eet_data_put_unknown(ed, NULL, ede, ds, &str);
2969 data = _eet_data_descriptor_encode(ed,
2971 edd->func.list_data(l),
2973 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2979 eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
2981 Eet_Data_Encode_Hash_Info fdata;
2984 l = *((void **)(((char *)data_in)));
2988 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
2992 eet_data_dump_cipher(Eet_File *ef,
2993 const char *name, const char *key,
2994 void (*dumpfunc) (void *data, const char *str),
2997 const Eet_Dictionary *ed = NULL;
2998 const void *data = NULL;
2999 Eet_Free_Context context;
3001 int required_free = 0;
3004 ed = eet_dictionary_get(ef);
3007 data = eet_read_direct(ef, name, &size);
3011 data = eet_read_cipher(ef, name, &size, key);
3012 if (!data) return 0;
3015 memset(&context, 0, sizeof (context));
3016 if (_eet_data_descriptor_decode(&context, ed, NULL, data, size, 0,
3017 dumpfunc, dumpdata))
3027 eet_data_dump(Eet_File *ef,
3029 void (*dumpfunc) (void *data, const char *str),
3032 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
3037 eet_data_text_dump_cipher(const void *data_in,
3038 const char *key, int size_in,
3039 void (*dumpfunc) (void *data, const char *str),
3043 Eet_Free_Context context;
3044 unsigned int ret_len = 0;
3048 if (eet_decipher(data_in, size_in, key, strlen(key), &ret, &ret_len))
3053 memset(&context, 0, sizeof (context));
3054 if (_eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len, 0,
3055 dumpfunc, dumpdata))
3063 memset(&context, 0, sizeof (context));
3064 if (_eet_data_descriptor_decode(&context, NULL, NULL, data_in, size_in, 0,
3065 dumpfunc, dumpdata))
3071 eet_data_text_dump(const void *data_in,
3073 void (*dumpfunc) (void *data, const char *str),
3076 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
3080 eet_data_text_undump_cipher(const char *text,
3087 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
3090 void *ciphered = NULL;
3091 unsigned int ciphered_len;
3093 if (eet_cipher(ret, *size_ret, key, strlen(key), &ciphered, &ciphered_len))
3095 if (ciphered) free(ciphered);
3101 *size_ret = ciphered_len;
3108 eet_data_text_undump(const char *text,
3112 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
3116 eet_data_undump_cipher(Eet_File *ef,
3128 ed = eet_dictionary_get(ef);
3130 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
3131 if (!data_enc) return 0;
3132 val = eet_write_cipher(ef, name, data_enc, size, compress, key);
3138 eet_data_undump(Eet_File *ef,
3144 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
3148 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
3149 const void *data_in,
3153 void *deciphered = NULL;
3155 Eet_Free_Context context;
3156 unsigned int deciphered_len = 0;
3160 if (eet_decipher(data_in, size_in, key, strlen(key), &deciphered, &deciphered_len))
3162 if (deciphered) free(deciphered);
3165 memset(&context, 0, sizeof (context));
3166 ret = _eet_data_descriptor_decode(&context, NULL, edd, deciphered, deciphered_len, 0,
3171 memset(&context, 0, sizeof (context));
3172 return _eet_data_descriptor_decode(&context, NULL, edd, data_in, size_in, 0,
3177 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
3178 const void *data_in,
3181 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
3185 _eet_data_descriptor_encode(Eet_Dictionary *ed,
3186 Eet_Data_Descriptor *edd,
3187 const void *data_in,
3190 Eet_Data_Stream *ds;
3191 Eet_Data_Chunk *chnk;
3196 if (words_bigendian == -1)
3198 unsigned long int v;
3200 v = htonl(0x12345678);
3201 if (v == 0x12345678) words_bigendian = 1;
3202 else words_bigendian = 0;
3205 ds = eet_data_stream_new();
3206 for (i = 0; i < edd->elements.num; i++)
3208 Eet_Data_Element *ede;
3210 ede = &(edd->elements.set[i]);
3211 eet_group_codec[ede->group_type - 100].put(ed, edd, ede, ds, ((char *)data_in) + ede->offset);
3213 chnk = eet_data_chunk_new(ds->data, ds->pos, edd->name, EET_T_UNKNOW, EET_G_UNKNOWN);
3216 eet_data_stream_free(ds);
3218 ds = eet_data_stream_new();
3219 eet_data_chunk_put(ed, chnk, ds);
3225 eet_data_stream_free(ds);
3229 eet_data_chunk_free(chnk);
3235 eet_data_node_write_cipher(Eet_File *ef, const char *name, const char *key, Eet_Node *node, int compress)
3242 ed = eet_dictionary_get(ef);
3244 data_enc = _eet_data_dump_encode(ed, node, &size);
3245 if (!data_enc) return 0;
3246 val = eet_write_cipher(ef, name, data_enc, size, compress, key);
3252 eet_data_node_encode_cipher(Eet_Node *node,
3257 void *ciphered = NULL;
3258 unsigned int ciphered_len = 0;
3261 ret = _eet_data_dump_encode(NULL, node, &size);
3264 if (eet_cipher(ret, size, key, strlen(key), &ciphered, &ciphered_len))
3266 if (ciphered) free(ciphered);
3267 if (size_ret) *size_ret = 0;
3272 size = (int) ciphered_len;
3276 if (size_ret) *size_ret = size;
3281 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
3282 const void *data_in,
3287 void *ciphered = NULL;
3288 unsigned int ciphered_len = 0;
3291 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
3294 if (eet_cipher(ret, size, key, strlen(key), &ciphered, &ciphered_len))
3296 if (ciphered) free(ciphered);
3297 if (size_ret) *size_ret = 0;
3302 size = ciphered_len;
3306 if (size_ret) *size_ret = size;
3311 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
3312 const void *data_in,
3315 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);