2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
15 #ifdef HAVE_NETINET_IN_H
16 # include <netinet/in.h>
20 # include <winsock2.h>
26 #include "Eet_private.h"
29 * routines for doing data -> struct and struct -> data conversion
49 * multiple entries ordered as...
51 * fixed size array [ of basic types ]
52 * variable size array [ of basic types ]
53 * linked list [ of basic types ]
54 * hash table [ of basic types ]
56 * need to provide builder/accessor funcs for:
68 typedef struct _Eet_Data_Element Eet_Data_Element;
69 typedef struct _Eet_Data_Basic_Type_Codec Eet_Data_Basic_Type_Codec;
70 typedef struct _Eet_Data_Group_Type_Codec Eet_Data_Group_Type_Codec;
71 typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
72 typedef struct _Eet_Data_Stream Eet_Data_Stream;
73 typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash;
74 typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info;
75 typedef struct _Eet_Free Eet_Free;
76 typedef struct _Eet_Free_Context Eet_Free_Context;
81 * Eet_Data_Basic_Type_Codec (Coder, Decoder)
82 * Eet_Data_Group_Type_Codec (Coder, Decoder)
84 struct _Eet_Data_Basic_Type_Codec
88 int (*get) (const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
89 void *(*put) (Eet_Dictionary *ed, const void *src, int *size_ret);
92 struct _Eet_Data_Group_Type_Codec
94 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, char **p, int *size);
95 void (*put) (Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
98 struct _Eet_Data_Chunk
106 unsigned char group_type;
109 struct _Eet_Data_Stream
116 struct _Eet_Data_Descriptor_Hash
118 Eet_Data_Element *element;
119 Eet_Data_Descriptor_Hash *next;
122 struct _Eet_Data_Descriptor
125 const Eet_Dictionary *ed;
128 void *(*mem_alloc) (size_t size);
129 void (*mem_free) (void *mem);
130 char *(*str_alloc) (const char *str);
131 char *(*str_direct_alloc) (const char *str);
132 void (*str_free) (const char *str);
133 void (*str_direct_free) (const char *str);
134 void *(*list_next) (void *l);
135 void *(*list_append) (void *l, void *d);
136 void *(*list_data) (void *l);
137 void *(*list_free) (void *l);
138 void (*hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt);
139 void *(*hash_add) (void *h, const char *k, void *d);
140 void (*hash_free) (void *h);
144 Eet_Data_Element *set;
147 Eet_Data_Descriptor_Hash *buckets;
154 struct _Eet_Data_Element
157 const char *counter_name;
158 const char *directory_name_ptr;
159 Eet_Data_Descriptor *subtype;
160 int offset; /* offset in bytes from the base element */
161 int count; /* number of elements for a fixed array */
162 int counter_offset; /* for a variable array we need the offset of the count variable */
163 unsigned char type; /* EET_T_XXX */
164 unsigned char group_type; /* EET_G_XXX */
167 struct _Eet_Data_Encode_Hash_Info
170 Eet_Data_Element *ede;
182 struct _Eet_Free_Context
185 Eet_Free freelist_list;
186 Eet_Free freelist_hash;
187 Eet_Free freelist_str;
188 Eet_Free freelist_direct_str;
193 static int eet_data_get_char(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
194 static void *eet_data_put_char(Eet_Dictionary *ed, const void *src, int *size_ret);
195 static int eet_data_get_short(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
196 static void *eet_data_put_short(Eet_Dictionary *ed, const void *src, int *size_ret);
197 static inline int eet_data_get_int(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
198 static void *eet_data_put_int(Eet_Dictionary *ed, const void *src, int *size_ret);
199 static int eet_data_get_long_long(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
200 static void *eet_data_put_long_long(Eet_Dictionary *ed, const void *src, int *size_ret);
201 static int eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
202 static void *eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret);
203 static int eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
204 static void *eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret);
205 static int eet_data_get_f32p32(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
206 static void *eet_data_put_f32p32(Eet_Dictionary *ed, const void *src, int *size_ret);
207 static int eet_data_get_f16p16(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
208 static void *eet_data_put_f16p16(Eet_Dictionary *ed, const void *src, int *size_ret);
209 static int eet_data_get_f8p24(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
210 static void *eet_data_put_f8p24(Eet_Dictionary *ed, const void *src, int *size_ret);
211 static inline int eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
212 static void *eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret);
213 static int eet_data_get_istring(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
214 static void *eet_data_put_istring(Eet_Dictionary *ed, const void *src, int *size_ret);
215 static int eet_data_get_null(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
216 static void *eet_data_put_null(Eet_Dictionary *ed, const void *src, int *size_ret);
218 static int eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest);
219 static void *eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret);
221 static Eet_Node *eet_data_node_simple_type(int type, const char *name, void *dd);
223 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, char **p, int *size);
224 static void eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
225 static void eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
226 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, char **p, int *size);
227 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, char **p, int *size);
228 static void eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
229 static void eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
230 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, char **p, int *size);
232 static void eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk, const void *src, int size);
233 static Eet_Data_Chunk *eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type);
234 static void eet_data_chunk_free(Eet_Data_Chunk *chnk);
236 static Eet_Data_Stream *eet_data_stream_new(void);
237 static void eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size);
238 static void eet_data_stream_free(Eet_Data_Stream *ds);
240 static void eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds);
242 static int eet_data_descriptor_encode_hash_cb(void *hash, const char *key, void *hdata, void *fdata);
243 static void *_eet_data_descriptor_encode(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, const void *data_in, int *size_ret);
244 static void *_eet_data_descriptor_decode(Eet_Free_Context *context,
245 const Eet_Dictionary *ed,
246 Eet_Data_Descriptor *edd,
252 static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
254 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
255 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
256 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
257 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
258 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
259 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
260 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
261 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
262 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
263 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
264 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
265 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
266 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
267 {sizeof(Eina_F32p32),"f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
268 {sizeof(Eina_F16p16),"f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
269 {sizeof(Eina_F8p24),"f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
272 static const Eet_Data_Group_Type_Codec eet_group_codec[] =
274 { eet_data_get_unknown, eet_data_put_unknown },
275 { eet_data_get_array, eet_data_put_array },
276 { eet_data_get_array, eet_data_put_array },
277 { eet_data_get_list, eet_data_put_list },
278 { eet_data_get_hash, eet_data_put_hash }
281 static int _eet_data_words_bigendian = -1;
285 #define SWAP64(x) (x) = \
286 ((((unsigned long long)(x) & 0x00000000000000ffULL ) << 56) |\
287 (((unsigned long long)(x) & 0x000000000000ff00ULL ) << 40) |\
288 (((unsigned long long)(x) & 0x0000000000ff0000ULL ) << 24) |\
289 (((unsigned long long)(x) & 0x00000000ff000000ULL ) << 8) |\
290 (((unsigned long long)(x) & 0x000000ff00000000ULL ) >> 8) |\
291 (((unsigned long long)(x) & 0x0000ff0000000000ULL ) >> 24) |\
292 (((unsigned long long)(x) & 0x00ff000000000000ULL ) >> 40) |\
293 (((unsigned long long)(x) & 0xff00000000000000ULL ) >> 56))
294 #define SWAP32(x) (x) = \
295 ((((int)(x) & 0x000000ff ) << 24) |\
296 (((int)(x) & 0x0000ff00 ) << 8) |\
297 (((int)(x) & 0x00ff0000 ) >> 8) |\
298 (((int)(x) & 0xff000000 ) >> 24))
299 #define SWAP16(x) (x) = \
300 ((((short)(x) & 0x00ff ) << 8) |\
301 (((short)(x) & 0xff00 ) >> 8))
317 #define CONV16(x) {if (_eet_data_words_bigendian) SWAP16(x);}
318 #define CONV32(x) {if (_eet_data_words_bigendian) SWAP32(x);}
319 #define CONV64(x) {if (_eet_data_words_bigendian) SWAP64(x);}
321 #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
322 #define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL)
324 #define EET_I_STRING 1 << 4
325 #define EET_I_INLINED_STRING 2 << 4
326 #define EET_I_NULL 3 << 4
332 eet_data_get_char(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
336 if (((char *)src + sizeof(char)) > (char *)src_end) return -1;
345 eet_data_put_char(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
349 d = (char *)malloc(sizeof(char));
354 *size_ret = sizeof(char);
360 eet_data_get_short(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
364 if (((char *)src + sizeof(short)) > (char *)src_end) return -1;
365 memcpy(dst, src, sizeof(short));
368 return sizeof(short);
372 eet_data_put_short(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
376 d = (short *)malloc(sizeof(short));
381 *size_ret = sizeof(short);
387 eet_data_get_int(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
391 if (((char *)src + sizeof(int)) > (char *)src_end) return -1;
392 memcpy(dst, src, sizeof(int));
399 eet_data_put_int(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
403 d = (int *)malloc(sizeof(int));
408 *size_ret = sizeof(int);
414 eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
416 unsigned long long *d;
418 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end) return -1;
419 memcpy(dst, src, sizeof(unsigned long long));
420 d = (unsigned long long *)dst;
422 return sizeof(unsigned long long);
426 eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
428 unsigned long long *s, *d;
430 d = (unsigned long long *)malloc(sizeof(unsigned long long));
432 s = (unsigned long long *)src;
435 *size_ret = sizeof(unsigned long long);
441 eet_data_get_string_hash(const Eet_Dictionary *ed, const void *src, const void *src_end)
447 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
449 return eet_dictionary_string_get_hash(ed, idx);
456 eet_data_get_string(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
467 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
469 str = eet_dictionary_string_get_char(ed, idx);
474 return eet_dictionary_string_get_size(ed, idx);
485 return strlen(s) + 1;
489 eet_data_put_string(Eet_Dictionary *ed, const void *src, int *size_ret)
499 str = *((const char **) src);
500 if (!str) return NULL;
502 idx = eet_dictionary_string_add(ed, str);
503 if (idx == -1) return NULL;
505 return eet_data_put_int(ed, &idx, size_ret);
508 s = (char *)(*((char **)src));
513 memcpy(d, s, len + 1);
518 /* ALWAYS INLINED STRING TYPE */
520 eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__, const void *src, const void *src_end, void *dst)
522 return eet_data_get_string(NULL, src, src_end, dst);
526 eet_data_put_istring(Eet_Dictionary *ed __UNUSED__, const void *src, int *size_ret)
528 return eet_data_put_string(NULL, src, size_ret);
531 /* ALWAYS NULL TYPE */
533 eet_data_get_null(const Eet_Dictionary *ed __UNUSED__, const void *src __UNUSED__, const void *src_end __UNUSED__, void *dst)
544 eet_data_put_null(Eet_Dictionary *ed __UNUSED__, const void *src __UNUSED__, int *size_ret)
551 * Fast lookups of simple doubles/floats.
553 * These aren't properly a cache because they don't store pre-calculated
554 * values, but have a so simple math that is almost as fast.
557 _eet_data_float_cache_get(const char *s, int len, float *d)
559 /* fast handle of simple case 0xMp+E*/
560 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
562 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
563 int exponent = (s[5] - '0');
565 if (s[4] == '+') *d = (float)(mantisse << exponent);
566 else *d = (float)mantisse / (float)(1 << exponent);
574 _eet_data_double_cache_get(const char *s, int len, double *d)
576 /* fast handle of simple case 0xMp+E*/
577 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
579 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
580 int exponent = (s[5] - '0');
582 if (s[4] == '+') *d = (double)(mantisse << exponent);
583 else *d = (double)mantisse / (double)(1 << exponent);
592 eet_data_get_float(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
605 s = (const char *)src;
608 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
610 if (_eet_data_float_cache_get(s, len, d) != 0) return len + 1;
612 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) return -1;
613 *d = (float)ldexp((double)mantisse, exponent);
618 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
620 if (!eet_dictionary_string_get_float(ed, idx, d))
626 eet_data_put_float(Eet_Dictionary *ed, const void *src, int *size_ret)
631 eina_convert_dtoa((double)(*(float *)src), buf);
641 memcpy(d, buf, len + 1);
646 idx = eet_dictionary_string_add(ed, buf);
647 if (idx == -1) return NULL;
649 return eet_data_put_int(ed, &idx, size_ret);
654 eet_data_get_double(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
664 long long mantisse = 0;
668 s = (const char *) src;
671 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++;}
673 if (_eet_data_double_cache_get(s, len, d) != 0) return len + 1;
675 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE) return -1;
676 *d = ldexp((double) mantisse, exponent);
681 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
683 if (!eet_dictionary_string_get_double(ed, idx, d))
689 eet_data_put_double(Eet_Dictionary *ed, const void *src, int *size_ret)
694 eina_convert_dtoa((double)(*(double *)src), buf);
704 memcpy(d, buf, len + 1);
710 idx = eet_dictionary_string_add(ed, buf);
711 if (idx == -1) return NULL;
713 return eet_data_put_int(ed, &idx, size_ret);
717 eet_data_get_f32p32(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
722 fp = (Eina_F32p32*) dst;
729 s = (const char *) src;
732 while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; }
734 if (!(eina_convert_atofp(s, len, fp)))
739 if (eet_data_get_int(ed, src, src_end, &idx) < 0) return -1;
741 if (!eet_dictionary_string_get_fp(ed, idx, fp))
747 eet_data_put_f32p32(Eet_Dictionary *ed, const void *src, int *size_ret)
752 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
762 memcpy(d, buf, len + 1);
768 idx = eet_dictionary_string_add(ed, buf);
769 if (idx == -1) return NULL;
771 return eet_data_put_int(ed, &idx, size_ret);
775 eet_data_get_f16p16(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
780 fp = (Eina_F16p16*) dst;
782 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) return -1;
784 *fp = eina_f32p32_to_f16p16(tmp);
789 eet_data_put_f16p16(Eet_Dictionary *ed, const void *src, int *size_ret)
793 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
794 return eet_data_put_f32p32(ed, &tmp, size_ret);
798 eet_data_get_f8p24(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dst)
803 fp = (Eina_F8p24*) dst;
805 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0) return -1;
807 *fp = eina_f32p32_to_f8p24(tmp);
812 eet_data_put_f8p24(Eet_Dictionary *ed, const void *src, int *size_ret)
816 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
817 return eet_data_put_f32p32(ed, &tmp, size_ret);
821 eet_data_get_type(const Eet_Dictionary *ed, int type, const void *src, const void *src_end, void *dest)
825 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
830 eet_data_put_type(Eet_Dictionary *ed, int type, const void *src, int *size_ret)
834 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
838 static inline Eina_Bool
839 eet_data_type_match(int type1, int type2)
841 if (type1 == type2) return EINA_TRUE;
843 /* Note: All floating point type are equivalent and could be read
844 without problem by any other floating point getter. */
873 * char[4] = "CHnK"; // untyped data ... or
874 * char[4] = "CHKx"; // typed data - x == type
876 * int = chunk size (including magic string);
877 * char[] = chunk magic/name string (0 byte terminated);
878 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
880 * ... payload data ...
885 eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk,
886 const void *src, int size)
892 if (size <= 8) return;
898 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
901 chnk->type = (unsigned char)(s[3]);
902 if (chnk->type >= EET_I_LIMIT)
904 chnk->group_type = ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
905 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
907 #define EET_UNMATCH_TYPE(Type) \
908 case EET_I_##Type: chnk->type = EET_T_##Type; break;
910 EET_UNMATCH_TYPE(STRING);
911 EET_UNMATCH_TYPE(INLINED_STRING);
912 EET_UNMATCH_TYPE(NULL);
917 else if (chnk->type > EET_T_LAST)
919 chnk->group_type = chnk->type;
920 chnk->type = EET_T_UNKNOW;
923 chnk->group_type = EET_G_UNKNOWN;
924 if ((chnk->type >= EET_T_LAST) ||
925 (chnk->group_type >= EET_G_LAST))
928 chnk->group_type = 0;
933 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
936 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
938 if (ret1 <= 0) return;
939 if ((chnk->size < 0) || ((chnk->size + 8) > size)) return;
940 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
942 if (ret2 <= 0) return;
947 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
951 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
952 chnk->size -= sizeof(int);
956 chnk->data = (char *)src + 4 + ret1 + chnk->len;
957 chnk->size -= chnk->len;
963 static inline Eet_Data_Chunk *
964 eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type)
966 Eet_Data_Chunk *chnk;
968 if (!name) return NULL;
969 chnk = calloc(1, sizeof(Eet_Data_Chunk));
970 if (!chnk) return NULL;
972 /* Note: Another security, so older eet library could read file
973 saved with fixed point value. */
974 if (type == EET_T_F32P32
975 || type == EET_T_F16P16
976 || type == EET_T_F8P24)
979 chnk->name = strdup(name);
980 chnk->len = strlen(name) + 1;
984 chnk->group_type = group_type;
989 eet_data_chunk_free(Eet_Data_Chunk *chnk)
991 if (chnk->name) free(chnk->name);
995 static inline Eet_Data_Stream *
996 eet_data_stream_new(void)
1000 ds = calloc(1, sizeof(Eet_Data_Stream));
1001 if (!ds) return NULL;
1006 eet_data_stream_free(Eet_Data_Stream *ds)
1008 if (ds->data) free(ds->data);
1013 eet_data_stream_flush(Eet_Data_Stream *ds)
1019 eet_data_stream_write(Eet_Data_Stream *ds, const void *data, int size)
1023 if ((ds->pos + size) > ds->size)
1025 ds->data = realloc(ds->data, ds->size + size + 512);
1032 ds->size = ds->size + size + 512;
1035 memcpy(p + ds->pos, data, size);
1040 eet_data_chunk_put(Eet_Dictionary *ed, Eet_Data_Chunk *chnk, Eet_Data_Stream *ds)
1047 unsigned char buf[4] = "CHK";
1049 /* disable this check - it will allow empty chunks to be written. this is
1050 * right for corner-cases when y have a struct with empty fields (empty
1051 * strings or empty list ptrs etc.) */
1052 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1055 /* eet_data_stream_write(ds, "CHnK", 4);*/
1056 if (chnk->type != EET_T_UNKNOW)
1058 if (chnk->group_type != EET_G_UNKNOWN)
1060 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1064 /* Only make sense with pointer type. */
1065 #define EET_MATCH_TYPE(Type) \
1066 case EET_T_##Type: type += EET_I_##Type; break;
1068 EET_MATCH_TYPE(STRING);
1069 EET_MATCH_TYPE(INLINED_STRING);
1070 EET_MATCH_TYPE(NULL);
1078 buf[3] = chnk->type;
1080 else buf[3] = chnk->group_type;
1082 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1086 /* size of chunk payload data + name */
1087 s = chnk->size + string_ret;
1088 size = eet_data_put_int(ed, &s, &size_ret);
1090 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1094 eet_data_stream_write(ds, buf, 4);
1096 /* write chunk length */
1097 eet_data_stream_write(ds, size, size_ret);
1099 /* write chunk name */
1100 eet_data_stream_write(ds, string, string_ret);
1104 eet_data_stream_write(ds, chnk->data, chnk->size);
1114 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1118 edd->elements.hash.size = 1 << 6;
1119 edd->elements.hash.buckets = calloc(1, sizeof(Eet_Data_Descriptor_Hash) * edd->elements.hash.size);
1120 for (i = 0; i < edd->elements.num; i++)
1122 Eet_Data_Element *ede;
1125 ede = &(edd->elements.set[i]);
1126 hash = _eet_hash_gen((char *) ede->name, 6);
1127 if (!edd->elements.hash.buckets[hash].element)
1128 edd->elements.hash.buckets[hash].element = ede;
1131 Eet_Data_Descriptor_Hash *bucket;
1133 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1134 bucket->element = ede;
1135 bucket->next = edd->elements.hash.buckets[hash].next;
1136 edd->elements.hash.buckets[hash].next = bucket;
1142 _eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1146 for (i = 0; i < edd->elements.hash.size; i++)
1148 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1150 bucket = edd->elements.hash.buckets[i].next;
1154 bucket = bucket->next;
1158 if (edd->elements.hash.buckets) free(edd->elements.hash.buckets);
1161 static Eet_Data_Element *
1162 _eet_descriptor_hash_find(Eet_Data_Descriptor *edd, char *name, int hash)
1164 Eet_Data_Descriptor_Hash *bucket;
1166 if (hash < 0) hash = _eet_hash_gen(name, 6);
1168 if (!edd->elements.hash.buckets[hash].element) return NULL;
1170 When we use the dictionnary as a source for chunk name, we will always
1171 have the same pointer in name. It's a good idea to just compare pointer
1172 instead of running strcmp on both string.
1174 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1175 return edd->elements.hash.buckets[hash].element;
1176 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1178 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1179 return edd->elements.hash.buckets[hash].element;
1181 bucket = edd->elements.hash.buckets[hash].next;
1184 if (bucket->element->directory_name_ptr == name) return bucket->element;
1185 if (!strcmp(bucket->element->name, name))
1187 bucket->element->directory_name_ptr = name;
1188 return bucket->element;
1190 bucket = bucket->next;
1196 _eet_mem_alloc(size_t size)
1198 return calloc(1, size);
1202 _eet_mem_free(void *mem)
1208 _eet_str_alloc(const char *str)
1214 _eet_str_free(const char *str)
1220 _eet_eina_hash_add_alloc(Eina_Hash *hash, const char *key, void *data)
1222 if (!hash) hash = eina_hash_string_small_new(NULL);
1223 if (!hash) return NULL;
1225 eina_hash_add(hash, key, data);
1230 _eet_eina_hash_direct_add_alloc(Eina_Hash *hash, const char *key, void *data)
1232 if (!hash) hash = eina_hash_string_small_new(NULL);
1233 if (!hash) return NULL;
1235 eina_hash_direct_add(hash, key, data);
1240 _eet_str_direct_alloc(const char *str)
1246 _eet_str_direct_free(__UNUSED__ const char *str)
1251 _eet_eina_hash_foreach(void *hash, Eina_Hash_Foreach cb, void *fdata)
1253 if (hash) eina_hash_foreach(hash, cb, fdata);
1257 _eet_eina_hash_free(void *hash)
1259 if (hash) eina_hash_free(hash);
1264 eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc, const char *name, int size)
1266 if (!eddc || !name) return EINA_FALSE;
1272 eddc->func.mem_alloc = _eet_mem_alloc;
1273 eddc->func.mem_free = _eet_mem_free;
1274 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1275 eddc->func.str_free = eina_stringshare_del;
1276 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1277 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1278 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1279 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1280 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach;
1281 eddc->func.hash_add = (void* (*)(void *, const char *, void *)) _eet_eina_hash_add_alloc;
1282 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1288 eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc, const char *name, int size)
1290 if (!eet_eina_stream_data_descriptor_class_set(eddc, name, size))
1295 eddc->func.hash_add = (void* (*)(void *, const char *, void *)) _eet_eina_hash_direct_add_alloc;
1296 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1297 eddc->func.str_direct_free = _eet_str_direct_free;
1302 static Eet_Data_Descriptor *
1303 _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc, int version)
1305 Eet_Data_Descriptor *edd;
1307 if (!eddc) return NULL;
1308 if (eddc->version < version) return NULL;
1310 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1311 if (!edd) return NULL;
1313 edd->name = eddc->name;
1315 edd->size = eddc->size;
1316 edd->func.mem_alloc = _eet_mem_alloc;
1317 edd->func.mem_free = _eet_mem_free;
1318 edd->func.str_alloc = _eet_str_alloc;
1319 edd->func.str_free = _eet_str_free;
1320 if (eddc->func.mem_alloc)
1321 edd->func.mem_alloc = eddc->func.mem_alloc;
1322 if (eddc->func.mem_free)
1323 edd->func.mem_free = eddc->func.mem_free;
1324 if (eddc->func.str_alloc)
1325 edd->func.str_alloc = eddc->func.str_alloc;
1326 if (eddc->func.str_free)
1327 edd->func.str_free = eddc->func.str_free;
1328 edd->func.list_next = eddc->func.list_next;
1329 edd->func.list_append = eddc->func.list_append;
1330 edd->func.list_data = eddc->func.list_data;
1331 edd->func.list_free = eddc->func.list_free;
1332 edd->func.hash_foreach = eddc->func.hash_foreach;
1333 edd->func.hash_add = eddc->func.hash_add;
1334 edd->func.hash_free = eddc->func.hash_free;
1338 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1339 edd->func.str_direct_free = eddc->func.str_direct_free;
1345 EAPI Eet_Data_Descriptor *
1346 eet_data_descriptor_new(const char *name,
1348 void *(*func_list_next) (void *l),
1349 void *(*func_list_append) (void *l, void *d),
1350 void *(*func_list_data) (void *l),
1351 void *(*func_list_free) (void *l),
1352 void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt),
1353 void *(*func_hash_add) (void *h, const char *k, void *d),
1354 void (*func_hash_free) (void *h))
1356 Eet_Data_Descriptor_Class eddc;
1358 if (!name) return NULL;
1360 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1366 eddc.func.list_next = func_list_next;
1367 eddc.func.list_append = func_list_append;
1368 eddc.func.list_data = func_list_data;
1369 eddc.func.list_free = func_list_free;
1370 eddc.func.hash_foreach = func_hash_foreach;
1371 eddc.func.hash_add = func_hash_add;
1372 eddc.func.hash_free = func_hash_free;
1374 return _eet_data_descriptor_new(&eddc, 0);
1377 EAPI Eet_Data_Descriptor *
1378 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1380 return _eet_data_descriptor_new(eddc, 1);
1383 EAPI Eet_Data_Descriptor *
1384 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1386 return _eet_data_descriptor_new(eddc, 2);
1389 EAPI Eet_Data_Descriptor *
1390 eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1392 return _eet_data_descriptor_new(eddc, 1);
1395 EAPI Eet_Data_Descriptor *
1396 eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1398 return _eet_data_descriptor_new(eddc, 2);
1402 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1405 _eet_descriptor_hash_free(edd);
1406 if (edd->elements.set) free(edd->elements.set);
1411 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1417 /* int counter_offset, */
1418 const char *counter_name /* FIXME: Useless should go on a major release */,
1419 Eet_Data_Descriptor *subtype)
1421 Eet_Data_Element *ede;
1422 Eet_Data_Element *tmp;
1424 edd->elements.num++;
1425 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1427 edd->elements.set = tmp;
1428 ede = &(edd->elements.set[edd->elements.num - 1]);
1430 ede->directory_name_ptr = NULL;
1433 * We do a special case when we do list,hash or whatever group of simple type.
1434 * Instead of handling it in encode/decode/dump/undump, we create an
1435 * implicit structure with only the simple type.
1437 if (group_type > EET_G_UNKNOWN
1438 && group_type < EET_G_LAST
1439 && ((type > EET_T_UNKNOW && type < EET_T_STRING)
1440 || (type > EET_T_NULL && type < EET_T_LAST))
1443 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
1444 if (!subtype) return ;
1445 subtype->name = "implicit";
1446 subtype->size = eet_basic_codec[type - 1].size;
1447 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
1449 eet_data_descriptor_element_add(subtype, eet_basic_codec[type - 1].name, type,
1450 EET_G_UNKNOWN, 0, 0, /* 0, */NULL, NULL);
1451 type = EET_T_UNKNOW;
1455 ede->group_type = group_type;
1456 ede->offset = offset;
1458 /* FIXME: For the time being, EET_G_VAR_ARRAY will put the counter_offset in count. */
1459 ede->counter_offset = count;
1460 /* ede->counter_offset = counter_offset; */
1461 ede->counter_name = counter_name;
1463 ede->subtype = subtype;
1467 eet_data_read_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *cipher_key)
1469 const Eet_Dictionary *ed = NULL;
1470 const void *data = NULL;
1472 Eet_Free_Context context;
1473 int required_free = 0;
1476 ed = eet_dictionary_get(ef);
1479 data = eet_read_direct(ef, name, &size);
1483 data = eet_read_cipher(ef, name, &size, cipher_key);
1484 if (!data) return NULL;
1487 memset(&context, 0, sizeof (context));
1488 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size);
1496 eet_data_node_read_cipher(Eet_File *ef, const char *name, const char *cipher_key)
1498 const Eet_Dictionary *ed = NULL;
1499 const void *data = NULL;
1501 Eet_Free_Context context;
1502 int required_free = 0;
1505 ed = eet_dictionary_get(ef);
1508 data = eet_read_direct(ef, name, &size);
1512 data = eet_read_cipher(ef, name, &size, cipher_key);
1513 if (!data) return NULL;
1516 memset(&context, 0, sizeof (context));
1517 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
1525 eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
1527 return eet_data_read_cipher(ef, edd, name, NULL);
1531 eet_data_write_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *cipher_key, const void *data, int compress)
1538 ed = eet_dictionary_get(ef);
1540 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
1541 if (!data_enc) return 0;
1542 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
1548 eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
1550 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
1554 _eet_free_hash(void *data)
1556 unsigned long ptr = (unsigned long)(data);
1575 _eet_free_add(Eet_Free *ef, void *data)
1580 hash = _eet_free_hash(data);
1582 for (i = 0; i < ef->num[hash]; ++i)
1583 if (ef->list[hash][i] == data) return;
1586 if (ef->num[hash] > ef->len[hash])
1590 tmp = realloc(ef->list[hash], (ef->len[hash] + 16) * sizeof(void*));
1593 ef->len[hash] += 16;
1594 ef->list[hash] = tmp;
1596 ef->list[hash][ef->num[hash] - 1] = data;
1599 _eet_free_reset(Eet_Free *ef)
1603 if (ef->ref > 0) return ;
1604 for (i = 0; i < 256; ++i)
1608 if (ef->list[i]) free(ef->list[i]);
1613 _eet_free_ref(Eet_Free *ef)
1618 _eet_free_unref(Eet_Free *ef)
1623 #define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
1624 #define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
1625 #define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
1626 #define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
1629 _eet_freelist_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1634 if (context->freelist.ref > 0) return;
1635 for (j = 0; j < 256; ++j)
1636 for (i = 0; i < context->freelist.num[j]; ++i)
1639 edd->func.mem_free(context->freelist.list[j][i]);
1641 free(context->freelist.list[j][i]);
1643 _eet_free_reset(&context->freelist);
1646 #define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
1647 #define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
1648 #define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
1649 #define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
1652 _eet_freelist_list_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1657 if (context->freelist_list.ref > 0) return;
1658 for (j = 0; j < 256; ++j)
1659 for (i = 0; i < context->freelist_list.num[j]; ++i)
1662 edd->func.list_free(*((void**)(context->freelist_list.list[j][i])));
1664 _eet_free_reset(&context->freelist_list);
1667 #define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
1668 #define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
1669 #define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
1670 #define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
1673 _eet_freelist_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1678 if (context->freelist_str.ref > 0) return;
1679 for (j = 0; j < 256; ++j)
1680 for (i = 0; i < context->freelist_str.num[j]; ++i)
1683 edd->func.str_free(context->freelist_str.list[j][i]);
1685 free(context->freelist_str.list[j][i]);
1687 _eet_free_reset(&context->freelist_str);
1690 #define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
1691 #define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
1692 #define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
1693 #define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
1696 _eet_freelist_direct_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1701 if (context->freelist_direct_str.ref > 0) return;
1702 for (j = 0; j < 256; ++j)
1703 for (i = 0; i < context->freelist_direct_str.num[j]; ++i)
1706 edd->func.str_direct_free(context->freelist_direct_str.list[j][i]);
1708 free(context->freelist_direct_str.list[j][i]);
1710 _eet_free_reset(&context->freelist_direct_str);
1713 #define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
1714 #define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
1715 #define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
1716 #define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
1719 _eet_freelist_hash_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
1724 if (context->freelist_hash.ref > 0) return;
1725 for (j = 0; j < 256; ++j)
1726 for (i = 0; i < context->freelist_hash.num[j]; ++i)
1729 edd->func.hash_free(context->freelist_hash.list[j][i]);
1731 free(context->freelist_hash.list[j][i]);
1733 _eet_free_reset(&context->freelist_hash);
1737 _eet_freelist_all_ref(Eet_Free_Context *freelist_context)
1739 _eet_freelist_ref(freelist_context);
1740 _eet_freelist_str_ref(freelist_context);
1741 _eet_freelist_list_ref(freelist_context);
1742 _eet_freelist_hash_ref(freelist_context);
1743 _eet_freelist_direct_str_ref(freelist_context);
1747 _eet_freelist_all_unref(Eet_Free_Context *freelist_context)
1749 _eet_freelist_unref(freelist_context);
1750 _eet_freelist_str_unref(freelist_context);
1751 _eet_freelist_list_unref(freelist_context);
1752 _eet_freelist_hash_unref(freelist_context);
1753 _eet_freelist_direct_str_unref(freelist_context);
1757 eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__, const char *cipher_key, void *hdata, void *fdata)
1760 Eet_Data_Encode_Hash_Info *edehi;
1761 Eet_Data_Stream *ds;
1762 Eet_Data_Element *ede;
1763 Eet_Data_Chunk *echnk;
1773 data = eet_data_put_type(ed,
1779 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
1780 eet_data_chunk_put(ed, echnk, ds);
1781 eet_data_chunk_free(echnk);
1786 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
1789 if (ede->type >= EET_T_STRING)
1790 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
1794 data = _eet_data_descriptor_encode(ed,
1800 echnk = eet_data_chunk_new(data, size, ede->name, ede->type, ede->group_type);
1801 eet_data_chunk_put(ed, echnk, ds);
1802 eet_data_chunk_free(echnk);
1812 _eet_data_dump_token_get(const char *src, int *len)
1818 int tlen = 0, tsize = 0;
1820 #define TOK_ADD(x) \
1823 if (tlen >= tsize) \
1826 tok = realloc(tok, tsize); \
1828 tok[tlen - 1] = x; \
1831 for (p = src; *len > 0; p++, (*len)--)
1837 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
1841 else if ((p[0] == '\\') && (*len > 1) && (p[1] == '\"'))
1845 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
1849 else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n'))
1853 else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\'))
1862 if (p[0] == '\"') in_quote = 1;
1865 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
1878 if (!((isspace(p[0])) || (p[0] == ';')))
1896 eet_data_encode(Eet_Dictionary *ed, Eet_Data_Stream *ds, void *data, const char *name, int size, int type, int group_type)
1898 Eet_Data_Chunk *echnk;
1900 if (!data) type = EET_T_NULL;
1902 if (group_type != EET_G_UNKNOWN)
1903 if (type >= EET_T_LAST)
1904 type = EET_T_UNKNOW;
1906 echnk = eet_data_chunk_new(data, size, name, type, group_type);
1907 eet_data_chunk_put(ed, echnk, ds);
1908 eet_data_chunk_free(echnk);
1913 _eet_data_dump_encode(int parent_type,
1918 Eet_Data_Chunk *chnk = NULL;
1919 Eet_Data_Stream *ds;
1926 if (_eet_data_words_bigendian == -1)
1928 unsigned long int v;
1930 v = htonl(0x12345678);
1931 if (v == 0x12345678) _eet_data_words_bigendian = 1;
1932 else _eet_data_words_bigendian = 0;
1935 if (node == NULL) return NULL;
1937 ds = eet_data_stream_new();
1938 if (!ds) return NULL;
1943 for (n = node->values; n; n = n->next)
1945 data = _eet_data_dump_encode(node->type, ed, n, &size);
1948 eet_data_stream_write(ds, data, size);
1954 case EET_G_VAR_ARRAY:
1955 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
1957 if (n->type != EET_T_NULL)
1959 child_type = n->type;
1964 data = eet_data_put_type(ed,
1968 eet_data_encode(ed, ds, data, node->name, size, child_type, node->type);
1970 count = node->count;
1972 for (n = node->values; n; n = n->next)
1979 case EET_T_INLINED_STRING:
1980 data = eet_data_put_type(ed, n->type, &(n->data.value.str), &size);
1981 if (data) eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
1986 data = _eet_data_dump_encode(n->type, ed, n, &size);
1987 eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
1990 if (ds->pos != pos) count--;
1993 for (; count; count--)
1995 eet_data_encode(ed, ds, NULL, node->name, 0, EET_T_NULL, node->type);
1998 /* Array is somekind of special case, so we should embed it inside another chunk. */
1999 *size_ret = ds->pos;
2004 eet_data_stream_free(ds);
2009 for (n = node->values; n; n = n->next)
2014 case EET_T_INLINED_STRING:
2015 data = eet_data_put_type(ed, n->type, &(n->data.value.str), &size);
2016 if (data) eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2021 data = _eet_data_dump_encode(node->type, ed, n, &size);
2022 eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2026 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
2027 *size_ret = ds->pos;
2032 eet_data_stream_free(ds);
2039 data = eet_data_put_type(ed,
2043 eet_data_encode(ed, ds, data, node->name, size, node->type, node->type);
2046 /* A Hash without key will not decode correctly. */
2049 for (n = node->values; n; n = n->next)
2054 case EET_T_INLINED_STRING:
2055 data = eet_data_put_type(ed, n->type, &(n->data.value.str), &size);
2056 if (data) eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2061 data = _eet_data_dump_encode(node->type, ed, n, &size);
2062 eet_data_encode(ed, ds, data, node->name, size, n->type, node->type);
2066 /* Hash is somekind of special case, so we should embed it inside another chunk. */
2067 *size_ret = ds->pos;
2070 eet_data_stream_flush(ds);
2076 #define EET_DATA_NODE_ENCODE(Eet_Type, Type) \
2078 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size); \
2081 eet_data_encode(ed, ds, data, node->name, size, node->type, parent_type); \
2083 *size_ret = ds->pos; \
2084 eet_data_stream_flush(ds); \
2089 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
2090 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
2091 EET_DATA_NODE_ENCODE(EET_T_INT, i);
2092 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
2093 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
2094 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
2095 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
2096 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
2097 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
2098 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
2099 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
2100 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
2105 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2106 chnk = eet_data_chunk_new(ds->data, ds->pos, node->name, EET_T_UNKNOW, node->type);
2108 chnk = eet_data_chunk_new(ds->data, ds->pos, node->name, node->type, EET_G_UNKNOWN);
2109 eet_data_stream_flush(ds);
2111 ds = eet_data_stream_new();
2112 eet_data_chunk_put(ed, chnk, ds);
2116 eet_data_stream_flush(ds);
2120 eet_data_chunk_free(chnk);
2126 _eet_data_dump_parse(Eet_Dictionary *ed,
2132 const char *p = NULL;
2137 Eet_Node *node_base = NULL;
2138 Eet_Node *node = NULL;
2139 Eet_Node *n = NULL, *nn = NULL;
2141 /* FIXME; handle parse errors */
2142 #define TOK_GET(t) \
2143 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
2145 for (p = src; p < (src + size);)
2147 char *tok1, *tok2, *tok3, *tok4;
2152 if (!strcmp(tok1, "group"))
2163 if (!strcmp(tok4, "{"))
2165 /* we have 'group NAM TYP {' */
2181 for (nn = node->values; nn; nn = nn->next)
2191 n->name = eina_stringshare_add(tok2);
2192 if (!strcmp(tok3, "struct")) n->type = EET_G_UNKNOWN;
2193 else if (!strcmp(tok3, "array")) n->type = EET_G_ARRAY;
2194 else if (!strcmp(tok3, "var_array")) n->type = EET_G_VAR_ARRAY;
2195 else if (!strcmp(tok3, "list")) n->type = EET_G_LIST;
2196 else if (!strcmp(tok3, "hash")) n->type = EET_G_HASH;
2199 ERR("ERROR: group type '%s' invalid.", tok3);
2211 else if (!strcmp(tok1, "value"))
2222 /* we have 'value NAME TYP XXX' */
2234 for (nn = node->values; nn; nn = nn->next)
2243 n->name = eina_stringshare_add(tok2);
2244 if (!strcmp(tok3, "char:"))
2246 n->type = EET_T_CHAR;
2247 sscanf(tok4, "%hhi", &(n->data.value.c));
2249 else if (!strcmp(tok3, "short:"))
2251 n->type = EET_T_SHORT;
2252 sscanf(tok4, "%hi", &(n->data.value.s));
2254 else if (!strcmp(tok3, "int:"))
2256 n->type = EET_T_INT;
2257 sscanf(tok4, "%i", &(n->data.value.i));
2259 else if (!strcmp(tok3, "long_long:"))
2261 n->type = EET_T_LONG_LONG;
2262 sscanf(tok4, "%lli", &(n->data.value.l));
2264 else if (!strcmp(tok3, "float:"))
2266 n->type = EET_T_FLOAT;
2267 sscanf(tok4, "%f", &(n->data.value.f));
2269 else if (!strcmp(tok3, "double:"))
2271 n->type = EET_T_DOUBLE;
2272 sscanf(tok4, "%lf", &(n->data.value.d));
2274 else if (!strcmp(tok3, "uchar:"))
2276 n->type = EET_T_UCHAR;
2277 sscanf(tok4, "%hhu", &(n->data.value.uc));
2279 else if (!strcmp(tok3, "ushort:"))
2281 n->type = EET_T_USHORT;
2282 sscanf(tok4, "%hu", &(n->data.value.us));
2284 else if (!strcmp(tok3, "uint:"))
2286 n->type = EET_T_UINT;
2287 sscanf(tok4, "%u", &(n->data.value.ui));
2289 else if (!strcmp(tok3, "ulong_long:"))
2291 n->type = EET_T_ULONG_LONG;
2292 sscanf(tok4, "%llu", &(n->data.value.ul));
2294 else if (!strcmp(tok3, "string:"))
2296 n->type = EET_T_STRING;
2297 n->data.value.str = eina_stringshare_add(tok4);
2299 else if (!strcmp(tok3, "inlined:"))
2301 n->type = EET_T_INLINED_STRING;
2302 n->data.value.str = eina_stringshare_add(tok4);
2304 else if (!strcmp(tok3, "null"))
2306 n->type = EET_T_NULL;
2307 n->data.value.str = NULL;
2311 ERR("ERROR: value type '%s' invalid.", tok4);
2322 else if (!strcmp(tok1, "key"))
2327 /* we have 'key NAME' */
2330 node->key = eina_stringshare_add(tok2);
2335 else if (!strcmp(tok1, "count"))
2340 /* we have a 'count COUNT' */
2343 sscanf(tok2, "%i", &(node->count));
2348 else if (!strcmp(tok1, "}"))
2350 /* we have an end of the group */
2351 if (node) node = node->parent;
2359 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
2360 eet_node_del(node_base);
2365 #define NEXT_CHUNK(P, Size, Echnk, Ed) \
2368 tmp = Ed ? (int) (sizeof(int) * 2) : Echnk.len + 4;\
2369 P += (4 + Echnk.size + tmp); \
2370 Size -= (4 + Echnk.size + tmp); \
2374 _eet_data_descriptor_decode(Eet_Free_Context *context,
2375 const Eet_Dictionary *ed,
2376 Eet_Data_Descriptor *edd,
2377 const void *data_in,
2380 Eet_Node *result = NULL;
2384 Eet_Data_Chunk chnk;
2386 if (_eet_data_words_bigendian == -1)
2388 unsigned long int v;
2390 v = htonl(0x12345678);
2391 if (v == 0x12345678) _eet_data_words_bigendian = 1;
2392 else _eet_data_words_bigendian = 0;
2397 data = edd->func.mem_alloc(edd->size);
2398 if (!data) return NULL;
2401 for (i = 0; i < edd->elements.num; i++)
2402 edd->elements.set[i].directory_name_ptr = NULL;
2406 _eet_freelist_all_ref(context);
2407 if (data) _eet_freelist_add(context, data);
2408 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
2409 eet_data_chunk_get(ed, &chnk, data_in, size_in);
2410 if (!chnk.name) goto error;
2413 if (strcmp(chnk.name, edd->name)) goto error;
2417 size = size_in - (4 + sizeof(int) * 2);
2419 size = size_in - (4 + 4 + chnk.len);
2422 if (!edd->elements.hash.buckets) _eet_descriptor_hash_new(edd);
2426 switch (chnk.group_type)
2432 return eet_node_string_new(chnk.name, chnk.data);
2433 case EET_T_INLINED_STRING:
2434 return eet_node_inlined_string_new(chnk.name, chnk.data);
2436 return eet_node_null_new(chnk.name);
2438 result = eet_node_struct_new(chnk.name, NULL);
2441 case EET_G_VAR_ARRAY:
2442 return eet_node_var_array_new(chnk.name, NULL);
2455 Eet_Data_Chunk echnk;
2456 Eet_Data_Element *ede = NULL;
2457 Eet_Node *child = NULL;
2458 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
2461 /* get next data chunk */
2462 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
2463 eet_data_chunk_get(ed, &echnk, p, size);
2464 if (!echnk.name) goto error;
2465 /* FIXME: don't REPLY on edd - work without */
2468 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
2471 group_type = ede->group_type;
2473 if ((echnk.type == 0) && (echnk.group_type == 0))
2476 group_type = ede->group_type;
2480 if (IS_SIMPLE_TYPE(echnk.type) &&
2481 eet_data_type_match(echnk.type, ede->type))
2482 /* Needed when converting on the fly from FP to Float */
2484 else if ((echnk.group_type > EET_G_UNKNOWN) &&
2485 (echnk.group_type < EET_G_LAST) &&
2486 (echnk.group_type == ede->group_type))
2487 group_type = echnk.group_type;
2491 /*...... dump to node */
2495 group_type = echnk.group_type;
2498 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
2500 unsigned char dd[128];
2502 ret = eet_data_get_type(ed,
2505 ((char *)echnk.data) + echnk.size,
2507 if (ret <= 0) goto error;
2509 child = eet_data_node_simple_type(type, echnk.name, dd);
2511 eet_node_struct_append(result, echnk.name, child);
2515 ret = eet_group_codec[group_type - 100].get(context,
2516 ed, edd, ede, &echnk,
2517 type, group_type, ede ? (void*) (((char *)data) + ede->offset) : (void**) &result,
2520 if (ret <= 0) goto error;
2523 /* advance to next chunk */
2524 NEXT_CHUNK(p, size, echnk, ed);
2527 _eet_freelist_all_unref(context);
2530 _eet_freelist_str_free(context, edd);
2531 _eet_freelist_direct_str_free(context, edd);
2532 _eet_freelist_list_free(context, edd);
2533 _eet_freelist_hash_free(context, edd);
2534 _eet_freelist_free(context, edd);
2538 _eet_freelist_reset(context);
2539 _eet_freelist_str_reset(context);
2540 _eet_freelist_list_reset(context);
2541 _eet_freelist_hash_reset(context);
2542 _eet_freelist_direct_str_reset(context);
2551 eet_node_del(result);
2553 _eet_freelist_all_unref(context);
2554 _eet_freelist_str_free(context, edd);
2555 _eet_freelist_direct_str_free(context, edd);
2556 _eet_freelist_list_free(context, edd);
2557 _eet_freelist_hash_free(context, edd);
2558 _eet_freelist_free(context, edd);
2560 /* FIXME: Warn that something goes wrong here. */
2565 eet_data_get_list(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2566 int type, int group_type __UNUSED__, void *data,
2567 char **p, int *size)
2569 Eet_Data_Descriptor *subtype = NULL;
2574 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2578 subtype = ede->subtype;
2580 if (type != ede->type)
2584 ptr = (void **)data;
2588 if (IS_POINTER_TYPE(type))
2592 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, type, EET_G_UNKNOWN,
2593 &data_ret, p, size);
2598 data_ret = _eet_data_descriptor_decode(context, ed, subtype,
2599 echnk->data, echnk->size);
2600 if (!data_ret) return 0;
2605 list = edd->func.list_append(list, data_ret);
2607 _eet_freelist_list_add(context, ptr);
2611 eet_node_list_append(*((Eet_Node**) data), echnk->name, data_ret);
2618 eet_data_get_hash(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2619 int type, int group_type __UNUSED__, void *data,
2620 char **p, int *size)
2625 void *data_ret = NULL;
2628 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2630 ptr = (void **)data;
2634 ret = eet_data_get_type(ed,
2637 ((char *)echnk->data) + echnk->size,
2639 if (ret <= 0) goto on_error;
2641 /* Advance to next chunk */
2642 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2643 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2646 eet_data_chunk_get(ed, echnk, *p, *size);
2647 if (!echnk->name) goto on_error;
2649 if (IS_POINTER_TYPE(echnk->type))
2651 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, echnk->type, EET_G_UNKNOWN,
2652 &data_ret, p, size);
2653 if (!ret) goto on_error;
2657 data_ret = _eet_data_descriptor_decode(context,
2659 ede ? ede->subtype : NULL,
2662 if (!data_ret) goto on_error;
2667 hash = edd->func.hash_add(hash, key, data_ret);
2669 _eet_freelist_hash_add(context, hash);
2673 eet_node_hash_add(*((Eet_Node **) data), echnk->name, key, data_ret);
2682 /* var arrays and fixed arrays have to
2683 * get all chunks at once. for fixed arrays
2684 * we can get each chunk and increment a
2685 * counter stored on the element itself but
2686 * it wont be thread safe. for var arrays
2687 * we still need a way to get the number of
2688 * elements from the data, so storing the
2689 * number of elements and the element data on
2690 * each chunk is pointless.
2693 eet_data_get_array(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd,
2694 Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2695 int type, int group_type, void *data,
2696 char **p, int *size)
2698 Eina_List *childs = NULL;
2707 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
2710 /* read the number of elements */
2711 ret = eet_data_get_type(ed,
2714 ((char *)echnk->data) + echnk->size,
2716 if (ret <= 0) return ret;
2722 if (IS_POINTER_TYPE(type))
2723 subsize = eet_basic_codec[ede->type].size;
2725 subsize = ede->subtype->size;
2727 if (group_type == EET_G_VAR_ARRAY)
2729 /* store the number of elements
2730 * on the counter offset */
2731 *(int *)(((char *)data) + ede->count - ede->offset) = count;
2732 /* allocate space for the array of elements */
2733 *(void **)ptr = edd->func.mem_alloc(count * subsize);
2735 if (!*(void **)ptr) return 0;
2737 memset(*(void **)ptr, 0, count * subsize);
2739 _eet_freelist_add(context, *(void **)ptr);
2743 /* get all array elements */
2744 for (i = 0; i < count; i++)
2747 void *data_ret = NULL;
2749 /* Advance to next chunk */
2750 NEXT_CHUNK((*p), (*size), (*echnk), ed);
2751 memset(echnk, 0, sizeof(Eet_Data_Chunk));
2753 eet_data_chunk_get(ed, echnk, *p, *size);
2754 if (!echnk->name || strcmp(echnk->name, name) != 0) goto on_error;
2757 if (echnk->group_type != group_type
2758 || (echnk->type != type && echnk->type != EET_T_NULL))
2762 if (ede->group_type != echnk->group_type
2763 || (echnk->type != ede->type && echnk->type != EET_T_NULL))
2766 /* get the destination pointer */
2769 if (group_type == EET_G_ARRAY)
2770 dst = (char *)ptr + (subsize * i);
2772 dst = *(char **)ptr + (subsize * i);
2775 if (IS_POINTER_TYPE(echnk->type))
2777 ret = eet_data_get_unknown(context, ed, edd, ede, echnk, echnk->type, EET_G_UNKNOWN,
2778 &data_ret, p, size);
2779 if (!ret) goto on_error;
2780 if (dst) memcpy(dst, &data_ret, subsize);
2781 if (!edd) childs = eina_list_append(childs, data_ret);
2785 data_ret = _eet_data_descriptor_decode(context, ed, ede ? ede->subtype : NULL,
2786 echnk->data, echnk->size);
2787 if (!data_ret) goto on_error;
2790 memcpy(dst, data_ret, subsize);
2791 _eet_freelist_add(context, data_ret);
2793 if (!edd) childs = eina_list_append(childs, data_ret);
2799 Eet_Node *parent = *((Eet_Node **) data);
2802 if (group_type == EET_G_ARRAY)
2803 array = eet_node_array_new(name, count, childs);
2805 array = eet_node_var_array_new(name, childs);
2807 if (!array) goto on_error;
2809 eet_node_struct_append(parent, name, array);
2815 EINA_LIST_FREE(childs, tmp)
2822 eet_data_node_simple_type(int type, const char *name, void *dd)
2828 #define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type) \
2830 return eet_node_##Eet_Node_Type##_new(name, *((Type *) dd)); \
2834 EET_T_TYPE(EET_T_CHAR, char, char);
2835 EET_T_TYPE(EET_T_SHORT, short, short);
2836 EET_T_TYPE(EET_T_INT, int, int);
2837 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
2838 EET_T_TYPE(EET_T_FLOAT, float, float);
2839 EET_T_TYPE(EET_T_DOUBLE, double, double);
2840 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
2841 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
2842 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
2843 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
2844 EET_T_TYPE(EET_T_STRING, string, char*);
2845 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char*);
2847 return eet_node_null_new(name);
2849 ERR("Unknow type passed to eet_data_node_simple_type");
2855 eet_data_get_unknown(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
2856 int type, int group_type __UNUSED__, void *data,
2857 char **p __UNUSED__, int *size __UNUSED__)
2862 if (IS_SIMPLE_TYPE(type))
2864 unsigned char dd[128];
2866 ret = eet_data_get_type(ed, type, echnk->data, ((char *)echnk->data) + echnk->size, edd ? (char*) data : (char*) dd);
2867 if (ret <= 0) return ret;
2871 Eet_Node **parent = data;
2874 node = eet_data_node_simple_type(type, echnk->name, dd);
2876 if (*parent) eet_node_struct_append(*parent, echnk->name, node);
2877 else *parent = node;
2881 if (type == EET_T_STRING)
2885 str = (char **)(((char *)data));
2888 if ((ed == NULL) || (edd->func.str_direct_alloc == NULL))
2890 *str = edd->func.str_alloc(*str);
2891 _eet_freelist_str_add(context, *str);
2895 *str = edd->func.str_direct_alloc(*str);
2896 _eet_freelist_direct_str_add(context, *str);
2900 else if (edd && type == EET_T_INLINED_STRING)
2904 str = (char **)(((char *)data));
2907 *str = edd->func.str_alloc(*str);
2908 _eet_freelist_str_add(context, *str);
2915 Eet_Data_Descriptor *subtype;
2917 subtype = ede ? ede->subtype : NULL;
2919 if (subtype || !edd)
2921 Eet_Node **parent = data;
2924 data_ret = _eet_data_descriptor_decode(context, ed, subtype, echnk->data, echnk->size);
2925 if (!data_ret) return 0;
2929 ptr = (void **)(((char *)data));
2930 *ptr = (void *)data_ret;
2934 Eet_Node *node = data_ret;
2938 node = eet_node_struct_child_new(echnk->name, node);
2939 eet_node_struct_append(*parent, echnk->name, node);
2941 else *parent = node;
2950 eet_data_put_array(Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
2959 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2961 if (ede->group_type == EET_G_ARRAY)
2962 count = ede->counter_offset;
2964 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
2966 if (count <= 0) return;
2967 /* Store number of elements */
2968 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
2969 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2971 if (IS_POINTER_TYPE(ede->type))
2972 subsize = eet_basic_codec[ede->type].size;
2974 subsize = ede->subtype->size;
2976 for (j = 0; j < count; j++)
2981 if (ede->group_type == EET_G_ARRAY)
2982 d = (void *)(((char *)data_in) + offset);
2984 d = *(((char **)data_in)) + offset;
2986 if (IS_POINTER_TYPE(ede->type))
2989 eet_data_put_unknown(ed, NULL, ede, ds, d);
2993 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
2994 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
2999 /* Add a NULL element just to have the correct array layout. */
3000 eet_data_encode(ed, ds, NULL, ede->name, 0, EET_T_NULL, ede->group_type);
3008 eet_data_put_unknown(Eet_Dictionary *ed, Eet_Data_Descriptor *edd __UNUSED__, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3013 if (IS_SIMPLE_TYPE(ede->type))
3014 data = eet_data_put_type(ed, ede->type, data_in, &size);
3015 else if (ede->subtype)
3017 if (*((char **)data_in))
3018 data = _eet_data_descriptor_encode(ed,
3020 *((char **)((char *)(data_in))),
3023 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3027 eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3033 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
3034 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
3037 l = *((void **)(((char *)data_in)));
3038 for (; l; l = edd->func.list_next(l))
3040 if (IS_POINTER_TYPE(ede->type))
3042 const void *str = edd->func.list_data(l);
3043 eet_data_put_unknown(ed, NULL, ede, ds, &str);
3047 data = _eet_data_descriptor_encode(ed,
3049 edd->func.list_data(l),
3051 if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
3057 eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
3059 Eet_Data_Encode_Hash_Info fdata;
3062 l = *((void **)(((char *)data_in)));
3066 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
3070 eet_data_dump_cipher(Eet_File *ef,
3071 const char *name, const char *cipher_key,
3072 void (*dumpfunc) (void *data, const char *str),
3075 const Eet_Dictionary *ed = NULL;
3076 const void *data = NULL;
3078 Eet_Free_Context context;
3079 int required_free = 0;
3082 ed = eet_dictionary_get(ef);
3085 data = eet_read_direct(ef, name, &size);
3089 data = eet_read_cipher(ef, name, &size, cipher_key);
3090 if (!data) return 0;
3093 memset(&context, 0, sizeof (context));
3094 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
3096 eet_node_dump(result, 0, dumpfunc, dumpdata);
3098 eet_node_del(result);
3103 return result ? 1 : 0;
3107 eet_data_dump(Eet_File *ef,
3109 void (*dumpfunc) (void *data, const char *str),
3112 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
3117 eet_data_text_dump_cipher(const void *data_in,
3118 const char *cipher_key, int size_in,
3119 void (*dumpfunc) (void *data, const char *str),
3124 Eet_Free_Context context;
3125 unsigned int ret_len = 0;
3127 if (!data_in) return 0;
3131 if (eet_decipher(data_in, size_in, cipher_key,
3132 strlen(cipher_key), &ret, &ret_len))
3140 ret = (void*) data_in;
3144 memset(&context, 0, sizeof (context));
3145 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len);
3147 eet_node_dump(result, 0, dumpfunc, dumpdata);
3149 eet_node_del(result);
3150 if (cipher_key) free(ret);
3152 return result ? 1 : 0;
3156 eet_data_text_dump(const void *data_in,
3158 void (*dumpfunc) (void *data, const char *str),
3161 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
3165 eet_data_text_undump_cipher(const char *text,
3166 const char *cipher_key,
3172 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
3173 if (ret && cipher_key)
3175 void *ciphered = NULL;
3176 unsigned int ciphered_len;
3178 if (eet_cipher(ret, *size_ret, cipher_key,
3179 strlen(cipher_key), &ciphered, &ciphered_len))
3181 if (ciphered) free(ciphered);
3187 *size_ret = ciphered_len;
3194 eet_data_text_undump(const char *text,
3198 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
3202 eet_data_undump_cipher(Eet_File *ef,
3204 const char *cipher_key,
3214 ed = eet_dictionary_get(ef);
3216 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
3217 if (!data_enc) return 0;
3218 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
3224 eet_data_undump(Eet_File *ef,
3230 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
3234 eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
3235 const void *data_in,
3236 const char *cipher_key,
3239 void *deciphered = (void*) data_in;
3241 Eet_Free_Context context;
3242 unsigned int deciphered_len = size_in;
3244 if (cipher_key && data_in)
3246 if (eet_decipher(data_in, size_in, cipher_key,
3247 strlen(cipher_key), &deciphered, &deciphered_len))
3249 if (deciphered) free(deciphered);
3254 memset(&context, 0, sizeof (context));
3255 ret = _eet_data_descriptor_decode(&context, NULL, edd, deciphered, deciphered_len);
3257 if (data_in != deciphered) free(deciphered);
3263 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
3264 const void *data_in,
3267 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
3271 eet_data_node_decode_cipher(const void *data_in, const char *cipher_key, int size_in)
3273 void *deciphered = (void*) data_in;
3275 Eet_Free_Context context;
3276 unsigned int deciphered_len = size_in;
3278 if (cipher_key && data_in)
3280 if (eet_decipher(data_in, size_in, cipher_key,
3281 strlen(cipher_key), &deciphered, &deciphered_len))
3283 if (deciphered) free(deciphered);
3288 memset(&context, 0, sizeof (context));
3289 ret = _eet_data_descriptor_decode(&context, NULL, NULL, deciphered, deciphered_len);
3291 if (data_in != deciphered) free(deciphered);
3297 _eet_data_descriptor_encode(Eet_Dictionary *ed,
3298 Eet_Data_Descriptor *edd,
3299 const void *data_in,
3302 Eet_Data_Stream *ds;
3303 Eet_Data_Chunk *chnk;
3308 if (_eet_data_words_bigendian == -1)
3310 unsigned long int v;
3312 v = htonl(0x12345678);
3313 if (v == 0x12345678) _eet_data_words_bigendian = 1;
3314 else _eet_data_words_bigendian = 0;
3317 ds = eet_data_stream_new();
3318 for (i = 0; i < edd->elements.num; i++)
3320 Eet_Data_Element *ede;
3322 ede = &(edd->elements.set[i]);
3323 eet_group_codec[ede->group_type - 100].put(ed, edd, ede, ds, ((char *)data_in) + ede->offset);
3325 chnk = eet_data_chunk_new(ds->data, ds->pos, edd->name, EET_T_UNKNOW, EET_G_UNKNOWN);
3328 eet_data_stream_free(ds);
3330 ds = eet_data_stream_new();
3331 eet_data_chunk_put(ed, chnk, ds);
3337 eet_data_stream_free(ds);
3341 eet_data_chunk_free(chnk);
3347 eet_data_node_write_cipher(Eet_File *ef, const char *name, const char *cipher_key, Eet_Node *node, int compress)
3354 ed = eet_dictionary_get(ef);
3356 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
3357 if (!data_enc) return 0;
3358 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
3364 eet_data_node_encode_cipher(Eet_Node *node,
3365 const char *cipher_key,
3369 void *ciphered = NULL;
3370 unsigned int ciphered_len = 0;
3373 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
3374 if (cipher_key && ret)
3376 if (eet_cipher(ret, size, cipher_key,
3377 strlen(cipher_key), &ciphered, &ciphered_len))
3379 if (ciphered) free(ciphered);
3380 if (size_ret) *size_ret = 0;
3385 size = (int) ciphered_len;
3389 if (size_ret) *size_ret = size;
3394 eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
3395 const void *data_in,
3396 const char *cipher_key,
3400 void *ciphered = NULL;
3401 unsigned int ciphered_len = 0;
3404 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
3405 if (cipher_key && ret)
3407 if (eet_cipher(ret, size, cipher_key,
3408 strlen(cipher_key), &ciphered, &ciphered_len))
3410 if (ciphered) free(ciphered);
3411 if (size_ret) *size_ret = 0;
3416 size = ciphered_len;
3420 if (size_ret) *size_ret = size;
3425 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
3426 const void *data_in,
3429 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);