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