aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eet/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eet/src/lib')
-rw-r--r--libraries/eet/src/lib/Eet.h4156
-rw-r--r--libraries/eet/src/lib/Eet_private.h191
-rw-r--r--libraries/eet/src/lib/Makefile.am162
-rw-r--r--libraries/eet/src/lib/Makefile.in846
-rw-r--r--libraries/eet/src/lib/eet_cipher.c1342
-rw-r--r--libraries/eet/src/lib/eet_connection.c249
-rw-r--r--libraries/eet/src/lib/eet_data.c4999
-rw-r--r--libraries/eet/src/lib/eet_dictionary.c439
-rw-r--r--libraries/eet/src/lib/eet_image.c1820
-rw-r--r--libraries/eet/src/lib/eet_lib.c2648
-rw-r--r--libraries/eet/src/lib/eet_node.c797
-rw-r--r--libraries/eet/src/lib/eet_utils.c36
12 files changed, 17685 insertions, 0 deletions
diff --git a/libraries/eet/src/lib/Eet.h b/libraries/eet/src/lib/Eet.h
new file mode 100644
index 0000000..8fda1e0
--- /dev/null
+++ b/libraries/eet/src/lib/Eet.h
@@ -0,0 +1,4156 @@
1/**
2 @brief Eet Data Handling Library Public API Calls
3
4 These routines are used for Eet Library interaction
5
6 @mainpage Eet Library Documentation
7
8 @version 1.5.0
9 @date 2000-2011
10
11 Please see the @ref authors page for contact details.
12
13 @section toc Table of Contents
14
15 @li @ref intro
16 @li @ref example
17 @li @ref compiling
18 @li @ref install
19 @li @ref next_steps
20 @li @ref intro_example
21
22 @section intro What is Eet?
23
24 It is a tiny library designed to write an arbitrary set of chunks of data
25 to a file and optionally compress each chunk (very much like a zip file)
26 and allow fast random-access reading of the file later on. It does not
27 do zip as a zip itself has more complexity than is needed, and it was much
28 simpler to implement this once here.
29
30 Eet is extremely fast, small and simple. Eet files can be very small and
31 highly compressed, making them very optimal for just sending across the
32 internet without having to archive, compress or decompress and install them.
33 They allow for lightning-fast random-acess reads once created, making them
34 perfect for storing data that is written once (or rarely) and read many
35 times, but the program does not want to have to read it all in at once.
36
37 It also can encode and decode data structures in memory, as well as image
38 data for saving to Eet files or sending across the network to other
39 machines, or just writing to arbitrary files on the system. All data is
40 encoded in a platform independent way and can be written and read by any
41 architecture.
42
43 @section example A simple example on using Eet
44
45 Here is a simple example on how to use Eet to save a series of strings to a
46 file and load them again. The advantage of using Eet over just
47 fprintf() and
48 fscanf() is that not only can these entries be strings, they need no special
49 parsing to handle delimiter characters or escaping, they can be binary data,
50 image data, data structures containing integers, strings, other data
51 structures, linked lists and much more, without the programmer having to
52 worry about parsing, and best of all, Eet is very fast.
53
54 This is just a very simple example that doesn't show all of the capabilities
55 of Eet, but it serves to illustrate its simplicity.
56
57 @include eet-basic.c
58
59 @section compiling How to compile using Eet ?
60
61 Eet is a library your application links to. The procedure for this is very
62 simple. You simply have to compile your application with the appropriate
63 compiler flags that the @p pkg-config script outputs. For example:
64
65 Compiling C or C++ files into object files:
66
67 @verbatim
68 gcc -c -o main.o main.c `pkg-config --cflags eet`
69 @endverbatim
70
71 Linking object files into a binary executable:
72
73 @verbatim
74 gcc -o my_application main.o `pkg-config --libs eet`
75 @endverbatim
76
77 You simply have to make sure that pkg-config is in your shell's PATH (see
78 the manual page for your appropriate shell) and eet.pc in /usr/lib/pkgconfig
79 or its path is in the PKG_CONFIG_PATH environment variable. It's that simple
80 to link and use Eet once you have written your code to use it.
81
82 Since the program is linked to Eet, it is now able to use any advertised
83 API calls to serialize your data.
84
85 You should make sure you add any extra compile and link flags to your
86 compile commands that your application may need as well. The above example
87 is only guaranteed to make Eet add it's own requirements.
88
89
90 @section install How is it installed?
91
92 Simple:
93
94 @verbatim
95 ./configure
96 make
97 su -
98 ...
99 make install
100 @endverbatim
101
102 @section next_steps Next Steps
103
104 After you understood what Eet is and installed it in your system you
105 should proceed understanding the programming interface. We'd recommend
106 you to take a while to learn Eina
107 (http://docs.enlightenment.org/auto/eina/) as it is very convenient
108 and optimized, and Eet provides integration with it.
109
110 Recommended reading:
111
112 @li @ref Eet_File_Group to know the basics to open and save files.
113 @li @ref Eet_Data_Group to know the convenient way to serialize and
114 parse your data structures automatically. Just create your
115 descriptors and let Eet do the work for you.
116
117 @section intro_example Introductory Examples
118
119 @ref Examples
120
121 @todo Document data format for images and data structures.
122
123 */
124
125/**
126 @page authors Authors
127 @author Carsten Haitzler <raster@@rasterman.com>
128 @author David Goodlad <dgoodlad@@gmail.com>
129 @author Cedric Bail <cedric.bail@@free.fr>
130 @author Arnaud de Turckheim <quarium@@gmail.com>
131 @author Luis Felipe Strano Moraes <lfelipe@@profusion.mobi>
132 @author Chidambar Zinnoury <illogict@@online.fr>
133 @author Vincent Torri <vtorri@@univ-evry.fr>
134 @author Gustavo Sverzut Barbieri <barbieri@@profusion.mobi>
135 @author Raphael Kubo da Costa <kubo@@profusion.mobi>
136 @author Mathieu Taillefumier <mathieu.taillefumier@@free.fr>
137 @author Albin "Lutin" Tonnerre <albin.tonnerre@@gmail.com>
138 @author Adam Simpkins <adam@@adamsimpkins.net>
139 @author Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
140
141 Please contact <enlightenment-devel@lists.sourceforge.net> to get in
142 contact with the developers and maintainers.
143 */
144
145#ifndef _EET_H
146#define _EET_H
147
148#include <stdlib.h>
149#include <stdio.h>
150#include <Eina.h>
151
152#ifdef EAPI
153# undef EAPI
154#endif /* ifdef EAPI */
155
156#ifdef _WIN32
157# ifdef EFL_EET_BUILD
158# ifdef DLL_EXPORT
159# define EAPI __declspec(dllexport)
160# else /* ifdef DLL_EXPORT */
161# define EAPI
162# endif /* ! DLL_EXPORT */
163# else /* ifdef EFL_EET_BUILD */
164# define EAPI __declspec(dllimport)
165# endif /* ! EFL_EET_BUILD */
166#else /* ifdef _WIN32 */
167# ifdef __GNUC__
168# if __GNUC__ >= 4
169# define EAPI __attribute__ ((visibility("default")))
170# else /* if __GNUC__ >= 4 */
171# define EAPI
172# endif /* if __GNUC__ >= 4 */
173# else /* ifdef __GNUC__ */
174# define EAPI
175# endif /* ifdef __GNUC__ */
176#endif /* ! _WIN32 */
177
178#ifdef __cplusplus
179extern "C" {
180#endif /* ifdef __cplusplus */
181
182/**
183 * @file Eet.h
184 * @brief The file that provides the eet functions.
185 *
186 * This header provides the Eet management functions.
187 *
188 */
189
190#define EET_VERSION_MAJOR 1
191#define EET_VERSION_MINOR 4
192/**
193 * @typedef Eet_Version
194 *
195 * This is the Eet version information structure that can be used at
196 * runtime to detect which version of eet is being used and adapt
197 * appropriately as follows for example:
198 *
199 * @code
200 * #if defined(EET_VERSION_MAJOR) && (EET_VERSION_MAJOR >= 1) && defined(EET_VERSION_MINOR) && (EET_VERSION_MINOR > 2)
201 * printf("Eet version: %i.%i.%i\n",
202 * eet_version->major,
203 * eet_version->minor,
204 * eet_version->micro);
205 * if (eet_version->revision > 0)
206 * {
207 * printf(" Built from SVN revision # %i\n", eet_version->revision);
208 * }
209 * #endif
210 * @endcode
211 *
212 * Note the #if check can be dropped if your program refuses to compile or
213 * work with an Eet version less than 1.3.0.
214 */
215typedef struct _Eet_Version
216{
217 int major; /** < major (binary or source incompatible changes) */
218 int minor; /** < minor (new features, bugfixes, major improvements version) */
219 int micro; /** < micro (bugfix, internal improvements, no new features version) */
220 int revision; /** < svn revision (0 if a proper rlease or the svn revsion number Eet is built from) */
221} Eet_Version;
222
223EAPI extern Eet_Version *eet_version;
224
225/**
226 * @defgroup Eet_Group Top level functions
227 * Functions that affect Eet as a whole.
228 *
229 * @{
230 */
231
232/**
233 * @enum _Eet_Error
234 * All the error identifiers known by Eet.
235 */
236typedef enum _Eet_Error
237{
238 EET_ERROR_NONE, /**< No error, it's all fine! */
239 EET_ERROR_BAD_OBJECT, /**< Given object or handle is NULL or invalid */
240 EET_ERROR_EMPTY, /**< There was nothing to do */
241 EET_ERROR_NOT_WRITABLE, /**< Could not write to file or file is #EET_FILE_MODE_READ */
242 EET_ERROR_OUT_OF_MEMORY, /**< Could not allocate memory */
243 EET_ERROR_WRITE_ERROR, /**< Failed to write data to destination */
244 EET_ERROR_WRITE_ERROR_FILE_TOO_BIG, /**< Failed to write file since it is too big */
245 EET_ERROR_WRITE_ERROR_IO_ERROR, /**< Failed to write due a generic Input/Output error */
246 EET_ERROR_WRITE_ERROR_OUT_OF_SPACE, /**< Failed to write due out of space */
247 EET_ERROR_WRITE_ERROR_FILE_CLOSED, /**< Failed to write because file was closed */
248 EET_ERROR_MMAP_FAILED, /**< Could not mmap file */
249 EET_ERROR_X509_ENCODING_FAILED, /**< Could not encode using X509 */
250 EET_ERROR_SIGNATURE_FAILED, /**< Could not validate signature */
251 EET_ERROR_INVALID_SIGNATURE, /**< Signature is invalid */
252 EET_ERROR_NOT_SIGNED, /**< File or contents are not signed */
253 EET_ERROR_NOT_IMPLEMENTED, /**< Function is not implemented */
254 EET_ERROR_PRNG_NOT_SEEDED, /**< Could not introduce random seed */
255 EET_ERROR_ENCRYPT_FAILED, /**< Could not encrypt contents */
256 EET_ERROR_DECRYPT_FAILED /**< Could not decrypt contents */
257} Eet_Error; /**< Eet error identifiers */
258
259/**
260 * @}
261 */
262
263/**
264 * Initialize the EET library.
265 *
266 * The first time this function is called, it will perform all the internal
267 * initialization required for the library to function properly and incrememnt
268 * the initializiation counter. Any subsequent call only increment this counter
269 * and return its new value, so it's safe to call this function more than once.
270 *
271 * @return The new init count. Will be 0 if initialization failed.
272 *
273 * @since 1.0.0
274 * @ingroup Eet_Group
275 */
276EAPI int
277eet_init(void);
278
279/**
280 * Shut down the EET library.
281 *
282 * If eet_init() was called more than once for the running application,
283 * eet_shutdown() will decrement the initialization counter and return its
284 * new value, without doing anything else. When the counter reaches 0, all
285 * of the internal elements will be shutdown and any memory used freed.
286 *
287 * @return The new init count.
288 *
289 * @since 1.0.0
290 * @ingroup Eet_Group
291 */
292EAPI int
293eet_shutdown(void);
294
295/**
296 * Clear eet cache
297 *
298 * For a faster access to previously accessed data, Eet keeps an internal
299 * cache of files. These files will be freed automatically only when
300 * they are unused and the cache gets full, in order based on the last time
301 * they were used.
302 * On systems with little memory this may present an unnecessary constraint,
303 * so eet_clearcache() is available for users to reclaim the memory used by
304 * files that are no longer needed. Those that were open using
305 * ::EET_FILE_MODE_WRITE or ::EET_FILE_MODE_READ_WRITE and have modifications,
306 * will be written down to disk before flushing them from memory.
307 *
308 * @since 1.0.0
309 * @ingroup Eet_Group
310 */
311EAPI void
312eet_clearcache(void);
313
314/**
315 * @defgroup Eet_File_Group Eet File Main Functions
316 *
317 * Functions to create, destroy and do basic manipulation of
318 * #Eet_File handles.
319 *
320 * This sections explains how to use the most basic Eet functions, which
321 * are used to work with eet files, read data from them, store it back in or
322 * take a look at what entries it contains, without making use of the
323 * serialization capabilities explained in @ref Eet_Data_Group.
324 *
325 * The following example will serve as an introduction to most, if not all,
326 * of these functions.
327 *
328 * If you are only using Eet, this is the only header you need to include.
329 * @dontinclude eet-file.c
330 * @skipline Eet.h
331 *
332 * Now let's create ourselves an eet file to play with. The following function
333 * shows step by step how to open a file and write some data in it.
334 * First, we define our file handler and some other things we'll put in it.
335 * @line static int
336 * @skip Eet_File
337 * @until ";
338 * @skip eet_open
339 *
340 * We open a new file in write mode, and if it fails, we just return, since
341 * there's not much more we can do about it..
342 * @until return
343 *
344 * Now, we need to write some data in our file. For now, strings will suffice,
345 * so let's just dump a bunch of them in there.
346 * @until }
347 *
348 * As you can see, we copied a string into our static buffer, which is a bit
349 * bigger than the full length of the string, and then told Eet to write it
350 * into the file, compressed, returning the size of the data written into the
351 * file.
352 * This is all to show that Eet treats data as just data. It doesn't matter
353 * what that data represents (for now), it's all just bytes for it. As running
354 * the following code will show, we took a string of around 30 bytes and put it
355 * in a buffer of 1024 bytes, but the returned size won't be any of those.
356 * @until printf
357 *
358 * Next, we copy into our buffer our set of strings, including their null
359 * terminators and write them into the file. No error checking for the sake
360 * of brevitiy. And a call to eet_sync() to make sure all out data is
361 * properly written down to disk, even though we haven't yet closed the file.
362 * @until eet_sync
363 *
364 * One more write, this time our large array of binary data and... well, I
365 * couldn't come up with a valid use of the last set of strings we stored,
366 * so let's take it out from the file with eet_delete().
367 * @until eet_delete
368 *
369 * Finally, we close the file, saving any changes back to disk and return.
370 * Notice how, if there's any error closing the file or saving its contents,
371 * the return value from the function will be a false one, which later on
372 * will make the program exit with an error code.
373 * @until return
374 *
375 * Moving onto our main function, we will open the same file and read it back.
376 * Trivial, but it'll show how we can do so in more than one way. We'll skip
377 * the variable declarations, as they aren't very different from what we've
378 * seen already.
379 *
380 * We start from the beginning by initializing Eet so things in general work.
381 * Forgetting to do so will result in weird results or crashes when calling
382 * any eet function, so if you experience something like that, the first thing
383 * to look at is whether eet_init() is missing.
384 * Then we call our @p create_eet_file function, described above, to make
385 * sure we have something to work with. If the function fails it will return
386 * 0 and we just exit, since nothing from here onwards will work anyway.
387 * @skip eet_init
388 * @until return
389 *
390 * Let's take a look now at what entries our file has. For this, we use
391 * eet_list(), which will return a list of strings, each being the name of
392 * one entry. Since we skipped before, it may be worth noting that @p list
393 * is declared as a @p char **.
394 * The @p num parameter will, of course, have the number of entries contained
395 * in our file.
396 * If everything's fine, we'll get our list and print it to the screen, and
397 * once done with it, we free the list. That's just the list, not its contents,
398 * as they are internal strings used by Eet and trying to free them will surely
399 * break things.
400 * @until }
401 *
402 * Reading back plain data is simple. Just a call to eet_read() with the file
403 * to read from, and the name of the entry we are interested in. We get back
404 * our data and the passed @p size parameter will contain the size of it. If
405 * the data was stored compressed, it will decompressed first.
406 * @until }
407 *
408 * Another simple read for the set of strings from before, except those were
409 * deleted, so we should get a NULL return and continue normally.
410 * @until }
411 *
412 * Finally, we'll get our binary data in the same way we got the strings. Once
413 * again, it makes no difference for Eet what the data is, it's up to us to
414 * know how to handle it.
415 * @until {
416 *
417 * Now some cheating, we know that this data is an Eet file because, well...
418 * we just know it. So we are going to open it and take a look at its insides.
419 * For this, eet_open() won't work, as it needs to have a file on disk to read
420 * from and all we have is some data in RAM.
421 *
422 * So how do we do? One way would be to create a normal file and write down
423 * our data, then open it with eet_open(). Another, faster and more efficient
424 * if all we want to do is read the file, is to use eet_memopen_read().
425 * @until memopen
426 *
427 * As you can see, the size we got from our previous read was put to good use
428 * this time. Unlike the first one where all we had were strings, the size
429 * of the data read only serves to demonstrate that we are reading back the
430 * entire size of our original @p buf variable.
431 *
432 * A little peeking to see how many entries the file has and to make an
433 * example of eet_num_entries() to get that number when we don't care about
434 * their names.
435 * @until printf
436 *
437 * More cheating follows. Just like we knew this was an Eet file, we also know
438 * what key to read from, and ontop of that we know that the data in it is not
439 * compressed.
440 * Knowing all this allows us to take some shortcuts.
441 * @until read_direct
442 *
443 * That's a direct print of our data, whatever that data is. We don't want
444 * to worry about having to free it later, so we just used eet_direct_read()
445 * to tell Eet to gives a pointer to the internal data in the file, without
446 * duplicating it. Since we said that data was not compressed, we shouldn't
447 * worry about printing garbage to the screen (and yes, we also know the data
448 * is yet another string).
449 * We also don't care about the size of the data as it was stored in the file,
450 * so we passed NULL as the size parameter.
451 * One very important note about this, however, is that we don't care about
452 * the size parameter because the data in the file contains the null
453 * terminator for the string. So when using Eet to store strings this way,
454 * it's very important to consider whether you will keep that final null
455 * byte, or to always get the size read and do the necessary checks and copies.
456 * It's up to the user and the particular use cases to decide how this will
457 * be done.
458 *
459 * With everything done, close this second file and free the data used to open
460 * it. And this is important, we can't free that data until we are done with
461 * the file, as Eet is using it. When opening with eet_memopen_read(), the data
462 * passed to it must be available for as long as the the file is open.
463 * @until }
464 *
465 * Finally, we close the first file, shutdown all internal resources used by
466 * Eet and leave our main function, thus terminating our program.
467 * @until return
468 *
469 * You can look at the full code of the example @ref eet-file.c "here".
470 * @{
471 */
472
473/**
474 * @enum _Eet_File_Mode
475 * Modes that a file can be opened.
476 */
477typedef enum _Eet_File_Mode
478{
479 EET_FILE_MODE_INVALID = -1,
480 EET_FILE_MODE_READ, /**< File is read-only. */
481 EET_FILE_MODE_WRITE, /**< File is write-only. */
482 EET_FILE_MODE_READ_WRITE /**< File is for both read and write */
483} Eet_File_Mode; /**< Modes that a file can be opened. */
484
485/**
486 * @typedef Eet_File
487 * Opaque handle that defines an Eet file (or memory).
488 *
489 * This handle will be returned by the functions eet_open() and
490 * eet_memopen_read() and is used by every other function that affects the
491 * file in any way. When you are done with it, call eet_close() to clsoe it
492 * and, if the file was open for writing, write down to disk any changes made
493 * to it.
494 *
495 * @see eet_open()
496 * @see eet_memopen_read()
497 * @see eet_close()
498 */
499typedef struct _Eet_File Eet_File;
500
501/**
502 * @typedef Eet_Dictionary
503 * Opaque handle that defines a file-backed (mmaped) dictionary of strings.
504 */
505typedef struct _Eet_Dictionary Eet_Dictionary;
506
507/**
508 * @}
509 */
510
511/**
512 * Open an eet file on disk, and returns a handle to it.
513 * @param file The file path to the eet file. eg: @c "/tmp/file.eet".
514 * @param mode The mode for opening. Either #EET_FILE_MODE_READ,
515 * #EET_FILE_MODE_WRITE or #EET_FILE_MODE_READ_WRITE.
516 * @return An opened eet file handle.
517 * @ingroup Eet_File_Group
518 *
519 * This function will open an exiting eet file for reading, and build
520 * the directory table in memory and return a handle to the file, if it
521 * exists and can be read, and no memory errors occur on the way, otherwise
522 * NULL will be returned.
523 *
524 * It will also open an eet file for writing. This will, if successful,
525 * delete the original file and replace it with a new empty file, till
526 * the eet file handle is closed or flushed. If it cannot be opened for
527 * writing or a memory error occurs, NULL is returned.
528 *
529 * You can also open the file for read/write. If you then write a key that
530 * does not exist it will be created, if the key exists it will be replaced
531 * by the new data.
532 *
533 * If the same file is opened multiple times, then the same file handle will
534 * be returned as eet maintains an internal list of all currently open
535 * files. Note that it considers files opened for read only and those opened
536 * for read/write and write only as 2 separate sets. Those that do not write
537 * to the file and those that do. Eet will allow 2 handles to the same file
538 * if they are in the 2 separate lists/groups. That means opening a file for
539 * read only looks in the read only set, and returns a handle to that file
540 * handle and increments its reference count. If you open a file for read/write
541 * or write only it looks in the write set and returns a handle after
542 * incrementing the reference count. You need to close an eet file handle
543 * as many times as it has been opened to maintain correct reference counts.
544 * Files whose modified timestamp or size do not match those of the existing
545 * referenced file handles will not be returned and a new handle will be
546 * returned instead.
547 *
548 * @since 1.0.0
549 */
550EAPI Eet_File *
551eet_open(const char *file,
552 Eet_File_Mode mode);
553
554/**
555 * Open an eet file directly from a memory location. The data is not copied,
556 * so you must keep it around as long as the eet file is open. There is
557 * currently no cache for this kind of Eet_File, so it's reopened every time
558 * you use eet_memopen_read.
559 * Files opened this way will always be in read-only mode.
560 *
561 * @since 1.1.0
562 * @ingroup Eet_File_Group
563 */
564EAPI Eet_File *
565eet_memopen_read(const void *data,
566 size_t size);
567
568/**
569 * Get the mode an Eet_File was opened with.
570 * @param ef A valid eet file handle.
571 * @return The mode ef was opened with.
572 *
573 * @since 1.0.0
574 * @ingroup Eet_File_Group
575 */
576EAPI Eet_File_Mode
577eet_mode_get(Eet_File *ef);
578
579/**
580 * Close an eet file handle and flush and writes pending.
581 * @param ef A valid eet file handle.
582 *
583 * This function will flush any pending writes to disk if the eet file
584 * was opened for write, and free all data associated with the file handle
585 * and file, and close the file.
586 *
587 * If the eet file handle is not valid nothing will be done.
588 *
589 * @since 1.0.0
590 * @ingroup Eet_File_Group
591 */
592EAPI Eet_Error
593eet_close(Eet_File *ef);
594
595/**
596 * Sync content of an eet file handle, flushing pending writes.
597 * @param ef A valid eet file handle.
598 *
599 * This function will flush any pending writes to disk. The eet file must
600 * be opened for write.
601 *
602 * If the eet file handle is not valid nothing will be done.
603 *
604 * @since 1.2.4
605 * @ingroup Eet_File_Group
606 */
607EAPI Eet_Error
608eet_sync(Eet_File *ef);
609
610/**
611 * Return a handle to the shared string dictionary of the Eet file
612 * @param ef A valid eet file handle.
613 * @return A handle to the dictionary of the file
614 *
615 * This function returns a handle to the dictionary of an Eet file whose
616 * handle is @p ef, if a dictionary exists. NULL is returned otherwise or
617 * if the file handle is known to be invalid.
618 *
619 * @see eet_dictionary_string_check() to know if given string came
620 * from the dictionary or it was dynamically allocated using
621 * the #Eet_Data_Descriptor_Class instructrions.
622 *
623 * @since 1.0.0
624 * @ingroup Eet_File_Group
625 */
626EAPI Eet_Dictionary *
627eet_dictionary_get(Eet_File *ef);
628
629/**
630 * Check if a given string comes from a given dictionary
631 * @param ed A valid dictionary handle
632 * @param string A valid 0 byte terminated C string
633 * @return 1 if it is in the dictionary, 0 otherwise
634 *
635 * This checks the given dictionary to see if the given string is actually
636 * inside that dictionary (i.e. comes from it) and returns 1 if it does.
637 * If the dictionary handle is invalid, the string is NULL or the string is
638 * not in the dictionary, 0 is returned.
639 *
640 * @since 1.0.0
641 * @ingroup Eet_File_Group
642 */
643EAPI int
644eet_dictionary_string_check(Eet_Dictionary *ed,
645 const char *string);
646
647/**
648 * Read a specified entry from an eet file and return data
649 * @param ef A valid eet file handle opened for reading.
650 * @param name Name of the entry. eg: "/base/file_i_want".
651 * @param size_ret Number of bytes read from entry and returned.
652 * @return The data stored in that entry in the eet file.
653 *
654 * This function finds an entry in the eet file that is stored under the
655 * name specified, and returns that data, decompressed, if successful.
656 * NULL is returned if the lookup fails or if memory errors are
657 * encountered. It is the job of the calling program to call free() on
658 * the returned data. The number of bytes in the returned data chunk are
659 * placed in size_ret.
660 *
661 * If the eet file handle is not valid NULL is returned and size_ret is
662 * filled with 0.
663 *
664 * @see eet_read_cipher()
665 *
666 * @since 1.0.0
667 * @ingroup Eet_File_Group
668 */
669EAPI void *
670eet_read(Eet_File *ef,
671 const char *name,
672 int *size_ret);
673
674/**
675 * Read a specified entry from an eet file and return data
676 * @param ef A valid eet file handle opened for reading.
677 * @param name Name of the entry. eg: "/base/file_i_want".
678 * @param size_ret Number of bytes read from entry and returned.
679 * @return The data stored in that entry in the eet file.
680 *
681 * This function finds an entry in the eet file that is stored under the
682 * name specified, and returns that data if not compressed and successful.
683 * NULL is returned if the lookup fails or if memory errors are
684 * encountered or if the data is comrpessed. The calling program must never
685 * call free() on the returned data. The number of bytes in the returned
686 * data chunk are placed in size_ret.
687 *
688 * If the eet file handle is not valid NULL is returned and size_ret is
689 * filled with 0.
690 *
691 * @since 1.0.0
692 * @ingroup Eet_File_Group
693 */
694EAPI const void *
695eet_read_direct(Eet_File *ef,
696 const char *name,
697 int *size_ret);
698
699/**
700 * Write a specified entry to an eet file handle
701 * @param ef A valid eet file handle opened for writing.
702 * @param name Name of the entry. eg: "/base/file_i_want".
703 * @param data Pointer to the data to be stored.
704 * @param size Length in bytes in the data to be stored.
705 * @param compress Compression flags (1 == compress, 0 = don't compress).
706 * @return bytes written on successful write, 0 on failure.
707 *
708 * This function will write the specified chunk of data to the eet file
709 * and return greater than 0 on success. 0 will be returned on failure.
710 *
711 * The eet file handle must be a valid file handle for an eet file opened
712 * for writing. If it is not, 0 will be returned and no action will be
713 * performed.
714 *
715 * Name, and data must not be NULL, and size must be > 0. If these
716 * conditions are not met, 0 will be returned.
717 *
718 * The data will be copied (and optionally compressed) in ram, pending
719 * a flush to disk (it will stay in ram till the eet file handle is
720 * closed though).
721 *
722 * @see eet_write_cipher()
723 *
724 * @since 1.0.0
725 * @ingroup Eet_File_Group
726 */
727EAPI int
728eet_write(Eet_File *ef,
729 const char *name,
730 const void *data,
731 int size,
732 int compress);
733
734/**
735 * Delete a specified entry from an Eet file being written or re-written
736 * @param ef A valid eet file handle opened for writing.
737 * @param name Name of the entry. eg: "/base/file_i_want".
738 * @return Success or failure of the delete.
739 *
740 * This function will delete the specified chunk of data from the eet file
741 * and return greater than 0 on success. 0 will be returned on failure.
742 *
743 * The eet file handle must be a valid file handle for an eet file opened
744 * for writing. If it is not, 0 will be returned and no action will be
745 * performed.
746 *
747 * Name, must not be NULL, otherwise 0 will be returned.
748 *
749 * @since 1.0.0
750 * @ingroup Eet_File_Group
751 */
752EAPI int
753eet_delete(Eet_File *ef,
754 const char *name);
755
756/**
757 * Alias a specific section to another one. Destination may exist or not,
758 * no check are done.
759 * @param ef A valid eet file handle opened for writing.
760 * @param name Name of the new entry. eg: "/base/file_i_want".
761 * @param destination Actual source of the aliased entry eg: "/base/the_real_stuff_i_want".
762 * @param compress Compression flags (1 == compress, 0 = don't compress).
763 * @return EINA_TRUE on success, EINA_FALSE on failure.
764 *
765 * Name and Destination must not be NULL, otherwise EINA_FALSE will be returned.
766 * The equivalent of this would be calling 'ln -s destination name'
767 *
768 * @since 1.3.3
769 * @ingroup Eet_File_Group
770 */
771EAPI Eina_Bool
772eet_alias(Eet_File *ef,
773 const char *name,
774 const char *destination,
775 int compress);
776
777/**
778 * Retrieve the destination name of an alias
779 * @param ef A valid eet file handle opened for writing
780 * @param name Name of the entry. eg: "/base/file_i_want"
781 * @return Destination of the alias. eg: "/base/the_real_stuff_i_want", NULL on failure
782 *
783 * Name must not be NULL, otherwise NULL will be returned.
784 *
785 * @since 1.5
786 * @ingroup Eet_File_Group
787 */
788EAPI const char *
789eet_alias_get(Eet_File *ef,
790 const char *name);
791
792/**
793 * List all entries in eet file matching shell glob.
794 * @param ef A valid eet file handle.
795 * @param glob A shell glob to match against.
796 * @param count_ret Number of entries found to match.
797 * @return Pointer to an array of strings.
798 *
799 * This function will list all entries in the eet file matching the
800 * supplied shell glob and return an allocated list of their names, if
801 * there are any, and if no memory errors occur.
802 *
803 * The eet file handle must be valid and glob must not be NULL, or NULL
804 * will be returned and count_ret will be filled with 0.
805 *
806 * The calling program must call free() on the array returned, but NOT
807 * on the string pointers in the array. They are taken as read-only
808 * internals from the eet file handle. They are only valid as long as
809 * the file handle is not closed. When it is closed those pointers in the
810 * array are now not valid and should not be used.
811 *
812 * On success the array returned will have a list of string pointers
813 * that are the names of the entries that matched, and count_ret will have
814 * the number of entries in this array placed in it.
815 *
816 * Hint: an easy way to list all entries in an eet file is to use a glob
817 * value of "*".
818 *
819 * @since 1.0.0
820 * @ingroup Eet_File_Group
821 */
822EAPI char **
823eet_list(Eet_File *ef,
824 const char *glob,
825 int *count_ret);
826
827/**
828 * Return the number of entries in the specified eet file.
829 * @param ef A valid eet file handle.
830 * @return Number of entries in ef or -1 if the number of entries
831 * cannot be read due to open mode restrictions.
832 *
833 * @since 1.0.0
834 * @ingroup Eet_File_Group
835 */
836EAPI int
837eet_num_entries(Eet_File *ef);
838
839/**
840 * @defgroup Eet_File_Cipher_Group Eet File Ciphered Main Functions
841 *
842 * Most of the @ref Eet_File_Group have alternative versions that
843 * accounts for ciphers to protect their content.
844 *
845 * @see @ref Eet_Cipher_Group
846 *
847 * @ingroup Eet_File_Group
848 */
849
850/**
851 * Read a specified entry from an eet file and return data using a cipher.
852 * @param ef A valid eet file handle opened for reading.
853 * @param name Name of the entry. eg: "/base/file_i_want".
854 * @param size_ret Number of bytes read from entry and returned.
855 * @param cipher_key The key to use as cipher.
856 * @return The data stored in that entry in the eet file.
857 *
858 * This function finds an entry in the eet file that is stored under the
859 * name specified, and returns that data, decompressed, if successful.
860 * NULL is returned if the lookup fails or if memory errors are
861 * encountered. It is the job of the calling program to call free() on
862 * the returned data. The number of bytes in the returned data chunk are
863 * placed in size_ret.
864 *
865 * If the eet file handle is not valid NULL is returned and size_ret is
866 * filled with 0.
867 *
868 * @see eet_read()
869 *
870 * @since 1.0.0
871 * @ingroup Eet_File_Cipher_Group
872 */
873EAPI void *
874eet_read_cipher(Eet_File *ef,
875 const char *name,
876 int *size_ret,
877 const char *cipher_key);
878
879/**
880 * Write a specified entry to an eet file handle using a cipher.
881 * @param ef A valid eet file handle opened for writing.
882 * @param name Name of the entry. eg: "/base/file_i_want".
883 * @param data Pointer to the data to be stored.
884 * @param size Length in bytes in the data to be stored.
885 * @param compress Compression flags (1 == compress, 0 = don't compress).
886 * @param cipher_key The key to use as cipher.
887 * @return bytes written on successful write, 0 on failure.
888 *
889 * This function will write the specified chunk of data to the eet file
890 * and return greater than 0 on success. 0 will be returned on failure.
891 *
892 * The eet file handle must be a valid file handle for an eet file opened
893 * for writing. If it is not, 0 will be returned and no action will be
894 * performed.
895 *
896 * Name, and data must not be NULL, and size must be > 0. If these
897 * conditions are not met, 0 will be returned.
898 *
899 * The data will be copied (and optionally compressed) in ram, pending
900 * a flush to disk (it will stay in ram till the eet file handle is
901 * closed though).
902 *
903 * @see eet_write()
904 *
905 * @since 1.0.0
906 * @ingroup Eet_File_Cipher_Group
907 */
908EAPI int
909eet_write_cipher(Eet_File *ef,
910 const char *name,
911 const void *data,
912 int size,
913 int compress,
914 const char *cipher_key);
915
916/**
917 * @defgroup Eet_File_Image_Group Image Store and Load
918 *
919 * Eet efficiently stores and loads images, including alpha
920 * channels and lossy compressions.
921 *
922 * Eet can handle both lossy compression with different levels of quality and
923 * non-lossy compression with different compression levels. It's also possible,
924 * given an image data, to only read its header to get the image information
925 * without decoding the entire content for it.
926 *
927 * The encode family of functions will take an image raw buffer and its
928 * parameters and compress it in memory, returning the new buffer.
929 * Likewise, the decode functions will read from the given location in memory
930 * and return the uncompressed image.
931 *
932 * The read and write functions will, respectively, encode and decode to or
933 * from an Eet file, under the specified key.
934 *
935 * These functions are fairly low level and the same functionality can be
936 * achieved using Evas and Edje, making it much easier to work with images
937 * as well as not needing to worry about things like scaling them.
938 */
939
940/**
941 * Read just the header data for an image and dont decode the pixels.
942 * @param ef A valid eet file handle opened for reading.
943 * @param name Name of the entry. eg: "/base/file_i_want".
944 * @param w A pointer to the unsigned int to hold the width in pixels.
945 * @param h A pointer to the unsigned int to hold the height in pixels.
946 * @param alpha A pointer to the int to hold the alpha flag.
947 * @param compress A pointer to the int to hold the compression amount.
948 * @param quality A pointer to the int to hold the quality amount.
949 * @param lossy A pointer to the int to hold the lossiness flag.
950 * @return 1 on successful decode, 0 otherwise
951 *
952 * Reads and decodes the image header data stored under the given key and
953 * Eet file.
954 *
955 * The information decoded is placed in each of the parameters, which must be
956 * provided. The width and height, measured in pixels, will be stored under
957 * the variables pointed by @p w and @p h, respectively. If the read or
958 * decode of the header fails, this values will be 0. The @p alpha parameter
959 * will be 1 or 0, denoting if the alpha channel of the image is used or not.
960 * If the image was losslessly compressed, the @p compress parameter will hold
961 * the compression amount used, ranging from 0 to 9 and @p lossy will be 0.
962 * In the case of lossy compression, @p lossy will be 1, and the compression
963 * quality will be placed under @p quality, with a value ranging from 0 to 100.
964 *
965 * @see eet_data_image_header_decode()
966 * @see eet_data_image_header_read_cipher()
967 *
968 * @since 1.0.0
969 * @ingroup Eet_File_Image_Group
970 */
971EAPI int
972eet_data_image_header_read(Eet_File *ef,
973 const char *name,
974 unsigned int *w,
975 unsigned int *h,
976 int *alpha,
977 int *compress,
978 int *quality,
979 int *lossy);
980
981/**
982 * Read image data from the named key in the eet file.
983 * @param ef A valid eet file handle opened for reading.
984 * @param name Name of the entry. eg: "/base/file_i_want".
985 * @param w A pointer to the unsigned int to hold the width in pixels.
986 * @param h A pointer to the unsigned int to hold the height in pixels.
987 * @param alpha A pointer to the int to hold the alpha flag.
988 * @param compress A pointer to the int to hold the compression amount.
989 * @param quality A pointer to the int to hold the quality amount.
990 * @param lossy A pointer to the int to hold the lossiness flag.
991 * @return The image pixel data decoded
992 *
993 * Reads and decodes the image stored in the given Eet file under the named
994 * key.
995 *
996 * The returned pixel data is a linear array of pixels starting from the
997 * top-left of the image, scanning row by row from left to right. Each pile
998 * is a 32bit value, with the high byte being the alpha channel, the next being
999 * red, then green, and the low byte being blue.
1000 *
1001 * The rest of the parameters are the same as in eet_data_image_header_read().
1002 *
1003 * On success the function returns a pointer to the image data decoded. The
1004 * calling application is responsible for calling free() on the image data
1005 * when it is done with it. On failure NULL is returned and the parameter
1006 * values may not contain any sensible data.
1007 *
1008 * @see eet_data_image_header_read()
1009 * @see eet_data_image_decode()
1010 * @see eet_data_image_read_cipher()
1011 * @see eet_data_image_read_to_surface()
1012 *
1013 * @since 1.0.0
1014 * @ingroup Eet_File_Image_Group
1015 */
1016EAPI void *
1017eet_data_image_read(Eet_File *ef,
1018 const char *name,
1019 unsigned int *w,
1020 unsigned int *h,
1021 int *alpha,
1022 int *compress,
1023 int *quality,
1024 int *lossy);
1025
1026/**
1027 * Read image data from the named key in the eet file and store it in the given buffer.
1028 * @param ef A valid eet file handle opened for reading.
1029 * @param name Name of the entry. eg: "/base/file_i_want".
1030 * @param src_x The starting x coordinate from where to dump the stream.
1031 * @param src_y The starting y coordinate from where to dump the stream.
1032 * @param d A pointer to the pixel surface.
1033 * @param w The expected width in pixels of the pixel surface to decode.
1034 * @param h The expected height in pixels of the pixel surface to decode.
1035 * @param row_stride The length of a pixels line in the destination surface.
1036 * @param alpha A pointer to the int to hold the alpha flag.
1037 * @param compress A pointer to the int to hold the compression amount.
1038 * @param quality A pointer to the int to hold the quality amount.
1039 * @param lossy A pointer to the int to hold the lossiness flag.
1040 * @return 1 on success, 0 otherwise.
1041 *
1042 * Reads and decodes the image stored in the given Eet file, placing the
1043 * resulting pixel data in the buffer pointed by the user.
1044 *
1045 * Like eet_data_image_read(), it takes the image data stored under the
1046 * @p name key in the @p ef file, but instead of returning a new buffer with
1047 * the pixel data, it places the result in the buffer pointed by @p d, which
1048 * must be provided by the user and of sufficient size to hold the requested
1049 * portion of the image.
1050 *
1051 * The @p src_x and @p src_y parameters indicate the top-left corner of the
1052 * section of the image to decode. These have to be higher or equal than 0 and
1053 * less than the respective total width and height of the image. The width
1054 * and height of the section of the image to decode are given in @p w and @p h
1055 * and also can't be higher than the total width and height of the image.
1056 *
1057 * The @p row_stride parameter indicates the length in bytes of each line in
1058 * the destination buffer and it has to be at least @p w * 4.
1059 *
1060 * All the other parameters are the same as in eet_data_image_read().
1061 *
1062 * On success the function returns 1, and 0 on failure. On failure the
1063 * parameter values may not contain any sensible data.
1064 *
1065 * @see eet_data_image_read()
1066 * @see eet_data_image_decode()
1067 * @see eet_data_image_decode_to_surface()
1068 * @see eet_data_image_read_to_surface_cipher()
1069 *
1070 * @since 1.0.2
1071 * @ingroup Eet_File_Image_Group
1072 */
1073EAPI int
1074eet_data_image_read_to_surface(Eet_File *ef,
1075 const char *name,
1076 unsigned int src_x,
1077 unsigned int src_y,
1078 unsigned int *d,
1079 unsigned int w,
1080 unsigned int h,
1081 unsigned int row_stride,
1082 int *alpha,
1083 int *compress,
1084 int *quality,
1085 int *lossy);
1086
1087/**
1088 * Write image data to the named key in an eet file.
1089 * @param ef A valid eet file handle opened for writing.
1090 * @param name Name of the entry. eg: "/base/file_i_want".
1091 * @param data A pointer to the image pixel data.
1092 * @param w The width of the image in pixels.
1093 * @param h The height of the image in pixels.
1094 * @param alpha The alpha channel flag.
1095 * @param compress The compression amount.
1096 * @param quality The quality encoding amount.
1097 * @param lossy The lossiness flag.
1098 * @return Success if the data was encoded and written or not.
1099 *
1100 * This function takes image pixel data and encodes it in an eet file
1101 * stored under the supplied name key, and returns how many bytes were
1102 * actually written to encode the image data.
1103 *
1104 * The data expected is the same format as returned by eet_data_image_read.
1105 * If this is not the case weird things may happen. Width and height must
1106 * be between 1 and 8000 pixels. The alpha flags can be 0 or 1 (0 meaning
1107 * the alpha values are not useful and 1 meaning they are). Compress can
1108 * be from 0 to 9 (0 meaning no compression, 9 meaning full compression).
1109 * This is only used if the image is not lossily encoded. Quality is used on
1110 * lossy compression and should be a value from 0 to 100. The lossy flag
1111 * can be 0 or 1. 0 means encode losslessly and 1 means to encode with
1112 * image quality loss (but then have a much smaller encoding).
1113 *
1114 * On success this function returns the number of bytes that were required
1115 * to encode the image data, or on failure it returns 0.
1116 *
1117 * @see eet_data_image_read()
1118 * @see eet_data_image_encode()
1119 * @see eet_data_image_write_cipher()
1120 *
1121 * @since 1.0.0
1122 * @ingroup Eet_File_Image_Group
1123 */
1124EAPI int
1125eet_data_image_write(Eet_File *ef,
1126 const char *name,
1127 const void *data,
1128 unsigned int w,
1129 unsigned int h,
1130 int alpha,
1131 int compress,
1132 int quality,
1133 int lossy);
1134
1135/**
1136 * Decode Image data header only to get information.
1137 * @param data The encoded pixel data.
1138 * @param size The size, in bytes, of the encoded pixel data.
1139 * @param w A pointer to the unsigned int to hold the width in pixels.
1140 * @param h A pointer to the unsigned int to hold the height in pixels.
1141 * @param alpha A pointer to the int to hold the alpha flag.
1142 * @param compress A pointer to the int to hold the compression amount.
1143 * @param quality A pointer to the int to hold the quality amount.
1144 * @param lossy A pointer to the int to hold the lossiness flag.
1145 * @return 1 on success, 0 on failure.
1146 *
1147 * This function works exactly like eet_data_image_header_read(), but instead
1148 * of reading from an Eet file, it takes the buffer of size @p size pointed
1149 * by @p data, which must be a valid Eet encoded image.
1150 *
1151 * On success the function returns 1 indicating the header was read and
1152 * decoded properly, or 0 on failure.
1153 *
1154 * @see eet_data_image_header_read()
1155 * @see eet_data_image_header_decode_cipher()
1156 *
1157 * @since 1.0.0
1158 * @ingroup Eet_File_Image_Group
1159 */
1160EAPI int
1161eet_data_image_header_decode(const void *data,
1162 int size,
1163 unsigned int *w,
1164 unsigned int *h,
1165 int *alpha,
1166 int *compress,
1167 int *quality,
1168 int *lossy);
1169
1170/**
1171 * Decode Image data into pixel data.
1172 * @param data The encoded pixel data.
1173 * @param size The size, in bytes, of the encoded pixel data.
1174 * @param w A pointer to the unsigned int to hold the width in pixels.
1175 * @param h A pointer to the unsigned int to hold the height in pixels.
1176 * @param alpha A pointer to the int to hold the alpha flag.
1177 * @param compress A pointer to the int to hold the compression amount.
1178 * @param quality A pointer to the int to hold the quality amount.
1179 * @param lossy A pointer to the int to hold the lossiness flag.
1180 * @return The image pixel data decoded
1181 *
1182 * This function takes encoded pixel data and decodes it into raw RGBA
1183 * pixels on success.
1184 *
1185 * It works exactly like eet_data_image_read(), but it takes the encoded
1186 * data in the @p data buffer of size @p size, instead of reading from a file.
1187 * All the others parameters are also the same.
1188 *
1189 * On success the function returns a pointer to the image data decoded. The
1190 * calling application is responsible for calling free() on the image data
1191 * when it is done with it. On failure NULL is returned and the parameter
1192 * values may not contain any sensible data.
1193 *
1194 * @see eet_data_image_read()
1195 * @see eet_data_image_decode_cipher()
1196 *
1197 * @since 1.0.0
1198 * @ingroup Eet_File_Image_Group
1199 */
1200EAPI void *
1201eet_data_image_decode(const void *data,
1202 int size,
1203 unsigned int *w,
1204 unsigned int *h,
1205 int *alpha,
1206 int *compress,
1207 int *quality,
1208 int *lossy);
1209
1210/**
1211 * Decode Image data into pixel data and stores in the given buffer.
1212 * @param data The encoded pixel data.
1213 * @param size The size, in bytes, of the encoded pixel data.
1214 * @param src_x The starting x coordinate from where to dump the stream.
1215 * @param src_y The starting y coordinate from where to dump the stream.
1216 * @param d A pointer to the pixel surface.
1217 * @param w The expected width in pixels of the pixel surface to decode.
1218 * @param h The expected height in pixels of the pixel surface to decode.
1219 * @param row_stride The length of a pixels line in the destination surface.
1220 * @param alpha A pointer to the int to hold the alpha flag.
1221 * @param compress A pointer to the int to hold the compression amount.
1222 * @param quality A pointer to the int to hold the quality amount.
1223 * @param lossy A pointer to the int to hold the lossiness flag.
1224 * @return 1 on success, 0 otherwise.
1225 *
1226 * Like eet_data_image_read_to_surface(), but reading the given @p data buffer
1227 * instead of a file.
1228 *
1229 * On success the function returns 1, and 0 on failure. On failure the
1230 * parameter values may not contain any sensible data.
1231 *
1232 * @see eet_data_image_read_to_surface()
1233 * @see eet_data_image_decode_to_surface_cipher()
1234 *
1235 * @since 1.0.2
1236 * @ingroup Eet_File_Image_Group
1237 */
1238EAPI int
1239eet_data_image_decode_to_surface(const void *data,
1240 int size,
1241 unsigned int src_x,
1242 unsigned int src_y,
1243 unsigned int *d,
1244 unsigned int w,
1245 unsigned int h,
1246 unsigned int row_stride,
1247 int *alpha,
1248 int *compress,
1249 int *quality,
1250 int *lossy);
1251
1252/**
1253 * Encode image data for storage or transmission.
1254 * @param data A pointer to the image pixel data.
1255 * @param size_ret A pointer to an int to hold the size of the returned data.
1256 * @param w The width of the image in pixels.
1257 * @param h The height of the image in pixels.
1258 * @param alpha The alpha channel flag.
1259 * @param compress The compression amount.
1260 * @param quality The quality encoding amount.
1261 * @param lossy The lossiness flag.
1262 * @return The encoded image data.
1263 *
1264 * This function stakes image pixel data and encodes it with compression and
1265 * possible loss of quality (as a trade off for size) for storage or
1266 * transmission to another system.
1267 *
1268 * It works like eet_data_image_write(), but instead of writing the encoded
1269 * image into an Eet file, it allocates a new buffer of the size required and
1270 * returns the encoded data in it.
1271 *
1272 * On success this function returns a pointer to the encoded data that you
1273 * can free with free() when no longer needed.
1274 *
1275 * @see eet_data_image_write()
1276 * @see eet_data_image_read()
1277 * @see eet_data_image_encode_cipher()
1278 *
1279 * @since 1.0.0
1280 * @ingroup Eet_File_Image_Group
1281 */
1282EAPI void *
1283eet_data_image_encode(const void *data,
1284 int *size_ret,
1285 unsigned int w,
1286 unsigned int h,
1287 int alpha,
1288 int compress,
1289 int quality,
1290 int lossy);
1291
1292/**
1293 * @defgroup Eet_File_Image_Cipher_Group Image Store and Load using a Cipher
1294 *
1295 * Most of the @ref Eet_File_Image_Group have alternative versions
1296 * that accounts for ciphers to protect their content.
1297 *
1298 * @see @ref Eet_Cipher_Group
1299 *
1300 * @ingroup Eet_File_Image_Group
1301 */
1302
1303/**
1304 * Read just the header data for an image and dont decode the pixels using a cipher.
1305 * @param ef A valid eet file handle opened for reading.
1306 * @param name Name of the entry. eg: "/base/file_i_want".
1307 * @param cipher_key The key to use as cipher.
1308 * @param w A pointer to the unsigned int to hold the width in pixels.
1309 * @param h A pointer to the unsigned int to hold the height in pixels.
1310 * @param alpha A pointer to the int to hold the alpha flag.
1311 * @param compress A pointer to the int to hold the compression amount.
1312 * @param quality A pointer to the int to hold the quality amount.
1313 * @param lossy A pointer to the int to hold the lossiness flag.
1314 * @return 1 on successful decode, 0 otherwise
1315 *
1316 * This function reads an image from an eet file stored under the named
1317 * key in the eet file and return a pointer to the decompressed pixel data.
1318 *
1319 * The other parameters of the image (width, height etc.) are placed into
1320 * the values pointed to (they must be supplied). The pixel data is a linear
1321 * array of pixels starting from the top-left of the image scanning row by
1322 * row from left to right. Each pixel is a 32bit value, with the high byte
1323 * being the alpha channel, the next being red, then green, and the low byte
1324 * being blue. The width and height are measured in pixels and will be
1325 * greater than 0 when returned. The alpha flag is either 0 or 1. 0 denotes
1326 * that the alpha channel is not used. 1 denotes that it is significant.
1327 * Compress is filled with the compression value/amount the image was
1328 * stored with. The quality value is filled with the quality encoding of
1329 * the image file (0 - 100). The lossy flags is either 0 or 1 as to if
1330 * the image was encoded lossily or not.
1331 *
1332 * On success the function returns 1 indicating the header was read and
1333 * decoded properly, or 0 on failure.
1334 *
1335 * @see eet_data_image_header_read()
1336 *
1337 * @since 1.0.0
1338 * @ingroup Eet_File_Image_Cipher_Group
1339 */
1340EAPI int
1341eet_data_image_header_read_cipher(Eet_File *ef,
1342 const char *name,
1343 const char *cipher_key,
1344 unsigned int *w,
1345 unsigned int *h,
1346 int *alpha,
1347 int *compress,
1348 int *quality,
1349 int *lossy);
1350
1351/**
1352 * Read image data from the named key in the eet file using a cipher.
1353 * @param ef A valid eet file handle opened for reading.
1354 * @param name Name of the entry. eg: "/base/file_i_want".
1355 * @param cipher_key The key to use as cipher.
1356 * @param w A pointer to the unsigned int to hold the width in pixels.
1357 * @param h A pointer to the unsigned int to hold the height in pixels.
1358 * @param alpha A pointer to the int to hold the alpha flag.
1359 * @param compress A pointer to the int to hold the compression amount.
1360 * @param quality A pointer to the int to hold the quality amount.
1361 * @param lossy A pointer to the int to hold the lossiness flag.
1362 * @return The image pixel data decoded
1363 *
1364 * This function reads an image from an eet file stored under the named
1365 * key in the eet file and return a pointer to the decompressed pixel data.
1366 *
1367 * The other parameters of the image (width, height etc.) are placed into
1368 * the values pointed to (they must be supplied). The pixel data is a linear
1369 * array of pixels starting from the top-left of the image scanning row by
1370 * row from left to right. Each pixel is a 32bit value, with the high byte
1371 * being the alpha channel, the next being red, then green, and the low byte
1372 * being blue. The width and height are measured in pixels and will be
1373 * greater than 0 when returned. The alpha flag is either 0 or 1. 0 denotes
1374 * that the alpha channel is not used. 1 denotes that it is significant.
1375 * Compress is filled with the compression value/amount the image was
1376 * stored with. The quality value is filled with the quality encoding of
1377 * the image file (0 - 100). The lossy flags is either 0 or 1 as to if
1378 * the image was encoded lossily or not.
1379 *
1380 * On success the function returns a pointer to the image data decoded. The
1381 * calling application is responsible for calling free() on the image data
1382 * when it is done with it. On failure NULL is returned and the parameter
1383 * values may not contain any sensible data.
1384 *
1385 * @see eet_data_image_read()
1386 *
1387 * @since 1.0.0
1388 * @ingroup Eet_File_Image_Cipher_Group
1389 */
1390EAPI void *
1391eet_data_image_read_cipher(Eet_File *ef,
1392 const char *name,
1393 const char *cipher_key,
1394 unsigned int *w,
1395 unsigned int *h,
1396 int *alpha,
1397 int *compress,
1398 int *quality,
1399 int *lossy);
1400
1401/**
1402 * Read image data from the named key in the eet file using a cipher.
1403 * @param ef A valid eet file handle opened for reading.
1404 * @param name Name of the entry. eg: "/base/file_i_want".
1405 * @param cipher_key The key to use as cipher.
1406 * @param src_x The starting x coordinate from where to dump the stream.
1407 * @param src_y The starting y coordinate from where to dump the stream.
1408 * @param d A pointer to the pixel surface.
1409 * @param w The expected width in pixels of the pixel surface to decode.
1410 * @param h The expected height in pixels of the pixel surface to decode.
1411 * @param row_stride The length of a pixels line in the destination surface.
1412 * @param alpha A pointer to the int to hold the alpha flag.
1413 * @param compress A pointer to the int to hold the compression amount.
1414 * @param quality A pointer to the int to hold the quality amount.
1415 * @param lossy A pointer to the int to hold the lossiness flag.
1416 * @return 1 on success, 0 otherwise.
1417 *
1418 * This function reads an image from an eet file stored under the named
1419 * key in the eet file and return a pointer to the decompressed pixel data.
1420 *
1421 * The other parameters of the image (width, height etc.) are placed into
1422 * the values pointed to (they must be supplied). The pixel data is a linear
1423 * array of pixels starting from the top-left of the image scanning row by
1424 * row from left to right. Each pixel is a 32bit value, with the high byte
1425 * being the alpha channel, the next being red, then green, and the low byte
1426 * being blue. The width and height are measured in pixels and will be
1427 * greater than 0 when returned. The alpha flag is either 0 or 1. 0 denotes
1428 * that the alpha channel is not used. 1 denotes that it is significant.
1429 * Compress is filled with the compression value/amount the image was
1430 * stored with. The quality value is filled with the quality encoding of
1431 * the image file (0 - 100). The lossy flags is either 0 or 1 as to if
1432 * the image was encoded lossily or not.
1433 *
1434 * On success the function returns 1, and 0 on failure. On failure the
1435 * parameter values may not contain any sensible data.
1436 *
1437 * @see eet_data_image_read_to_surface()
1438 *
1439 * @since 1.0.2
1440 * @ingroup Eet_File_Image_Cipher_Group
1441 */
1442EAPI int
1443eet_data_image_read_to_surface_cipher(Eet_File *ef,
1444 const char *name,
1445 const char *cipher_key,
1446 unsigned int src_x,
1447 unsigned int src_y,
1448 unsigned int *d,
1449 unsigned int w,
1450 unsigned int h,
1451 unsigned int row_stride,
1452 int *alpha,
1453 int *compress,
1454 int *quality,
1455 int *lossy);
1456
1457/**
1458 * Write image data to the named key in an eet file using a cipher.
1459 * @param ef A valid eet file handle opened for writing.
1460 * @param name Name of the entry. eg: "/base/file_i_want".
1461 * @param cipher_key The key to use as cipher.
1462 * @param data A pointer to the image pixel data.
1463 * @param w The width of the image in pixels.
1464 * @param h The height of the image in pixels.
1465 * @param alpha The alpha channel flag.
1466 * @param compress The compression amount.
1467 * @param quality The quality encoding amount.
1468 * @param lossy The lossiness flag.
1469 * @return Success if the data was encoded and written or not.
1470 *
1471 * This function takes image pixel data and encodes it in an eet file
1472 * stored under the supplied name key, and returns how many bytes were
1473 * actually written to encode the image data.
1474 *
1475 * The data expected is the same format as returned by eet_data_image_read.
1476 * If this is not the case weird things may happen. Width and height must
1477 * be between 1 and 8000 pixels. The alpha flags can be 0 or 1 (0 meaning
1478 * the alpha values are not useful and 1 meaning they are). Compress can
1479 * be from 0 to 9 (0 meaning no compression, 9 meaning full compression).
1480 * This is only used if the image is not lossily encoded. Quality is used on
1481 * lossy compression and should be a value from 0 to 100. The lossy flag
1482 * can be 0 or 1. 0 means encode losslessly and 1 means to encode with
1483 * image quality loss (but then have a much smaller encoding).
1484 *
1485 * On success this function returns the number of bytes that were required
1486 * to encode the image data, or on failure it returns 0.
1487 *
1488 * @see eet_data_image_write()
1489 *
1490 * @since 1.0.0
1491 * @ingroup Eet_File_Image_Cipher_Group
1492 */
1493EAPI int
1494eet_data_image_write_cipher(Eet_File *ef,
1495 const char *name,
1496 const char *cipher_key,
1497 const void *data,
1498 unsigned int w,
1499 unsigned int h,
1500 int alpha,
1501 int compress,
1502 int quality,
1503 int lossy);
1504
1505/**
1506 * Decode Image data header only to get information using a cipher.
1507 * @param data The encoded pixel data.
1508 * @param cipher_key The key to use as cipher.
1509 * @param size The size, in bytes, of the encoded pixel data.
1510 * @param w A pointer to the unsigned int to hold the width in pixels.
1511 * @param h A pointer to the unsigned int to hold the height in pixels.
1512 * @param alpha A pointer to the int to hold the alpha flag.
1513 * @param compress A pointer to the int to hold the compression amount.
1514 * @param quality A pointer to the int to hold the quality amount.
1515 * @param lossy A pointer to the int to hold the lossiness flag.
1516 * @return 1 on success, 0 on failure.
1517 *
1518 * This function takes encoded pixel data and decodes it into raw RGBA
1519 * pixels on success.
1520 *
1521 * The other parameters of the image (width, height etc.) are placed into
1522 * the values pointed to (they must be supplied). The pixel data is a linear
1523 * array of pixels starting from the top-left of the image scanning row by
1524 * row from left to right. Each pixel is a 32bit value, with the high byte
1525 * being the alpha channel, the next being red, then green, and the low byte
1526 * being blue. The width and height are measured in pixels and will be
1527 * greater than 0 when returned. The alpha flag is either 0 or 1. 0 denotes
1528 * that the alpha channel is not used. 1 denotes that it is significant.
1529 * Compress is filled with the compression value/amount the image was
1530 * stored with. The quality value is filled with the quality encoding of
1531 * the image file (0 - 100). The lossy flags is either 0 or 1 as to if
1532 * the image was encoded lossily or not.
1533 *
1534 * On success the function returns 1 indicating the header was read and
1535 * decoded properly, or 0 on failure.
1536 *
1537 * @see eet_data_image_header_decode()
1538 *
1539 * @since 1.0.0
1540 * @ingroup Eet_File_Image_Cipher_Group
1541 */
1542EAPI int
1543eet_data_image_header_decode_cipher(const void *data,
1544 const char *cipher_key,
1545 int size,
1546 unsigned int *w,
1547 unsigned int *h,
1548 int *alpha,
1549 int *compress,
1550 int *quality,
1551 int *lossy);
1552
1553/**
1554 * Decode Image data into pixel data using a cipher.
1555 * @param data The encoded pixel data.
1556 * @param cipher_key The key to use as cipher.
1557 * @param size The size, in bytes, of the encoded pixel data.
1558 * @param w A pointer to the unsigned int to hold the width in pixels.
1559 * @param h A pointer to the unsigned int to hold the height in pixels.
1560 * @param alpha A pointer to the int to hold the alpha flag.
1561 * @param compress A pointer to the int to hold the compression amount.
1562 * @param quality A pointer to the int to hold the quality amount.
1563 * @param lossy A pointer to the int to hold the lossiness flag.
1564 * @return The image pixel data decoded
1565 *
1566 * This function takes encoded pixel data and decodes it into raw RGBA
1567 * pixels on success.
1568 *
1569 * The other parameters of the image (width, height etc.) are placed into
1570 * the values pointed to (they must be supplied). The pixel data is a linear
1571 * array of pixels starting from the top-left of the image scanning row by
1572 * row from left to right. Each pixel is a 32bit value, with the high byte
1573 * being the alpha channel, the next being red, then green, and the low byte
1574 * being blue. The width and height are measured in pixels and will be
1575 * greater than 0 when returned. The alpha flag is either 0 or 1. 0 denotes
1576 * that the alpha channel is not used. 1 denotes that it is significant.
1577 * Compress is filled with the compression value/amount the image was
1578 * stored with. The quality value is filled with the quality encoding of
1579 * the image file (0 - 100). The lossy flags is either 0 or 1 as to if
1580 * the image was encoded lossily or not.
1581 *
1582 * On success the function returns a pointer to the image data decoded. The
1583 * calling application is responsible for calling free() on the image data
1584 * when it is done with it. On failure NULL is returned and the parameter
1585 * values may not contain any sensible data.
1586 *
1587 * @see eet_data_image_decode()
1588 *
1589 * @since 1.0.0
1590 * @ingroup Eet_File_Image_Cipher_Group
1591 */
1592EAPI void *
1593eet_data_image_decode_cipher(const void *data,
1594 const char *cipher_key,
1595 int size,
1596 unsigned int *w,
1597 unsigned int *h,
1598 int *alpha,
1599 int *compress,
1600 int *quality,
1601 int *lossy);
1602
1603/**
1604 * Decode Image data into pixel data using a cipher.
1605 * @param data The encoded pixel data.
1606 * @param cipher_key The key to use as cipher.
1607 * @param size The size, in bytes, of the encoded pixel data.
1608 * @param src_x The starting x coordinate from where to dump the stream.
1609 * @param src_y The starting y coordinate from where to dump the stream.
1610 * @param d A pointer to the pixel surface.
1611 * @param w The expected width in pixels of the pixel surface to decode.
1612 * @param h The expected height in pixels of the pixel surface to decode.
1613 * @param row_stride The length of a pixels line in the destination surface.
1614 * @param alpha A pointer to the int to hold the alpha flag.
1615 * @param compress A pointer to the int to hold the compression amount.
1616 * @param quality A pointer to the int to hold the quality amount.
1617 * @param lossy A pointer to the int to hold the lossiness flag.
1618 * @return 1 on success, 0 otherwise.
1619 *
1620 * This function takes encoded pixel data and decodes it into raw RGBA
1621 * pixels on success.
1622 *
1623 * The other parameters of the image (alpha, compress etc.) are placed into
1624 * the values pointed to (they must be supplied). The pixel data is a linear
1625 * array of pixels starting from the top-left of the image scanning row by
1626 * row from left to right. Each pixel is a 32bit value, with the high byte
1627 * being the alpha channel, the next being red, then green, and the low byte
1628 * being blue. The width and height are measured in pixels and will be
1629 * greater than 0 when returned. The alpha flag is either 0 or 1. 0 denotes
1630 * that the alpha channel is not used. 1 denotes that it is significant.
1631 * Compress is filled with the compression value/amount the image was
1632 * stored with. The quality value is filled with the quality encoding of
1633 * the image file (0 - 100). The lossy flags is either 0 or 1 as to if
1634 * the image was encoded lossily or not.
1635 *
1636 * On success the function returns 1, and 0 on failure. On failure the
1637 * parameter values may not contain any sensible data.
1638 *
1639 * @see eet_data_image_decode_to_surface()
1640 *
1641 * @since 1.0.2
1642 * @ingroup Eet_File_Image_Cipher_Group
1643 */
1644EAPI int
1645eet_data_image_decode_to_surface_cipher(const void *data,
1646 const char *cipher_key,
1647 int size,
1648 unsigned int src_x,
1649 unsigned int src_y,
1650 unsigned int *d,
1651 unsigned int w,
1652 unsigned int h,
1653 unsigned int row_stride,
1654 int *alpha,
1655 int *compress,
1656 int *quality,
1657 int *lossy);
1658
1659/**
1660 * Encode image data for storage or transmission using a cipher.
1661 * @param data A pointer to the image pixel data.
1662 * @param cipher_key The key to use as cipher.
1663 * @param size_ret A pointer to an int to hold the size of the returned data.
1664 * @param w The width of the image in pixels.
1665 * @param h The height of the image in pixels.
1666 * @param alpha The alpha channel flag.
1667 * @param compress The compression amount.
1668 * @param quality The quality encoding amount.
1669 * @param lossy The lossiness flag.
1670 * @return The encoded image data.
1671 *
1672 * This function stakes image pixel data and encodes it with compression and
1673 * possible loss of quality (as a trade off for size) for storage or
1674 * transmission to another system.
1675 *
1676 * The data expected is the same format as returned by eet_data_image_read.
1677 * If this is not the case weird things may happen. Width and height must
1678 * be between 1 and 8000 pixels. The alpha flags can be 0 or 1 (0 meaning
1679 * the alpha values are not useful and 1 meaning they are). Compress can
1680 * be from 0 to 9 (0 meaning no compression, 9 meaning full compression).
1681 * This is only used if the image is not lossily encoded. Quality is used on
1682 * lossy compression and should be a value from 0 to 100. The lossy flag
1683 * can be 0 or 1. 0 means encode losslessly and 1 means to encode with
1684 * image quality loss (but then have a much smaller encoding).
1685 *
1686 * On success this function returns a pointer to the encoded data that you
1687 * can free with free() when no longer needed.
1688 *
1689 * @see eet_data_image_encode()
1690 *
1691 * @since 1.0.0
1692 * @ingroup Eet_File_Image_Cipher_Group
1693 */
1694EAPI void *
1695eet_data_image_encode_cipher(const void *data,
1696 const char *cipher_key,
1697 unsigned int w,
1698 unsigned int h,
1699 int alpha,
1700 int compress,
1701 int quality,
1702 int lossy,
1703 int *size_ret);
1704
1705/**
1706 * @defgroup Eet_Cipher_Group Cipher, Identity and Protection Mechanisms
1707 *
1708 * Eet allows one to protect entries of an #Eet_File
1709 * individually. This may be used to ensure data was not tampered or
1710 * that third party does not read your data.
1711 *
1712 * @see @ref Eet_File_Cipher_Group
1713 * @see @ref Eet_File_Image_Cipher_Group
1714 *
1715 * @{
1716 */
1717
1718/**
1719 * @typedef Eet_Key
1720 * Opaque handle that defines an identity (also known as key)
1721 * in Eet's cipher system.
1722 */
1723typedef struct _Eet_Key Eet_Key;
1724
1725/**
1726 * @}
1727 */
1728
1729/**
1730 * Callback used to request if needed the password of a private key.
1731 *
1732 * @param buffer the buffer where to store the password.
1733 * @param size the maximum password size (size of buffer, including '@\0').
1734 * @param rwflag if the buffer is also readable or just writable.
1735 * @param data currently unused, may contain some context in future.
1736 * @return 1 on success and password was set to @p buffer, 0 on failure.
1737 *
1738 * @since 1.2.0
1739 * @ingroup Eet_Cipher_Group
1740 */
1741typedef int (*Eet_Key_Password_Callback)(char *buffer, int size, int rwflag, void *data);
1742
1743/**
1744 * Create an Eet_Key needed for signing an eet file.
1745 *
1746 * The certificate should provide the public that match the private key.
1747 * No verification is done to ensure that.
1748 *
1749 * @param certificate_file The file where to find the certificate.
1750 * @param private_key_file The file that contains the private key.
1751 * @param cb Function to callback if password is required to unlock
1752 * private key.
1753 * @return A key handle to use, or @c NULL on failure.
1754 *
1755 * @see eet_identity_close()
1756 *
1757 * @since 1.2.0
1758 * @ingroup Eet_Cipher_Group
1759 */
1760EAPI Eet_Key *
1761eet_identity_open(const char *certificate_file,
1762 const char *private_key_file,
1763 Eet_Key_Password_Callback cb);
1764
1765/**
1766 * Close and release all ressource used by an Eet_Key. An
1767 * reference counter prevent it from being freed until all file
1768 * using it are also closed.
1769 *
1770 * @param key the key handle to close and free resources.
1771 *
1772 * @since 1.2.0
1773 * @ingroup Eet_Cipher_Group
1774 */
1775EAPI void
1776eet_identity_close(Eet_Key *key);
1777
1778/**
1779 * Set a key to sign a file
1780 *
1781 * @param ef the file to set the identity.
1782 * @param key the key handle to set as identity.
1783 * @return #EET_ERROR_BAD_OBJECT if @p ef is invalid or
1784 * #EET_ERROR_NONE on success.
1785 *
1786 * @since 1.2.0
1787 * @ingroup Eet_Cipher_Group
1788 */
1789EAPI Eet_Error
1790eet_identity_set(Eet_File *ef,
1791 Eet_Key *key);
1792
1793/**
1794 * Display both private and public key of an Eet_Key.
1795 *
1796 * @param key the handle to print.
1797 * @param out where to print.
1798 *
1799 * @since 1.2.0
1800 * @ingroup Eet_Cipher_Group
1801 */
1802EAPI void
1803eet_identity_print(Eet_Key *key,
1804 FILE *out);
1805
1806/**
1807 * Get the x509 der certificate associated with an Eet_File. Will return NULL
1808 * if the file is not signed.
1809 *
1810 * @param ef The file handle to query.
1811 * @param der_length The length of returned data, may be @c NULL.
1812 * @return the x509 certificate or @c NULL on error.
1813 *
1814 * @since 1.2.0
1815 * @ingroup Eet_Cipher_Group
1816 */
1817EAPI const void *
1818eet_identity_x509(Eet_File *ef,
1819 int *der_length);
1820
1821/**
1822 * Get the raw signature associated with an Eet_File. Will return NULL
1823 * if the file is not signed.
1824 *
1825 * @param ef The file handle to query.
1826 * @param signature_length The length of returned data, may be @c NULL.
1827 * @return the raw signature or @c NULL on error.
1828 *
1829 * @ingroup Eet_Cipher_Group
1830 */
1831EAPI const void *
1832eet_identity_signature(Eet_File *ef,
1833 int *signature_length);
1834
1835/**
1836 * Get the SHA1 associated with a file. Could be the one used to
1837 * sign the data or if the data where not signed, it will be the
1838 * SHA1 of the file.
1839 *
1840 * @param ef The file handle to query.
1841 * @param sha1_length The length of returned data, may be @c NULL.
1842 * @return the associated SHA1 or @c NULL on error.
1843 *
1844 * @since 1.2.0
1845 * @ingroup Eet_Cipher_Group
1846 */
1847EAPI const void *
1848eet_identity_sha1(Eet_File *ef,
1849 int *sha1_length);
1850
1851/**
1852 * Display the x509 der certificate to out.
1853 *
1854 * @param certificate the x509 certificate to print
1855 * @param der_length The length the certificate.
1856 * @param out where to print.
1857 *
1858 * @since 1.2.0
1859 * @ingroup Eet_Cipher_Group
1860 */
1861EAPI void
1862eet_identity_certificate_print(const unsigned char *certificate,
1863 int der_length,
1864 FILE *out);
1865
1866/**
1867 * @defgroup Eet_Data_Group Eet Data Serialization
1868 *
1869 * Convenience functions to serialize and parse complex data
1870 * structures to binary blobs.
1871 *
1872 * While Eet core just handles binary blobs, it is often required
1873 * to save some structured data of different types, such as
1874 * strings, integers, lists, hashes and so on.
1875 *
1876 * Eet can serialize and then parse data types given some
1877 * construction instructions. These are defined in two levels:
1878 *
1879 * - #Eet_Data_Descriptor_Class to tell generic memory handling,
1880 * such as the size of the type, how to allocate memory, strings,
1881 * lists, hashes and so on.
1882 *
1883 * - #Eet_Data_Descriptor to tell inside such type, the members and
1884 * their offsets inside the memory blob, their types and
1885 * names. These members can be simple types or other
1886 * #Eet_Data_Descriptor, allowing hierarchical types to be
1887 * defined.
1888 *
1889 * Given that C provides no introspection, this process can be
1890 * quite cumbersome, so we provide lots of macros and convenience
1891 * functions to aid creating the types.
1892 *
1893 * We make now a quick overview of some of the most commonly used elements
1894 * of this part of the library. A simple example of a configuration system
1895 * will work as a somewhat real life example that is still simple enough to
1896 * follow.
1897 * Only the relevant sections will be shown here, but you can get the full
1898 * code @ref eet-data-simple.c "here".
1899 *
1900 * Ignoring the included headers, we'll begin by defining our configuration
1901 * struct.
1902 * @dontinclude eet-data-simple.c
1903 * @skip typedef
1904 * @until }
1905 *
1906 * When using Eet, you don't think in matters of what data the program needs
1907 * to run and which you would like to store. It's all the same and if it makes
1908 * more sense to keep them together, it's perfectly fine to do so. At the time
1909 * of telling Eet how your data is comprised you can leave out the things
1910 * that are runtime only and let Eet take care of the rest for you.
1911 *
1912 * The key used to store the config follows, as well as the variable used to
1913 * store our data descriptor.
1914 * This last one is very important. It's the one thing that Eet will use to
1915 * identify your data, both at the time of writing it to the file and when
1916 * loading from it.
1917 * @skipline MY_CONF
1918 * @skipline Eet_Data_Descriptor
1919 *
1920 * Now we'll see how to create this descriptor, so Eet knows how to handle
1921 * our data later on.
1922 * Begin our function by declaring an Eet_Data_Descriptor_Class, which is
1923 * used to create the actual descriptor. This class contains the name of
1924 * our data type, its size and several functions that dictate how Eet should
1925 * handle memory to allocate the necessary bits to bring our data to life.
1926 * You, as a user, will very hardly set this class' contents directly. The
1927 * most common scenario is to use one of the provided macros that set it using
1928 * the Eina data types, so that's what we'll be doing across all our examples.
1929 * @skip static void
1930 * @until eet_data_descriptor_stream_new
1931 *
1932 * Now that we have our descriptor, we need to make it describe something.
1933 * We do so by telling it which members of our struct we want it to know about
1934 * and their types.
1935 * The eet_data_descriptor_element_add() function takes care of this, but it's
1936 * too cumbersome for normal use, so several macros are provided that make
1937 * it easier to handle. Even with them, however, code can get very repetitive
1938 * and it's not uncommon to define custom macros using them to save on typing.
1939 * @skip #define
1940 * @until }
1941 *
1942 * Now our descriptor knows about the parts of our structure that we are
1943 * interesting in saving. You can see that not all of them are there, yet Eet
1944 * will find those that need saving and do the right thing. When loading our
1945 * data, any non-described fields in the structure will be zeroed, so there's
1946 * no need to worry about garbage memory in them.
1947 * Refer to the documentation of #EET_DATA_DESCRIPTOR_ADD_BASIC to understand
1948 * what our macro does.
1949 *
1950 * We are done with our descriptor init function and it's proper to have the
1951 * relevant shutdown. Proper coding guidelines indiciate that all memory
1952 * allocated should be freed when the program ends, and since you will most
1953 * likely keep your descriptor around for the life or your application, it's
1954 * only right to free it at the end.
1955 * @skip static void
1956 * @until }
1957 *
1958 * Not listed here, but included in the full example are functions to create
1959 * a blank configuration and free it. The first one will only be used when
1960 * no file exists to load from, or nothing is found in it, but the latter is
1961 * used regardless of where our data comes from. Unless you are reading direct
1962 * data from the Eet file, you will be in charge of freeing anything loaded
1963 * from it.
1964 *
1965 * Now it's time to look at how we can load our config from some file.
1966 * Begin by opening the Eet file normally.
1967 * @skip static My_Conf_Type
1968 * @until }
1969 *
1970 * And now we need to read the data from the file and decode it using our
1971 * descriptor. Fortunately, that's all done in one single step.
1972 * @until goto
1973 *
1974 * And that's it for all Eet cares about. But since we are dealing with a
1975 * common case, as is save and load of user configurations, the next fragment
1976 * of code shows why we have a version field in our struct, and how you can
1977 * use it to load older configuration files and update them as needed.
1978 * @until }
1979 *
1980 * Finally, clsoe the file and return the newly loaded config data.
1981 * @until }
1982 *
1983 * Saving data is just as easy. The full version of the following function
1984 * includes code to save to a temporary file first, so you can be sure not
1985 * to lose all your data in the case of a failure mid-writing. You can look
1986 * at it @ref eet-data-simple.c "here".
1987 * @skip static Eina_Bool
1988 * @until {
1989 * @skipline Eina_Bool ret
1990 * @skip eet_open
1991 * @until eet_close
1992 * @skip return
1993 * @until }
1994 *
1995 * To close, our main function, which doesn't do much. Just take some arguments
1996 * from the command line with the name of the file to load and another one
1997 * where to save again. If input file doesn't exist, a new config structure
1998 * will be created and saved to our output file.
1999 * @skip int main
2000 * @until return ret
2001 * @until }
2002 *
2003 * The following is a list of more advanced and detailed examples.
2004 * @li @ref eet_data_nested_example
2005 * @li @ref eet_data_file_descriptor
2006 * @li @ref Example_Eet_Data_File_Descriptor_02
2007 * @li @ref Example_Eet_Data_Cipher_Decipher
2008 */
2009
2010/**
2011 * @page eet_data_nested_example Nested structures and Eet Data Descriptors
2012 *
2013 * We've seen already a simple example of how to use Eet Data Descriptors
2014 * to handle our structures, but it didn't show how this works when you
2015 * have structures inside other structures.
2016 *
2017 * Now, there's a very simple case of this, for when you have inline structs
2018 * to keep your big structure more organized, you don't need anything else
2019 * besides what @ref eet-data-simple.c "this simple example does".
2020 * Just use something like @p some_struct.sub_struct.member when adding the
2021 * member to the descriptor and it will work.
2022 *
2023 * For example:
2024 * @code
2025 * typedef struct
2026 * {
2027 * int a_number;
2028 * char *a_string;
2029 * struct {
2030 * int other_num;
2031 * int one_more;
2032 * } sub;
2033 * } some_struct;
2034 *
2035 * void some_function()
2036 * {
2037 * ...
2038 * my_desc = eet_data_descriptor_stream_new(&eddc);
2039 * EET_DATA_DESCRIPTOR_ADD_BASIC(my_desc, some_struct, "a_number",
2040 * a_number, EET_T_INT);
2041 * EET_DATA_DESCRIPTOR_ADD_BASIC(my_desc, some_struct, "a_string",
2042 * a_string, EET_T_STRING);
2043 * EET_DATA_DESCRIPTOR_ADD_BASIC(my_desc, some_struct, "sub.other_num",
2044 * sub.other_num, EET_T_INT);
2045 * EET_DATA_DESCRIPTOR_ADD_BASIC(my_desc, some_struct, "sub.one_more",
2046 * sub.one_more", EET_T_INT);
2047 * ...
2048 * }
2049 * @endcode
2050 *
2051 * But this is not what we are here for today. When we talk about nested
2052 * structures, what we really want are things like lists and hashes to be
2053 * taken into consideration automatically, and all their contents saved and
2054 * loaded just like ordinary integers and strings are.
2055 *
2056 * And of course, Eet can do that, and considering the work it saves you as a
2057 * programmer, we could say it's even easier to do than handling just integers.
2058 *
2059 * Let's begin with our example then, which is not all too different from the
2060 * simple one introduced earlier.
2061 *
2062 * We won't ignore the headers this time to show how easy it is to use Eina
2063 * data types with Eet, but we'll still skip most of the code that is not
2064 * pertinent to what we want to show now, but as usual, you can get it full
2065 * by follwing @ref eet-data-nested.c "this link".
2066 *
2067 * @dontinclude eet-data-nested.c
2068 * @skipline Eina.h
2069 * @skipline Eet.h
2070 * @skip typedef struct
2071 * @until } My_Conf_Subtype
2072 *
2073 * Extremely similar to our previous example. Just a new struct in there, and
2074 * a pointer to a list in the one we already had. Handling a list of subtypes
2075 * is easy on our program, but now we'll see what Eet needs to work with them
2076 * (Hint: it's easy too).
2077 * @skip _my_conf_descriptor
2078 * @until _my_conf_sub_descriptor
2079 *
2080 * Since we have two structures now, it's only natural that we'll need two
2081 * descriptors. One for each, which will be defined exactly as before.
2082 * @skip static void
2083 * @until eddc
2084 * @skip EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET
2085 * @until _my_conf_sub_descriptor
2086 *
2087 * We create our descriptors, each for one type, and as before, we are going to
2088 * use a simple macro to set their contents, to save on typing.
2089 * @skip #define
2090 * @until EET_T_UCHAR
2091 *
2092 * So far, nothing new. We have our descriptors and we know already how to
2093 * save them separately. But what we want is to link them together, and even
2094 * more so, we want our main type to hold a list of more than one of the new
2095 * sub type. So how do we do that?
2096 *
2097 * Simple enough, we tell Eet that our main descriptor will hold a list, of
2098 * which each node will point to some type described by our new descriptor.
2099 * @skip EET_DATA_DESCRIPTOR_ADD_LIST
2100 * @until _my_conf_sub_descriptor
2101 *
2102 * And that's all. We are closing the function now so as to not leave dangling
2103 * curly braces, but there's nothing more to show in this example. Only other
2104 * additions are the necessary code to free our new data, but you can see it
2105 * in the full code listing.
2106 * @until }
2107 */
2108
2109/**
2110 * @page eet_data_file_descriptor Advanced use of Eet Data Descriptors
2111 *
2112 * A real life example is usually the best way to see how things are used,
2113 * but they also involve a lot more code than what needs to be shown, so
2114 * instead of going that way, we'll be borrowing some pieces from one in
2115 * the following example. It's been slightly modified from the original
2116 * source to show more of the varied ways in which Eet can handle our data.
2117 *
2118 * @ref eet-data-file_descriptor_01.c "This example" shows a cache of user
2119 * accounts and messages received, and it's a bit more interactive than
2120 * previous examples.
2121 *
2122 * Let's begin by looking at the structures we'll be using. First we have
2123 * one to define the messages the user receives and one for the one he posts.
2124 * Straight forward and nothing new here.
2125 * @dontinclude eet-data-file_descriptor_01.c
2126 * @skip typedef
2127 * @until My_Post
2128 *
2129 * One more to declare the account itself. This one will contain a list of
2130 * all messages received, and the posts we make ourselves will be kept in an
2131 * array. No special reason other than to show how to use arrays with Eet.
2132 * @until My_Account
2133 *
2134 * Finally, the main structure to hold our cache of accounts. We'll be looking
2135 * for these accounts by their names, so let's keep them in a hash, using
2136 * that name as the key.
2137 * @until My_Cache
2138 *
2139 * As explained before, we need one descriptor for each struct we want Eet
2140 * to handle, but this time we also want to keep around our Eet file and its
2141 * string dictionary. You will see why in a moment.
2142 * @skip Eet_Data_Descriptor
2143 * @until _my_post_descriptor
2144 * @skip Eet_File
2145 * @until Eet_Dictionary
2146 *
2147 * The differences begin now. They aren't much, but we'll be creating our
2148 * descriptors differently. Things can be added to our cache, but we won't
2149 * be modifying the current contents, so we can consider the data read from
2150 * it to be read-only, and thus allow Eet to save time and memory by not
2151 * duplicating thins unnecessary.
2152 * @skip static void
2153 * @until _my_post_descriptor
2154 *
2155 * As the comment in the code explains, we are asking Eet to give us strings
2156 * directly from the mapped file, which avoids having to load it in memory
2157 * and data duplication.
2158 * Of course, there are things to take into account when doing things this
2159 * way, and they will be mentioned as we encounter those special cases.
2160 *
2161 * Next comes the actual description of our data, just like we did in the
2162 * previous examples.
2163 * @skip #define
2164 * @until #undef
2165 * @until #define
2166 * @until #undef
2167 *
2168 * And the account struct's description doesn't add much new, but it's worth
2169 * commenting on it.
2170 * @skip #define
2171 * @until _my_post_descriptor
2172 *
2173 * How to add a list we've seen before, but now we are also adding an array.
2174 * There's nothing really special about it, but it's important to note that
2175 * the EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY is used to add arrays of variable
2176 * length to a descriptor. That is, arrays just like the one we defined.
2177 * Since there's no way in C to know how long they are, we need to keep
2178 * track of the count ourselves and Eet needs to know how to do so as well.
2179 * That's what the @p posts_count member of our struct is for. When adding
2180 * our array member, this macro will look for another variable in the struct
2181 * named just like the array, but with @p _count attached to the end.
2182 * When saving our data, Eet will know how many elements the array contains
2183 * by looking into this count variable. When loading back from a file, this
2184 * variable will be set to the right number of elements.
2185 *
2186 * Another option for arrays is to use EET_DATA_DESCRIPTOR_ADD_ARRAY, which
2187 * takes care of fixed sized arrays.
2188 * For example, let's suppose that we want to keep track of only the last
2189 * ten posts the user sent, and we declare our account struct as follows
2190 * @code
2191 * typedef struct
2192 * {
2193 * unsigned int id;
2194 * const char *name;
2195 * Eina_List *messages;
2196 * My_Post posts[10];
2197 * } My_Account;
2198 * @endcode
2199 * Then we would add the array to our descriptor with
2200 * @code
2201 * EET_DATA_DESCRIPTOR_ADD_ARRAY(_my_account_descriptor, My_Account, "posts",
2202 * posts, _my_post_descriptor);
2203 * @endcode
2204 *
2205 * Notice how this time we don't have a @p posts_count variable in our struct.
2206 * We could have it for the program to keep track of how many posts the
2207 * array actually contains, but Eet no longer needs it. Being defined that
2208 * way the array is already taking up all the memory needed for the ten
2209 * elements, and it is possible in C to determine how much it is in code.
2210 * When saving our data, Eet will just dump the entire memory blob into the
2211 * file, regardless of how much of it is really used. So it's important to
2212 * take into consideration this kind of things when defining your data types.
2213 * Each has its uses, its advantages and disadvantages and it's up to you
2214 * to decide which to use.
2215 *
2216 * Now, going back to our example, we have to finish adding our data to the
2217 * descriptors. We are only missing the main one for the cache, which
2218 * contains our hash of accounts.
2219 * Unless you are using your own hash functions when setting the descriptor
2220 * class, always use hashes with string type keys.
2221 * @skip #define
2222 * @until }
2223 *
2224 * If you remember, we told Eet not to duplicate memory when possible at the
2225 * time of loading back our data. But this doesn't mean everything will be
2226 * loaded straight from disk and we don't have to worry about freeing it.
2227 * Data in the Eet file is compressed and encoded, so it still needs to be
2228 * decoded and memory will be allocated to convert it back into something we
2229 * can use. We also need to take care of anything we add in the current
2230 * instance of the program.
2231 * To summarize, any string we get from Eet is likely to be a pointer to the
2232 * internal dictionary, and trying to free it will, in the best case, crash
2233 * our application right away.
2234 *
2235 * So how do we know if we have to free a string? We check if it's part of
2236 * the dictionary, and if it's not there we can be sure it's safe to get
2237 * rid of it.
2238 * @skip static void
2239 * @skip }
2240 * @skip static void
2241 * @until }
2242 *
2243 * See how this is used when adding a new message to our cache.
2244 * @skip static My_Message
2245 * @until return msg
2246 * @until free(msg)
2247 * @until }
2248 *
2249 * Skipping all the utility functions used by our program (remember you can
2250 * look at the full example @ref eet-data-file_descriptor_01.c "here") we get to
2251 * our cache loading code. Nothing out of the ordinary at first, just the
2252 * same old open file, read data using our main descriptor to decode it
2253 * into something we can use and check version of loaded data and if it doesn't
2254 * match, do something accordingly.
2255 * @skip static My_Cache
2256 * @until }
2257 * @until }
2258 * @until }
2259 *
2260 * Then comes the interesting part. Remember how we kept two more global
2261 * variables with our descriptors? One of them we already used to check if
2262 * it was right to free a string or not, but we didn't know where it came from.
2263 * Loading our data straight from the mmapped file means that we can't close
2264 * it until we are done using it, so we need to keep its handler around until
2265 * then. It also means that any changes done to the file can, and will,
2266 * invalidate all our pointers to the file backed data, so if we add something
2267 * and save the file, we need to reload our cache.
2268 *
2269 * Thus our load function checks if we had an open file, if there is it gets
2270 * closed and our variable is updated to the new handler. Then we get the
2271 * string dictionary we use to check if a string is part of it or not.
2272 * Updating any references to the cache data is up you as a programmer to
2273 * handle properly, there's nothing Eet can do in this situation.
2274 * @until }
2275 *
2276 * The save function doesn't have anything new, and all that's left after it
2277 * is the main program, which doesn't really have anything of interest within
2278 * the scope of what we are learning.
2279 */
2280
2281/**
2282 * @addtogroup Eet_Data_Group
2283 * @{
2284 */
2285#define EET_T_UNKNOW 0 /**< Unknown data encoding type */
2286#define EET_T_CHAR 1 /**< Data type: char */
2287#define EET_T_SHORT 2 /**< Data type: short */
2288#define EET_T_INT 3 /**< Data type: int */
2289#define EET_T_LONG_LONG 4 /**< Data type: long long */
2290#define EET_T_FLOAT 5 /**< Data type: float */
2291#define EET_T_DOUBLE 6 /**< Data type: double */
2292#define EET_T_UCHAR 7 /**< Data type: unsigned char */
2293#define EET_T_USHORT 8 /**< Data type: unsigned short */
2294#define EET_T_UINT 9 /**< Data type: unsigned int */
2295#define EET_T_ULONG_LONG 10 /**< Data type: unsigned long long */
2296#define EET_T_STRING 11 /**< Data type: char * */
2297#define EET_T_INLINED_STRING 12 /**< Data type: char * (but compressed inside the resulting eet) */
2298#define EET_T_NULL 13 /**< Data type: (void *) (only use it if you know why) */
2299#define EET_T_F32P32 14 /**< Data type: fixed point 32.32 */
2300#define EET_T_F16P16 15 /**< Data type: fixed point 16.16 */
2301#define EET_T_F8P24 16 /**< Data type: fixed point 8.24 */
2302#define EET_T_LAST 18 /**< Last data type */
2303
2304#define EET_G_UNKNOWN 100 /**< Unknown group data encoding type */
2305#define EET_G_ARRAY 101 /**< Fixed size array group type */
2306#define EET_G_VAR_ARRAY 102 /**< Variable size array group type */
2307#define EET_G_LIST 103 /**< Linked list group type */
2308#define EET_G_HASH 104 /**< Hash table group type */
2309#define EET_G_UNION 105 /**< Union group type */
2310#define EET_G_VARIANT 106 /**< Selectable subtype group */
2311#define EET_G_LAST 107 /**< Last group type */
2312
2313#define EET_I_LIMIT 128 /**< Other type exist but are reserved for internal purpose. */
2314
2315/**
2316 * @typedef Eet_Data_Descriptor
2317 *
2318 * Opaque handle that have information on a type members.
2319 *
2320 * Descriptors are created using an #Eet_Data_Descriptor_Class, and they
2321 * describe the contents of the structure that will be serialized by Eet.
2322 * Not all members need be described by it, just those that should be handled
2323 * by Eet. This way it's possible to have one structure with both data to be
2324 * saved to a file, like application configuration, and runtime information
2325 * that would be meaningless to store, but is appropriate to keep together
2326 * during the program execution.
2327 * The members are added by means of
2328 * EET_DATA_DESCRIPTOR_ADD_BASIC(), EET_DATA_DESCRIPTOR_ADD_SUB(),
2329 * EET_DATA_DESCRIPTOR_ADD_LIST(), EET_DATA_DESCRIPTOR_ADD_HASH()
2330 * or eet_data_descriptor_element_add().
2331 *
2332 * @see eet_data_descriptor_stream_new()
2333 * @see eet_data_descriptor_file_new()
2334 * @see eet_data_descriptor_free()
2335 */
2336typedef struct _Eet_Data_Descriptor Eet_Data_Descriptor;
2337
2338/**
2339 * @def EET_DATA_DESCRIPTOR_CLASS_VERSION
2340 * The version of #Eet_Data_Descriptor_Class at the time of the
2341 * distribution of the sources. One should define this to its
2342 * version member so it is compatible with abi changes, or at least
2343 * will not crash with them.
2344 */
2345#define EET_DATA_DESCRIPTOR_CLASS_VERSION 4
2346
2347/**
2348 * @typedef Eet_Data_Descriptor_Class
2349 *
2350 * Instructs Eet about memory management for different needs under
2351 * serialization and parse process.
2352 */
2353typedef struct _Eet_Data_Descriptor_Class Eet_Data_Descriptor_Class;
2354
2355typedef int (*Eet_Descriptor_Hash_Foreach_Callback_Callback)(void *h, const char *k, void *dt, void *fdt);
2356
2357typedef void * (*Eet_Descriptor_Mem_Alloc_Callback)(size_t size);
2358typedef void (*Eet_Descriptor_Mem_Free_Callback)(void *mem);
2359typedef char * (*Eet_Descriptor_Str_Alloc_Callback)(const char *str);
2360typedef void (*Eet_Descriptor_Str_Free_Callback)(const char *str);
2361typedef void * (*Eet_Descriptor_List_Next_Callback)(void *l);
2362typedef void * (*Eet_Descriptor_List_Append_Callback)(void *l, void *d);
2363typedef void * (*Eet_Descriptor_List_Data_Callback)(void *l);
2364typedef void * (*Eet_Descriptor_List_Free_Callback)(void *l);
2365typedef void (*Eet_Descriptor_Hash_Foreach_Callback)(void *h, Eet_Descriptor_Hash_Foreach_Callback_Callback func, void *fdt);
2366typedef void * (*Eet_Descriptor_Hash_Add_Callback)(void *h, const char *k, void *d);
2367typedef void (*Eet_Descriptor_Hash_Free_Callback)(void *h);
2368typedef char * (*Eet_Descriptor_Str_Direct_Alloc_Callback)(const char *str);
2369typedef void (*Eet_Descriptor_Str_Direct_Free_Callback)(const char *str);
2370typedef const char * (*Eet_Descriptor_Type_Get_Callback)(const void *data, Eina_Bool *unknow);
2371typedef Eina_Bool (*Eet_Descriptor_Type_Set_Callback)(const char *type, void *data, Eina_Bool unknow);
2372typedef void * (*Eet_Descriptor_Array_Alloc_Callback)(size_t size);
2373typedef void (*Eet_Descriptor_Array_Free_Callback)(void *mem);
2374/**
2375 * @struct _Eet_Data_Descriptor_Class
2376 *
2377 * Instructs Eet about memory management for different needs under
2378 * serialization and parse process.
2379 *
2380 * The list and hash methods match the Eina API, so for a more detalied
2381 * reference on them, look at the Eina_List and Eina_Hash documentation,
2382 * respectively.
2383 * For the most part these will be used with the standard Eina functions,
2384 * so using EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET() and
2385 * EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET() will set up everything
2386 * accordingly.
2387 */
2388struct _Eet_Data_Descriptor_Class
2389{
2390 int version; /**< ABI version. Should always be set to #EET_DATA_DESCRIPTOR_CLASS_VERSION */
2391 const char *name; /**< Name of the user data type to be serialized */
2392 int size; /**< Size in bytes of the user data type to be serialized */
2393 struct
2394 {
2395 Eet_Descriptor_Mem_Alloc_Callback mem_alloc; /**< how to allocate memory (usually malloc()) */
2396 Eet_Descriptor_Mem_Free_Callback mem_free; /**< how to free memory (usually free()) */
2397 Eet_Descriptor_Str_Alloc_Callback str_alloc; /**< how to allocate a string */
2398 Eet_Descriptor_Str_Free_Callback str_free; /**< how to free a string */
2399 Eet_Descriptor_List_Next_Callback list_next; /**< how to iterate to the next element of a list. Receives and should return the list node. */
2400 Eet_Descriptor_List_Append_Callback list_append; /**< how to append data @p d to list which head node is @p l */
2401 Eet_Descriptor_List_Data_Callback list_data; /**< retrieves the data from node @p l */
2402 Eet_Descriptor_List_Free_Callback list_free; /**< free all the nodes from the list which head node is @p l */
2403 Eet_Descriptor_Hash_Foreach_Callback hash_foreach; /**< iterates over all elements in the hash @p h in no specific order */
2404 Eet_Descriptor_Hash_Add_Callback hash_add; /**< add a new data @p d with key @p k in hash @p h */
2405 Eet_Descriptor_Hash_Free_Callback hash_free; /**< free all entries from the hash @p h */
2406 Eet_Descriptor_Str_Direct_Alloc_Callback str_direct_alloc; /**< how to allocate a string directly from file backed/mmaped region pointed by @p str */
2407 Eet_Descriptor_Str_Direct_Free_Callback str_direct_free; /**< how to free a string returned by str_direct_alloc */
2408 Eet_Descriptor_Type_Get_Callback type_get; /**< get the type, as used in the union or variant mapping, that should be used to store the given data into the eet file. */
2409 Eet_Descriptor_Type_Set_Callback type_set; /**< called when loading a mapped type with the given @p type used to describe the type in the descriptor */
2410 Eet_Descriptor_Array_Alloc_Callback array_alloc; /**< how to allocate memory for array (usually malloc()) */
2411 Eet_Descriptor_Array_Free_Callback array_free; /**< how to free memory for array (usually free()) */
2412 } func;
2413};
2414
2415/**
2416 * @}
2417 */
2418
2419/**
2420 * Create a new empty data structure descriptor.
2421 * @param name The string name of this data structure (most be a
2422 * global constant and never change).
2423 * @param size The size of the struct (in bytes).
2424 * @param func_list_next The function to get the next list node.
2425 * @param func_list_append The function to append a member to a list.
2426 * @param func_list_data The function to get the data from a list node.
2427 * @param func_list_free The function to free an entire linked list.
2428 * @param func_hash_foreach The function to iterate through all
2429 * hash table entries.
2430 * @param func_hash_add The function to add a member to a hash table.
2431 * @param func_hash_free The function to free an entire hash table.
2432 * @return A new empty data descriptor.
2433 *
2434 * This function creates a new data descriptore and returns a handle to the
2435 * new data descriptor. On creation it will be empty, containing no contents
2436 * describing anything other than the shell of the data structure.
2437 *
2438 * You add structure members to the data descriptor using the macros
2439 * EET_DATA_DESCRIPTOR_ADD_BASIC(), EET_DATA_DESCRIPTOR_ADD_SUB() and
2440 * EET_DATA_DESCRIPTOR_ADD_LIST(), depending on what type of member you are
2441 * adding to the description.
2442 *
2443 * Once you have described all the members of a struct you want loaded, or
2444 * saved eet can load and save those members for you, encode them into
2445 * endian-independent serialised data chunks for transmission across a
2446 * a network or more.
2447 *
2448 * The function pointers to the list and hash table functions are only
2449 * needed if you use those data types, else you can pass NULL instead.
2450 *
2451 * @since 1.0.0
2452 * @ingroup Eet_Data_Group
2453 *
2454 * @deprecated use eet_data_descriptor_stream_new() or
2455 * eet_data_descriptor_file_new()
2456 */
2457EINA_DEPRECATED EAPI Eet_Data_Descriptor *
2458eet_data_descriptor_new(const char *name,
2459 int size,
2460 Eet_Descriptor_List_Next_Callback func_list_next,
2461 Eet_Descriptor_List_Append_Callback func_list_append,
2462 Eet_Descriptor_List_Data_Callback func_list_data,
2463 Eet_Descriptor_List_Free_Callback func_list_free,
2464 Eet_Descriptor_Hash_Foreach_Callback func_hash_foreach,
2465 Eet_Descriptor_Hash_Add_Callback func_hash_add,
2466 Eet_Descriptor_Hash_Free_Callback func_hash_free);
2467/*
2468 * FIXME:
2469 *
2470 * moving to this api from the old above. this will break things when the
2471 * move happens - but be warned
2472 */
2473EINA_DEPRECATED EAPI Eet_Data_Descriptor *
2474 eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc);
2475EINA_DEPRECATED EAPI Eet_Data_Descriptor *
2476 eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc);
2477
2478/**
2479 * This function creates a new data descriptor and returns a handle to the
2480 * new data descriptor. On creation it will be empty, containing no contents
2481 * describing anything other than the shell of the data structure.
2482 * @param eddc The class from where to create the data descriptor.
2483 *
2484 * You add structure members to the data descriptor using the macros
2485 * EET_DATA_DESCRIPTOR_ADD_BASIC(), EET_DATA_DESCRIPTOR_ADD_SUB() and
2486 * EET_DATA_DESCRIPTOR_ADD_LIST(), depending on what type of member you are
2487 * adding to the description.
2488 *
2489 * Once you have described all the members of a struct you want loaded or
2490 * savedi, eet can load and save those members for you, encode them into
2491 * endian-independent serialised data chunks for transmission across a
2492 * a network or more.
2493 *
2494 * This function specially ignores str_direct_alloc and str_direct_free. It
2495 * is useful when the eet_data you are reading doesn't have a dictionary,
2496 * like network stream or IPC. It also mean that all string will be allocated
2497 * and duplicated in memory.
2498 *
2499 * @since 1.2.3
2500 * @ingroup Eet_Data_Group
2501 */
2502EAPI Eet_Data_Descriptor *
2503eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc);
2504
2505/**
2506 * This function creates a new data descriptor and returns a handle to the
2507 * new data descriptor. On creation it will be empty, containing no contents
2508 * describing anything other than the shell of the data structure.
2509 * @param eddc The class from where to create the data descriptor.
2510 *
2511 * You add structure members to the data descriptor using the macros
2512 * EET_DATA_DESCRIPTOR_ADD_BASIC(), EET_DATA_DESCRIPTOR_ADD_SUB() and
2513 * EET_DATA_DESCRIPTOR_ADD_LIST(), depending on what type of member you are
2514 * adding to the description.
2515 *
2516 * Once you have described all the members of a struct you want loaded or
2517 * savedi, eet can load and save those members for you, encode them into
2518 * endian-independent serialised data chunks for transmission across a
2519 * a network or more.
2520 *
2521 * This function uses str_direct_alloc and str_direct_free. It is
2522 * useful when the eet_data you are reading come from a file and
2523 * have a dictionary. This will reduce memory use and improve the
2524 * possibility for the OS to page this string out.
2525 * However, the load speed and memory saving comes with some drawbacks to keep
2526 * in mind. If you never modify the contents of the structures loaded from
2527 * the file, all you need to remember is that closing the eet file will make
2528 * the strings go away. On the other hand, should you need to free a string,
2529 * before doing so you have to verify that it's not part of the eet dictionary.
2530 * You can do this in the following way, assuming @p ef is a valid Eet_File
2531 * and @p str is a string loaded from said file.
2532 *
2533 * @code
2534 * void eet_string_free(Eet_File *ef, const char *str)
2535 * {
2536 * Eet_Dictionary *dict = eet_dictionary_get(ef);
2537 * if (dict && eet_dictionary_string_check(dict, str))
2538 * {
2539 * // The file contains a dictionary and the given string is a part of
2540 * // of it, so we can't free it, just return.
2541 * return;
2542 * }
2543 * // We assume eina_stringshare was used on the descriptor
2544 * eina_stringshare_del(str);
2545 * }
2546 * @endcode
2547 *
2548 * @since 1.2.3
2549 * @ingroup Eet_Data_Group
2550 */
2551EAPI Eet_Data_Descriptor *
2552eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc);
2553
2554/**
2555 * This function is an helper that set all the parameters of an
2556 * Eet_Data_Descriptor_Class correctly when you use Eina data type
2557 * with a stream.
2558 * @param eddc The Eet_Data_Descriptor_Class you want to set.
2559 * @param eddc_size The size of the Eet_Data_Descriptor_Class at the compilation time.
2560 * @param name The name of the structure described by this class.
2561 * @param size The size of the structure described by this class.
2562 * @return EINA_TRUE if the structure was correctly set (The only
2563 * reason that could make it fail is if you did give wrong
2564 * parameter).
2565 *
2566 * @note Unless there's a very specific reason to use this function directly,
2567 * the EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET macro is recommended.
2568 *
2569 * @since 1.2.3
2570 * @ingroup Eet_Data_Group
2571 */
2572EAPI Eina_Bool
2573eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
2574 unsigned int eddc_size,
2575 const char *name,
2576 int size);
2577
2578/**
2579 * This macro is an helper that set all the parameter of an
2580 * Eet_Data_Descriptor_Class correctly when you use Eina data type
2581 * with stream.
2582 * @param clas The Eet_Data_Descriptor_Class you want to set.
2583 * @param type The type of the structure described by this class.
2584 * @return EINA_TRUE if the structure was correctly set (The only
2585 * reason that could make it fail is if you did give wrong
2586 * parameter).
2587 *
2588 * @see eet_data_descriptor_stream_new
2589 * @since 1.2.3
2590 * @ingroup Eet_Data_Group
2591 */
2592#define EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(clas, type) \
2593 (eet_eina_stream_data_descriptor_class_set(clas, sizeof (*(clas)), # type, sizeof(type)))
2594
2595/**
2596 * This function is an helper that set all the parameter of an
2597 * Eet_Data_Descriptor_Class correctly when you use Eina data type
2598 * with a file.
2599 * @param eddc The Eet_Data_Descriptor_Class you want to set.
2600 * @param eddc_size The size of the Eet_Data_Descriptor_Class at the compilation time.
2601 * @param name The name of the structure described by this class.
2602 * @param size The size of the structure described by this class.
2603 * @return EINA_TRUE if the structure was correctly set (The only
2604 * reason that could make it fail is if you did give wrong
2605 * parameter).
2606 *
2607 * @note Unless there's a very specific reason to use this function directly,
2608 * the EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET macro is recommended.
2609 *
2610 * @since 1.2.3
2611 * @ingroup Eet_Data_Group
2612 */
2613EAPI Eina_Bool
2614eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
2615 unsigned int eddc_size,
2616 const char *name,
2617 int size);
2618
2619/**
2620 * This macro is an helper that set all the parameter of an
2621 * Eet_Data_Descriptor_Class correctly when you use Eina data type
2622 * with file.
2623 * @param clas The Eet_Data_Descriptor_Class you want to set.
2624 * @param type The type of the structure described by this class.
2625 * @return EINA_TRUE if the structure was correctly set (The only
2626 * reason that could make it fail is if you did give wrong
2627 * parameter).
2628 *
2629 * @see eet_data_descriptor_file_new
2630 * @since 1.2.3
2631 * @ingroup Eet_Data_Group
2632 */
2633#define EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(clas, type) \
2634 (eet_eina_file_data_descriptor_class_set(clas, sizeof (*(clas)), # type, sizeof(type)))
2635
2636/**
2637 * This function frees a data descriptor when it is not needed anymore.
2638 * @param edd The data descriptor to free.
2639 *
2640 * This function takes a data descriptor handle as a parameter and frees all
2641 * data allocated for the data descriptor and the handle itself. After this
2642 * call the descriptor is no longer valid.
2643 *
2644 * @since 1.0.0
2645 * @ingroup Eet_Data_Group
2646 */
2647EAPI void
2648eet_data_descriptor_free(Eet_Data_Descriptor *edd);
2649
2650/**
2651 * This function is an internal used by macros.
2652 *
2653 * This function is used by macros EET_DATA_DESCRIPTOR_ADD_BASIC(),
2654 * EET_DATA_DESCRIPTOR_ADD_SUB() and EET_DATA_DESCRIPTOR_ADD_LIST(). It is
2655 * complex to use by hand and should be left to be used by the macros, and
2656 * thus is not documented.
2657 *
2658 * @param edd The data descriptor handle to add element (member).
2659 * @param name The name of element to be serialized.
2660 * @param type The type of element to be serialized, like
2661 * #EET_T_INT. If #EET_T_UNKNOW, then it is considered to be a
2662 * group, list or hash.
2663 * @param group_type If element type is #EET_T_UNKNOW, then the @p
2664 * group_type will speficy if it is a list (#EET_G_LIST),
2665 * array (#EET_G_ARRAY) and so on. If #EET_G_UNKNOWN, then
2666 * the member is a subtype (pointer to another type defined by
2667 * another #Eet_Data_Descriptor).
2668 * @param offset byte offset inside the source memory to be serialized.
2669 * @param count number of elements (if #EET_G_ARRAY or #EET_G_VAR_ARRAY).
2670 * @param counter_name variable that defines the name of number of elements.
2671 * @param subtype If contains a subtype, then its data descriptor.
2672 *
2673 * @since 1.0.0
2674 * @ingroup Eet_Data_Group
2675 */
2676EAPI void
2677eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
2678 const char *name,
2679 int type,
2680 int group_type,
2681 int offset,
2682 /* int count_offset, */
2683 int count,
2684 const char *counter_name,
2685 Eet_Data_Descriptor *subtype);
2686
2687/**
2688 * Read a data structure from an eet file and decodes it.
2689 * @param ef The eet file handle to read from.
2690 * @param edd The data descriptor handle to use when decoding.
2691 * @param name The key the data is stored under in the eet file.
2692 * @return A pointer to the decoded data structure.
2693 *
2694 * This function decodes a data structure stored in an eet file, returning
2695 * a pointer to it if it decoded successfully, or NULL on failure. This
2696 * can save a programmer dozens of hours of work in writing configuration
2697 * file parsing and writing code, as eet does all that work for the program
2698 * and presents a program-friendly data structure, just as the programmer
2699 * likes. Eet can handle members being added or deleted from the data in
2700 * storage and safely zero-fills unfilled members if they were not found
2701 * in the data. It checks sizes and headers whenever it reads data, allowing
2702 * the programmer to not worry about corrupt data.
2703 *
2704 * Once a data structure has been described by the programmer with the
2705 * fields they wish to save or load, storing or retrieving a data structure
2706 * from an eet file, or from a chunk of memory is as simple as a single
2707 * function call.
2708 *
2709 * @see eet_data_read_cipher()
2710 *
2711 * @since 1.0.0
2712 * @ingroup Eet_Data_Group
2713 */
2714EAPI void *
2715eet_data_read(Eet_File *ef,
2716 Eet_Data_Descriptor *edd,
2717 const char *name);
2718
2719/**
2720 * Write a data structure from memory and store in an eet file.
2721 * @param ef The eet file handle to write to.
2722 * @param edd The data descriptor to use when encoding.
2723 * @param name The key to store the data under in the eet file.
2724 * @param data A pointer to the data structure to ssave and encode.
2725 * @param compress Compression flags for storage.
2726 * @return bytes written on successful write, 0 on failure.
2727 *
2728 * This function is the reverse of eet_data_read(), saving a data structure
2729 * to an eet file. The file must have been opening in write mode and the data
2730 * will be kept in memory until the file is either closed or eet_sync() is
2731 * called to flush any unwritten changes.
2732 *
2733 * @see eet_data_write_cipher()
2734 *
2735 * @since 1.0.0
2736 * @ingroup Eet_Data_Group
2737 */
2738EAPI int
2739eet_data_write(Eet_File *ef,
2740 Eet_Data_Descriptor *edd,
2741 const char *name,
2742 const void *data,
2743 int compress);
2744
2745typedef void (*Eet_Dump_Callback)(void *data, const char *str);
2746
2747/**
2748 * Dump an eet encoded data structure into ascii text
2749 * @param data_in The pointer to the data to decode into a struct.
2750 * @param size_in The size of the data pointed to in bytes.
2751 * @param dumpfunc The function to call passed a string when new
2752 * data is converted to text
2753 * @param dumpdata The data to pass to the @p dumpfunc callback.
2754 * @return 1 on success, 0 on failure
2755 *
2756 * This function will take a chunk of data encoded by
2757 * eet_data_descriptor_encode() and convert it into human readable
2758 * ascii text. It does this by calling the @p dumpfunc callback
2759 * for all new text that is generated. This callback should append
2760 * to any existing text buffer and will be passed the pointer @p
2761 * dumpdata as a parameter as well as a string with new text to be
2762 * appended.
2763 *
2764 * Example:
2765 *
2766 * @code
2767 * void output(void *data, const char *string)
2768 * {
2769 * printf("%s", string);
2770 * }
2771 *
2772 * void dump(const char *file)
2773 * {
2774 * FILE *f;
2775 * int len;
2776 * void *data;
2777 *
2778 * f = fopen(file, "r");
2779 * fseek(f, 0, SEEK_END);
2780 * len = ftell(f);
2781 * rewind(f);
2782 * data = malloc(len);
2783 * fread(data, len, 1, f);
2784 * fclose(f);
2785 * eet_data_text_dump(data, len, output, NULL);
2786 * }
2787 * @endcode
2788 *
2789 * @see eet_data_text_dump_cipher()
2790 *
2791 * @since 1.0.0
2792 * @ingroup Eet_Data_Group
2793 */
2794EAPI int
2795eet_data_text_dump(const void *data_in,
2796 int size_in,
2797 Eet_Dump_Callback dumpfunc,
2798 void *dumpdata);
2799
2800/**
2801 * Take an ascii encoding from eet_data_text_dump() and re-encode in binary.
2802 * @param text The pointer to the string data to parse and encode.
2803 * @param textlen The size of the string in bytes (not including 0
2804 * byte terminator).
2805 * @param size_ret This gets filled in with the encoded data blob
2806 * size in bytes.
2807 * @return The encoded data on success, NULL on failure.
2808 *
2809 * This function will parse the string pointed to by @p text and return
2810 * an encoded data lump the same way eet_data_descriptor_encode() takes an
2811 * in-memory data struct and encodes into a binary blob. @p text is a normal
2812 * C string.
2813 *
2814 * @see eet_data_text_undump_cipher()
2815 *
2816 * @since 1.0.0
2817 * @ingroup Eet_Data_Group
2818 */
2819EAPI void *
2820eet_data_text_undump(const char *text,
2821 int textlen,
2822 int *size_ret);
2823
2824/**
2825 * Dump an eet encoded data structure from an eet file into ascii text
2826 * @param ef A valid eet file handle.
2827 * @param name Name of the entry. eg: "/base/file_i_want".
2828 * @param dumpfunc The function to call passed a string when new
2829 * data is converted to text
2830 * @param dumpdata The data to pass to the @p dumpfunc callback.
2831 * @return 1 on success, 0 on failure
2832 *
2833 * This function will take an open and valid eet file from
2834 * eet_open() request the data encoded by
2835 * eet_data_descriptor_encode() corresponding to the key @p name
2836 * and convert it into human readable ascii text. It does this by
2837 * calling the @p dumpfunc callback for all new text that is
2838 * generated. This callback should append to any existing text
2839 * buffer and will be passed the pointer @p dumpdata as a parameter
2840 * as well as a string with new text to be appended.
2841 *
2842 * @see eet_data_dump_cipher()
2843 *
2844 * @since 1.0.0
2845 * @ingroup Eet_Data_Group
2846 */
2847EAPI int
2848eet_data_dump(Eet_File *ef,
2849 const char *name,
2850 Eet_Dump_Callback dumpfunc,
2851 void *dumpdata);
2852
2853/**
2854 * Take an ascii encoding from eet_data_dump() and re-encode in binary.
2855 * @param ef A valid eet file handle.
2856 * @param name Name of the entry. eg: "/base/file_i_want".
2857 * @param text The pointer to the string data to parse and encode.
2858 * @param textlen The size of the string in bytes (not including 0
2859 * byte terminator).
2860 * @param compress Compression flags (1 == compress, 0 = don't compress).
2861 * @return 1 on success, 0 on failure
2862 *
2863 * This function will parse the string pointed to by @p text,
2864 * encode it the same way eet_data_descriptor_encode() takes an
2865 * in-memory data struct and encodes into a binary blob.
2866 *
2867 * The data (optionally compressed) will be in ram, pending a flush to
2868 * disk (it will stay in ram till the eet file handle is closed though).
2869 *
2870 * @see eet_data_undump_cipher()
2871 *
2872 * @since 1.0.0
2873 * @ingroup Eet_Data_Group
2874 */
2875EAPI int
2876eet_data_undump(Eet_File *ef,
2877 const char *name,
2878 const char *text,
2879 int textlen,
2880 int compress);
2881
2882/**
2883 * Decode a data structure from an arbitrary location in memory.
2884 * @param edd The data descriptor to use when decoding.
2885 * @param data_in The pointer to the data to decode into a struct.
2886 * @param size_in The size of the data pointed to in bytes.
2887 * @return NULL on failure, or a valid decoded struct pointer on success.
2888 *
2889 * This function will decode a data structure that has been encoded using
2890 * eet_data_descriptor_encode(), and return a data structure with all its
2891 * elements filled out, if successful, or NULL on failure.
2892 *
2893 * The data to be decoded is stored at the memory pointed to by @p data_in,
2894 * and is described by the descriptor pointed to by @p edd. The data size is
2895 * passed in as the value to @p size_in, ande must be greater than 0 to
2896 * succeed.
2897 *
2898 * This function is useful for decoding data structures delivered to the
2899 * application by means other than an eet file, such as an IPC or socket
2900 * connection, raw files, shared memory etc.
2901 *
2902 * Please see eet_data_read() for more information.
2903 *
2904 * @see eet_data_descriptor_decode_cipher()
2905 *
2906 * @since 1.0.0
2907 * @ingroup Eet_Data_Group
2908 */
2909EAPI void *
2910eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
2911 const void *data_in,
2912 int size_in);
2913
2914/**
2915 * Encode a dsata struct to memory and return that encoded data.
2916 * @param edd The data descriptor to use when encoding.
2917 * @param data_in The pointer to the struct to encode into data.
2918 * @param size_ret pointer to the an int to be filled with the decoded size.
2919 * @return NULL on failure, or a valid encoded data chunk on success.
2920 *
2921 * This function takes a data structutre in memory and encodes it into a
2922 * serialised chunk of data that can be decoded again by
2923 * eet_data_descriptor_decode(). This is useful for being able to transmit
2924 * data structures across sockets, pipes, IPC or shared file mechanisms,
2925 * without having to worry about memory space, machine type, endianess etc.
2926 *
2927 * The parameter @p edd must point to a valid data descriptor, and
2928 * @p data_in must point to the right data structure to encode. If not, the
2929 * encoding may fail.
2930 *
2931 * On success a non NULL valid pointer is returned and what @p size_ret
2932 * points to is set to the size of this decoded data, in bytes. When the
2933 * encoded data is no longer needed, call free() on it. On failure NULL is
2934 * returned and what @p size_ret points to is set to 0.
2935 *
2936 * Please see eet_data_write() for more information.
2937 *
2938 * @see eet_data_descriptor_encode_cipher()
2939 *
2940 * @since 1.0.0
2941 * @ingroup Eet_Data_Group
2942 */
2943EAPI void *
2944eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
2945 const void *data_in,
2946 int *size_ret);
2947
2948/**
2949 * Add a basic data element to a data descriptor.
2950 * @param edd The data descriptor to add the type to.
2951 * @param struct_type The type of the struct.
2952 * @param name The string name to use to encode/decode this member
2953 * (must be a constant global and never change).
2954 * @param member The struct member itself to be encoded.
2955 * @param type The type of the member to encode.
2956 *
2957 * This macro is a convenience macro provided to add a member to
2958 * the data descriptor @p edd. The type of the structure is
2959 * provided as the @p struct_type parameter (for example: struct
2960 * my_struct). The @p name parameter defines a string that will be
2961 * used to uniquely name that member of the struct (it is suggested
2962 * to use the struct member itself). The @p member parameter is
2963 * the actual struct member itself (for example: values), and @p type is the
2964 * basic data type of the member which must be one of: EET_T_CHAR, EET_T_SHORT,
2965 * EET_T_INT, EET_T_LONG_LONG, EET_T_FLOAT, EET_T_DOUBLE, EET_T_UCHAR,
2966 * EET_T_USHORT, EET_T_UINT, EET_T_ULONG_LONG or EET_T_STRING.
2967 *
2968 * @since 1.0.0
2969 * @ingroup Eet_Data_Group
2970 */
2971#define EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, name, member, type) \
2972 do { \
2973 struct_type ___ett; \
2974 eet_data_descriptor_element_add(edd, name, type, EET_G_UNKNOWN, \
2975 (char *)(& (___ett.member)) - \
2976 (char *)(& (___ett)), \
2977 0, /* 0, */ NULL, NULL); \
2978 } while(0)
2979
2980/**
2981 * Add a sub-element type to a data descriptor
2982 * @param edd The data descriptor to add the type to.
2983 * @param struct_type The type of the struct.
2984 * @param name The string name to use to encode/decode this member
2985 * (must be a constant global and never change).
2986 * @param member The struct member itself to be encoded.
2987 * @param subtype The type of sub-type struct to add.
2988 *
2989 * This macro lets you easily add a sub-type (a struct that's pointed to
2990 * by this one). All the parameters are the same as for
2991 * EET_DATA_DESCRIPTOR_ADD_BASIC(), with the @p subtype being the exception.
2992 * This must be the data descriptor of the struct that is pointed to by
2993 * this element.
2994 *
2995 * @since 1.0.0
2996 * @ingroup Eet_Data_Group
2997 */
2998#define EET_DATA_DESCRIPTOR_ADD_SUB(edd, struct_type, name, member, subtype) \
2999 do { \
3000 struct_type ___ett; \
3001 eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_UNKNOWN, \
3002 (char *)(& (___ett.member)) - \
3003 (char *)(& (___ett)), \
3004 0, /* 0, */ NULL, subtype); \
3005 } while (0)
3006
3007/**
3008 * Add a linked list type to a data descriptor
3009 * @param edd The data descriptor to add the type to.
3010 * @param struct_type The type of the struct.
3011 * @param name The string name to use to encode/decode this member
3012 * (must be a constant global and never change).
3013 * @param member The struct member itself to be encoded.
3014 * @param subtype The type of linked list member to add.
3015 *
3016 * This macro lets you easily add a linked list of other data types. All the
3017 * parameters are the same as for EET_DATA_DESCRIPTOR_ADD_BASIC(), with the
3018 * @p subtype being the exception. This must be the data descriptor of the
3019 * element that is in each member of the linked list to be stored.
3020 *
3021 * @since 1.0.0
3022 * @ingroup Eet_Data_Group
3023 */
3024#define EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, name, member, subtype) \
3025 do { \
3026 struct_type ___ett; \
3027 eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_LIST, \
3028 (char *)(& (___ett.member)) - \
3029 (char *)(& (___ett)), \
3030 0, /* 0, */ NULL, subtype); \
3031 } while (0)
3032
3033/**
3034 * Add a linked list of string to a data descriptor
3035 * @param edd The data descriptor to add the type to.
3036 * @param struct_type The type of the struct.
3037 * @param name The string name to use to encode/decode this member
3038 * (must be a constant global and never change).
3039 * @param member The struct member itself to be encoded.
3040 *
3041 * This macro lets you easily add a linked list of char *. All the
3042 * parameters are the same as for EET_DATA_DESCRIPTOR_ADD_BASIC().
3043 *
3044 * @since 1.5.0
3045 * @ingroup Eet_Data_Group
3046 */
3047#define EET_DATA_DESCRIPTOR_ADD_LIST_STRING(edd, struct_type, name, member) \
3048 do { \
3049 struct_type ___ett; \
3050 eet_data_descriptor_element_add(edd, name, EET_T_STRING, EET_G_LIST, \
3051 (char *)(& (___ett.member)) - \
3052 (char *)(& (___ett)), \
3053 0, /* 0, */ NULL, NULL); \
3054 } while (0)
3055
3056/**
3057 * Add a hash type to a data descriptor
3058 * @param edd The data descriptor to add the type to.
3059 * @param struct_type The type of the struct.
3060 * @param name The string name to use to encode/decode this member
3061 * (must be a constant global and never change).
3062 * @param member The struct member itself to be encoded.
3063 * @param subtype The type of hash member to add.
3064 *
3065 * This macro lets you easily add a hash of other data types. All the
3066 * parameters are the same as for EET_DATA_DESCRIPTOR_ADD_BASIC(), with the
3067 * @p subtype being the exception. This must be the data descriptor of the
3068 * element that is in each member of the hash to be stored.
3069 * The hash keys must be strings.
3070 *
3071 * @since 1.0.0
3072 * @ingroup Eet_Data_Group
3073 */
3074#define EET_DATA_DESCRIPTOR_ADD_HASH(edd, struct_type, name, member, subtype) \
3075 do { \
3076 struct_type ___ett; \
3077 eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_HASH, \
3078 (char *)(& (___ett.member)) - \
3079 (char *)(& (___ett)), \
3080 0, /* 0, */ NULL, subtype); \
3081 } while (0)
3082
3083/**
3084 * Add a hash of string to a data descriptor
3085 * @param edd The data descriptor to add the type to.
3086 * @param struct_type The type of the struct.
3087 * @param name The string name to use to encode/decode this member
3088 * (must be a constant global and never change).
3089 * @param member The struct member itself to be encoded.
3090 *
3091 * This macro lets you easily add a hash of string elements. All the
3092 * parameters are the same as for EET_DATA_DESCRIPTOR_ADD_HASH().
3093 *
3094 * @since 1.3.4
3095 * @ingroup Eet_Data_Group
3096 */
3097#define EET_DATA_DESCRIPTOR_ADD_HASH_STRING(edd, struct_type, name, member) \
3098 do { \
3099 struct_type ___ett; \
3100 eet_data_descriptor_element_add(edd, name, EET_T_STRING, EET_G_HASH, \
3101 (char *)(& (___ett.member)) - \
3102 (char *)(& (___ett)), \
3103 0, /* 0, */ NULL, NULL); \
3104 } while (0)
3105
3106/**
3107 * Add an array of basic data elements to a data descriptor.
3108 * @param edd The data descriptor to add the type to.
3109 * @param struct_type The type of the struct.
3110 * @param name The string name to use to encode/decode this member
3111 * (must be a constant global and never change).
3112 * @param member The struct member itself to be encoded.
3113 * @param type The type of the member to encode.
3114 *
3115 * This macro lets you easily add a fixed size array of basic data
3116 * types. All the parameters are the same as for
3117 * EET_DATA_DESCRIPTOR_ADD_BASIC().
3118 * The array must be defined with a fixed size in the declaration of the
3119 * struct containing it.
3120 *
3121 * @since 1.5.0
3122 * @ingroup Eet_Data_Group
3123 */
3124#define EET_DATA_DESCRIPTOR_ADD_BASIC_ARRAY(edd, struct_type, name, member, type) \
3125 do { \
3126 struct_type ___ett; \
3127 eet_data_descriptor_element_add(edd, name, type, EET_G_ARRAY, \
3128 (char *)(& (___ett.member)) - \
3129 (char *)(& (___ett)), \
3130 sizeof(___ett.member) / \
3131 sizeof(___ett.member[0]), \
3132 NULL, NULL); \
3133 } while(0)
3134
3135/**
3136 * Add a fixed size array type to a data descriptor
3137 * @param edd The data descriptor to add the type to.
3138 * @param struct_type The type of the struct.
3139 * @param name The string name to use to encode/decode this member
3140 * (must be a constant global and never change).
3141 * @param member The struct member itself to be encoded.
3142 * @param subtype The type of hash member to add.
3143 *
3144 * This macro lets you easily add a fixed size array of other data
3145 * types. All the parameters are the same as for
3146 * EET_DATA_DESCRIPTOR_ADD_BASIC(), with the @p subtype being the
3147 * exception. This must be the data descriptor of the element that
3148 * is in each member of the array to be stored.
3149 * The array must be defined with a fixed size in the declaration of the
3150 * struct containing it.
3151 *
3152 * @since 1.0.2
3153 * @ingroup Eet_Data_Group
3154 */
3155#define EET_DATA_DESCRIPTOR_ADD_ARRAY(edd, struct_type, name, member, subtype) \
3156 do { \
3157 struct_type ___ett; \
3158 eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_ARRAY, \
3159 (char *)(& (___ett.member)) - \
3160 (char *)(& (___ett)), \
3161 /* 0, */ sizeof(___ett.member) / \
3162 sizeof(___ett.member[0]), NULL, subtype); \
3163 } while (0)
3164
3165/**
3166 * Add a variable size array type to a data descriptor
3167 * @param edd The data descriptor to add the type to.
3168 * @param struct_type The type of the struct.
3169 * @param name The string name to use to encode/decode this member
3170 * (must be a constant global and never change).
3171 * @param member The struct member itself to be encoded.
3172 * @param subtype The type of hash member to add.
3173 *
3174 * This macro lets you easily add a variable size array of other data
3175 * types. All the parameters are the same as for
3176 * EET_DATA_DESCRIPTOR_ADD_BASIC(), with the @p subtype being the
3177 * exception. This must be the data descriptor of the element that
3178 * is in each member of the array to be stored. This assumes you have
3179 * a struct member (of type EET_T_INT) called member_count (note the
3180 * _count appended to the member) that holds the number of items in
3181 * the array. This array will be allocated separately to the struct it
3182 * is in.
3183 *
3184 * @since 1.0.2
3185 * @ingroup Eet_Data_Group
3186 */
3187#define EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(edd, struct_type, name, member, subtype) \
3188 do { \
3189 struct_type ___ett; \
3190 eet_data_descriptor_element_add(edd, \
3191 name, \
3192 EET_T_UNKNOW, \
3193 EET_G_VAR_ARRAY, \
3194 (char *)(& (___ett.member)) - \
3195 (char *)(& (___ett)), \
3196 (char *)(& (___ett.member ## _count)) - \
3197 (char *)(& (___ett)), \
3198 /* 0, */ NULL, \
3199 subtype); \
3200 } while (0)
3201
3202/**
3203 * Add a variable size array type to a data descriptor
3204 * @param edd The data descriptor to add the type to.
3205 * @param struct_type The type of the struct.
3206 * @param name The string name to use to encode/decode this member
3207 * (must be a constant global and never change).
3208 * @param member The struct member itself to be encoded.
3209 *
3210 * This macro lets you easily add a variable size array of strings. All
3211 * the parameters are the same as for EET_DATA_DESCRIPTOR_ADD_BASIC().
3212 *
3213 * @since 1.4.0
3214 * @ingroup Eet_Data_Group
3215 */
3216#define EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY_STRING(edd, struct_type, name, member) \
3217 do { \
3218 struct_type ___ett; \
3219 eet_data_descriptor_element_add(edd, \
3220 name, \
3221 EET_T_STRING, \
3222 EET_G_VAR_ARRAY, \
3223 (char *)(& (___ett.member)) - \
3224 (char *)(& (___ett)), \
3225 (char *)(& (___ett.member ## _count)) - \
3226 (char *)(& (___ett)), \
3227 /* 0, */ NULL, \
3228 NULL); \
3229 } while (0)
3230
3231/**
3232 * Add an union type to a data descriptor
3233 * @param edd The data descriptor to add the type to.
3234 * @param struct_type The type of the struct.
3235 * @param name The string name to use to encode/decode this member
3236 * (must be a constant global and never change).
3237 * @param member The struct member itself to be encoded.
3238 * @param type_member The member that give hints on what is in the union.
3239 * @param unified_type Describe all possible type the union could handle.
3240 *
3241 * This macro lets you easily add an union with a member that specify what is inside.
3242 * The @p unified_type is an Eet_Data_Descriptor, but only the entry that match the name
3243 * returned by type_get will be used for each serialized data. The type_get and type_set
3244 * callback of unified_type should be defined.
3245 *
3246 * @since 1.2.4
3247 * @ingroup Eet_Data_Group
3248 * @see Eet_Data_Descriptor_Class
3249 */
3250#define EET_DATA_DESCRIPTOR_ADD_UNION(edd, struct_type, name, member, type_member, unified_type) \
3251 do { \
3252 struct_type ___ett; \
3253 eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_UNION, \
3254 (char *)(& (___ett.member)) - \
3255 (char *)(& (___ett)), \
3256 (char *)(& (___ett.type_member)) - \
3257 (char *)(& (___ett)), \
3258 NULL, unified_type); \
3259 } while (0)
3260
3261/**
3262 * Add a automatically selectable type to a data descriptor
3263 * @param edd The data descriptor to add the type to.
3264 * @param struct_type The type of the struct.
3265 * @param name The string name to use to encode/decode this member
3266 * (must be a constant global and never change).
3267 * @param member The struct member itself to be encoded.
3268 * @param type_member The member that give hints on what is in the union.
3269 * @param unified_type Describe all possible type the union could handle.
3270 *
3271 * This macro lets you easily define what the content of @p member points to depending of
3272 * the content of @p type_member. The type_get and type_set callback of unified_type should
3273 * be defined. If the the type is not know at the time of restoring it, eet will still call
3274 * type_set of @p unified_type but the pointer will be set to a serialized binary representation
3275 * of what eet know. This make it possible, to save this pointer again by just returning the string
3276 * given previously and telling it by setting unknow to EINA_TRUE.
3277 *
3278 * @since 1.2.4
3279 * @ingroup Eet_Data_Group
3280 * @see Eet_Data_Descriptor_Class
3281 */
3282#define EET_DATA_DESCRIPTOR_ADD_VARIANT(edd, struct_type, name, member, type_member, unified_type) \
3283 do { \
3284 struct_type ___ett; \
3285 eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_VARIANT, \
3286 (char *)(& (___ett.member)) - \
3287 (char *)(& (___ett)), \
3288 (char *)(& (___ett.type_member)) - \
3289 (char *)(& (___ett)), \
3290 NULL, unified_type); \
3291 } while (0)
3292
3293/**
3294 * Add a mapping to a data descriptor that will be used by union, variant or inherited type
3295 * @param unified_type The data descriptor to add the mapping to.
3296 * @param name The string name to get/set type.
3297 * @param subtype The matching data descriptor.
3298 *
3299 * @since 1.2.4
3300 * @ingroup Eet_Data_Group
3301 * @see Eet_Data_Descriptor_Class
3302 */
3303#define EET_DATA_DESCRIPTOR_ADD_MAPPING(unified_type, name, subtype) \
3304 eet_data_descriptor_element_add(unified_type, \
3305 name, \
3306 EET_T_UNKNOW, \
3307 EET_G_UNKNOWN, \
3308 0, \
3309 0, \
3310 NULL, \
3311 subtype)
3312
3313/**
3314 * @defgroup Eet_Data_Cipher_Group Eet Data Serialization using A Ciphers
3315 *
3316 * Most of the @ref Eet_Data_Group have alternative versions that
3317 * accounts for ciphers to protect their content.
3318 *
3319 * @see @ref Eet_Cipher_Group
3320 *
3321 * @ingroup Eet_Data_Group
3322 */
3323
3324/**
3325 * Read a data structure from an eet file and decodes it using a cipher.
3326 * @param ef The eet file handle to read from.
3327 * @param edd The data descriptor handle to use when decoding.
3328 * @param name The key the data is stored under in the eet file.
3329 * @param cipher_key The key to use as cipher.
3330 * @return A pointer to the decoded data structure.
3331 *
3332 * This function decodes a data structure stored in an eet file, returning
3333 * a pointer to it if it decoded successfully, or NULL on failure. This
3334 * can save a programmer dozens of hours of work in writing configuration
3335 * file parsing and writing code, as eet does all that work for the program
3336 * and presents a program-friendly data structure, just as the programmer
3337 * likes. Eet can handle members being added or deleted from the data in
3338 * storage and safely zero-fills unfilled members if they were not found
3339 * in the data. It checks sizes and headers whenever it reads data, allowing
3340 * the programmer to not worry about corrupt data.
3341 *
3342 * Once a data structure has been described by the programmer with the
3343 * fields they wish to save or load, storing or retrieving a data structure
3344 * from an eet file, or from a chunk of memory is as simple as a single
3345 * function call.
3346 *
3347 * @see eet_data_read()
3348 *
3349 * @since 1.0.0
3350 * @ingroup Eet_Data_Cipher_Group
3351 */
3352EAPI void *
3353eet_data_read_cipher(Eet_File *ef,
3354 Eet_Data_Descriptor *edd,
3355 const char *name,
3356 const char *cipher_key);
3357
3358/**
3359 * Read a data structure from an eet extended attribute and decodes it using a cipher.
3360 * @param filename The file to extract the extended attribute from.
3361 * @param attribute The attribute to get the data from.
3362 * @param edd The data descriptor handle to use when decoding.
3363 * @param cipher_key The key to use as cipher.
3364 * @return A pointer to the decoded data structure.
3365 *
3366 * This function decodes a data structure stored in an eet extended attribute,
3367 * returning a pointer to it if it decoded successfully, or NULL on failure.
3368 * Eet can handle members being added or deleted from the data in
3369 * storage and safely zero-fills unfilled members if they were not found
3370 * in the data. It checks sizes and headers whenever it reads data, allowing
3371 * the programmer to not worry about corrupt data.
3372 *
3373 * Once a data structure has been described by the programmer with the
3374 * fields they wish to save or load, storing or retrieving a data structure
3375 * from an eet file, from a chunk of memory or from an extended attribute
3376 * is as simple as a single function call.
3377 *
3378 * @since 1.5.0
3379 * @ingroup Eet_Data_Cipher_Group
3380 */
3381EAPI void *
3382eet_data_xattr_cipher_get(const char *filename,
3383 const char *attribute,
3384 Eet_Data_Descriptor *edd,
3385 const char *cipher_key);
3386
3387/**
3388 * Write a data structure from memory and store in an eet file
3389 * using a cipher.
3390 * @param ef The eet file handle to write to.
3391 * @param edd The data descriptor to use when encoding.
3392 * @param name The key to store the data under in the eet file.
3393 * @param cipher_key The key to use as cipher.
3394 * @param data A pointer to the data structure to ssave and encode.
3395 * @param compress Compression flags for storage.
3396 * @return bytes written on successful write, 0 on failure.
3397 *
3398 * This function is the reverse of eet_data_read_cipher(), saving a data structure
3399 * to an eet file.
3400 *
3401 * @since 1.0.0
3402 * @ingroup Eet_Data_Cipher_Group
3403 */
3404EAPI int
3405eet_data_write_cipher(Eet_File *ef,
3406 Eet_Data_Descriptor *edd,
3407 const char *name,
3408 const char *cipher_key,
3409 const void *data,
3410 int compress);
3411
3412/**
3413 * Write a data structure from memory and store in an eet extended attribute
3414 * using a cipher.
3415 * @param filename The file to write the extended attribute to.
3416 * @param attribute The attribute to store the data to.
3417 * @param edd The data descriptor to use when encoding.
3418 * @param cipher_key The key to use as cipher.
3419 * @param data A pointer to the data structure to ssave and encode.
3420 * @param flags The policy to use when setting the data.
3421 * @return EINA_TRUE on success, EINA_FALSE on failure.
3422 *
3423 * This function is the reverse of eet_data_xattr_cipher_get(), saving a data structure
3424 * to an eet extended attribute.
3425 *
3426 * @since 1.5.0
3427 * @ingroup Eet_Data_Cipher_Group
3428 */
3429EAPI Eina_Bool
3430eet_data_xattr_cipher_set(const char *filename,
3431 const char *attribute,
3432 Eet_Data_Descriptor *edd,
3433 const char *cipher_key,
3434 const void *data,
3435 Eina_Xattr_Flags flags);
3436
3437/**
3438 * Dump an eet encoded data structure into ascii text using a cipher.
3439 * @param data_in The pointer to the data to decode into a struct.
3440 * @param cipher_key The key to use as cipher.
3441 * @param size_in The size of the data pointed to in bytes.
3442 * @param dumpfunc The function to call passed a string when new
3443 * data is converted to text
3444 * @param dumpdata The data to pass to the @p dumpfunc callback.
3445 * @return 1 on success, 0 on failure
3446 *
3447 * This function will take a chunk of data encoded by
3448 * eet_data_descriptor_encode() and convert it into human readable
3449 * ascii text. It does this by calling the @p dumpfunc callback
3450 * for all new text that is generated. This callback should append
3451 * to any existing text buffer and will be passed the pointer @p
3452 * dumpdata as a parameter as well as a string with new text to be
3453 * appended.
3454 *
3455 * Example:
3456 *
3457 * @code
3458 * void output(void *data, const char *string)
3459 * {
3460 * printf("%s", string);
3461 * }
3462 *
3463 * void dump(const char *file)
3464 * {
3465 * FILE *f;
3466 * int len;
3467 * void *data;
3468 *
3469 * f = fopen(file, "r");
3470 * fseek(f, 0, SEEK_END);
3471 * len = ftell(f);
3472 * rewind(f);
3473 * data = malloc(len);
3474 * fread(data, len, 1, f);
3475 * fclose(f);
3476 * eet_data_text_dump_cipher(data, cipher_key, len, output, NULL);
3477 * }
3478 * @endcode
3479 *
3480 * @see eet_data_text_dump()
3481 *
3482 * @since 1.0.0
3483 * @ingroup Eet_Data_Cipher_Group
3484 */
3485EAPI int
3486eet_data_text_dump_cipher(const void *data_in,
3487 const char *cipher_key,
3488 int size_in,
3489 Eet_Dump_Callback dumpfunc,
3490 void *dumpdata);
3491
3492/**
3493 * Take an ascii encoding from eet_data_text_dump() and re-encode
3494 * in binary using a cipher.
3495 * @param text The pointer to the string data to parse and encode.
3496 * @param cipher_key The key to use as cipher.
3497 * @param textlen The size of the string in bytes (not including 0
3498 * byte terminator).
3499 * @param size_ret This gets filled in with the encoded data blob
3500 * size in bytes.
3501 * @return The encoded data on success, NULL on failure.
3502 *
3503 * This function will parse the string pointed to by @p text and return
3504 * an encoded data lump the same way eet_data_descriptor_encode() takes an
3505 * in-memory data struct and encodes into a binary blob. @p text is a normal
3506 * C string.
3507 *
3508 * @see eet_data_text_undump()
3509 *
3510 * @since 1.0.0
3511 * @ingroup Eet_Data_Cipher_Group
3512 */
3513EAPI void *
3514eet_data_text_undump_cipher(const char *text,
3515 const char *cipher_key,
3516 int textlen,
3517 int *size_ret);
3518
3519/**
3520 * Dump an eet encoded data structure from an eet file into ascii
3521 * text using a cipher.
3522 * @param ef A valid eet file handle.
3523 * @param name Name of the entry. eg: "/base/file_i_want".
3524 * @param cipher_key The key to use as cipher.
3525 * @param dumpfunc The function to call passed a string when new
3526 * data is converted to text
3527 * @param dumpdata The data to pass to the @p dumpfunc callback.
3528 * @return 1 on success, 0 on failure
3529 *
3530 * This function will take an open and valid eet file from
3531 * eet_open() request the data encoded by
3532 * eet_data_descriptor_encode() corresponding to the key @p name
3533 * and convert it into human readable ascii text. It does this by
3534 * calling the @p dumpfunc callback for all new text that is
3535 * generated. This callback should append to any existing text
3536 * buffer and will be passed the pointer @p dumpdata as a parameter
3537 * as well as a string with new text to be appended.
3538 *
3539 * @see eet_data_dump()
3540 *
3541 * @since 1.0.0
3542 * @ingroup Eet_Data_Cipher_Group
3543 */
3544EAPI int
3545eet_data_dump_cipher(Eet_File *ef,
3546 const char *name,
3547 const char *cipher_key,
3548 Eet_Dump_Callback dumpfunc,
3549 void *dumpdata);
3550
3551/**
3552 * Take an ascii encoding from eet_data_dump() and re-encode in
3553 * binary using a cipher.
3554 * @param ef A valid eet file handle.
3555 * @param name Name of the entry. eg: "/base/file_i_want".
3556 * @param cipher_key The key to use as cipher.
3557 * @param text The pointer to the string data to parse and encode.
3558 * @param textlen The size of the string in bytes (not including 0
3559 * byte terminator).
3560 * @param compress Compression flags (1 == compress, 0 = don't compress).
3561 * @return 1 on success, 0 on failure
3562 *
3563 * This function will parse the string pointed to by @p text,
3564 * encode it the same way eet_data_descriptor_encode() takes an
3565 * in-memory data struct and encodes into a binary blob.
3566 *
3567 * The data (optionally compressed) will be in ram, pending a flush to
3568 * disk (it will stay in ram till the eet file handle is closed though).
3569 *
3570 * @see eet_data_undump()
3571 *
3572 * @since 1.0.0
3573 * @ingroup Eet_Data_Cipher_Group
3574 */
3575EAPI int
3576eet_data_undump_cipher(Eet_File *ef,
3577 const char *name,
3578 const char *cipher_key,
3579 const char *text,
3580 int textlen,
3581 int compress);
3582
3583/**
3584 * Decode a data structure from an arbitrary location in memory
3585 * using a cipher.
3586 * @param edd The data descriptor to use when decoding.
3587 * @param data_in The pointer to the data to decode into a struct.
3588 * @param cipher_key The key to use as cipher.
3589 * @param size_in The size of the data pointed to in bytes.
3590 * @return NULL on failure, or a valid decoded struct pointer on success.
3591 *
3592 * This function will decode a data structure that has been encoded using
3593 * eet_data_descriptor_encode(), and return a data structure with all its
3594 * elements filled out, if successful, or NULL on failure.
3595 *
3596 * The data to be decoded is stored at the memory pointed to by @p data_in,
3597 * and is described by the descriptor pointed to by @p edd. The data size is
3598 * passed in as the value to @p size_in, ande must be greater than 0 to
3599 * succeed.
3600 *
3601 * This function is useful for decoding data structures delivered to the
3602 * application by means other than an eet file, such as an IPC or socket
3603 * connection, raw files, shared memory etc.
3604 *
3605 * Please see eet_data_read() for more information.
3606 *
3607 * @see eet_data_descriptor_decode()
3608 *
3609 * @since 1.0.0
3610 * @ingroup Eet_Data_Cipher_Group
3611 */
3612EAPI void *
3613eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
3614 const void *data_in,
3615 const char *cipher_key,
3616 int size_in);
3617
3618/**
3619 * Encode a data struct to memory and return that encoded data
3620 * using a cipher.
3621 * @param edd The data descriptor to use when encoding.
3622 * @param data_in The pointer to the struct to encode into data.
3623 * @param cipher_key The key to use as cipher.
3624 * @param size_ret pointer to the an int to be filled with the decoded size.
3625 * @return NULL on failure, or a valid encoded data chunk on success.
3626 *
3627 * This function takes a data structutre in memory and encodes it into a
3628 * serialised chunk of data that can be decoded again by
3629 * eet_data_descriptor_decode(). This is useful for being able to transmit
3630 * data structures across sockets, pipes, IPC or shared file mechanisms,
3631 * without having to worry about memory space, machine type, endianess etc.
3632 *
3633 * The parameter @p edd must point to a valid data descriptor, and
3634 * @p data_in must point to the right data structure to encode. If not, the
3635 * encoding may fail.
3636 *
3637 * On success a non NULL valid pointer is returned and what @p size_ret
3638 * points to is set to the size of this decoded data, in bytes. When the
3639 * encoded data is no longer needed, call free() on it. On failure NULL is
3640 * returned and what @p size_ret points to is set to 0.
3641 *
3642 * Please see eet_data_write() for more information.
3643 *
3644 * @see eet_data_descriptor_encode()
3645 *
3646 * @since 1.0.0
3647 * @ingroup Eet_Data_Cipher_Group
3648 */
3649EAPI void *
3650eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
3651 const void *data_in,
3652 const char *cipher_key,
3653 int *size_ret);
3654
3655/**
3656 * @defgroup Eet_Node_Group Low-level Serialization Structures.
3657 *
3658 * Functions that create, destroy and manipulate serialization nodes
3659 * used by @ref Eet_Data_Group.
3660 *
3661 * @{
3662 */
3663
3664/**
3665 * @typedef Eet_Node
3666 * Opaque handle to manage serialization node.
3667 */
3668typedef struct _Eet_Node Eet_Node;
3669
3670/**
3671 * @typedef Eet_Node_Data
3672 * Contains an union that can fit any kind of node.
3673 */
3674typedef struct _Eet_Node_Data Eet_Node_Data;
3675
3676/**
3677 * @struct _Eet_Node_Data
3678 * Contains an union that can fit any kind of node.
3679 */
3680struct _Eet_Node_Data
3681{
3682 union {
3683 char c;
3684 short s;
3685 int i;
3686 long long l;
3687 float f;
3688 double d;
3689 unsigned char uc;
3690 unsigned short us;
3691 unsigned int ui;
3692 unsigned long long ul;
3693 const char *str;
3694 } value;
3695};
3696
3697/**
3698 * @}
3699 */
3700
3701/**
3702 * TODO FIX ME
3703 * @ingroup Eet_Node_Group
3704 */
3705EAPI Eet_Node *
3706eet_node_char_new(const char *name,
3707 char c);
3708
3709/**
3710 * TODO FIX ME
3711 * @ingroup Eet_Node_Group
3712 */
3713EAPI Eet_Node *
3714eet_node_short_new(const char *name,
3715 short s);
3716
3717/**
3718 * TODO FIX ME
3719 * @ingroup Eet_Node_Group
3720 */
3721EAPI Eet_Node *
3722eet_node_int_new(const char *name,
3723 int i);
3724
3725/**
3726 * TODO FIX ME
3727 * @ingroup Eet_Node_Group
3728 */
3729EAPI Eet_Node *
3730eet_node_long_long_new(const char *name,
3731 long long l);
3732
3733/**
3734 * TODO FIX ME
3735 * @ingroup Eet_Node_Group
3736 */
3737EAPI Eet_Node *
3738eet_node_float_new(const char *name,
3739 float f);
3740
3741/**
3742 * TODO FIX ME
3743 * @ingroup Eet_Node_Group
3744 */
3745EAPI Eet_Node *
3746eet_node_double_new(const char *name,
3747 double d);
3748
3749/**
3750 * TODO FIX ME
3751 * @ingroup Eet_Node_Group
3752 */
3753EAPI Eet_Node *
3754eet_node_unsigned_char_new(const char *name,
3755 unsigned char uc);
3756
3757/**
3758 * TODO FIX ME
3759 * @ingroup Eet_Node_Group
3760 */
3761EAPI Eet_Node *
3762eet_node_unsigned_short_new(const char *name,
3763 unsigned short us);
3764
3765/**
3766 * TODO FIX ME
3767 * @ingroup Eet_Node_Group
3768 */
3769EAPI Eet_Node *
3770eet_node_unsigned_int_new(const char *name,
3771 unsigned int ui);
3772
3773/**
3774 * TODO FIX ME
3775 * @ingroup Eet_Node_Group
3776 */
3777EAPI Eet_Node *
3778eet_node_unsigned_long_long_new(const char *name,
3779 unsigned long long l);
3780
3781/**
3782 * TODO FIX ME
3783 * @ingroup Eet_Node_Group
3784 */
3785EAPI Eet_Node *
3786eet_node_string_new(const char *name,
3787 const char *str);
3788
3789/**
3790 * TODO FIX ME
3791 * @ingroup Eet_Node_Group
3792 */
3793EAPI Eet_Node *
3794eet_node_inlined_string_new(const char *name,
3795 const char *str);
3796
3797/**
3798 * TODO FIX ME
3799 * @ingroup Eet_Node_Group
3800 */
3801EAPI Eet_Node *
3802eet_node_null_new(const char *name);
3803
3804/**
3805 * TODO FIX ME
3806 * @ingroup Eet_Node_Group
3807 */
3808EAPI Eet_Node *
3809eet_node_list_new(const char *name,
3810 Eina_List *nodes);
3811
3812/**
3813 * TODO FIX ME
3814 * @ingroup Eet_Node_Group
3815 */
3816EAPI Eet_Node *
3817eet_node_array_new(const char *name,
3818 int count,
3819 Eina_List *nodes);
3820
3821/**
3822 * TODO FIX ME
3823 * @ingroup Eet_Node_Group
3824 */
3825EAPI Eet_Node *
3826eet_node_var_array_new(const char *name,
3827 Eina_List *nodes);
3828
3829/**
3830 * TODO FIX ME
3831 * @ingroup Eet_Node_Group
3832 */
3833EAPI Eet_Node *
3834eet_node_hash_new(const char *name,
3835 const char *key,
3836 Eet_Node *node);
3837
3838/**
3839 * TODO FIX ME
3840 * @ingroup Eet_Node_Group
3841 */
3842EAPI Eet_Node *
3843eet_node_struct_new(const char *name,
3844 Eina_List *nodes);
3845
3846/**
3847 * TODO FIX ME
3848 * @ingroup Eet_Node_Group
3849 */
3850EAPI Eet_Node *
3851eet_node_struct_child_new(const char *parent,
3852 Eet_Node *child);
3853
3854/**
3855 * @brief Get a node's child nodes
3856 * @param node The node
3857 * @return The first child node which contains a pointer to the
3858 * next child node and the parent.
3859 * @since 1.5
3860 */
3861EAPI Eet_Node *
3862eet_node_children_get(Eet_Node *node);
3863
3864/**
3865 * @brief Get the next node in a list of nodes
3866 * @param node The node
3867 * @return A node which contains a pointer to the
3868 * next child node and the parent.
3869 * @since 1.5
3870 */
3871EAPI Eet_Node *
3872eet_node_next_get(Eet_Node *node);
3873
3874/**
3875 * @brief Get the parent node of a node
3876 * @param node The node
3877 * @return The parent node of @p node
3878 * @since 1.5
3879 */
3880EAPI Eet_Node *
3881eet_node_parent_get(Eet_Node *node);
3882
3883/**
3884 * TODO FIX ME
3885 * @ingroup Eet_Node_Group
3886 */
3887EAPI void
3888eet_node_list_append(Eet_Node *parent,
3889 const char *name,
3890 Eet_Node *child);
3891
3892/**
3893 * TODO FIX ME
3894 * @ingroup Eet_Node_Group
3895 */
3896EAPI void
3897eet_node_struct_append(Eet_Node *parent,
3898 const char *name,
3899 Eet_Node *child);
3900
3901/**
3902 * TODO FIX ME
3903 * @ingroup Eet_Node_Group
3904 */
3905EAPI void
3906eet_node_hash_add(Eet_Node *parent,
3907 const char *name,
3908 const char *key,
3909 Eet_Node *child);
3910
3911/**
3912 * TODO FIX ME
3913 * @ingroup Eet_Node_Group
3914 */
3915EAPI void
3916eet_node_dump(Eet_Node *n,
3917 int dumplevel,
3918 Eet_Dump_Callback dumpfunc,
3919 void *dumpdata);
3920
3921/**
3922 * @brief Return the type of a node
3923 * @param node The node
3924 * @return The node's type (EET_T_$TYPE)
3925 * @since 1.5
3926 */
3927EAPI int
3928eet_node_type_get(Eet_Node *node);
3929
3930/**
3931 * @brief Return the node's data
3932 * @param node The node
3933 * @return The data contained in the node
3934 * @since 1.5
3935 */
3936EAPI Eet_Node_Data *
3937eet_node_value_get(Eet_Node *node);
3938
3939/**
3940 * TODO FIX ME
3941 * @ingroup Eet_Node_Group
3942 */
3943EAPI void
3944eet_node_del(Eet_Node *n);
3945
3946/**
3947 * TODO FIX ME
3948 * @ingroup Eet_Node_Group
3949 */
3950EAPI void *
3951eet_data_node_encode_cipher(Eet_Node *node,
3952 const char *cipher_key,
3953 int *size_ret);
3954
3955/**
3956 * TODO FIX ME
3957 * @ingroup Eet_Node_Group
3958 */
3959EAPI Eet_Node *
3960eet_data_node_decode_cipher(const void *data_in,
3961 const char *cipher_key,
3962 int size_in);
3963
3964/**
3965 * TODO FIX ME
3966 * @ingroup Eet_Node_Group
3967 */
3968EAPI Eet_Node *
3969eet_data_node_read_cipher(Eet_File *ef,
3970 const char *name,
3971 const char *cipher_key);
3972
3973/**
3974 * TODO FIX ME
3975 * @ingroup Eet_Node_Group
3976 */
3977EAPI int
3978eet_data_node_write_cipher(Eet_File *ef,
3979 const char *name,
3980 const char *cipher_key,
3981 Eet_Node *node,
3982 int compress);
3983
3984/* EXPERIMENTAL: THIS API MAY CHANGE IN THE FUTURE, USE IT ONLY IF YOU KNOW WHAT YOU ARE DOING. */
3985
3986/**
3987 * @typedef Eet_Node_Walk
3988 * Describes how to walk trees of #Eet_Node.
3989 */
3990typedef struct _Eet_Node_Walk Eet_Node_Walk;
3991
3992typedef void * (*Eet_Node_Walk_Struct_Alloc_Callback)(const char *type, void *user_data);
3993typedef void (*Eet_Node_Walk_Struct_Add_Callback)(void *parent, const char *name, void *child, void *user_data);
3994typedef void * (*Eet_Node_Walk_Array_Callback)(Eina_Bool variable, const char *name, int count, void *user_data);
3995typedef void (*Eet_Node_Walk_Insert_Callback)(void *array, int index, void *child, void *user_data);
3996typedef void * (*Eet_Node_Walk_List_Callback)(const char *name, void *user_data);
3997typedef void (*Eet_Node_Walk_Append_Callback)(void *list, void *child, void *user_data);
3998typedef void * (*Eet_Node_Walk_Hash_Callback)(void *parent, const char *name, const char *key, void *value, void *user_data);
3999typedef void * (*Eet_Node_Walk_Simple_Callback)(int type, Eet_Node_Data *data, void *user_data);
4000
4001/**
4002 * @struct _Eet_Node_Walk
4003 * Describes how to walk trees of #Eet_Node.
4004 */
4005struct _Eet_Node_Walk
4006{
4007 Eet_Node_Walk_Struct_Alloc_Callback struct_alloc;
4008 Eet_Node_Walk_Struct_Add_Callback struct_add;
4009 Eet_Node_Walk_Array_Callback array;
4010 Eet_Node_Walk_Insert_Callback insert;
4011 Eet_Node_Walk_List_Callback list;
4012 Eet_Node_Walk_Append_Callback append;
4013 Eet_Node_Walk_Hash_Callback hash;
4014 Eet_Node_Walk_Simple_Callback simple;
4015};
4016
4017EAPI void *
4018eet_node_walk(void *parent,
4019 const char *name,
4020 Eet_Node *root,
4021 Eet_Node_Walk *cb,
4022 void *user_data);
4023
4024/*******/
4025
4026/**
4027 * @defgroup Eet_Connection_Group Helper function to use eet over a network link
4028 *
4029 * Function that reconstruct and prepare packet of @ref Eet_Data_Group to be send.
4030 *
4031 */
4032
4033/**
4034 * @typedef Eet_Connection
4035 * Opaque handle to track paquet for a specific connection.
4036 *
4037 * @ingroup Eet_Connection_Group
4038 */
4039typedef struct _Eet_Connection Eet_Connection;
4040
4041/**
4042 * @typedef Eet_Read_Cb
4043 * Called back when an @ref Eet_Data_Group has been received completly and could be used.
4044 *
4045 * @ingroup Eet_Connection_Group
4046 */
4047typedef Eina_Bool Eet_Read_Cb (const void *eet_data, size_t size, void *user_data);
4048
4049/**
4050 * @typedef Eet_Write_Cb
4051 * Called back when a packet containing @ref Eet_Data_Group data is ready to be send.
4052 *
4053 * @ingroup Eet_Connection_Group
4054 */
4055typedef Eina_Bool Eet_Write_Cb (const void *data, size_t size, void *user_data);
4056
4057/**
4058 * Instanciate a new connection to track.
4059 * @param eet_read_cb Function to call when one Eet_Data packet has been fully assemble.
4060 * @param eet_write_cb Function to call when one Eet_Data packet is ready to be send over the wire.
4061 * @param user_data Pointer provided to both functions to be used as a context handler.
4062 * @return NULL on failure, or a valid Eet_Connection handler.
4063 *
4064 * For every connection to track you will need a separate Eet_Connection provider.
4065 *
4066 * @since 1.2.4
4067 * @ingroup Eet_Connection_Group
4068 */
4069EAPI Eet_Connection *
4070eet_connection_new(Eet_Read_Cb *eet_read_cb,
4071 Eet_Write_Cb *eet_write_cb,
4072 const void *user_data);
4073
4074/**
4075 * Process a raw packet received over the link
4076 * @param conn Connection handler to track.
4077 * @param data Raw data packet.
4078 * @param size The size of that packet.
4079 * @return 0 on complete success, any other value indicate where in the stream it got wrong (It could be before that packet).
4080 *
4081 * Every time you receive a packet related to your connection, you should pass
4082 * it to that function so that it could process and assemble packet has you
4083 * receive it. It will automatically call Eet_Read_Cb when one is fully received.
4084 *
4085 * @since 1.2.4
4086 * @ingroup Eet_Connection_Group
4087 */
4088EAPI int
4089eet_connection_received(Eet_Connection *conn,
4090 const void *data,
4091 size_t size);
4092
4093/**
4094 * Convert a complex structure and prepare it to be send.
4095 * @param conn Connection handler to track.
4096 * @param edd The data descriptor to use when encoding.
4097 * @param data_in The pointer to the struct to encode into data.
4098 * @param cipher_key The key to use as cipher.
4099 * @return EINA_TRUE if the data where correctly send, EINA_FALSE if they don't.
4100 *
4101 * This function serialize data_in with edd, assemble the packet and call
4102 * Eet_Write_Cb when ready. The data passed Eet_Write_Cb are temporary allocated
4103 * and will vanish just after the return of the callback.
4104 *
4105 * @see eet_data_descriptor_encode_cipher
4106 *
4107 * @since 1.2.4
4108 * @ingroup Eet_Connection_Group
4109 */
4110EAPI Eina_Bool
4111eet_connection_send(Eet_Connection *conn,
4112 Eet_Data_Descriptor *edd,
4113 const void *data_in,
4114 const char *cipher_key);
4115
4116/**
4117 * Convert a Eet_Node tree and prepare it to be send.
4118 * @param conn Connection handler to track.
4119 * @param node The data tree to use when encoding.
4120 * @param cipher_key The key to use as cipher.
4121 * @return EINA_TRUE if the data where correctly send, EINA_FALSE if they don't.
4122 *
4123 * This function serialize node, assemble the packet and call
4124 * Eet_Write_Cb when ready. The data passed Eet_Write_Cb are temporary allocated
4125 * and will vanish just after the return of the callback.
4126 *
4127 * @see eet_data_node_encode_cipher
4128 *
4129 * @since 1.2.4
4130 * @ingroup Eet_Connection_Group
4131 */
4132EAPI Eina_Bool
4133eet_connection_node_send(Eet_Connection *conn,
4134 Eet_Node *node,
4135 const char *cipher_key);
4136
4137/**
4138 * Close a connection and lost its track.
4139 * @param conn Connection handler to close.
4140 * @param on_going Signal if a partial packet wasn't completed.
4141 * @return the user_data passed to both callback.
4142 *
4143 * @since 1.2.4
4144 * @ingroup Eet_Connection_Group
4145 */
4146EAPI void *
4147eet_connection_close(Eet_Connection *conn,
4148 Eina_Bool *on_going);
4149
4150/***************************************************************************/
4151
4152#ifdef __cplusplus
4153}
4154#endif /* ifdef __cplusplus */
4155
4156#endif /* ifndef _EET_H */
diff --git a/libraries/eet/src/lib/Eet_private.h b/libraries/eet/src/lib/Eet_private.h
new file mode 100644
index 0000000..83f4c18
--- /dev/null
+++ b/libraries/eet/src/lib/Eet_private.h
@@ -0,0 +1,191 @@
1#ifndef _EET_PRIVATE_H
2#define _EET_PRIVATE_H
3
4#include <Eina.h>
5
6typedef enum _Eet_Convert_Type Eet_Convert_Type;
7
8enum _Eet_Convert_Type
9{
10 EET_D_NOTHING = 0,
11 EET_D_FLOAT = 1 << 1,
12 EET_D_DOUBLE = 1 << 2,
13 EET_D_FIXED_POINT = 1 << 4
14};
15
16typedef struct _Eet_String Eet_String;
17typedef struct _Eet_Convert Eet_Convert;
18
19struct _Eet_Convert
20{
21 float f;
22 double d;
23 Eina_F32p32 fp;
24
25 Eet_Convert_Type type;
26};
27
28struct _Eet_String
29{
30 const char *str;
31
32 int len;
33
34 int next;
35 int prev;
36
37 unsigned char hash;
38 unsigned char allocated : 1;
39};
40struct _Eet_Dictionary
41{
42 Eet_String *all;
43 Eina_Hash *converts;
44
45 int size;
46 int offset;
47
48 int hash[256];
49
50 int count;
51 int total;
52
53 const char *start;
54 const char *end;
55};
56
57struct _Eet_Node
58{
59 int type;
60 int count;
61 const char *name;
62 const char *key;
63 Eet_Node *values;
64 Eet_Node *next;
65 Eet_Node *parent;
66 Eet_Node_Data data;
67};
68
69/*
70 * variable and macros used for the eina_log module
71 */
72extern int _eet_log_dom_global;
73
74/*
75 * Macros that are used everywhere
76 *
77 * the first four macros are the general macros for the lib
78 */
79#ifdef EET_DEFAULT_LOG_COLOR
80# undef EET_DEFAULT_LOG_COLOR
81#endif /* ifdef EET_DEFAULT_LOG_COLOR */
82#define EET_DEFAULT_LOG_COLOR EINA_COLOR_CYAN
83#ifdef ERR
84# undef ERR
85#endif /* ifdef ERR */
86#define ERR(...) EINA_LOG_DOM_ERR(_eet_log_dom_global, __VA_ARGS__)
87#ifdef DBG
88# undef DBG
89#endif /* ifdef DBG */
90#define DBG(...) EINA_LOG_DOM_DBG(_eet_log_dom_global, __VA_ARGS__)
91#ifdef INF
92# undef INF
93#endif /* ifdef INF */
94#define INF(...) EINA_LOG_DOM_INFO(_eet_log_dom_global, __VA_ARGS__)
95#ifdef WRN
96# undef WRN
97#endif /* ifdef WRN */
98#define WRN(...) EINA_LOG_DOM_WARN(_eet_log_dom_global, __VA_ARGS__)
99#ifdef CRIT
100# undef CRIT
101#endif /* ifdef CRIT */
102#define CRIT(...) EINA_LOG_DOM_CRIT(_eet_log_dom_global, __VA_ARGS__)
103
104Eet_Dictionary *
105 eet_dictionary_add(void);
106void
107 eet_dictionary_free(Eet_Dictionary *ed);
108int
109 eet_dictionary_string_add(Eet_Dictionary *ed,
110 const char *string);
111int
112eet_dictionary_string_get_size(const Eet_Dictionary *ed,
113 int index);
114const char *
115eet_dictionary_string_get_char(const Eet_Dictionary *ed,
116 int index);
117Eina_Bool
118eet_dictionary_string_get_float(const Eet_Dictionary *ed,
119 int index,
120 float *result);
121Eina_Bool
122eet_dictionary_string_get_double(const Eet_Dictionary *ed,
123 int index,
124 double *result);
125Eina_Bool
126eet_dictionary_string_get_fp(const Eet_Dictionary *ed,
127 int index,
128 Eina_F32p32 *result);
129int
130eet_dictionary_string_get_hash(const Eet_Dictionary *ed,
131 int index);
132
133int _eet_hash_gen(const char *key,
134 int hash_size);
135
136const void *
137eet_identity_check(const void *data_base,
138 unsigned int data_length,
139 void **sha1,
140 int *sha1_length,
141 const void *signature_base,
142 unsigned int signature_length,
143 const void **raw_signature_base,
144 unsigned int *raw_signature_length,
145 int *x509_length);
146void *
147eet_identity_compute_sha1(const void *data_base,
148 unsigned int data_length,
149 int *sha1_length);
150Eet_Error
151eet_cipher(const void *data,
152 unsigned int size,
153 const char *key,
154 unsigned int length,
155 void **result,
156 unsigned int *result_length);
157Eet_Error
158eet_decipher(const void *data,
159 unsigned int size,
160 const char *key,
161 unsigned int length,
162 void **result,
163 unsigned int *result_length);
164Eet_Error
165eet_identity_sign(FILE *fp,
166 Eet_Key *key);
167void
168 eet_identity_unref(Eet_Key *key);
169void
170 eet_identity_ref(Eet_Key *key);
171
172void
173 eet_node_shutdown(void);
174int
175 eet_node_init(void);
176Eet_Node *
177 eet_node_new(void);
178void
179 eet_node_free(Eet_Node *node);
180
181#ifndef PATH_MAX
182# define PATH_MAX 4096
183#endif /* ifndef PATH_MAX */
184
185#ifdef DNDEBUG
186# define EET_ASSERT(Test, Do) if (Test == 0) {Do; }
187#else /* ifdef DNDEBUG */
188# define EET_ASSERT(Test, Do) if (Test == 0) {abort(); }
189#endif /* ifdef DNDEBUG */
190
191#endif /* ifndef _EET_PRIVATE_H */
diff --git a/libraries/eet/src/lib/Makefile.am b/libraries/eet/src/lib/Makefile.am
new file mode 100644
index 0000000..4633749
--- /dev/null
+++ b/libraries/eet/src/lib/Makefile.am
@@ -0,0 +1,162 @@
1
2MAINTAINERCLEANFILES = Makefile.in
3
4AM_CPPFLAGS = \
5-I. \
6-I$(top_srcdir)/src/lib \
7-I$(top_builddir)/src/lib \
8-DPACKAGE_BIN_DIR=\"$(bindir)\" \
9-DPACKAGE_LIB_DIR=\"$(libdir)\" \
10-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
11@EVIL_CFLAGS@ \
12@EINA_CFLAGS@ \
13@EET_CPPFLAGS@ \
14@EFL_EET_BUILD@ \
15@EFL_COVERAGE_CFLAGS@ \
16@OPENSSL_CFLAGS@ \
17@GNUTLS_CFLAGS@
18
19includes_HEADERS = Eet.h
20includesdir = $(includedir)/eet-@VMAJ@
21
22lib_LTLIBRARIES = libeet.la
23
24base_sources = \
25eet_lib.c \
26eet_data.c \
27eet_image.c \
28eet_cipher.c \
29eet_dictionary.c \
30eet_node.c \
31eet_utils.c \
32eet_connection.c
33
34if EET_AMALGAMATION
35nodist_libeet_la_SOURCES = eet_amalgamation.c
36
37eet_amalgamation.c: $(base_sources) Makefile
38 -rm -f eet_amalgamation.c
39
40 @echo "#ifdef HAVE_CONFIG_H" >> eet_amalgamation.c
41 @echo "# include \"config.h\"" >> eet_amalgamation.c
42 @echo "#endif" >> eet_amalgamation.c
43
44 @echo "#ifdef HAVE_ALLOCA_H" >> eet_amalgamation.c
45 @echo "# include <alloca.h>" >> eet_amalgamation.c
46 @echo "#elif defined __GNUC__" >> eet_amalgamation.c
47 @echo "# define alloca __builtin_alloca" >> eet_amalgamation.c
48 @echo "#elif defined _AIX" >> eet_amalgamation.c
49 @echo "# define alloca __alloca" >> eet_amalgamation.c
50 @echo "#elif defined _MSC_VER" >> eet_amalgamation.c
51 @echo "# include <malloc.h>" >> eet_amalgamation.c
52 @echo "# define alloca _alloca" >> eet_amalgamation.c
53 @echo "#else" >> eet_amalgamation.c
54 @echo "# include <stddef.h>" >> eet_amalgamation.c
55 @echo "# ifdef __cplusplus" >> eet_amalgamation.c
56 @echo "#extern \"C\"" >> eet_amalgamation.c
57 @echo "# endif" >> eet_amalgamation.c
58 @echo "#void *alloca (size_t);" >> eet_amalgamation.c
59 @echo "#endif" >> eet_amalgamation.c
60
61 @echo "#include <stdio.h>" >> eet_amalgamation.c
62 @echo "#include <string.h>" >> eet_amalgamation.c
63 @echo "#include <math.h>" >> eet_amalgamation.c
64 @echo "#include <ctype.h>" >> eet_amalgamation.c
65 @echo "#include <limits.h>" >> eet_amalgamation.c
66 @echo "#include <sys/types.h>" >> eet_amalgamation.c
67 @echo "#include <sys/stat.h>" >> eet_amalgamation.c
68 @echo "#ifdef HAVE_SIGNATURE" >> eet_amalgamation.c
69 @echo "# include <sys/mman.h>" >> eet_amalgamation.c
70 @echo "#endif" >> eet_amalgamation.c
71 @echo "#include <setjmp.h>" >> eet_amalgamation.c
72 @echo "#include <errno.h>" >> eet_amalgamation.c
73 @echo "#include <time.h>" >> eet_amalgamation.c
74 @echo "#include <fnmatch.h>" >> eet_amalgamation.c
75 @echo "#include <fcntl.h>" >> eet_amalgamation.c
76
77 @echo "#ifdef _WIN32" >> eet_amalgamation.c
78 @echo "# include <winsock2.h>" >> eet_amalgamation.c
79 @echo "#endif" >> eet_amalgamation.c
80
81 @echo "#ifndef _MSC_VER" >> eet_amalgamation.c
82 @echo "# include <unistd.h>" >> eet_amalgamation.c
83 @echo "#endif" >> eet_amalgamation.c
84
85 @echo "#ifdef HAVE_NETINET_IN_H" >> eet_amalgamation.c
86 @echo "# include <netinet/in.h>" >> eet_amalgamation.c
87 @echo "#endif" >> eet_amalgamation.c
88
89 @echo "#ifdef HAVE_GNUTLS" >> eet_amalgamation.c
90 @echo "# include <gnutls/gnutls.h>" >> eet_amalgamation.c
91 @echo "# include <gcrypt.h>" >> eet_amalgamation.c
92 @echo "#endif" >> eet_amalgamation.c
93
94 @echo "#ifdef HAVE_OPENSSL" >> eet_amalgamation.c
95 @echo "# include <openssl/err.h>" >> eet_amalgamation.c
96 @echo "# include <openssl/evp.h>" >> eet_amalgamation.c
97 @echo "# include <openssl/sha.h>" >> eet_amalgamation.c
98 @echo "#endif" >> eet_amalgamation.c
99
100 @echo "#ifdef HAVE_SIGNATURE" >> eet_amalgamation.c
101 @echo "# ifdef HAVE_GNUTLS" >> eet_amalgamation.c
102 @echo "# include <gnutls/gnutls.h>" >> eet_amalgamation.c
103 @echo "# include <gnutls/x509.h>" >> eet_amalgamation.c
104 @echo "# else" >> eet_amalgamation.c
105 @echo "# include <openssl/rsa.h>" >> eet_amalgamation.c
106 @echo "# include <openssl/objects.h>" >> eet_amalgamation.c
107 @echo "# include <openssl/err.h>" >> eet_amalgamation.c
108 @echo "# include <openssl/ssl.h>" >> eet_amalgamation.c
109 @echo "# include <openssl/dh.h>" >> eet_amalgamation.c
110 @echo "# include <openssl/dsa.h>" >> eet_amalgamation.c
111 @echo "# include <openssl/evp.h>" >> eet_amalgamation.c
112 @echo "# include <openssl/x509.h>" >> eet_amalgamation.c
113 @echo "# include <openssl/pem.h>" >> eet_amalgamation.c
114 @echo "# endif" >> eet_amalgamation.c
115 @echo "#endif" >> eet_amalgamation.c
116
117 @echo "#ifdef HAVE_CIPHER" >> eet_amalgamation.c
118 @echo "# ifdef HAVE_GNUTLS" >> eet_amalgamation.c
119 @echo "# include <gnutls/x509.h>" >> eet_amalgamation.c
120 @echo "# include <gcrypt.h>" >> eet_amalgamation.c
121 @echo "# else" >> eet_amalgamation.c
122 @echo "# include <openssl/evp.h>" >> eet_amalgamation.c
123 @echo "# include <openssl/hmac.h>" >> eet_amalgamation.c
124 @echo "# include <openssl/rand.h>" >> eet_amalgamation.c
125 @echo "# endif" >> eet_amalgamation.c
126 @echo "#endif" >> eet_amalgamation.c
127
128 @echo "#include <zlib.h>" >> eet_amalgamation.c
129 @echo "#include <jpeglib.h>" >> eet_amalgamation.c
130
131 @echo "#ifdef HAVE_EVIL" >> eet_amalgamation.c
132 @echo "# include <Evil.h>" >> eet_amalgamation.c
133 @echo "#endif" >> eet_amalgamation.c
134
135 @echo "#include <Eet.h>" >> eet_amalgamation.c
136
137 @echo "#include \"Eet_private.h\"" >> eet_amalgamation.c
138 @echo "#include \"Eet.h\"" >> eet_amalgamation.c
139
140 @for f in $(base_sources); do \
141 if [ `echo $$f | sed -e 's/^...\(.\).*/\1/'` != '/' ]; then \
142 file="$(srcdir)/$$f" ; \
143 else \
144 file="$$f" ; \
145 fi ; \
146 echo "/* file: $$file */" >> eet_amalgamation.c; \
147 grep -v -e '^# *include \+.\(config\|\|Evil\|Eina\|stdio\|string\|math\|ctype\|limits\|sys/types\|sys/stat\|sys/mman\|setjmp\|errno\|time\|fnmatch\|fcntl\|winsock2\|unistd\|netinet/in\|gnutls/gnutls\|gcrypt\|gnutls/x509\|openssl/rsa\|openssl/objects\|openssl/err\|openssl/ssl\|openssl/dh\|openssl/dsa\|openssl/evp\|openssl/pem\|openssl/sha\|openssl/hmac\|openssl/x509\|openssl/rand\|zlib\|jpeglib\|Eet_private\|Eet\)[.]h.*' $$file >> eet_amalgamation.c; \
148 done
149 @echo "eet_amalgamation.c generated"
150
151else
152libeet_la_SOURCES = $(base_sources)
153endif
154
155libeet_la_CFLAGS = @EET_CFLAGS@ @DEBUG_CFLAGS@
156libeet_la_LIBADD = @GNUTLS_LIBS@ @OPENSSL_LIBS@ @EFL_COVERAGE_LIBS@ @EET_LIBS@ @EINA_LIBS@ @EVIL_LIBS@ -lz -ljpeg -lm
157libeet_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@
158
159EXTRA_DIST = Eet_private.h
160
161clean-local:
162 @rm -rf *.gcno eet_amalgamation.c
diff --git a/libraries/eet/src/lib/Makefile.in b/libraries/eet/src/lib/Makefile.in
new file mode 100644
index 0000000..f80bcd8
--- /dev/null
+++ b/libraries/eet/src/lib/Makefile.in
@@ -0,0 +1,846 @@
1# Makefile.in generated by automake 1.11.1 from Makefile.am.
2# @configure_input@
3
4# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
5# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
6# Inc.
7# This Makefile.in is free software; the Free Software Foundation
8# gives unlimited permission to copy and/or distribute it,
9# with or without modifications, as long as this notice is preserved.
10
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
13# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
14# PARTICULAR PURPOSE.
15
16@SET_MAKE@
17
18
19VPATH = @srcdir@
20pkgdatadir = $(datadir)/@PACKAGE@
21pkgincludedir = $(includedir)/@PACKAGE@
22pkglibdir = $(libdir)/@PACKAGE@
23pkglibexecdir = $(libexecdir)/@PACKAGE@
24am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
25install_sh_DATA = $(install_sh) -c -m 644
26install_sh_PROGRAM = $(install_sh) -c
27install_sh_SCRIPT = $(install_sh) -c
28INSTALL_HEADER = $(INSTALL_DATA)
29transform = $(program_transform_name)
30NORMAL_INSTALL = :
31PRE_INSTALL = :
32POST_INSTALL = :
33NORMAL_UNINSTALL = :
34PRE_UNINSTALL = :
35POST_UNINSTALL = :
36build_triplet = @build@
37host_triplet = @host@
38subdir = src/lib
39DIST_COMMON = $(includes_HEADERS) $(srcdir)/Makefile.am \
40 $(srcdir)/Makefile.in
41ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
42am__aclocal_m4_deps = $(top_srcdir)/m4/ac_attribute.m4 \
43 $(top_srcdir)/m4/ac_path_generic.m4 \
44 $(top_srcdir)/m4/efl_binary.m4 \
45 $(top_srcdir)/m4/efl_compiler_flag.m4 \
46 $(top_srcdir)/m4/efl_coverage.m4 \
47 $(top_srcdir)/m4/efl_doxygen.m4 \
48 $(top_srcdir)/m4/efl_fnmatch.m4 \
49 $(top_srcdir)/m4/efl_path_max.m4 $(top_srcdir)/m4/efl_tests.m4 \
50 $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
51 $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
52 $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
53am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
54 $(ACLOCAL_M4)
55mkinstalldirs = $(install_sh) -d
56CONFIG_HEADER = $(top_builddir)/config.h
57CONFIG_CLEAN_FILES =
58CONFIG_CLEAN_VPATH_FILES =
59am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
60am__vpath_adj = case $$p in \
61 $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
62 *) f=$$p;; \
63 esac;
64am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
65am__install_max = 40
66am__nobase_strip_setup = \
67 srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
68am__nobase_strip = \
69 for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
70am__nobase_list = $(am__nobase_strip_setup); \
71 for p in $$list; do echo "$$p $$p"; done | \
72 sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
73 $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
74 if (++n[$$2] == $(am__install_max)) \
75 { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
76 END { for (dir in files) print dir, files[dir] }'
77am__base_list = \
78 sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
79 sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
80am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)"
81LTLIBRARIES = $(lib_LTLIBRARIES)
82libeet_la_DEPENDENCIES =
83am__libeet_la_SOURCES_DIST = eet_lib.c eet_data.c eet_image.c \
84 eet_cipher.c eet_dictionary.c eet_node.c eet_utils.c \
85 eet_connection.c
86am__objects_1 = libeet_la-eet_lib.lo libeet_la-eet_data.lo \
87 libeet_la-eet_image.lo libeet_la-eet_cipher.lo \
88 libeet_la-eet_dictionary.lo libeet_la-eet_node.lo \
89 libeet_la-eet_utils.lo libeet_la-eet_connection.lo
90@EET_AMALGAMATION_FALSE@am_libeet_la_OBJECTS = $(am__objects_1)
91@EET_AMALGAMATION_TRUE@nodist_libeet_la_OBJECTS = \
92@EET_AMALGAMATION_TRUE@ libeet_la-eet_amalgamation.lo
93libeet_la_OBJECTS = $(am_libeet_la_OBJECTS) \
94 $(nodist_libeet_la_OBJECTS)
95AM_V_lt = $(am__v_lt_$(V))
96am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
97am__v_lt_0 = --silent
98libeet_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
99 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libeet_la_CFLAGS) \
100 $(CFLAGS) $(libeet_la_LDFLAGS) $(LDFLAGS) -o $@
101DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
102depcomp = $(SHELL) $(top_srcdir)/depcomp
103am__depfiles_maybe = depfiles
104am__mv = mv -f
105COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
106 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
107LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
108 $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
109 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
110 $(AM_CFLAGS) $(CFLAGS)
111AM_V_CC = $(am__v_CC_$(V))
112am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
113am__v_CC_0 = @echo " CC " $@;
114AM_V_at = $(am__v_at_$(V))
115am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
116am__v_at_0 = @
117CCLD = $(CC)
118LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
119 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
120 $(AM_LDFLAGS) $(LDFLAGS) -o $@
121AM_V_CCLD = $(am__v_CCLD_$(V))
122am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
123am__v_CCLD_0 = @echo " CCLD " $@;
124AM_V_GEN = $(am__v_GEN_$(V))
125am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
126am__v_GEN_0 = @echo " GEN " $@;
127SOURCES = $(libeet_la_SOURCES) $(nodist_libeet_la_SOURCES)
128DIST_SOURCES = $(am__libeet_la_SOURCES_DIST)
129HEADERS = $(includes_HEADERS)
130ETAGS = etags
131CTAGS = ctags
132DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
133ACLOCAL = @ACLOCAL@
134ALLOCA = @ALLOCA@
135AMTAR = @AMTAR@
136AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
137AR = @AR@
138AS = @AS@
139AUTOCONF = @AUTOCONF@
140AUTOHEADER = @AUTOHEADER@
141AUTOMAKE = @AUTOMAKE@
142AWK = @AWK@
143CC = @CC@
144CCDEPMODE = @CCDEPMODE@
145CFLAGS = @CFLAGS@
146CHECK_CFLAGS = @CHECK_CFLAGS@
147CHECK_LIBS = @CHECK_LIBS@
148CPP = @CPP@
149CPPFLAGS = @CPPFLAGS@
150CYGPATH_W = @CYGPATH_W@
151DEBUG_CFLAGS = @DEBUG_CFLAGS@
152DEFS = @DEFS@
153DEPDIR = @DEPDIR@
154DLLTOOL = @DLLTOOL@
155DSYMUTIL = @DSYMUTIL@
156DUMPBIN = @DUMPBIN@
157ECHO_C = @ECHO_C@
158ECHO_N = @ECHO_N@
159ECHO_T = @ECHO_T@
160EET_CFLAGS = @EET_CFLAGS@
161EET_CPPFLAGS = @EET_CPPFLAGS@
162EET_LIBS = @EET_LIBS@
163EET_PRG = @EET_PRG@
164EFL_COVERAGE_CFLAGS = @EFL_COVERAGE_CFLAGS@
165EFL_COVERAGE_LIBS = @EFL_COVERAGE_LIBS@
166EFL_EET_BUILD = @EFL_EET_BUILD@
167EFL_FNMATCH_LIBS = @EFL_FNMATCH_LIBS@
168EGREP = @EGREP@
169EINA_CFLAGS = @EINA_CFLAGS@
170EINA_LIBS = @EINA_LIBS@
171EVIL_CFLAGS = @EVIL_CFLAGS@
172EVIL_LIBS = @EVIL_LIBS@
173EXEEXT = @EXEEXT@
174FGREP = @FGREP@
175GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
176GNUTLS_LIBS = @GNUTLS_LIBS@
177GREP = @GREP@
178INSTALL = @INSTALL@
179INSTALL_DATA = @INSTALL_DATA@
180INSTALL_PROGRAM = @INSTALL_PROGRAM@
181INSTALL_SCRIPT = @INSTALL_SCRIPT@
182INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
183LD = @LD@
184LDFLAGS = @LDFLAGS@
185LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
186LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
187LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
188LIBOBJS = @LIBOBJS@
189LIBS = @LIBS@
190LIBTOOL = @LIBTOOL@
191LIPO = @LIPO@
192LN_S = @LN_S@
193LTLIBOBJS = @LTLIBOBJS@
194MAKEINFO = @MAKEINFO@
195MKDIR_P = @MKDIR_P@
196NM = @NM@
197NMEDIT = @NMEDIT@
198OBJDUMP = @OBJDUMP@
199OBJEXT = @OBJEXT@
200OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
201OPENSSL_LIBS = @OPENSSL_LIBS@
202OTOOL = @OTOOL@
203OTOOL64 = @OTOOL64@
204PACKAGE = @PACKAGE@
205PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
206PACKAGE_NAME = @PACKAGE_NAME@
207PACKAGE_STRING = @PACKAGE_STRING@
208PACKAGE_TARNAME = @PACKAGE_TARNAME@
209PACKAGE_URL = @PACKAGE_URL@
210PACKAGE_VERSION = @PACKAGE_VERSION@
211PATH_SEPARATOR = @PATH_SEPARATOR@
212PKG_CONFIG = @PKG_CONFIG@
213PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
214PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
215RANLIB = @RANLIB@
216SED = @SED@
217SET_MAKE = @SET_MAKE@
218SHELL = @SHELL@
219STRIP = @STRIP@
220VERSION = @VERSION@
221VMAJ = @VMAJ@
222abs_builddir = @abs_builddir@
223abs_srcdir = @abs_srcdir@
224abs_top_builddir = @abs_top_builddir@
225abs_top_srcdir = @abs_top_srcdir@
226ac_ct_CC = @ac_ct_CC@
227ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
228am__include = @am__include@
229am__leading_dot = @am__leading_dot@
230am__quote = @am__quote@
231am__tar = @am__tar@
232am__untar = @am__untar@
233bindir = @bindir@
234build = @build@
235build_alias = @build_alias@
236build_cpu = @build_cpu@
237build_os = @build_os@
238build_vendor = @build_vendor@
239builddir = @builddir@
240datadir = @datadir@
241datarootdir = @datarootdir@
242docdir = @docdir@
243dvidir = @dvidir@
244efl_doxygen = @efl_doxygen@
245efl_have_doxygen = @efl_have_doxygen@
246exec_prefix = @exec_prefix@
247have_lcov = @have_lcov@
248host = @host@
249host_alias = @host_alias@
250host_cpu = @host_cpu@
251host_os = @host_os@
252host_vendor = @host_vendor@
253htmldir = @htmldir@
254includedir = @includedir@
255infodir = @infodir@
256install_sh = @install_sh@
257libdir = @libdir@
258libexecdir = @libexecdir@
259localedir = @localedir@
260localstatedir = @localstatedir@
261lt_ECHO = @lt_ECHO@
262lt_enable_auto_import = @lt_enable_auto_import@
263mandir = @mandir@
264mkdir_p = @mkdir_p@
265oldincludedir = @oldincludedir@
266pdfdir = @pdfdir@
267pkgconfig_requires_private = @pkgconfig_requires_private@
268prefix = @prefix@
269program_transform_name = @program_transform_name@
270psdir = @psdir@
271release_info = @release_info@
272requirement_eet = @requirement_eet@
273sbindir = @sbindir@
274sharedstatedir = @sharedstatedir@
275srcdir = @srcdir@
276sysconfdir = @sysconfdir@
277target_alias = @target_alias@
278top_build_prefix = @top_build_prefix@
279top_builddir = @top_builddir@
280top_srcdir = @top_srcdir@
281version_info = @version_info@
282MAINTAINERCLEANFILES = Makefile.in
283AM_CPPFLAGS = \
284-I. \
285-I$(top_srcdir)/src/lib \
286-I$(top_builddir)/src/lib \
287-DPACKAGE_BIN_DIR=\"$(bindir)\" \
288-DPACKAGE_LIB_DIR=\"$(libdir)\" \
289-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
290@EVIL_CFLAGS@ \
291@EINA_CFLAGS@ \
292@EET_CPPFLAGS@ \
293@EFL_EET_BUILD@ \
294@EFL_COVERAGE_CFLAGS@ \
295@OPENSSL_CFLAGS@ \
296@GNUTLS_CFLAGS@
297
298includes_HEADERS = Eet.h
299includesdir = $(includedir)/eet-@VMAJ@
300lib_LTLIBRARIES = libeet.la
301base_sources = \
302eet_lib.c \
303eet_data.c \
304eet_image.c \
305eet_cipher.c \
306eet_dictionary.c \
307eet_node.c \
308eet_utils.c \
309eet_connection.c
310
311@EET_AMALGAMATION_TRUE@nodist_libeet_la_SOURCES = eet_amalgamation.c
312@EET_AMALGAMATION_FALSE@libeet_la_SOURCES = $(base_sources)
313libeet_la_CFLAGS = @EET_CFLAGS@ @DEBUG_CFLAGS@
314libeet_la_LIBADD = @GNUTLS_LIBS@ @OPENSSL_LIBS@ @EFL_COVERAGE_LIBS@ @EET_LIBS@ @EINA_LIBS@ @EVIL_LIBS@ -lz -ljpeg -lm
315libeet_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@ @release_info@
316EXTRA_DIST = Eet_private.h
317all: all-am
318
319.SUFFIXES:
320.SUFFIXES: .c .lo .o .obj
321$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
322 @for dep in $?; do \
323 case '$(am__configure_deps)' in \
324 *$$dep*) \
325 ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
326 && { if test -f $@; then exit 0; else break; fi; }; \
327 exit 1;; \
328 esac; \
329 done; \
330 echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/lib/Makefile'; \
331 $(am__cd) $(top_srcdir) && \
332 $(AUTOMAKE) --gnu src/lib/Makefile
333.PRECIOUS: Makefile
334Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
335 @case '$?' in \
336 *config.status*) \
337 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
338 *) \
339 echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
340 cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
341 esac;
342
343$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
344 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
345
346$(top_srcdir)/configure: $(am__configure_deps)
347 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
348$(ACLOCAL_M4): $(am__aclocal_m4_deps)
349 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
350$(am__aclocal_m4_deps):
351install-libLTLIBRARIES: $(lib_LTLIBRARIES)
352 @$(NORMAL_INSTALL)
353 test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
354 @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
355 list2=; for p in $$list; do \
356 if test -f $$p; then \
357 list2="$$list2 $$p"; \
358 else :; fi; \
359 done; \
360 test -z "$$list2" || { \
361 echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
362 $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
363 }
364
365uninstall-libLTLIBRARIES:
366 @$(NORMAL_UNINSTALL)
367 @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
368 for p in $$list; do \
369 $(am__strip_dir) \
370 echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
371 $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
372 done
373
374clean-libLTLIBRARIES:
375 -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
376 @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
377 dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
378 test "$$dir" != "$$p" || dir=.; \
379 echo "rm -f \"$${dir}/so_locations\""; \
380 rm -f "$${dir}/so_locations"; \
381 done
382libeet.la: $(libeet_la_OBJECTS) $(libeet_la_DEPENDENCIES)
383 $(AM_V_CCLD)$(libeet_la_LINK) -rpath $(libdir) $(libeet_la_OBJECTS) $(libeet_la_LIBADD) $(LIBS)
384
385mostlyclean-compile:
386 -rm -f *.$(OBJEXT)
387
388distclean-compile:
389 -rm -f *.tab.c
390
391@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeet_la-eet_amalgamation.Plo@am__quote@
392@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeet_la-eet_cipher.Plo@am__quote@
393@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeet_la-eet_connection.Plo@am__quote@
394@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeet_la-eet_data.Plo@am__quote@
395@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeet_la-eet_dictionary.Plo@am__quote@
396@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeet_la-eet_image.Plo@am__quote@
397@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeet_la-eet_lib.Plo@am__quote@
398@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeet_la-eet_node.Plo@am__quote@
399@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeet_la-eet_utils.Plo@am__quote@
400
401.c.o:
402@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
403@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
404@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
405@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
406@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
407@am__fastdepCC_FALSE@ $(COMPILE) -c $<
408
409.c.obj:
410@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
411@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
412@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
413@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
414@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
415@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
416
417.c.lo:
418@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
419@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
420@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
421@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
422@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
423@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
424
425libeet_la-eet_lib.lo: eet_lib.c
426@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -MT libeet_la-eet_lib.lo -MD -MP -MF $(DEPDIR)/libeet_la-eet_lib.Tpo -c -o libeet_la-eet_lib.lo `test -f 'eet_lib.c' || echo '$(srcdir)/'`eet_lib.c
427@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeet_la-eet_lib.Tpo $(DEPDIR)/libeet_la-eet_lib.Plo
428@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
429@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eet_lib.c' object='libeet_la-eet_lib.lo' libtool=yes @AMDEPBACKSLASH@
430@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
431@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -c -o libeet_la-eet_lib.lo `test -f 'eet_lib.c' || echo '$(srcdir)/'`eet_lib.c
432
433libeet_la-eet_data.lo: eet_data.c
434@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -MT libeet_la-eet_data.lo -MD -MP -MF $(DEPDIR)/libeet_la-eet_data.Tpo -c -o libeet_la-eet_data.lo `test -f 'eet_data.c' || echo '$(srcdir)/'`eet_data.c
435@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeet_la-eet_data.Tpo $(DEPDIR)/libeet_la-eet_data.Plo
436@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
437@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eet_data.c' object='libeet_la-eet_data.lo' libtool=yes @AMDEPBACKSLASH@
438@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
439@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -c -o libeet_la-eet_data.lo `test -f 'eet_data.c' || echo '$(srcdir)/'`eet_data.c
440
441libeet_la-eet_image.lo: eet_image.c
442@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -MT libeet_la-eet_image.lo -MD -MP -MF $(DEPDIR)/libeet_la-eet_image.Tpo -c -o libeet_la-eet_image.lo `test -f 'eet_image.c' || echo '$(srcdir)/'`eet_image.c
443@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeet_la-eet_image.Tpo $(DEPDIR)/libeet_la-eet_image.Plo
444@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
445@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eet_image.c' object='libeet_la-eet_image.lo' libtool=yes @AMDEPBACKSLASH@
446@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
447@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -c -o libeet_la-eet_image.lo `test -f 'eet_image.c' || echo '$(srcdir)/'`eet_image.c
448
449libeet_la-eet_cipher.lo: eet_cipher.c
450@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -MT libeet_la-eet_cipher.lo -MD -MP -MF $(DEPDIR)/libeet_la-eet_cipher.Tpo -c -o libeet_la-eet_cipher.lo `test -f 'eet_cipher.c' || echo '$(srcdir)/'`eet_cipher.c
451@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeet_la-eet_cipher.Tpo $(DEPDIR)/libeet_la-eet_cipher.Plo
452@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
453@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eet_cipher.c' object='libeet_la-eet_cipher.lo' libtool=yes @AMDEPBACKSLASH@
454@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
455@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -c -o libeet_la-eet_cipher.lo `test -f 'eet_cipher.c' || echo '$(srcdir)/'`eet_cipher.c
456
457libeet_la-eet_dictionary.lo: eet_dictionary.c
458@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -MT libeet_la-eet_dictionary.lo -MD -MP -MF $(DEPDIR)/libeet_la-eet_dictionary.Tpo -c -o libeet_la-eet_dictionary.lo `test -f 'eet_dictionary.c' || echo '$(srcdir)/'`eet_dictionary.c
459@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeet_la-eet_dictionary.Tpo $(DEPDIR)/libeet_la-eet_dictionary.Plo
460@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
461@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eet_dictionary.c' object='libeet_la-eet_dictionary.lo' libtool=yes @AMDEPBACKSLASH@
462@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
463@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -c -o libeet_la-eet_dictionary.lo `test -f 'eet_dictionary.c' || echo '$(srcdir)/'`eet_dictionary.c
464
465libeet_la-eet_node.lo: eet_node.c
466@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -MT libeet_la-eet_node.lo -MD -MP -MF $(DEPDIR)/libeet_la-eet_node.Tpo -c -o libeet_la-eet_node.lo `test -f 'eet_node.c' || echo '$(srcdir)/'`eet_node.c
467@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeet_la-eet_node.Tpo $(DEPDIR)/libeet_la-eet_node.Plo
468@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
469@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eet_node.c' object='libeet_la-eet_node.lo' libtool=yes @AMDEPBACKSLASH@
470@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
471@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -c -o libeet_la-eet_node.lo `test -f 'eet_node.c' || echo '$(srcdir)/'`eet_node.c
472
473libeet_la-eet_utils.lo: eet_utils.c
474@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -MT libeet_la-eet_utils.lo -MD -MP -MF $(DEPDIR)/libeet_la-eet_utils.Tpo -c -o libeet_la-eet_utils.lo `test -f 'eet_utils.c' || echo '$(srcdir)/'`eet_utils.c
475@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeet_la-eet_utils.Tpo $(DEPDIR)/libeet_la-eet_utils.Plo
476@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
477@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eet_utils.c' object='libeet_la-eet_utils.lo' libtool=yes @AMDEPBACKSLASH@
478@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
479@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -c -o libeet_la-eet_utils.lo `test -f 'eet_utils.c' || echo '$(srcdir)/'`eet_utils.c
480
481libeet_la-eet_connection.lo: eet_connection.c
482@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -MT libeet_la-eet_connection.lo -MD -MP -MF $(DEPDIR)/libeet_la-eet_connection.Tpo -c -o libeet_la-eet_connection.lo `test -f 'eet_connection.c' || echo '$(srcdir)/'`eet_connection.c
483@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeet_la-eet_connection.Tpo $(DEPDIR)/libeet_la-eet_connection.Plo
484@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
485@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eet_connection.c' object='libeet_la-eet_connection.lo' libtool=yes @AMDEPBACKSLASH@
486@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
487@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -c -o libeet_la-eet_connection.lo `test -f 'eet_connection.c' || echo '$(srcdir)/'`eet_connection.c
488
489libeet_la-eet_amalgamation.lo: eet_amalgamation.c
490@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -MT libeet_la-eet_amalgamation.lo -MD -MP -MF $(DEPDIR)/libeet_la-eet_amalgamation.Tpo -c -o libeet_la-eet_amalgamation.lo `test -f 'eet_amalgamation.c' || echo '$(srcdir)/'`eet_amalgamation.c
491@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libeet_la-eet_amalgamation.Tpo $(DEPDIR)/libeet_la-eet_amalgamation.Plo
492@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
493@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eet_amalgamation.c' object='libeet_la-eet_amalgamation.lo' libtool=yes @AMDEPBACKSLASH@
494@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
495@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libeet_la_CFLAGS) $(CFLAGS) -c -o libeet_la-eet_amalgamation.lo `test -f 'eet_amalgamation.c' || echo '$(srcdir)/'`eet_amalgamation.c
496
497mostlyclean-libtool:
498 -rm -f *.lo
499
500clean-libtool:
501 -rm -rf .libs _libs
502install-includesHEADERS: $(includes_HEADERS)
503 @$(NORMAL_INSTALL)
504 test -z "$(includesdir)" || $(MKDIR_P) "$(DESTDIR)$(includesdir)"
505 @list='$(includes_HEADERS)'; test -n "$(includesdir)" || list=; \
506 for p in $$list; do \
507 if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
508 echo "$$d$$p"; \
509 done | $(am__base_list) | \
510 while read files; do \
511 echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includesdir)'"; \
512 $(INSTALL_HEADER) $$files "$(DESTDIR)$(includesdir)" || exit $$?; \
513 done
514
515uninstall-includesHEADERS:
516 @$(NORMAL_UNINSTALL)
517 @list='$(includes_HEADERS)'; test -n "$(includesdir)" || list=; \
518 files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
519 test -n "$$files" || exit 0; \
520 echo " ( cd '$(DESTDIR)$(includesdir)' && rm -f" $$files ")"; \
521 cd "$(DESTDIR)$(includesdir)" && rm -f $$files
522
523ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
524 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
525 unique=`for i in $$list; do \
526 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
527 done | \
528 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
529 END { if (nonempty) { for (i in files) print i; }; }'`; \
530 mkid -fID $$unique
531tags: TAGS
532
533TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
534 $(TAGS_FILES) $(LISP)
535 set x; \
536 here=`pwd`; \
537 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
538 unique=`for i in $$list; do \
539 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
540 done | \
541 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
542 END { if (nonempty) { for (i in files) print i; }; }'`; \
543 shift; \
544 if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
545 test -n "$$unique" || unique=$$empty_fix; \
546 if test $$# -gt 0; then \
547 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
548 "$$@" $$unique; \
549 else \
550 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
551 $$unique; \
552 fi; \
553 fi
554ctags: CTAGS
555CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
556 $(TAGS_FILES) $(LISP)
557 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
558 unique=`for i in $$list; do \
559 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
560 done | \
561 $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
562 END { if (nonempty) { for (i in files) print i; }; }'`; \
563 test -z "$(CTAGS_ARGS)$$unique" \
564 || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
565 $$unique
566
567GTAGS:
568 here=`$(am__cd) $(top_builddir) && pwd` \
569 && $(am__cd) $(top_srcdir) \
570 && gtags -i $(GTAGS_ARGS) "$$here"
571
572distclean-tags:
573 -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
574
575distdir: $(DISTFILES)
576 @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
577 topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
578 list='$(DISTFILES)'; \
579 dist_files=`for file in $$list; do echo $$file; done | \
580 sed -e "s|^$$srcdirstrip/||;t" \
581 -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
582 case $$dist_files in \
583 */*) $(MKDIR_P) `echo "$$dist_files" | \
584 sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
585 sort -u` ;; \
586 esac; \
587 for file in $$dist_files; do \
588 if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
589 if test -d $$d/$$file; then \
590 dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
591 if test -d "$(distdir)/$$file"; then \
592 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
593 fi; \
594 if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
595 cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
596 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
597 fi; \
598 cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
599 else \
600 test -f "$(distdir)/$$file" \
601 || cp -p $$d/$$file "$(distdir)/$$file" \
602 || exit 1; \
603 fi; \
604 done
605check-am: all-am
606check: check-am
607all-am: Makefile $(LTLIBRARIES) $(HEADERS)
608installdirs:
609 for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includesdir)"; do \
610 test -z "$$dir" || $(MKDIR_P) "$$dir"; \
611 done
612install: install-am
613install-exec: install-exec-am
614install-data: install-data-am
615uninstall: uninstall-am
616
617install-am: all-am
618 @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
619
620installcheck: installcheck-am
621install-strip:
622 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
623 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
624 `test -z '$(STRIP)' || \
625 echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
626mostlyclean-generic:
627
628clean-generic:
629
630distclean-generic:
631 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
632 -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
633
634maintainer-clean-generic:
635 @echo "This command is intended for maintainers to use"
636 @echo "it deletes files that may require special tools to rebuild."
637 -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
638clean: clean-am
639
640clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \
641 mostlyclean-am
642
643distclean: distclean-am
644 -rm -rf ./$(DEPDIR)
645 -rm -f Makefile
646distclean-am: clean-am distclean-compile distclean-generic \
647 distclean-tags
648
649dvi: dvi-am
650
651dvi-am:
652
653html: html-am
654
655html-am:
656
657info: info-am
658
659info-am:
660
661install-data-am: install-includesHEADERS
662
663install-dvi: install-dvi-am
664
665install-dvi-am:
666
667install-exec-am: install-libLTLIBRARIES
668
669install-html: install-html-am
670
671install-html-am:
672
673install-info: install-info-am
674
675install-info-am:
676
677install-man:
678
679install-pdf: install-pdf-am
680
681install-pdf-am:
682
683install-ps: install-ps-am
684
685install-ps-am:
686
687installcheck-am:
688
689maintainer-clean: maintainer-clean-am
690 -rm -rf ./$(DEPDIR)
691 -rm -f Makefile
692maintainer-clean-am: distclean-am maintainer-clean-generic
693
694mostlyclean: mostlyclean-am
695
696mostlyclean-am: mostlyclean-compile mostlyclean-generic \
697 mostlyclean-libtool
698
699pdf: pdf-am
700
701pdf-am:
702
703ps: ps-am
704
705ps-am:
706
707uninstall-am: uninstall-includesHEADERS uninstall-libLTLIBRARIES
708
709.MAKE: install-am install-strip
710
711.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
712 clean-libLTLIBRARIES clean-libtool clean-local ctags distclean \
713 distclean-compile distclean-generic distclean-libtool \
714 distclean-tags distdir dvi dvi-am html html-am info info-am \
715 install install-am install-data install-data-am install-dvi \
716 install-dvi-am install-exec install-exec-am install-html \
717 install-html-am install-includesHEADERS install-info \
718 install-info-am install-libLTLIBRARIES install-man install-pdf \
719 install-pdf-am install-ps install-ps-am install-strip \
720 installcheck installcheck-am installdirs maintainer-clean \
721 maintainer-clean-generic mostlyclean mostlyclean-compile \
722 mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
723 tags uninstall uninstall-am uninstall-includesHEADERS \
724 uninstall-libLTLIBRARIES
725
726
727@EET_AMALGAMATION_TRUE@eet_amalgamation.c: $(base_sources) Makefile
728@EET_AMALGAMATION_TRUE@ -rm -f eet_amalgamation.c
729
730@EET_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_CONFIG_H" >> eet_amalgamation.c
731@EET_AMALGAMATION_TRUE@ @echo "# include \"config.h\"" >> eet_amalgamation.c
732@EET_AMALGAMATION_TRUE@ @echo "#endif" >> eet_amalgamation.c
733
734@EET_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_ALLOCA_H" >> eet_amalgamation.c
735@EET_AMALGAMATION_TRUE@ @echo "# include <alloca.h>" >> eet_amalgamation.c
736@EET_AMALGAMATION_TRUE@ @echo "#elif defined __GNUC__" >> eet_amalgamation.c
737@EET_AMALGAMATION_TRUE@ @echo "# define alloca __builtin_alloca" >> eet_amalgamation.c
738@EET_AMALGAMATION_TRUE@ @echo "#elif defined _AIX" >> eet_amalgamation.c
739@EET_AMALGAMATION_TRUE@ @echo "# define alloca __alloca" >> eet_amalgamation.c
740@EET_AMALGAMATION_TRUE@ @echo "#elif defined _MSC_VER" >> eet_amalgamation.c
741@EET_AMALGAMATION_TRUE@ @echo "# include <malloc.h>" >> eet_amalgamation.c
742@EET_AMALGAMATION_TRUE@ @echo "# define alloca _alloca" >> eet_amalgamation.c
743@EET_AMALGAMATION_TRUE@ @echo "#else" >> eet_amalgamation.c
744@EET_AMALGAMATION_TRUE@ @echo "# include <stddef.h>" >> eet_amalgamation.c
745@EET_AMALGAMATION_TRUE@ @echo "# ifdef __cplusplus" >> eet_amalgamation.c
746@EET_AMALGAMATION_TRUE@ @echo "#extern \"C\"" >> eet_amalgamation.c
747@EET_AMALGAMATION_TRUE@ @echo "# endif" >> eet_amalgamation.c
748@EET_AMALGAMATION_TRUE@ @echo "#void *alloca (size_t);" >> eet_amalgamation.c
749@EET_AMALGAMATION_TRUE@ @echo "#endif" >> eet_amalgamation.c
750
751@EET_AMALGAMATION_TRUE@ @echo "#include <stdio.h>" >> eet_amalgamation.c
752@EET_AMALGAMATION_TRUE@ @echo "#include <string.h>" >> eet_amalgamation.c
753@EET_AMALGAMATION_TRUE@ @echo "#include <math.h>" >> eet_amalgamation.c
754@EET_AMALGAMATION_TRUE@ @echo "#include <ctype.h>" >> eet_amalgamation.c
755@EET_AMALGAMATION_TRUE@ @echo "#include <limits.h>" >> eet_amalgamation.c
756@EET_AMALGAMATION_TRUE@ @echo "#include <sys/types.h>" >> eet_amalgamation.c
757@EET_AMALGAMATION_TRUE@ @echo "#include <sys/stat.h>" >> eet_amalgamation.c
758@EET_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_SIGNATURE" >> eet_amalgamation.c
759@EET_AMALGAMATION_TRUE@ @echo "# include <sys/mman.h>" >> eet_amalgamation.c
760@EET_AMALGAMATION_TRUE@ @echo "#endif" >> eet_amalgamation.c
761@EET_AMALGAMATION_TRUE@ @echo "#include <setjmp.h>" >> eet_amalgamation.c
762@EET_AMALGAMATION_TRUE@ @echo "#include <errno.h>" >> eet_amalgamation.c
763@EET_AMALGAMATION_TRUE@ @echo "#include <time.h>" >> eet_amalgamation.c
764@EET_AMALGAMATION_TRUE@ @echo "#include <fnmatch.h>" >> eet_amalgamation.c
765@EET_AMALGAMATION_TRUE@ @echo "#include <fcntl.h>" >> eet_amalgamation.c
766
767@EET_AMALGAMATION_TRUE@ @echo "#ifdef _WIN32" >> eet_amalgamation.c
768@EET_AMALGAMATION_TRUE@ @echo "# include <winsock2.h>" >> eet_amalgamation.c
769@EET_AMALGAMATION_TRUE@ @echo "#endif" >> eet_amalgamation.c
770
771@EET_AMALGAMATION_TRUE@ @echo "#ifndef _MSC_VER" >> eet_amalgamation.c
772@EET_AMALGAMATION_TRUE@ @echo "# include <unistd.h>" >> eet_amalgamation.c
773@EET_AMALGAMATION_TRUE@ @echo "#endif" >> eet_amalgamation.c
774
775@EET_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_NETINET_IN_H" >> eet_amalgamation.c
776@EET_AMALGAMATION_TRUE@ @echo "# include <netinet/in.h>" >> eet_amalgamation.c
777@EET_AMALGAMATION_TRUE@ @echo "#endif" >> eet_amalgamation.c
778
779@EET_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_GNUTLS" >> eet_amalgamation.c
780@EET_AMALGAMATION_TRUE@ @echo "# include <gnutls/gnutls.h>" >> eet_amalgamation.c
781@EET_AMALGAMATION_TRUE@ @echo "# include <gcrypt.h>" >> eet_amalgamation.c
782@EET_AMALGAMATION_TRUE@ @echo "#endif" >> eet_amalgamation.c
783
784@EET_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_OPENSSL" >> eet_amalgamation.c
785@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/err.h>" >> eet_amalgamation.c
786@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/evp.h>" >> eet_amalgamation.c
787@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/sha.h>" >> eet_amalgamation.c
788@EET_AMALGAMATION_TRUE@ @echo "#endif" >> eet_amalgamation.c
789
790@EET_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_SIGNATURE" >> eet_amalgamation.c
791@EET_AMALGAMATION_TRUE@ @echo "# ifdef HAVE_GNUTLS" >> eet_amalgamation.c
792@EET_AMALGAMATION_TRUE@ @echo "# include <gnutls/gnutls.h>" >> eet_amalgamation.c
793@EET_AMALGAMATION_TRUE@ @echo "# include <gnutls/x509.h>" >> eet_amalgamation.c
794@EET_AMALGAMATION_TRUE@ @echo "# else" >> eet_amalgamation.c
795@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/rsa.h>" >> eet_amalgamation.c
796@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/objects.h>" >> eet_amalgamation.c
797@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/err.h>" >> eet_amalgamation.c
798@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/ssl.h>" >> eet_amalgamation.c
799@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/dh.h>" >> eet_amalgamation.c
800@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/dsa.h>" >> eet_amalgamation.c
801@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/evp.h>" >> eet_amalgamation.c
802@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/x509.h>" >> eet_amalgamation.c
803@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/pem.h>" >> eet_amalgamation.c
804@EET_AMALGAMATION_TRUE@ @echo "# endif" >> eet_amalgamation.c
805@EET_AMALGAMATION_TRUE@ @echo "#endif" >> eet_amalgamation.c
806
807@EET_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_CIPHER" >> eet_amalgamation.c
808@EET_AMALGAMATION_TRUE@ @echo "# ifdef HAVE_GNUTLS" >> eet_amalgamation.c
809@EET_AMALGAMATION_TRUE@ @echo "# include <gnutls/x509.h>" >> eet_amalgamation.c
810@EET_AMALGAMATION_TRUE@ @echo "# include <gcrypt.h>" >> eet_amalgamation.c
811@EET_AMALGAMATION_TRUE@ @echo "# else" >> eet_amalgamation.c
812@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/evp.h>" >> eet_amalgamation.c
813@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/hmac.h>" >> eet_amalgamation.c
814@EET_AMALGAMATION_TRUE@ @echo "# include <openssl/rand.h>" >> eet_amalgamation.c
815@EET_AMALGAMATION_TRUE@ @echo "# endif" >> eet_amalgamation.c
816@EET_AMALGAMATION_TRUE@ @echo "#endif" >> eet_amalgamation.c
817
818@EET_AMALGAMATION_TRUE@ @echo "#include <zlib.h>" >> eet_amalgamation.c
819@EET_AMALGAMATION_TRUE@ @echo "#include <jpeglib.h>" >> eet_amalgamation.c
820
821@EET_AMALGAMATION_TRUE@ @echo "#ifdef HAVE_EVIL" >> eet_amalgamation.c
822@EET_AMALGAMATION_TRUE@ @echo "# include <Evil.h>" >> eet_amalgamation.c
823@EET_AMALGAMATION_TRUE@ @echo "#endif" >> eet_amalgamation.c
824
825@EET_AMALGAMATION_TRUE@ @echo "#include <Eet.h>" >> eet_amalgamation.c
826
827@EET_AMALGAMATION_TRUE@ @echo "#include \"Eet_private.h\"" >> eet_amalgamation.c
828@EET_AMALGAMATION_TRUE@ @echo "#include \"Eet.h\"" >> eet_amalgamation.c
829
830@EET_AMALGAMATION_TRUE@ @for f in $(base_sources); do \
831@EET_AMALGAMATION_TRUE@ if [ `echo $$f | sed -e 's/^...\(.\).*/\1/'` != '/' ]; then \
832@EET_AMALGAMATION_TRUE@ file="$(srcdir)/$$f" ; \
833@EET_AMALGAMATION_TRUE@ else \
834@EET_AMALGAMATION_TRUE@ file="$$f" ; \
835@EET_AMALGAMATION_TRUE@ fi ; \
836@EET_AMALGAMATION_TRUE@ echo "/* file: $$file */" >> eet_amalgamation.c; \
837@EET_AMALGAMATION_TRUE@ grep -v -e '^# *include \+.\(config\|\|Evil\|Eina\|stdio\|string\|math\|ctype\|limits\|sys/types\|sys/stat\|sys/mman\|setjmp\|errno\|time\|fnmatch\|fcntl\|winsock2\|unistd\|netinet/in\|gnutls/gnutls\|gcrypt\|gnutls/x509\|openssl/rsa\|openssl/objects\|openssl/err\|openssl/ssl\|openssl/dh\|openssl/dsa\|openssl/evp\|openssl/pem\|openssl/sha\|openssl/hmac\|openssl/x509\|openssl/rand\|zlib\|jpeglib\|Eet_private\|Eet\)[.]h.*' $$file >> eet_amalgamation.c; \
838@EET_AMALGAMATION_TRUE@ done
839@EET_AMALGAMATION_TRUE@ @echo "eet_amalgamation.c generated"
840
841clean-local:
842 @rm -rf *.gcno eet_amalgamation.c
843
844# Tell versions [3.59,3.63) of GNU make to not export all variables.
845# Otherwise a system limit (for SysV at least) may be exceeded.
846.NOEXPORT:
diff --git a/libraries/eet/src/lib/eet_cipher.c b/libraries/eet/src/lib/eet_cipher.c
new file mode 100644
index 0000000..89ee65d
--- /dev/null
+++ b/libraries/eet/src/lib/eet_cipher.c
@@ -0,0 +1,1342 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif /* ifdef HAVE_CONFIG_H */
4
5#ifdef HAVE_ALLOCA_H
6# include <alloca.h>
7#elif defined __GNUC__
8# define alloca __builtin_alloca
9#elif defined _AIX
10# define alloca __alloca
11#elif defined _MSC_VER
12# include <malloc.h>
13# define alloca _alloca
14#else /* ifdef HAVE_ALLOCA_H */
15# include <stddef.h>
16# ifdef __cplusplus
17extern "C"
18# endif /* ifdef __cplusplus */
19void *alloca(size_t);
20#endif /* ifdef HAVE_ALLOCA_H */
21
22#include <stdio.h>
23#include <string.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26
27#ifdef HAVE_UNISTD_H
28# include <unistd.h>
29#endif /* ifdef HAVE_UNISTD_H */
30
31#ifdef HAVE_NETINET_IN_H
32# include <netinet/in.h>
33#endif /* ifdef HAVE_NETINET_IN_H */
34
35#ifdef HAVE_SIGNATURE
36# include <sys/mman.h>
37# ifdef HAVE_GNUTLS
38# include <gnutls/gnutls.h>
39# include <gnutls/x509.h>
40# else /* ifdef HAVE_GNUTLS */
41# include <openssl/rsa.h>
42# include <openssl/objects.h>
43# include <openssl/err.h>
44# include <openssl/ssl.h>
45# include <openssl/dh.h>
46# include <openssl/dsa.h>
47# include <openssl/evp.h>
48# include <openssl/x509.h>
49# include <openssl/pem.h>
50# endif /* ifdef HAVE_GNUTLS */
51#endif /* ifdef HAVE_SIGNATURE */
52
53#ifdef HAVE_OPENSSL
54# include <openssl/sha.h>
55#endif /* ifdef HAVE_OPENSSL */
56
57#ifdef HAVE_CIPHER
58# ifdef HAVE_GNUTLS
59# include <gnutls/x509.h>
60# include <gcrypt.h>
61# else /* ifdef HAVE_GNUTLS */
62# include <openssl/evp.h>
63# include <openssl/hmac.h>
64# include <openssl/rand.h>
65# endif /* ifdef HAVE_GNUTLS */
66#endif /* ifdef HAVE_CIPHER */
67
68#include "Eet.h"
69#include "Eet_private.h"
70
71#define EET_MAGIC_SIGN 0x1ee74271
72
73#ifdef HAVE_GNUTLS
74# define MAX_KEY_LEN 32
75# define MAX_IV_LEN 16
76#else /* ifdef HAVE_GNUTLS */
77# define MAX_KEY_LEN EVP_MAX_KEY_LENGTH
78# define MAX_IV_LEN EVP_MAX_IV_LENGTH
79#endif /* ifdef HAVE_GNUTLS */
80
81#ifdef HAVE_CIPHER
82# ifdef HAVE_GNUTLS
83static Eet_Error
84eet_hmac_sha1(const void *key,
85 size_t key_len,
86 const void *data,
87 size_t data_len,
88 unsigned char *res);
89# endif /* ifdef HAVE_GNUTLS */
90static Eet_Error
91eet_pbkdf2_sha1(const char *key,
92 int key_len,
93 const unsigned char *salt,
94 unsigned int salt_len,
95 int iter,
96 unsigned char *res,
97 int res_len);
98#endif /* ifdef HAVE_CIPHER */
99
100struct _Eet_Key
101{
102 int references;
103#ifdef HAVE_SIGNATURE
104# ifdef HAVE_GNUTLS
105 gnutls_x509_crt_t certificate;
106 gnutls_x509_privkey_t private_key;
107# else /* ifdef HAVE_GNUTLS */
108 X509 *certificate;
109 EVP_PKEY *private_key;
110# endif /* ifdef HAVE_GNUTLS */
111#endif /* ifdef HAVE_SIGNATURE */
112};
113
114EAPI Eet_Key *
115eet_identity_open(const char *certificate_file,
116 const char *private_key_file,
117 Eet_Key_Password_Callback cb)
118{
119#ifdef HAVE_SIGNATURE
120 /* Signature declarations */
121 Eet_Key *key = NULL;
122# ifdef HAVE_GNUTLS
123 /* Gnutls private declarations */
124 Eina_File *f = NULL;
125 void *data = NULL;
126 gnutls_datum_t load_file = { NULL, 0 };
127 char pass[1024];
128
129 /* Init */
130 if (!(key = malloc(sizeof(Eet_Key))))
131 goto on_error;
132
133 key->references = 1;
134
135 if (gnutls_x509_crt_init(&(key->certificate)))
136 goto on_error;
137
138 if (gnutls_x509_privkey_init(&(key->private_key)))
139 goto on_error;
140
141 /* Mmap certificate_file */
142 f = eina_file_open(certificate_file, 0);
143 if (!f)
144 goto on_error;
145
146 /* let's make mmap safe and just get 0 pages for IO erro */
147 eina_mmap_safety_enabled_set(EINA_TRUE);
148
149 data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
150 if (!data) goto on_error;
151
152 /* Import the certificate in Eet_Key structure */
153 load_file.data = data;
154 load_file.size = eina_file_size_get(f);
155 if (gnutls_x509_crt_import(key->certificate, &load_file,
156 GNUTLS_X509_FMT_PEM) < 0)
157 goto on_error;
158
159 eina_file_map_free(f, data);
160
161 /* Reset values */
162 eina_file_close(f);
163 f = NULL;
164 data = NULL;
165 load_file.data = NULL;
166 load_file.size = 0;
167
168 /* Mmap private_key_file */
169 f = eina_file_open(private_key_file, 0);
170 if (!f)
171 goto on_error;
172
173 /* let's make mmap safe and just get 0 pages for IO erro */
174 eina_mmap_safety_enabled_set(EINA_TRUE);
175
176 data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
177 if (!data)
178 goto on_error;
179
180 /* Import the private key in Eet_Key structure */
181 load_file.data = data;
182 load_file.size = eina_file_size_get(f);
183 /* Try to directly import the PEM encoded private key */
184 if (gnutls_x509_privkey_import(key->private_key, &load_file,
185 GNUTLS_X509_FMT_PEM) < 0)
186 {
187 /* Else ask for the private key pass */
188 if (cb && cb(pass, 1024, 0, NULL))
189 {
190 /* If pass then try to decode the pkcs 8 private key */
191 if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file,
192 GNUTLS_X509_FMT_PEM, pass, 0))
193 goto on_error;
194 }
195 else
196 /* Else try to import the pkcs 8 private key without pass */
197 if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file,
198 GNUTLS_X509_FMT_PEM, NULL, 1))
199 goto on_error;
200 }
201
202 eina_file_map_free(f, data);
203 eina_file_close(f);
204
205 return key;
206
207on_error:
208 if (data) eina_file_map_free(f, data);
209 if (f) eina_file_close(f);
210
211 if (key)
212 {
213 if (key->certificate)
214 gnutls_x509_crt_deinit(key->certificate);
215
216 if (key->private_key)
217 gnutls_x509_privkey_deinit(key->private_key);
218
219 free(key);
220 }
221
222# else /* ifdef HAVE_GNUTLS */
223 /* Openssl private declarations */
224 FILE *fp;
225 EVP_PKEY *pkey = NULL;
226 X509 *cert = NULL;
227
228 /* Load the X509 certificate in memory. */
229 fp = fopen(certificate_file, "r");
230 if (!fp)
231 return NULL;
232
233 cert = PEM_read_X509(fp, NULL, NULL, NULL);
234 fclose(fp);
235 if (!cert)
236 goto on_error;
237
238 /* Check the presence of the public key. Just in case. */
239 pkey = X509_get_pubkey(cert);
240 if (!pkey)
241 goto on_error;
242
243 /* Load the private key in memory. */
244 fp = fopen(private_key_file, "r");
245 if (!fp)
246 goto on_error;
247
248 pkey = PEM_read_PrivateKey(fp, NULL, cb, NULL);
249 fclose(fp);
250 if (!pkey)
251 goto on_error;
252
253 /* Load the certificate and the private key in Eet_Key structure */
254 key = malloc(sizeof(Eet_Key));
255 if (!key)
256 goto on_error;
257
258 key->references = 1;
259 key->certificate = cert;
260 key->private_key = pkey;
261
262 return key;
263
264on_error:
265 if (cert)
266 X509_free(cert);
267
268 if (pkey)
269 EVP_PKEY_free(pkey);
270
271# endif /* ifdef HAVE_GNUTLS */
272#else
273 certificate_file = NULL;
274 private_key_file = NULL;
275 cb = NULL;
276#endif /* ifdef HAVE_SIGNATURE */
277 return NULL;
278} /* eet_identity_open */
279
280EAPI void
281eet_identity_close(Eet_Key *key)
282{
283#ifdef HAVE_SIGNATURE
284 if (!key || (key->references > 0))
285 return;
286
287# ifdef HAVE_GNUTLS
288 gnutls_x509_crt_deinit(key->certificate);
289 gnutls_x509_privkey_deinit(key->private_key);
290# else /* ifdef HAVE_GNUTLS */
291 X509_free(key->certificate);
292 EVP_PKEY_free(key->private_key);
293# endif /* ifdef HAVE_GNUTLS */
294 free(key);
295#else
296 key = NULL;
297#endif /* ifdef HAVE_SIGNATURE */
298} /* eet_identity_close */
299
300EAPI void
301eet_identity_print(Eet_Key *key,
302 FILE *out)
303{
304#ifdef HAVE_SIGNATURE
305# ifdef HAVE_GNUTLS
306 const char *names[6] = {
307 "Modulus",
308 "Public exponent",
309 "Private exponent",
310 "First prime",
311 "Second prime",
312 "Coefficient"
313 };
314 int err = 0;
315 gnutls_datum_t data = { NULL, 0 };
316 gnutls_datum_t rsa_raw[6];
317 size_t size = 128;
318 char *res = NULL;
319 char buf[33];
320 unsigned int i, j;
321
322 if (!key)
323 return;
324
325 if (key->private_key)
326 {
327 if (gnutls_x509_privkey_export_rsa_raw(key->private_key,
328 rsa_raw + 0, /* Modulus */
329 rsa_raw + 1, /* Public exponent */
330 rsa_raw + 2, /* Private exponent */
331 rsa_raw + 3, /* First prime */
332 rsa_raw + 4, /* Second prime */
333 rsa_raw + 5)) /* Coefficient */
334 goto on_error;
335
336 if (!(res = malloc(size)))
337 goto on_error;
338
339 fprintf(out, "Private Key:\n");
340 buf[32] = '\0';
341
342 for (i = 0; i < 6; i++)
343 {
344 while ((err = gnutls_hex_encode(rsa_raw + i, res, &size)) ==
345 GNUTLS_E_SHORT_MEMORY_BUFFER)
346 {
347 size += 128;
348 if (!(res = realloc(res, size)))
349 goto on_error;
350 }
351 if (err)
352 goto on_error;
353
354 fprintf(out, "\t%s:\n", names[i]);
355 for (j = 0; strlen(res) > j; j += 32)
356 {
357 snprintf(buf, 32, "%s", res + j);
358 fprintf(out, "\t\t%s\n", buf);
359 }
360 }
361 free(res);
362 res = NULL;
363 }
364
365 if (key->certificate)
366 {
367 fprintf(out, "Public certificate:\n");
368 if (gnutls_x509_crt_print(key->certificate, GNUTLS_X509_CRT_FULL,
369 &data))
370 goto on_error;
371
372 fprintf(out, "%s\n", data.data);
373 gnutls_free(data.data);
374 data.data = NULL;
375 }
376
377on_error:
378 if (res)
379 free(res);
380
381 if (data.data)
382 gnutls_free(data.data);
383
384 return;
385# else /* ifdef HAVE_GNUTLS */
386 RSA *rsa;
387 DSA *dsa;
388 DH *dh;
389
390 if (!key)
391 return;
392
393 rsa = EVP_PKEY_get1_RSA(key->private_key);
394 if (rsa)
395 {
396 fprintf(out, "Private key (RSA):\n");
397 RSA_print_fp(out, rsa, 0);
398 }
399
400 dsa = EVP_PKEY_get1_DSA(key->private_key);
401 if (dsa)
402 {
403 fprintf(out, "Private key (DSA):\n");
404 DSA_print_fp(out, dsa, 0);
405 }
406
407 dh = EVP_PKEY_get1_DH(key->private_key);
408 if (dh)
409 {
410 fprintf(out, "Private key (DH):\n");
411 DHparams_print_fp(out, dh);
412 }
413
414 fprintf(out, "Public certificate:\n");
415 X509_print_fp(out, key->certificate);
416# endif /* ifdef HAVE_GNUTLS */
417#else /* ifdef HAVE_SIGNATURE */
418 key = NULL;
419 out = NULL;
420 ERR("You need to compile signature support in EET.");
421#endif /* ifdef HAVE_SIGNATURE */
422} /* eet_identity_print */
423
424void
425eet_identity_ref(Eet_Key *key)
426{
427 if (!key)
428 return;
429
430 key->references++;
431} /* eet_identity_ref */
432
433void
434eet_identity_unref(Eet_Key *key)
435{
436 if (!key)
437 return;
438
439 key->references--;
440 eet_identity_close(key);
441} /* eet_identity_unref */
442
443void *
444eet_identity_compute_sha1(const void *data_base,
445 unsigned int data_length,
446 int *sha1_length)
447{
448 void *result;
449
450#ifdef HAVE_SIGNATURE
451# ifdef HAVE_GNUTLS
452 result = malloc(gcry_md_get_algo_dlen(GCRY_MD_SHA1));
453 if (!result)
454 return NULL;
455
456 gcry_md_hash_buffer(GCRY_MD_SHA1, result, data_base, data_length);
457 if (sha1_length)
458 *sha1_length = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
459
460# else /* ifdef HAVE_GNUTLS */
461# ifdef HAVE_OPENSSL
462 result = malloc(SHA_DIGEST_LENGTH);
463 if (!result)
464 return NULL;
465
466 SHA1(data_base, data_length, result);
467 if (sha1_length)
468 *sha1_length = SHA_DIGEST_LENGTH;
469
470# else /* ifdef HAVE_OPENSSL */
471 result = NULL;
472# endif /* ifdef HAVE_OPENSSL */
473# endif /* ifdef HAVE_GNUTLS */
474#else /* ifdef HAVE_SIGNATURE */
475 data_base = NULL;
476 data_length = 0;
477 sha1_length = NULL;
478 result = NULL;
479#endif /* ifdef HAVE_SIGNATURE */
480
481 return result;
482} /* eet_identity_compute_sha1 */
483
484Eet_Error
485eet_identity_sign(FILE *fp,
486 Eet_Key *key)
487{
488#ifdef HAVE_SIGNATURE
489 Eet_Error err = EET_ERROR_NONE;
490 struct stat st_buf;
491 void *data;
492 int fd;
493 int head[3];
494 unsigned char *sign = NULL;
495 unsigned char *cert = NULL;
496# ifdef HAVE_GNUTLS
497 gnutls_datum_t datum = { NULL, 0 };
498 size_t sign_len = 0;
499 size_t cert_len = 0;
500# else /* ifdef HAVE_GNUTLS */
501 EVP_MD_CTX md_ctx;
502 unsigned int sign_len = 0;
503 int cert_len = 0;
504# endif /* ifdef HAVE_GNUTLS */
505
506 /* A few check and flush pending write. */
507 if (!fp || !key || !key->certificate || !key->private_key)
508 return EET_ERROR_BAD_OBJECT;
509
510 /* Get the file size. */
511 fd = fileno(fp);
512 if (fd < 0)
513 return EET_ERROR_BAD_OBJECT;
514
515 if (fstat(fd, &st_buf) < 0)
516 return EET_ERROR_MMAP_FAILED;
517
518 /* let's make mmap safe and just get 0 pages for IO erro */
519 eina_mmap_safety_enabled_set(EINA_TRUE);
520
521 /* Map the file in memory. */
522 data = mmap(NULL, st_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
523 if (data == MAP_FAILED)
524 return EET_ERROR_MMAP_FAILED;
525
526# ifdef HAVE_GNUTLS
527 datum.data = data;
528 datum.size = st_buf.st_size;
529
530 /* Get the signature length */
531 if (gnutls_x509_privkey_sign_data(key->private_key, GNUTLS_DIG_SHA1, 0,
532 &datum, sign, &sign_len) &&
533 !sign_len)
534 {
535 err = EET_ERROR_SIGNATURE_FAILED;
536 goto on_error;
537 }
538
539 /* Get the signature */
540 sign = malloc(sign_len);
541 if (!sign ||
542 gnutls_x509_privkey_sign_data(key->private_key, GNUTLS_DIG_SHA1, 0,
543 &datum,
544 sign, &sign_len))
545 {
546 if (!sign)
547 err = EET_ERROR_OUT_OF_MEMORY;
548 else
549 err = EET_ERROR_SIGNATURE_FAILED;
550
551 goto on_error;
552 }
553
554 /* Get the certificate length */
555 if (gnutls_x509_crt_export(key->certificate, GNUTLS_X509_FMT_DER, cert,
556 &cert_len) &&
557 !cert_len)
558 {
559 err = EET_ERROR_SIGNATURE_FAILED;
560 goto on_error;
561 }
562
563 /* Get the certificate */
564 cert = malloc(cert_len);
565 if (!cert ||
566 gnutls_x509_crt_export(key->certificate, GNUTLS_X509_FMT_DER, cert,
567 &cert_len))
568 {
569 if (!cert)
570 err = EET_ERROR_OUT_OF_MEMORY;
571 else
572 err = EET_ERROR_SIGNATURE_FAILED;
573
574 goto on_error;
575 }
576
577# else /* ifdef HAVE_GNUTLS */
578 sign_len = EVP_PKEY_size(key->private_key);
579 sign = malloc(sign_len);
580 if (!sign)
581 {
582 err = EET_ERROR_OUT_OF_MEMORY;
583 goto on_error;
584 }
585
586 /* Do the signature. */
587 EVP_SignInit(&md_ctx, EVP_sha1());
588 EVP_SignUpdate(&md_ctx, data, st_buf.st_size);
589 err = EVP_SignFinal(&md_ctx,
590 sign,
591 (unsigned int *)&sign_len,
592 key->private_key);
593 if (err != 1)
594 {
595 ERR_print_errors_fp(stdout);
596 err = EET_ERROR_SIGNATURE_FAILED;
597 goto on_error;
598 }
599
600 /* Give me the der (binary form for X509). */
601 cert_len = i2d_X509(key->certificate, &cert);
602 if (cert_len < 0)
603 {
604 ERR_print_errors_fp(stdout);
605 err = EET_ERROR_X509_ENCODING_FAILED;
606 goto on_error;
607 }
608
609# endif /* ifdef HAVE_GNUTLS */
610 /* Append the signature at the end of the file. */
611 head[0] = (int)htonl ((unsigned int)EET_MAGIC_SIGN);
612 head[1] = (int)htonl ((unsigned int)sign_len);
613 head[2] = (int)htonl ((unsigned int)cert_len);
614
615 if (fwrite(head, sizeof(head), 1, fp) != 1)
616 {
617 err = EET_ERROR_WRITE_ERROR;
618 goto on_error;
619 }
620
621 if (fwrite(sign, sign_len, 1, fp) != 1)
622 {
623 err = EET_ERROR_WRITE_ERROR;
624 goto on_error;
625 }
626
627 if (fwrite(cert, cert_len, 1, fp) != 1)
628 {
629 err = EET_ERROR_WRITE_ERROR;
630 goto on_error;
631 }
632
633on_error:
634# ifdef HAVE_GNUTLS
635 if (cert)
636 free(cert);
637
638# else /* ifdef HAVE_GNUTLS */
639 if (cert)
640 OPENSSL_free(cert);
641
642# endif /* ifdef HAVE_GNUTLS */
643 if (sign)
644 free(sign);
645
646 munmap(data, st_buf.st_size);
647 return err;
648#else /* ifdef HAVE_SIGNATURE */
649 fp = NULL;
650 key = NULL;
651 return EET_ERROR_NOT_IMPLEMENTED;
652#endif /* ifdef HAVE_SIGNATURE */
653} /* eet_identity_sign */
654
655const void *
656eet_identity_check(const void *data_base,
657 unsigned int data_length,
658 void **sha1,
659 int *sha1_length,
660 const void *signature_base,
661 unsigned int signature_length,
662 const void **raw_signature_base,
663 unsigned int *raw_signature_length,
664 int *x509_length)
665{
666#ifdef HAVE_SIGNATURE
667 const int *header = signature_base;
668 const unsigned char *sign;
669 const unsigned char *cert_der;
670 int sign_len;
671 int cert_len;
672 int magic;
673
674 /* At least the header size */
675 if (signature_length < sizeof(int) * 3)
676 return NULL;
677
678 /* Get the header */
679 magic = ntohl(header[0]);
680 sign_len = ntohl(header[1]);
681 cert_len = ntohl(header[2]);
682
683 /* Verify the header */
684 if (magic != EET_MAGIC_SIGN)
685 return NULL;
686
687 if (sign_len + cert_len + sizeof(int) * 3 > signature_length)
688 return NULL;
689
690 /* Update the signature and certificate pointer */
691 sign = (unsigned char *)signature_base + sizeof(int) * 3;
692 cert_der = sign + sign_len;
693
694# ifdef HAVE_GNUTLS
695 gnutls_x509_crt_t cert;
696 gnutls_datum_t datum;
697 gnutls_datum_t signature;
698# if EET_USE_NEW_GNUTLS_API
699 unsigned char *hash;
700 gcry_md_hd_t md;
701 int err;
702# endif /* if EET_USE_NEW_GNUTLS_API */
703
704 /* Create an understanding certificate structure for gnutls */
705 datum.data = (void *)cert_der;
706 datum.size = cert_len;
707 gnutls_x509_crt_init(&cert);
708 gnutls_x509_crt_import(cert, &datum, GNUTLS_X509_FMT_DER);
709
710 signature.data = (void *)sign;
711 signature.size = sign_len;
712
713 /* Verify the signature */
714# if EET_USE_NEW_GNUTLS_API
715 /*
716 I am waiting for my patch being accepted in GnuTLS release.
717 But we now have a way to prevent double computation of SHA1.
718 */
719 err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
720 if (err < 0)
721 return NULL;
722
723 gcry_md_write(md, data_base, data_length);
724
725 hash = gcry_md_read(md, GCRY_MD_SHA1);
726 if (!hash)
727 {
728 gcry_md_close(md);
729 return NULL;
730 }
731
732 datum.size = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
733 datum.data = hash;
734
735 if (!gnutls_x509_crt_verify_hash(cert, 0, &datum, &signature))
736 {
737 gcry_md_close(md);
738 return NULL;
739 }
740
741 if (sha1)
742 {
743 *sha1 = malloc(datum.size);
744 if (!*sha1)
745 {
746 gcry_md_close(md);
747 return NULL;
748 }
749
750 memcpy(*sha1, hash, datum.size);
751 *sha1_length = datum.size;
752 }
753
754 gcry_md_close(md);
755# else /* if EET_USE_NEW_GNUTLS_API */
756 datum.data = (void *)data_base;
757 datum.size = data_length;
758
759 if (!gnutls_x509_crt_verify_data(cert, 0, &datum, &signature))
760 return NULL;
761
762 if (sha1)
763 {
764 *sha1 = NULL;
765 *sha1_length = -1;
766 }
767
768# endif /* if EET_USE_NEW_GNUTLS_API */
769 gnutls_x509_crt_deinit(cert);
770
771# else /* ifdef HAVE_GNUTLS */
772 const unsigned char *tmp;
773 EVP_PKEY *pkey;
774 X509 *x509;
775 EVP_MD_CTX md_ctx;
776 int err;
777
778 /* Strange but d2i_X509 seems to put 0 all over the place. */
779 tmp = alloca(cert_len);
780 memcpy((char *)tmp, cert_der, cert_len);
781 x509 = d2i_X509(NULL, &tmp, cert_len);
782 if (!x509)
783 return NULL;
784
785 /* Get public key - eay */
786 pkey = X509_get_pubkey(x509);
787 if (!pkey)
788 {
789 X509_free(x509);
790 return NULL;
791 }
792
793 /* Verify the signature */
794 EVP_VerifyInit(&md_ctx, EVP_sha1());
795 EVP_VerifyUpdate(&md_ctx, data_base, data_length);
796 err = EVP_VerifyFinal(&md_ctx, sign, sign_len, pkey);
797
798 X509_free(x509);
799 EVP_PKEY_free(pkey);
800
801 if (sha1)
802 {
803 *sha1 = NULL;
804 *sha1_length = -1;
805 }
806
807 if (err != 1)
808 return NULL;
809
810# endif /* ifdef HAVE_GNUTLS */
811 if (x509_length)
812 *x509_length = cert_len;
813
814 if (raw_signature_base)
815 *raw_signature_base = sign;
816
817 if (raw_signature_length)
818 *raw_signature_length = sign_len;
819
820 return cert_der;
821#else /* ifdef HAVE_SIGNATURE */
822 data_base = NULL;
823 data_length = 0;
824 sha1 = NULL;
825 sha1_length = NULL;
826 signature_base = NULL;
827 signature_length = 0;
828 raw_signature_base = NULL;
829 raw_signature_length = NULL;
830 x509_length = NULL;
831 return NULL;
832#endif /* ifdef HAVE_SIGNATURE */
833} /* eet_identity_check */
834
835EAPI void
836eet_identity_certificate_print(const unsigned char *certificate,
837 int der_length,
838 FILE *out)
839{
840#ifdef HAVE_SIGNATURE
841 if (!certificate || !out || der_length <= 0)
842 {
843 ERR("No certificate provided.");
844 return;
845 }
846
847# ifdef HAVE_GNUTLS
848 gnutls_datum_t datum;
849 gnutls_x509_crt_t cert;
850
851 /* Create an understanding certificate structure for gnutls */
852 datum.data = (void *)certificate;
853 datum.size = der_length;
854 if (gnutls_x509_crt_init(&cert))
855 goto on_error;
856
857 if (gnutls_x509_crt_import(cert, &datum, GNUTLS_X509_FMT_DER))
858 goto on_error;
859
860 /* Pretty print the certificate */
861 datum.data = NULL;
862 datum.size = 0;
863 if (gnutls_x509_crt_print(cert, GNUTLS_X509_CRT_FULL, &datum))
864 goto on_error;
865
866 INF("Public certificate :");
867 INF("%s", datum.data);
868
869on_error:
870 if (datum.data)
871 gnutls_free(datum.data);
872
873 gnutls_x509_crt_deinit(cert);
874# else /* ifdef HAVE_GNUTLS */
875 const unsigned char *tmp;
876 X509 *x509;
877
878 /* Strange but d2i_X509 seems to put 0 all over the place. */
879 tmp = alloca(der_length);
880 memcpy((char *)tmp, certificate, der_length);
881 x509 = d2i_X509(NULL, &tmp, der_length);
882 if (!x509)
883 {
884 INF("Not a valid certificate.");
885 return;
886 }
887
888 INF("Public certificate :");
889 X509_print_fp(out, x509);
890
891 X509_free(x509);
892# endif /* ifdef HAVE_GNUTLS */
893#else /* ifdef HAVE_SIGNATURE */
894 certificate = NULL;
895 der_length = 0;
896 out = NULL;
897 ERR("You need to compile signature support in EET.");
898#endif /* ifdef HAVE_SIGNATURE */
899} /* eet_identity_certificate_print */
900
901Eet_Error
902eet_cipher(const void *data,
903 unsigned int size,
904 const char *key,
905 unsigned int length,
906 void **result,
907 unsigned int *result_length)
908{
909#ifdef HAVE_CIPHER
910 /* Cipher declarations */
911 unsigned int *ret = NULL;
912 unsigned char iv[MAX_IV_LEN];
913 unsigned char ik[MAX_KEY_LEN];
914 unsigned char key_material[MAX_IV_LEN + MAX_KEY_LEN];
915 unsigned int salt;
916 unsigned int tmp = 0;
917 int crypted_length;
918 int opened = 0;
919# ifdef HAVE_GNUTLS
920 /* Gcrypt declarations */
921 gcry_error_t err = 0;
922 gcry_cipher_hd_t cipher;
923# else /* ifdef HAVE_GNUTLS */
924 /* Openssl declarations*/
925 EVP_CIPHER_CTX ctx;
926 unsigned int *buffer;
927 int tmp_len;
928# endif /* ifdef HAVE_GNUTLS */
929
930# ifdef HAVE_GNUTLS
931 /* Gcrypt salt generation */
932 gcry_create_nonce((unsigned char *)&salt, sizeof(salt));
933# else /* ifdef HAVE_GNUTLS */
934 /* Openssl salt generation */
935 if (!RAND_bytes((unsigned char *)&salt, sizeof (unsigned int)))
936 return EET_ERROR_PRNG_NOT_SEEDED;
937
938# endif /* ifdef HAVE_GNUTLS */
939
940 eet_pbkdf2_sha1(key,
941 length,
942 (unsigned char *)&salt,
943 sizeof(unsigned int),
944 2048,
945 key_material,
946 MAX_KEY_LEN + MAX_IV_LEN);
947
948 memcpy(iv, key_material, MAX_IV_LEN);
949 memcpy(ik, key_material + MAX_IV_LEN, MAX_KEY_LEN);
950
951 memset(key_material, 0, sizeof (key_material));
952
953 crypted_length = ((((size + sizeof (unsigned int)) >> 5) + 1) << 5);
954 ret = malloc(crypted_length + sizeof(unsigned int));
955 if (!ret)
956 {
957 memset(iv, 0, sizeof (iv));
958 memset(ik, 0, sizeof (ik));
959 memset(&salt, 0, sizeof (salt));
960 return EET_ERROR_OUT_OF_MEMORY;
961 }
962
963 *ret = salt;
964 memset(&salt, 0, sizeof (salt));
965 tmp = htonl(size);
966
967# ifdef HAVE_GNUTLS
968 *(ret + 1) = tmp;
969 memcpy(ret + 2, data, size);
970
971 /* Gcrypt create the corresponding cipher
972 AES with a 256 bit key, Cipher Block Chaining mode */
973 err = gcry_cipher_open(&cipher, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, 0);
974 if (err)
975 goto on_error;
976
977 opened = 1;
978 err = gcry_cipher_setiv(cipher, iv, MAX_IV_LEN);
979 if (err)
980 goto on_error;
981
982 err = gcry_cipher_setkey(cipher, ik, MAX_KEY_LEN);
983 if (err)
984 goto on_error;
985
986 memset(iv, 0, sizeof (iv));
987 memset(ik, 0, sizeof (ik));
988
989 /* Gcrypt encrypt */
990 err = gcry_cipher_encrypt(cipher,
991 (unsigned char *)(ret + 1),
992 crypted_length,
993 NULL,
994 0);
995 if (err)
996 goto on_error;
997
998 /* Gcrypt close the cipher */
999 gcry_cipher_close(cipher);
1000# else /* ifdef HAVE_GNUTLS */
1001 buffer = alloca(crypted_length);
1002 *buffer = tmp;
1003
1004 memcpy(buffer + 1, data, size);
1005
1006 /* Openssl create the corresponding cipher
1007 AES with a 256 bit key, Cipher Block Chaining mode */
1008 EVP_CIPHER_CTX_init(&ctx);
1009 if (!EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, ik, iv))
1010 goto on_error;
1011
1012 opened = 1;
1013
1014 memset(iv, 0, sizeof (iv));
1015 memset(ik, 0, sizeof (ik));
1016
1017 /* Openssl encrypt */
1018 if (!EVP_EncryptUpdate(&ctx, (unsigned char *)(ret + 1), &tmp_len,
1019 (unsigned char *)buffer,
1020 size + sizeof(unsigned int)))
1021 goto on_error;
1022
1023 /* Openssl close the cipher */
1024 if (!EVP_EncryptFinal_ex(&ctx, ((unsigned char *)(ret + 1)) + tmp_len,
1025 &tmp_len))
1026 goto on_error;
1027
1028 EVP_CIPHER_CTX_cleanup(&ctx);
1029# endif /* ifdef HAVE_GNUTLS */
1030
1031 /* Set return values */
1032 if (result_length)
1033 *result_length = crypted_length + sizeof(unsigned int);
1034
1035 if (result)
1036 *result = ret;
1037 else
1038 free(ret);
1039
1040 return EET_ERROR_NONE;
1041
1042on_error:
1043 memset(iv, 0, sizeof (iv));
1044 memset(ik, 0, sizeof (ik));
1045
1046# ifdef HAVE_GNUTLS
1047 /* Gcrypt error */
1048 if (opened)
1049 gcry_cipher_close(cipher);
1050
1051# else /* ifdef HAVE_GNUTLS */
1052 /* Openssl error */
1053 if (opened)
1054 EVP_CIPHER_CTX_cleanup(&ctx);
1055
1056# endif /* ifdef HAVE_GNUTLS */
1057 /* General error */
1058 free(ret);
1059 if (result)
1060 *result = NULL;
1061
1062 if (result_length)
1063 *result_length = 0;
1064
1065 return EET_ERROR_ENCRYPT_FAILED;
1066#else /* ifdef HAVE_CIPHER */
1067 /* Cipher not supported */
1068 (void)data;
1069 (void)size;
1070 (void)key;
1071 (void)length;
1072 (void)result;
1073 (void)result_length;
1074 return EET_ERROR_NOT_IMPLEMENTED;
1075#endif /* ifdef HAVE_CIPHER */
1076} /* eet_cipher */
1077
1078Eet_Error
1079eet_decipher(const void *data,
1080 unsigned int size,
1081 const char *key,
1082 unsigned int length,
1083 void **result,
1084 unsigned int *result_length)
1085{
1086#ifdef HAVE_CIPHER
1087 const unsigned int *over = data;
1088 unsigned int *ret = NULL;
1089 unsigned char ik[MAX_KEY_LEN];
1090 unsigned char iv[MAX_IV_LEN];
1091 unsigned char key_material[MAX_KEY_LEN + MAX_IV_LEN];
1092 unsigned int salt;
1093 int tmp_len;
1094 int tmp = 0;
1095
1096 /* At least the salt and an AES block */
1097 if (size < sizeof(unsigned int) + 16)
1098 return EET_ERROR_BAD_OBJECT;
1099
1100 /* Get the salt */
1101 salt = *over;
1102
1103 /* Generate the iv and the key with the salt */
1104 eet_pbkdf2_sha1(key, length, (unsigned char *)&salt,
1105 sizeof(unsigned int), 2048, key_material,
1106 MAX_KEY_LEN + MAX_IV_LEN);
1107
1108 memcpy(iv, key_material, MAX_IV_LEN);
1109 memcpy(ik, key_material + MAX_IV_LEN, MAX_KEY_LEN);
1110
1111 memset(key_material, 0, sizeof (key_material));
1112 memset(&salt, 0, sizeof (salt));
1113
1114 /* Align to AES block size if size is not align */
1115 tmp_len = size - sizeof (unsigned int);
1116 if ((tmp_len & 0x1F) != 0)
1117 goto on_error;
1118
1119 ret = malloc(tmp_len);
1120 if (!ret)
1121 goto on_error;
1122
1123# ifdef HAVE_GNUTLS
1124 gcry_error_t err = 0;
1125 gcry_cipher_hd_t cipher;
1126
1127 /* Gcrypt create the corresponding cipher */
1128 err = gcry_cipher_open(&cipher, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, 0);
1129 if (err)
1130 return EET_ERROR_DECRYPT_FAILED;
1131
1132 err = gcry_cipher_setiv(cipher, iv, MAX_IV_LEN);
1133 if (err)
1134 goto on_error;
1135
1136 err = gcry_cipher_setkey(cipher, ik, MAX_KEY_LEN);
1137 if (err)
1138 goto on_error;
1139
1140 memset(iv, 0, sizeof (iv));
1141 memset(ik, 0, sizeof (ik));
1142
1143 /* Gcrypt decrypt */
1144 err = gcry_cipher_decrypt(cipher, ret, tmp_len,
1145 ((unsigned int *)data) + 1, tmp_len);
1146 if (err)
1147 goto on_error;
1148
1149 /* Gcrypt close the cipher */
1150 gcry_cipher_close(cipher);
1151
1152# else /* ifdef HAVE_GNUTLS */
1153 EVP_CIPHER_CTX ctx;
1154 int opened = 0;
1155
1156 /* Openssl create the corresponding cipher */
1157 EVP_CIPHER_CTX_init(&ctx);
1158 opened = 1;
1159
1160 if (!EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, ik, iv))
1161 goto on_error;
1162
1163 memset(iv, 0, sizeof (iv));
1164 memset(ik, 0, sizeof (ik));
1165
1166 /* Openssl decrypt */
1167 if (!EVP_DecryptUpdate(&ctx, (unsigned char *)ret, &tmp,
1168 (unsigned char *)(over + 1), tmp_len))
1169 goto on_error;
1170
1171 /* Openssl close the cipher*/
1172 EVP_CIPHER_CTX_cleanup(&ctx);
1173# endif /* ifdef HAVE_GNUTLS */
1174 /* Get the decrypted data size */
1175 tmp = *ret;
1176 tmp = ntohl(tmp);
1177 if (tmp > tmp_len)
1178 goto on_error;
1179
1180 /* Update the return values */
1181 if (result_length)
1182 *result_length = tmp;
1183
1184 if (result)
1185 {
1186 *result = NULL;
1187 *result = malloc(tmp);
1188 if (!*result)
1189 goto on_error;
1190
1191 memcpy(*result, ret + 1, tmp);
1192 }
1193
1194 free(ret);
1195
1196 return EET_ERROR_NONE;
1197
1198on_error:
1199 memset(iv, 0, sizeof (iv));
1200 memset(ik, 0, sizeof (ik));
1201
1202# ifdef HAVE_GNUTLS
1203# else
1204 if (opened)
1205 EVP_CIPHER_CTX_cleanup(&ctx);
1206
1207# endif /* ifdef HAVE_GNUTLS */
1208 if (result)
1209 *result = NULL;
1210
1211 if (result_length)
1212 *result_length = 0;
1213
1214 if (ret)
1215 free(ret);
1216
1217 return EET_ERROR_DECRYPT_FAILED;
1218#else /* ifdef HAVE_CIPHER */
1219 (void)data;
1220 (void)size;
1221 (void)key;
1222 (void)length;
1223 (void)result;
1224 (void)result_length;
1225 return EET_ERROR_NOT_IMPLEMENTED;
1226#endif /* ifdef HAVE_CIPHER */
1227} /* eet_decipher */
1228
1229#ifdef HAVE_CIPHER
1230# ifdef HAVE_GNUTLS
1231static Eet_Error
1232eet_hmac_sha1(const void *key,
1233 size_t key_len,
1234 const void *data,
1235 size_t data_len,
1236 unsigned char *res)
1237{
1238 size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
1239 gcry_md_hd_t mdh;
1240 unsigned char *hash;
1241 gpg_error_t err;
1242
1243 err = gcry_md_open(&mdh, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
1244 if (err != GPG_ERR_NO_ERROR)
1245 return 1;
1246
1247 err = gcry_md_setkey(mdh, key, key_len);
1248 if (err != GPG_ERR_NO_ERROR)
1249 {
1250 gcry_md_close(mdh);
1251 return 1;
1252 }
1253
1254 gcry_md_write(mdh, data, data_len);
1255
1256 hash = gcry_md_read(mdh, GCRY_MD_SHA1);
1257 if (!hash)
1258 {
1259 gcry_md_close(mdh);
1260 return 1;
1261 }
1262
1263 memcpy(res, hash, hlen);
1264
1265 gcry_md_close(mdh);
1266
1267 return 0;
1268} /* eet_hmac_sha1 */
1269
1270# endif /* ifdef HAVE_GNUTLS */
1271
1272static Eet_Error
1273eet_pbkdf2_sha1(const char *key,
1274 int key_len,
1275 const unsigned char *salt,
1276 unsigned int salt_len,
1277 int iter,
1278 unsigned char *res,
1279 int res_len)
1280{
1281 unsigned char digest[20];
1282 unsigned char tab[4];
1283 unsigned char *p = res;
1284 unsigned char *buf;
1285 unsigned long i;
1286 int digest_len = 20;
1287 int len = res_len;
1288 int tmp_len;
1289 int j, k;
1290# ifdef HAVE_GNUTLS
1291# else
1292 HMAC_CTX hctx;
1293# endif /* ifdef HAVE_GNUTLS */
1294
1295 buf = alloca(salt_len + 4);
1296 if (!buf)
1297 return 1;
1298
1299 for (i = 1; len; len -= tmp_len, p += tmp_len, i++)
1300 {
1301 if (len > digest_len)
1302 tmp_len = digest_len;
1303 else
1304 tmp_len = len;
1305
1306 tab[0] = (unsigned char)(i & 0xff000000) >> 24;
1307 tab[1] = (unsigned char)(i & 0x00ff0000) >> 16;
1308 tab[2] = (unsigned char)(i & 0x0000ff00) >> 8;
1309 tab[3] = (unsigned char)(i & 0x000000ff) >> 0;
1310
1311# ifdef HAVE_GNUTLS
1312 memcpy(buf, salt, salt_len);
1313 memcpy(buf + salt_len, tab, 4);
1314 eet_hmac_sha1(key, key_len, buf, salt_len + 4, digest);
1315# else /* ifdef HAVE_GNUTLS */
1316 HMAC_Init(&hctx, key, key_len, EVP_sha1());
1317 HMAC_Update(&hctx, salt, salt_len);
1318 HMAC_Update(&hctx, tab, 4);
1319 HMAC_Final(&hctx, digest, NULL);
1320# endif /* ifdef HAVE_GNUTLS */
1321 memcpy(p, digest, tmp_len);
1322
1323 for (j = 1; j < iter; j++)
1324 {
1325# ifdef HAVE_GNUTLS
1326 eet_hmac_sha1(key, key_len, digest, 20, digest);
1327# else /* ifdef HAVE_GNUTLS */
1328 HMAC(EVP_sha1(), key, key_len, digest, 20, digest, NULL);
1329# endif /* ifdef HAVE_GNUTLS */
1330 for (k = 0; k < tmp_len; k++)
1331 p[k] ^= digest[k];
1332 }
1333 }
1334
1335# ifdef HAVE_GNUTLS
1336# else
1337 HMAC_cleanup(&hctx);
1338# endif /* ifdef HAVE_GNUTLS */
1339 return 0;
1340} /* eet_pbkdf2_sha1 */
1341
1342#endif /* ifdef HAVE_CIPHER */
diff --git a/libraries/eet/src/lib/eet_connection.c b/libraries/eet/src/lib/eet_connection.c
new file mode 100644
index 0000000..6171b7e
--- /dev/null
+++ b/libraries/eet/src/lib/eet_connection.c
@@ -0,0 +1,249 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif /* ifdef HAVE_CONFIG_H */
4
5#ifdef HAVE_ALLOCA_H
6# include <alloca.h>
7#elif defined __GNUC__
8# define alloca __builtin_alloca
9#elif defined _AIX
10# define alloca __alloca
11#elif defined _MSC_VER
12# include <malloc.h>
13# define alloca _alloca
14#else /* ifdef HAVE_ALLOCA_H */
15# include <stddef.h>
16# ifdef __cplusplus
17extern "C"
18# endif /* ifdef __cplusplus */
19void *alloca(size_t);
20#endif /* ifdef HAVE_ALLOCA_H */
21
22#include <string.h>
23#include <stdlib.h>
24
25#ifdef HAVE_NETINET_IN_H
26# include <netinet/in.h>
27#endif /* ifdef HAVE_NETINET_IN_H */
28
29#ifdef _WIN32
30# include <winsock2.h>
31#endif /* ifdef _WIN32 */
32
33#include <Eina.h>
34
35#include "Eet.h"
36#include "Eet_private.h"
37
38#define MAGIC_EET_DATA_PACKET 0x4270ACE1
39
40struct _Eet_Connection
41{
42 Eet_Read_Cb *eet_read_cb;
43 Eet_Write_Cb *eet_write_cb;
44 void *user_data;
45
46 size_t allocated;
47 size_t size;
48 size_t received;
49
50 void *buffer;
51};
52
53EAPI Eet_Connection *
54eet_connection_new(Eet_Read_Cb *eet_read_cb,
55 Eet_Write_Cb *eet_write_cb,
56 const void *user_data)
57{
58 Eet_Connection *conn;
59
60 if (!eet_read_cb || !eet_write_cb)
61 return NULL;
62
63 conn = calloc(1, sizeof (Eet_Connection));
64 if (!conn)
65 return NULL;
66
67 conn->eet_read_cb = eet_read_cb;
68 conn->eet_write_cb = eet_write_cb;
69 conn->user_data = (void *)user_data;
70
71 return conn;
72} /* eet_connection_new */
73
74EAPI int
75eet_connection_received(Eet_Connection *conn,
76 const void *data,
77 size_t size)
78{
79 if ((!conn) || (!data) || (!size))
80 return size;
81
82 do {
83 size_t copy_size;
84
85 if (conn->size == 0)
86 {
87 const int *msg;
88 size_t packet_size;
89
90 if (size < sizeof (int) * 2)
91 break;
92
93 msg = data;
94 /* Check the magic */
95 if (ntohl(msg[0]) != MAGIC_EET_DATA_PACKET)
96 break;
97
98 packet_size = ntohl(msg[1]);
99 /* Message should always be under 64K */
100 if (packet_size > 64 * 1024)
101 break;
102
103 data = (void *)(msg + 2);
104 size -= sizeof (int) * 2;
105 if ((size_t)packet_size <= size)
106 {
107 /* Not a partial receive, go the quick way. */
108 if (!conn->eet_read_cb(data, packet_size, conn->user_data))
109 break;
110
111 data = (void *)((char *)data + packet_size);
112 size -= packet_size;
113
114 conn->received = 0;
115 continue;
116 }
117
118 conn->size = packet_size;
119 if (conn->allocated < conn->size)
120 {
121 void *tmp;
122
123 tmp = realloc(conn->buffer, conn->size);
124 if (!tmp)
125 break;
126
127 conn->buffer = tmp;
128 conn->allocated = conn->size;
129 }
130 }
131
132 /* Partial receive */
133 copy_size =
134 (conn->size - conn->received >=
135 size) ? size : conn->size - conn->received;
136 memcpy((char *)conn->buffer + conn->received, data, copy_size);
137
138 conn->received += copy_size;
139 data = (void *)((char *)data + copy_size);
140 size -= copy_size;
141
142 if (conn->received == conn->size)
143 {
144 size_t data_size;
145
146 data_size = conn->size;
147 conn->size = 0;
148 conn->received = 0;
149
150 /* Completed a packet. */
151 if (!conn->eet_read_cb(conn->buffer, data_size, conn->user_data))
152 {
153 /* Something goes wrong. Stop now. */
154 size += data_size;
155 break;
156 }
157 }
158 } while (size > 0);
159
160 return size;
161} /* eet_connection_received */
162
163static Eina_Bool
164_eet_connection_raw_send(Eet_Connection *conn,
165 void *data,
166 int data_size)
167{
168 int *message;
169
170 /* Message should never be above 64K */
171 if (data_size > 64 * 1024)
172 return EINA_FALSE;
173
174 message = alloca(data_size + sizeof (int) * 2);
175 message[0] = htonl(MAGIC_EET_DATA_PACKET);
176 message[1] = htonl(data_size);
177
178 memcpy(message + 2, data, data_size);
179
180 conn->eet_write_cb(message,
181 data_size + sizeof (int) * 2,
182 conn->user_data);
183 return EINA_TRUE;
184} /* _eet_connection_raw_send */
185
186EAPI Eina_Bool
187eet_connection_send(Eet_Connection *conn,
188 Eet_Data_Descriptor *edd,
189 const void *data_in,
190 const char *cipher_key)
191{
192 void *flat_data;
193 int data_size;
194 Eina_Bool ret = EINA_FALSE;
195
196 flat_data = eet_data_descriptor_encode_cipher(edd,
197 data_in,
198 cipher_key,
199 &data_size);
200 if (!flat_data)
201 return EINA_FALSE;
202
203 if (_eet_connection_raw_send(conn, flat_data, data_size))
204 ret = EINA_TRUE;
205
206 free(flat_data);
207 return ret;
208} /* eet_connection_send */
209
210EAPI Eina_Bool
211eet_connection_node_send(Eet_Connection *conn,
212 Eet_Node *node,
213 const char *cipher_key)
214{
215 void *data;
216 int data_size;
217 Eina_Bool ret = EINA_FALSE;
218
219 data = eet_data_node_encode_cipher(node, cipher_key, &data_size);
220 if (!data)
221 return EINA_FALSE;
222
223 if (_eet_connection_raw_send(conn, data, data_size))
224 ret = EINA_TRUE;
225
226 free(data);
227 return ret;
228} /* eet_connection_node_send */
229
230EAPI void *
231eet_connection_close(Eet_Connection *conn,
232 Eina_Bool *on_going)
233{
234 void *user_data;
235
236 if (!conn)
237 return NULL;
238
239 if (on_going)
240 *on_going = conn->received == 0 ? EINA_FALSE : EINA_TRUE;
241
242 user_data = conn->user_data;
243
244 free(conn->buffer);
245 free(conn);
246
247 return user_data;
248} /* eet_connection_close */
249
diff --git a/libraries/eet/src/lib/eet_data.c b/libraries/eet/src/lib/eet_data.c
new file mode 100644
index 0000000..23b0b97
--- /dev/null
+++ b/libraries/eet/src/lib/eet_data.c
@@ -0,0 +1,4999 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif /* ifdef HAVE_CONFIG_H */
4
5#include <stdio.h>
6#include <string.h>
7#include <math.h>
8#include <ctype.h>
9#include <limits.h>
10
11#ifdef HAVE_NETINET_IN_H
12# include <netinet/in.h>
13#endif /* ifdef HAVE_NETINET_IN_H */
14
15#ifdef _WIN32
16# include <winsock2.h>
17#endif /* ifdef _WIN32 */
18
19#include <Eina.h>
20
21#include "Eet.h"
22#include "Eet_private.h"
23
24#ifdef _WIN32
25# define FMT_CHAR "%c"
26# define FMT_UCHAR "%c"
27# define FMT_LONG_LONG "%I64i"
28# define FMT_ULONG_LONG "%I64u"
29#else
30# define FMT_CHAR "%hhi"
31# define FMT_UCHAR "%hhu"
32# define FMT_LONG_LONG "%lli"
33# define FMT_ULONG_LONG "%llu"
34#endif
35
36/*
37 * routines for doing data -> struct and struct -> data conversion
38 *
39 * types:
40 *
41 * basic types:
42 * a sequence of...
43 *
44 * char
45 * short
46 * int
47 * long long
48 * float
49 * double
50 * unsigned char
51 * unsigned short
52 * unsigned int
53 * unsgined long long
54 * string
55 *
56 * groupings:
57 * multiple entries ordered as...
58 *
59 * fixed size array [ of basic types ]
60 * variable size array [ of basic types ]
61 * linked list [ of basic types ]
62 * hash table [ of basic types ]
63 *
64 * need to provide builder/accessor funcs for:
65 *
66 * list_next
67 * list_append
68 *
69 * hash_foreach
70 * hash_add
71 *
72 */
73
74/*---*/
75
76typedef struct _Eet_Data_Element Eet_Data_Element;
77typedef struct _Eet_Data_Basic_Type_Codec Eet_Data_Basic_Type_Codec;
78typedef struct _Eet_Data_Group_Type_Codec Eet_Data_Group_Type_Codec;
79typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
80typedef struct _Eet_Data_Stream Eet_Data_Stream;
81typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash;
82typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info;
83typedef struct _Eet_Free Eet_Free;
84typedef struct _Eet_Free_Context Eet_Free_Context;
85typedef struct _Eet_Variant_Unknow Eet_Variant_Unknow;
86
87/*---*/
88
89/* TODO:
90 * Eet_Data_Basic_Type_Codec (Coder, Decoder)
91 * Eet_Data_Group_Type_Codec (Coder, Decoder)
92 */
93struct _Eet_Data_Basic_Type_Codec
94{
95 int size;
96 const char *name;
97 int (*get)(const Eet_Dictionary *ed,
98 const void *src,
99 const void *src_end,
100 void *dest);
101 void * (*put)(Eet_Dictionary *ed, const void *src, int *size_ret);
102};
103
104struct _Eet_Data_Group_Type_Codec
105{
106 int (*get)(Eet_Free_Context *context,
107 const Eet_Dictionary *ed,
108 Eet_Data_Descriptor *edd,
109 Eet_Data_Element *ede,
110 Eet_Data_Chunk *echnk,
111 int type,
112 int group_type,
113 void *data_in,
114 char **p,
115 int *size);
116 void (*put)(Eet_Dictionary *ed,
117 Eet_Data_Descriptor *edd,
118 Eet_Data_Element *ede,
119 Eet_Data_Stream *ds,
120 void *data_in);
121};
122
123struct _Eet_Data_Chunk
124{
125 char *name;
126 int len;
127 int size;
128 int hash;
129 void *data;
130 unsigned char type;
131 unsigned char group_type;
132};
133
134struct _Eet_Data_Stream
135{
136 void *data;
137 int size;
138 int pos;
139};
140
141struct _Eet_Data_Descriptor_Hash
142{
143 Eet_Data_Element *element;
144 Eet_Data_Descriptor_Hash *next;
145};
146
147struct _Eet_Data_Descriptor
148{
149 const char *name;
150 const Eet_Dictionary *ed;
151 int size;
152 struct
153 {
154 void * (*mem_alloc)(size_t size);
155 void (*mem_free)(void *mem);
156 char * (*str_alloc)(const char *str);
157 char * (*str_direct_alloc)(const char *str);
158 void (*str_free)(const char *str);
159 void (*str_direct_free)(const char *str);
160 void * (*list_next)(void *l);
161 void * (*list_append)(void *l, void *d);
162 void * (*list_data)(void *l);
163 void * (*list_free)(void *l);
164 void (*hash_foreach)(void *h,
165 int (*func)(void *h,
166 const char *k,
167 void *dt,
168 void *fdt),
169 void *fdt);
170 void * (*hash_add)(void *h, const char *k, void *d);
171 void (*hash_free)(void *h);
172 const char *(*type_get)(const void *data, Eina_Bool *unknow);
173 Eina_Bool (*type_set)(const char *type,
174 void *data,
175 Eina_Bool unknow);
176 void * (*array_alloc)(size_t size);
177 void (*array_free)(void *mem);
178 } func;
179 struct
180 {
181 int num;
182 Eet_Data_Element *set;
183 struct
184 {
185 int size;
186 Eet_Data_Descriptor_Hash *buckets;
187 } hash;
188 } elements;
189
190 Eina_Bool unified_type : 1;
191// char *strings;
192// int strings_len;
193};
194
195struct _Eet_Data_Element
196{
197 const char *name;
198 const char *counter_name;
199 const char *directory_name_ptr;
200 Eet_Data_Descriptor *subtype;
201 int offset; /* offset in bytes from the base element */
202 int count; /* number of elements for a fixed array */
203 int counter_offset; /* for a variable array we need the offset of the count variable */
204 unsigned char type; /* EET_T_XXX */
205 unsigned char group_type; /* EET_G_XXX */
206};
207
208struct _Eet_Data_Encode_Hash_Info
209{
210 Eet_Data_Stream *ds;
211 Eet_Data_Element *ede;
212 Eet_Dictionary *ed;
213};
214
215#define EET_FREE_COUNT 256
216struct _Eet_Free
217{
218 int ref;
219 Eina_Array list[EET_FREE_COUNT];
220};
221
222struct _Eet_Free_Context
223{
224 Eet_Free freelist;
225 Eet_Free freelist_array;
226 Eet_Free freelist_list;
227 Eet_Free freelist_hash;
228 Eet_Free freelist_str;
229 Eet_Free freelist_direct_str;
230};
231
232struct _Eet_Variant_Unknow
233{
234 EINA_MAGIC
235
236 int size;
237 char data[1];
238};
239
240/*---*/
241
242static void
243 eet_free_context_init(Eet_Free_Context *context);
244static void
245 eet_free_context_shutdown(Eet_Free_Context *context);
246
247static int
248eet_data_get_char(const Eet_Dictionary *ed,
249 const void *src,
250 const void *src_end,
251 void *dest);
252static void *
253eet_data_put_char(Eet_Dictionary *ed,
254 const void *src,
255 int *size_ret);
256static int
257eet_data_get_short(const Eet_Dictionary *ed,
258 const void *src,
259 const void *src_end,
260 void *dest);
261static void *
262eet_data_put_short(Eet_Dictionary *ed,
263 const void *src,
264 int *size_ret);
265static inline int
266eet_data_get_int(const Eet_Dictionary *ed,
267 const void *src,
268 const void *src_end,
269 void *dest);
270static void *
271eet_data_put_int(Eet_Dictionary *ed,
272 const void *src,
273 int *size_ret);
274static int
275eet_data_get_long_long(const Eet_Dictionary *ed,
276 const void *src,
277 const void *src_end,
278 void *dest);
279static void *
280eet_data_put_long_long(Eet_Dictionary *ed,
281 const void *src,
282 int *size_ret);
283static int
284eet_data_get_float(const Eet_Dictionary *ed,
285 const void *src,
286 const void *src_end,
287 void *dest);
288static void *
289eet_data_put_float(Eet_Dictionary *ed,
290 const void *src,
291 int *size_ret);
292static int
293eet_data_get_double(const Eet_Dictionary *ed,
294 const void *src,
295 const void *src_end,
296 void *dest);
297static void *
298eet_data_put_double(Eet_Dictionary *ed,
299 const void *src,
300 int *size_ret);
301static int
302eet_data_get_f32p32(const Eet_Dictionary *ed,
303 const void *src,
304 const void *src_end,
305 void *dest);
306static void *
307eet_data_put_f32p32(Eet_Dictionary *ed,
308 const void *src,
309 int *size_ret);
310static int
311eet_data_get_f16p16(const Eet_Dictionary *ed,
312 const void *src,
313 const void *src_end,
314 void *dest);
315static void *
316eet_data_put_f16p16(Eet_Dictionary *ed,
317 const void *src,
318 int *size_ret);
319static int
320eet_data_get_f8p24(const Eet_Dictionary *ed,
321 const void *src,
322 const void *src_end,
323 void *dest);
324static void *
325eet_data_put_f8p24(Eet_Dictionary *ed,
326 const void *src,
327 int *size_ret);
328static inline int
329eet_data_get_string(const Eet_Dictionary *ed,
330 const void *src,
331 const void *src_end,
332 void *dest);
333static void *
334eet_data_put_string(Eet_Dictionary *ed,
335 const void *src,
336 int *size_ret);
337static int
338eet_data_get_istring(const Eet_Dictionary *ed,
339 const void *src,
340 const void *src_end,
341 void *dest);
342static void *
343eet_data_put_istring(Eet_Dictionary *ed,
344 const void *src,
345 int *size_ret);
346static int
347eet_data_get_null(const Eet_Dictionary *ed,
348 const void *src,
349 const void *src_end,
350 void *dest);
351static void *
352eet_data_put_null(Eet_Dictionary *ed,
353 const void *src,
354 int *size_ret);
355
356static int
357eet_data_get_type(const Eet_Dictionary *ed,
358 int type,
359 const void *src,
360 const void *src_end,
361 void *dest);
362static void *
363eet_data_put_type(Eet_Dictionary *ed,
364 int type,
365 const void *src,
366 int *size_ret);
367
368static Eet_Node *
369eet_data_node_simple_type(int type,
370 const char *name,
371 void *dd);
372
373static int
374eet_data_get_unknown(Eet_Free_Context *context,
375 const Eet_Dictionary *ed,
376 Eet_Data_Descriptor *edd,
377 Eet_Data_Element *ede,
378 Eet_Data_Chunk *echnk,
379 int type,
380 int group_type,
381 void *data_in,
382 char **p,
383 int *size);
384static void
385eet_data_put_unknown(Eet_Dictionary *ed,
386 Eet_Data_Descriptor *edd,
387 Eet_Data_Element *ede,
388 Eet_Data_Stream *ds,
389 void *data_in);
390static void
391eet_data_put_array(Eet_Dictionary *ed,
392 Eet_Data_Descriptor *edd,
393 Eet_Data_Element *ede,
394 Eet_Data_Stream *ds,
395 void *data_in);
396static int
397eet_data_get_array(Eet_Free_Context *context,
398 const Eet_Dictionary *ed,
399 Eet_Data_Descriptor *edd,
400 Eet_Data_Element *ede,
401 Eet_Data_Chunk *echnk,
402 int type,
403 int group_type,
404 void *data,
405 char **p,
406 int *size);
407static int
408eet_data_get_list(Eet_Free_Context *context,
409 const Eet_Dictionary *ed,
410 Eet_Data_Descriptor *edd,
411 Eet_Data_Element *ede,
412 Eet_Data_Chunk *echnk,
413 int type,
414 int group_type,
415 void *data_in,
416 char **p,
417 int *size);
418static void
419eet_data_put_list(Eet_Dictionary *ed,
420 Eet_Data_Descriptor *edd,
421 Eet_Data_Element *ede,
422 Eet_Data_Stream *ds,
423 void *data_in);
424static void
425eet_data_put_hash(Eet_Dictionary *ed,
426 Eet_Data_Descriptor *edd,
427 Eet_Data_Element *ede,
428 Eet_Data_Stream *ds,
429 void *data_in);
430static int
431eet_data_get_hash(Eet_Free_Context *context,
432 const Eet_Dictionary *ed,
433 Eet_Data_Descriptor *edd,
434 Eet_Data_Element *ede,
435 Eet_Data_Chunk *echnk,
436 int type,
437 int group_type,
438 void *data,
439 char **p,
440 int *size);
441static void
442eet_data_put_union(Eet_Dictionary *ed,
443 Eet_Data_Descriptor *edd,
444 Eet_Data_Element *ede,
445 Eet_Data_Stream *ds,
446 void *data_in);
447static int
448eet_data_get_union(Eet_Free_Context *context,
449 const Eet_Dictionary *ed,
450 Eet_Data_Descriptor *edd,
451 Eet_Data_Element *ede,
452 Eet_Data_Chunk *echnk,
453 int type,
454 int group_type,
455 void *data,
456 char **p,
457 int *size);
458static void
459eet_data_put_variant(Eet_Dictionary *ed,
460 Eet_Data_Descriptor *edd,
461 Eet_Data_Element *ede,
462 Eet_Data_Stream *ds,
463 void *data_in);
464static int
465eet_data_get_variant(Eet_Free_Context *context,
466 const Eet_Dictionary *ed,
467 Eet_Data_Descriptor *edd,
468 Eet_Data_Element *ede,
469 Eet_Data_Chunk *echnk,
470 int type,
471 int group_type,
472 void *data,
473 char **p,
474 int *size);
475
476static void
477eet_data_chunk_get(const Eet_Dictionary *ed,
478 Eet_Data_Chunk *chnk,
479 const void *src,
480 int size);
481static Eet_Data_Chunk *
482eet_data_chunk_new(void *data,
483 int size,
484 const char *name,
485 int type,
486 int group_type);
487static void
488eet_data_chunk_free(Eet_Data_Chunk *chnk);
489
490static Eet_Data_Stream *
491 eet_data_stream_new(void);
492static void
493 eet_data_stream_write(Eet_Data_Stream *ds,
494 const void *data,
495 int size);
496static void
497eet_data_stream_free(Eet_Data_Stream *ds);
498
499static void
500eet_data_chunk_put(Eet_Dictionary *ed,
501 Eet_Data_Chunk *chnk,
502 Eet_Data_Stream *ds);
503
504static int
505eet_data_descriptor_encode_hash_cb(void *hash,
506 const char *key,
507 void *hdata,
508 void *fdata);
509static void *_eet_data_descriptor_encode(Eet_Dictionary *ed,
510 Eet_Data_Descriptor *edd,
511 const void *data_in,
512 int *size_ret);
513static void *_eet_data_descriptor_decode(Eet_Free_Context *context,
514 const Eet_Dictionary *ed,
515 Eet_Data_Descriptor *edd,
516 const void *data_in,
517 int size_in,
518 void *data_out,
519 int size_out);
520
521/*---*/
522
523static const Eet_Data_Basic_Type_Codec eet_basic_codec[] =
524{
525 {sizeof(char), "char", eet_data_get_char, eet_data_put_char },
526 {sizeof(short), "short", eet_data_get_short, eet_data_put_short },
527 {sizeof(int), "int", eet_data_get_int, eet_data_put_int },
528 {sizeof(long long), "long_long", eet_data_get_long_long, eet_data_put_long_long},
529 {sizeof(float), "float", eet_data_get_float, eet_data_put_float },
530 {sizeof(double), "double", eet_data_get_double, eet_data_put_double },
531 {sizeof(char), "uchar", eet_data_get_char, eet_data_put_char },
532 {sizeof(short), "ushort", eet_data_get_short, eet_data_put_short },
533 {sizeof(int), "uint", eet_data_get_int, eet_data_put_int },
534 {sizeof(long long), "ulong_long", eet_data_get_long_long, eet_data_put_long_long},
535 {sizeof(char *), "string", eet_data_get_string, eet_data_put_string },
536 {sizeof(char *), "inlined", eet_data_get_istring, eet_data_put_istring },
537 {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null },
538 {sizeof(Eina_F32p32), "f32p32", eet_data_get_f32p32, eet_data_put_f32p32 },
539 {sizeof(Eina_F16p16), "f16p16", eet_data_get_f16p16, eet_data_put_f16p16 },
540 {sizeof(Eina_F8p24), "f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }
541};
542
543static const Eet_Data_Group_Type_Codec eet_group_codec[] =
544{
545 { eet_data_get_unknown, eet_data_put_unknown },
546 { eet_data_get_array, eet_data_put_array },
547 { eet_data_get_array, eet_data_put_array },
548 { eet_data_get_list, eet_data_put_list },
549 { eet_data_get_hash, eet_data_put_hash },
550 { eet_data_get_union, eet_data_put_union },
551 { eet_data_get_variant, eet_data_put_variant }
552};
553
554static int _eet_data_words_bigendian = -1;
555
556/*---*/
557
558#define SWAP64(x) (x) = \
559 ((((unsigned long long)(x) & 0x00000000000000ffULL) << 56) | \
560 (((unsigned long long)(x) & 0x000000000000ff00ULL) << 40) | \
561 (((unsigned long long)(x) & 0x0000000000ff0000ULL) << 24) | \
562 (((unsigned long long)(x) & 0x00000000ff000000ULL) << 8) | \
563 (((unsigned long long)(x) & 0x000000ff00000000ULL) >> 8) | \
564 (((unsigned long long)(x) & 0x0000ff0000000000ULL) >> 24) | \
565 (((unsigned long long)(x) & 0x00ff000000000000ULL) >> 40) | \
566 (((unsigned long long)(x) & 0xff00000000000000ULL) >> 56))
567#define SWAP32(x) (x) = \
568 ((((int)(x) & 0x000000ff) << 24) | \
569 (((int)(x) & 0x0000ff00) << 8) | \
570 (((int)(x) & 0x00ff0000) >> 8) | \
571 (((int)(x) & 0xff000000) >> 24))
572#define SWAP16(x) (x) = \
573 ((((short)(x) & 0x00ff) << 8) | \
574 (((short)(x) & 0xff00) >> 8))
575
576#ifdef CONV8
577# undef CONV8
578#endif /* ifdef CONV8 */
579#ifdef CONV16
580# undef CONV16
581#endif /* ifdef CONV16 */
582#ifdef CONV32
583# undef CONV32
584#endif /* ifdef CONV32 */
585#ifdef CONV64
586# undef CONV64
587#endif /* ifdef CONV64 */
588
589#define CONV8(x)
590#define CONV16(x) {if (_eet_data_words_bigendian) {SWAP16(x); }}
591#define CONV32(x) {if (_eet_data_words_bigendian) {SWAP32(x); }}
592#define CONV64(x) {if (_eet_data_words_bigendian) {SWAP64(x); }}
593
594#define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST)
595#define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL)
596
597#define POINTER_TYPE_DECODE(Context, \
598 Ed, \
599 Edd, \
600 Ede, \
601 Echnk, \
602 Type, \
603 Data, \
604 P, \
605 Size, \
606 Label) \
607 do { \
608 int ___r; \
609 ___r = eet_data_get_unknown(Context, \
610 Ed, \
611 Edd, Ede, \
612 Echnk, \
613 Type, EET_G_UNKNOWN, \
614 Data, P, Size); \
615 if (!___r) { goto Label; } \
616 } while (0)
617
618#define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, SubSize, Label) \
619 do { \
620 Data_Ret = _eet_data_descriptor_decode(Context, \
621 Ed, \
622 Ede, \
623 Data, \
624 Size, \
625 SubSize > 0 ? Data_Ret : NULL, \
626 SubSize); \
627 if (!Data_Ret) { goto Label; } \
628 } while (0)
629
630#define EET_I_STRING 1 << 4
631#define EET_I_INLINED_STRING 2 << 4
632#define EET_I_NULL 3 << 4
633
634#define EET_MAGIC_VARIANT 0xF1234BC
635/*---*/
636
637/* CHAR TYPE */
638static int
639eet_data_get_char(const Eet_Dictionary *ed __UNUSED__,
640 const void *src,
641 const void *src_end,
642 void *dst)
643{
644 char *s, *d;
645
646 if (((char *)src + sizeof(char)) > (char *)src_end)
647 return -1;
648
649 s = (char *)src;
650 d = (char *)dst;
651 *d = *s;
652 CONV8(*d);
653 return sizeof(char);
654} /* eet_data_get_char */
655
656static void *
657eet_data_put_char(Eet_Dictionary *ed __UNUSED__,
658 const void *src,
659 int *size_ret)
660{
661 char *s, *d;
662
663 d = (char *)malloc(sizeof(char));
664 if (!d)
665 return NULL;
666
667 s = (char *)src;
668 *d = *s;
669 CONV8(*d);
670 *size_ret = sizeof(char);
671 return d;
672} /* eet_data_put_char */
673
674/* SHORT TYPE */
675static int
676eet_data_get_short(const Eet_Dictionary *ed __UNUSED__,
677 const void *src,
678 const void *src_end,
679 void *dst)
680{
681 short *d;
682
683 if (((char *)src + sizeof(short)) > (char *)src_end)
684 return -1;
685
686 memcpy(dst, src, sizeof(short));
687 d = (short *)dst;
688 CONV16(*d);
689 return sizeof(short);
690} /* eet_data_get_short */
691
692static void *
693eet_data_put_short(Eet_Dictionary *ed __UNUSED__,
694 const void *src,
695 int *size_ret)
696{
697 short *s, *d;
698
699 d = (short *)malloc(sizeof(short));
700 if (!d)
701 return NULL;
702
703 s = (short *)src;
704 *d = *s;
705 CONV16(*d);
706 *size_ret = sizeof(short);
707 return d;
708} /* eet_data_put_short */
709
710/* INT TYPE */
711static inline int
712eet_data_get_int(const Eet_Dictionary *ed __UNUSED__,
713 const void *src,
714 const void *src_end,
715 void *dst)
716{
717 int *d;
718
719 if (((char *)src + sizeof(int)) > (char *)src_end)
720 return -1;
721
722 memcpy(dst, src, sizeof(int));
723 d = (int *)dst;
724 CONV32(*d);
725 return sizeof(int);
726} /* eet_data_get_int */
727
728static void *
729eet_data_put_int(Eet_Dictionary *ed __UNUSED__,
730 const void *src,
731 int *size_ret)
732{
733 int *s, *d;
734
735 d = (int *)malloc(sizeof(int));
736 if (!d)
737 return NULL;
738
739 s = (int *)src;
740 *d = *s;
741 CONV32(*d);
742 *size_ret = sizeof(int);
743 return d;
744} /* eet_data_put_int */
745
746/* LONG LONG TYPE */
747static int
748eet_data_get_long_long(const Eet_Dictionary *ed __UNUSED__,
749 const void *src,
750 const void *src_end,
751 void *dst)
752{
753 unsigned long long *d;
754
755 if (((char *)src + sizeof(unsigned long long)) > (char *)src_end)
756 return -1;
757
758 memcpy(dst, src, sizeof(unsigned long long));
759 d = (unsigned long long *)dst;
760 CONV64(*d);
761 return sizeof(unsigned long long);
762} /* eet_data_get_long_long */
763
764static void *
765eet_data_put_long_long(Eet_Dictionary *ed __UNUSED__,
766 const void *src,
767 int *size_ret)
768{
769 unsigned long long *s, *d;
770
771 d = (unsigned long long *)malloc(sizeof(unsigned long long));
772 if (!d)
773 return NULL;
774
775 s = (unsigned long long *)src;
776 *d = *s;
777 CONV64(*d);
778 *size_ret = sizeof(unsigned long long);
779 return d;
780} /* eet_data_put_long_long */
781
782/* STRING TYPE */
783static inline int
784eet_data_get_string_hash(const Eet_Dictionary *ed,
785 const void *src,
786 const void *src_end)
787{
788 if (ed)
789 {
790 int idx;
791
792 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
793 return -1;
794
795 return eet_dictionary_string_get_hash(ed, idx);
796 }
797
798 return -1;
799} /* eet_data_get_string_hash */
800
801static inline int
802eet_data_get_string(const Eet_Dictionary *ed,
803 const void *src,
804 const void *src_end,
805 void *dst)
806{
807 char *s, **d;
808
809 d = (char **)dst;
810
811 if (ed)
812 {
813 const char *str;
814 int idx;
815
816 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
817 return -1;
818
819 str = eet_dictionary_string_get_char(ed, idx);
820 if (!str)
821 return -1;
822
823 *d = (char *)str;
824 return eet_dictionary_string_get_size(ed, idx);
825 }
826
827 s = (char *)src;
828 if (!s)
829 {
830 *d = NULL;
831 return 0;
832 }
833
834 *d = s;
835 return strlen(s) + 1;
836} /* eet_data_get_string */
837
838static void *
839eet_data_put_string(Eet_Dictionary *ed,
840 const void *src,
841 int *size_ret)
842{
843 char *s, *d;
844 int len;
845
846 if (ed)
847 {
848 const char *str;
849 int idx;
850
851 str = *((const char **)src);
852 if (!str)
853 return NULL;
854
855 idx = eet_dictionary_string_add(ed, str);
856 if (idx == -1)
857 return NULL;
858
859 return eet_data_put_int(ed, &idx, size_ret);
860 }
861
862 s = (char *)(*((char **)src));
863 if (!s)
864 return NULL;
865
866 len = strlen(s);
867 d = malloc(len + 1);
868 if (!d)
869 return NULL;
870
871 memcpy(d, s, len + 1);
872 *size_ret = len + 1;
873 return d;
874} /* eet_data_put_string */
875
876/* ALWAYS INLINED STRING TYPE */
877static int
878eet_data_get_istring(const Eet_Dictionary *ed __UNUSED__,
879 const void *src,
880 const void *src_end,
881 void *dst)
882{
883 return eet_data_get_string(NULL, src, src_end, dst);
884} /* eet_data_get_istring */
885
886static void *
887eet_data_put_istring(Eet_Dictionary *ed __UNUSED__,
888 const void *src,
889 int *size_ret)
890{
891 return eet_data_put_string(NULL, src, size_ret);
892} /* eet_data_put_istring */
893
894/* ALWAYS NULL TYPE */
895static int
896eet_data_get_null(const Eet_Dictionary *ed __UNUSED__,
897 const void *src __UNUSED__,
898 const void *src_end __UNUSED__,
899 void *dst)
900{
901 char **d;
902
903 d = (char **)dst;
904
905 *d = NULL;
906 return 1;
907} /* eet_data_get_null */
908
909static void *
910eet_data_put_null(Eet_Dictionary *ed __UNUSED__,
911 const void *src __UNUSED__,
912 int *size_ret)
913{
914 *size_ret = 0;
915 return NULL;
916} /* eet_data_put_null */
917
918/**
919 * Fast lookups of simple doubles/floats.
920 *
921 * These aren't properly a cache because they don't store pre-calculated
922 * values, but have a so simple math that is almost as fast.
923 */
924static inline int
925_eet_data_float_cache_get(const char *s,
926 int len,
927 float *d)
928{
929 /* fast handle of simple case 0xMp+E*/
930 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
931 {
932 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
933 int exponent = (s[5] - '0');
934
935 if (s[4] == '+')
936 *d = (float)(mantisse << exponent);
937 else
938 *d = (float)mantisse / (float)(1 << exponent);
939
940 return 1;
941 }
942
943 return 0;
944} /* _eet_data_float_cache_get */
945
946static inline int
947_eet_data_double_cache_get(const char *s,
948 int len,
949 double *d)
950{
951 /* fast handle of simple case 0xMp+E*/
952 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
953 {
954 int mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
955 int exponent = (s[5] - '0');
956
957 if (s[4] == '+')
958 *d = (double)(mantisse << exponent);
959 else
960 *d = (double)mantisse / (double)(1 << exponent);
961
962 return 1;
963 }
964
965 return 0;
966} /* _eet_data_double_cache_get */
967
968/* FLOAT TYPE */
969static int
970eet_data_get_float(const Eet_Dictionary *ed,
971 const void *src,
972 const void *src_end,
973 void *dst)
974{
975 float *d;
976 int idx;
977
978 d = (float *)dst;
979 if (!ed)
980 {
981 const char *s, *p;
982 long long mantisse;
983 long exponent;
984 int len;
985
986 s = (const char *)src;
987 p = s;
988 len = 0;
989 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
990
991 if (_eet_data_float_cache_get(s, len, d) != 0)
992 return len + 1;
993
994 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
995 return -1;
996
997 *d = (float)ldexp((double)mantisse, exponent);
998
999 return len + 1;
1000 }
1001
1002 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1003 return -1;
1004
1005 if (!eet_dictionary_string_get_float(ed, idx, d))
1006 return -1;
1007
1008 return 1;
1009} /* eet_data_get_float */
1010
1011static void *
1012eet_data_put_float(Eet_Dictionary *ed,
1013 const void *src,
1014 int *size_ret)
1015{
1016 char buf[128];
1017 int idx;
1018
1019 eina_convert_dtoa((double)(*(float *)src), buf);
1020
1021 if (!ed)
1022 {
1023 char *d;
1024 int len;
1025
1026 len = strlen(buf);
1027 d = malloc(len + 1);
1028 if (!d)
1029 return NULL;
1030
1031 memcpy(d, buf, len + 1);
1032 *size_ret = len + 1;
1033 return d;
1034 }
1035
1036 idx = eet_dictionary_string_add(ed, buf);
1037 if (idx == -1)
1038 return NULL;
1039
1040 return eet_data_put_int(ed, &idx, size_ret);
1041} /* eet_data_put_float */
1042
1043/* DOUBLE TYPE */
1044static int
1045eet_data_get_double(const Eet_Dictionary *ed,
1046 const void *src,
1047 const void *src_end,
1048 void *dst)
1049{
1050 double *d;
1051 int idx;
1052
1053 d = (double *)dst;
1054
1055 if (!ed)
1056 {
1057 const char *s, *p;
1058 long long mantisse = 0;
1059 long exponent = 0;
1060 int len;
1061
1062 s = (const char *)src;
1063 p = s;
1064 len = 0;
1065 while ((p < (const char *)src_end) && (*p != 0)) {len++; p++; }
1066
1067 if (_eet_data_double_cache_get(s, len, d) != 0)
1068 return len + 1;
1069
1070 if (eina_convert_atod(s, len, &mantisse, &exponent) == EINA_FALSE)
1071 return -1;
1072
1073 *d = ldexp((double)mantisse, exponent);
1074
1075 return len + 1;
1076 }
1077
1078 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1079 return -1;
1080
1081 if (!eet_dictionary_string_get_double(ed, idx, d))
1082 return -1;
1083
1084 return 1;
1085} /* eet_data_get_double */
1086
1087static void *
1088eet_data_put_double(Eet_Dictionary *ed,
1089 const void *src,
1090 int *size_ret)
1091{
1092 char buf[128];
1093 int idx;
1094
1095 eina_convert_dtoa((double)(*(double *)src), buf);
1096
1097 if (!ed)
1098 {
1099 char *d;
1100 int len;
1101
1102 len = strlen(buf);
1103 d = malloc(len + 1);
1104 if (!d)
1105 return NULL;
1106
1107 memcpy(d, buf, len + 1);
1108 *size_ret = len + 1;
1109
1110 return d;
1111 }
1112
1113 idx = eet_dictionary_string_add(ed, buf);
1114 if (idx == -1)
1115 return NULL;
1116
1117 return eet_data_put_int(ed, &idx, size_ret);
1118} /* eet_data_put_double */
1119
1120static int
1121eet_data_get_f32p32(const Eet_Dictionary *ed,
1122 const void *src,
1123 const void *src_end,
1124 void *dst)
1125{
1126 Eina_F32p32 *fp;
1127 int idx;
1128
1129 fp = (Eina_F32p32 *)dst;
1130
1131 if (!ed)
1132 {
1133 const char *s, *p;
1134 int len;
1135
1136 s = (const char *)src;
1137 p = s;
1138 len = 0;
1139 while ((p < (const char *)src_end) && (*p != 0)) { len++; p++; }
1140
1141 if (!(eina_convert_atofp(s, len, fp)))
1142 return -1;
1143
1144 return 1;
1145 }
1146
1147 if (eet_data_get_int(ed, src, src_end, &idx) < 0)
1148 return -1;
1149
1150 if (!eet_dictionary_string_get_fp(ed, idx, fp))
1151 return -1;
1152
1153 return 1;
1154} /* eet_data_get_f32p32 */
1155
1156static void *
1157eet_data_put_f32p32(Eet_Dictionary *ed,
1158 const void *src,
1159 int *size_ret)
1160{
1161 char buf[128];
1162 int idx;
1163
1164 eina_convert_fptoa((Eina_F32p32)(*(Eina_F32p32 *)src), buf);
1165
1166 if (!ed)
1167 {
1168 char *d;
1169 int len;
1170
1171 len = strlen(buf);
1172 d = malloc(len + 1);
1173 if (!d)
1174 return NULL;
1175
1176 memcpy(d, buf, len + 1);
1177 *size_ret = len + 1;
1178
1179 return d;
1180 }
1181
1182 idx = eet_dictionary_string_add(ed, buf);
1183 if (idx == -1)
1184 return NULL;
1185
1186 return eet_data_put_int(ed, &idx, size_ret);
1187} /* eet_data_put_f32p32 */
1188
1189static int
1190eet_data_get_f16p16(const Eet_Dictionary *ed,
1191 const void *src,
1192 const void *src_end,
1193 void *dst)
1194{
1195 Eina_F32p32 tmp;
1196 Eina_F16p16 *fp;
1197
1198 fp = (Eina_F16p16 *)dst;
1199
1200 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1201 return -1;
1202
1203 *fp = eina_f32p32_to_f16p16(tmp);
1204 return 1;
1205} /* eet_data_get_f16p16 */
1206
1207static void *
1208eet_data_put_f16p16(Eet_Dictionary *ed,
1209 const void *src,
1210 int *size_ret)
1211{
1212 Eina_F32p32 tmp;
1213
1214 tmp = eina_f16p16_to_f32p32((Eina_F16p16)(*(Eina_F16p16 *)src));
1215 return eet_data_put_f32p32(ed, &tmp, size_ret);
1216} /* eet_data_put_f16p16 */
1217
1218static int
1219eet_data_get_f8p24(const Eet_Dictionary *ed,
1220 const void *src,
1221 const void *src_end,
1222 void *dst)
1223{
1224 Eina_F32p32 tmp;
1225 Eina_F8p24 *fp;
1226
1227 fp = (Eina_F8p24 *)dst;
1228
1229 if (eet_data_get_f32p32(ed, src, src_end, &tmp) < 0)
1230 return -1;
1231
1232 *fp = eina_f32p32_to_f8p24(tmp);
1233 return 1;
1234} /* eet_data_get_f8p24 */
1235
1236static void *
1237eet_data_put_f8p24(Eet_Dictionary *ed,
1238 const void *src,
1239 int *size_ret)
1240{
1241 Eina_F32p32 tmp;
1242
1243 tmp = eina_f8p24_to_f32p32((Eina_F8p24)(*(Eina_F8p24 *)src));
1244 return eet_data_put_f32p32(ed, &tmp, size_ret);
1245} /* eet_data_put_f8p24 */
1246
1247static inline int
1248eet_data_get_type(const Eet_Dictionary *ed,
1249 int type,
1250 const void *src,
1251 const void *src_end,
1252 void *dest)
1253{
1254 int ret;
1255
1256 ret = eet_basic_codec[type - 1].get(ed, src, src_end, dest);
1257 return ret;
1258} /* eet_data_get_type */
1259
1260static inline void *
1261eet_data_put_type(Eet_Dictionary *ed,
1262 int type,
1263 const void *src,
1264 int *size_ret)
1265{
1266 void *ret;
1267
1268 ret = eet_basic_codec[type - 1].put(ed, src, size_ret);
1269 return ret;
1270} /* eet_data_put_type */
1271
1272static inline Eina_Bool
1273eet_data_type_match(int type1,
1274 int type2)
1275{
1276 if (type1 == type2)
1277 return EINA_TRUE;
1278
1279 /* Note: All floating point type are equivalent and could be read
1280 without problem by any other floating point getter. */
1281 switch (type1)
1282 {
1283 case EET_T_FLOAT:
1284 case EET_T_DOUBLE:
1285 case EET_T_F32P32:
1286 case EET_T_F16P16:
1287 case EET_T_F8P24:
1288 switch (type2)
1289 {
1290 case EET_T_FLOAT:
1291 case EET_T_DOUBLE:
1292 case EET_T_F32P32:
1293 case EET_T_F16P16:
1294 case EET_T_F8P24:
1295 return EINA_TRUE;
1296
1297 default:
1298 break;
1299 } /* switch */
1300 break;
1301
1302 default:
1303 break;
1304 } /* switch */
1305
1306 return EINA_FALSE;
1307} /* eet_data_type_match */
1308
1309/* chunk format...
1310 *
1311 * char[4] = "CHnK"; // untyped data ... or
1312 * char[4] = "CHKx"; // typed data - x == type
1313 *
1314 * int = chunk size (including magic string);
1315 * char[] = chunk magic/name string (0 byte terminated);
1316 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
1317 * or
1318 * ... payload data ...
1319 *
1320 */
1321
1322static inline void
1323eet_data_chunk_get(const Eet_Dictionary *ed,
1324 Eet_Data_Chunk *chnk,
1325 const void *src,
1326 int size)
1327{
1328 const char *s;
1329 int ret1, ret2;
1330
1331 if (!src)
1332 return;
1333
1334 if (size <= 8)
1335 return;
1336
1337 if (!chnk)
1338 return;
1339
1340 s = src;
1341 if (s[2] == 'K')
1342 {
1343 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'K'))
1344 return;
1345
1346 chnk->type = (unsigned char)(s[3]);
1347 if (chnk->type >= EET_I_LIMIT)
1348 {
1349 chnk->group_type =
1350 ((chnk->type - EET_I_LIMIT) & 0xF) + EET_G_UNKNOWN;
1351 switch ((chnk->type - EET_I_LIMIT) & 0xF0)
1352 {
1353#define EET_UNMATCH_TYPE(Type) \
1354case EET_I_ ## Type: chnk->type = EET_T_ ## Type; break;
1355
1356 EET_UNMATCH_TYPE(STRING);
1357 EET_UNMATCH_TYPE(INLINED_STRING);
1358 EET_UNMATCH_TYPE(NULL);
1359
1360 default:
1361 return;
1362 } /* switch */
1363 }
1364 else if (chnk->type > EET_T_LAST)
1365 {
1366 chnk->group_type = chnk->type;
1367 chnk->type = EET_T_UNKNOW;
1368 }
1369 else
1370 chnk->group_type = EET_G_UNKNOWN;
1371 if ((chnk->type >= EET_T_LAST) ||
1372 (chnk->group_type >=
1373 EET_G_LAST))
1374 {
1375 chnk->type = 0;
1376 chnk->group_type = 0;
1377 }
1378 }
1379 else if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
1380 return;
1381
1382 ret1 = eet_data_get_type(ed, EET_T_INT, (s + 4), (s + size), &(chnk->size));
1383
1384 if (ret1 <= 0)
1385 return;
1386
1387 if ((chnk->size < 0) || ((chnk->size + 8) > size))
1388 return;
1389
1390 ret2 = eet_data_get_type(ed, EET_T_STRING, (s + 8), (s + size), &(chnk->name));
1391
1392 if (ret2 <= 0)
1393 return;
1394
1395 chnk->len = ret2;
1396
1397 /* Precalc hash */
1398 chnk->hash = eet_data_get_string_hash(ed, (s + 8), (s + size));
1399
1400 if (ed)
1401 {
1402 chnk->data = (char *)src + 4 + ret1 + sizeof(int);
1403 chnk->size -= sizeof(int);
1404 }
1405 else
1406 {
1407 chnk->data = (char *)src + 4 + ret1 + chnk->len;
1408 chnk->size -= chnk->len;
1409 }
1410
1411 return;
1412} /* eet_data_chunk_get */
1413
1414static inline Eet_Data_Chunk *
1415eet_data_chunk_new(void *data,
1416 int size,
1417 const char *name,
1418 int type,
1419 int group_type)
1420{
1421 Eet_Data_Chunk *chnk;
1422
1423 if (!name)
1424 return NULL;
1425
1426 chnk = calloc(1, sizeof(Eet_Data_Chunk));
1427 if (!chnk)
1428 return NULL;
1429
1430 /* Note: Another security, so older eet library could read file
1431 saved with fixed point value. */
1432 if (type == EET_T_F32P32
1433 || type == EET_T_F16P16
1434 || type == EET_T_F8P24)
1435 type = EET_T_DOUBLE;
1436
1437 chnk->name = strdup(name);
1438 chnk->len = strlen(name) + 1;
1439 chnk->size = size;
1440 chnk->data = data;
1441 chnk->type = type;
1442 chnk->group_type = group_type;
1443 return chnk;
1444} /* eet_data_chunk_new */
1445
1446static inline void
1447eet_data_chunk_free(Eet_Data_Chunk *chnk)
1448{
1449 if (chnk->name)
1450 free(chnk->name);
1451
1452 free(chnk);
1453} /* eet_data_chunk_free */
1454
1455static inline Eet_Data_Stream *
1456eet_data_stream_new(void)
1457{
1458 Eet_Data_Stream *ds;
1459
1460 ds = calloc(1, sizeof(Eet_Data_Stream));
1461 if (!ds)
1462 return NULL;
1463
1464 return ds;
1465} /* eet_data_stream_new */
1466
1467static inline void
1468eet_data_stream_free(Eet_Data_Stream *ds)
1469{
1470 if (ds->data)
1471 free(ds->data);
1472
1473 free(ds);
1474} /* eet_data_stream_free */
1475
1476static inline void
1477eet_data_stream_flush(Eet_Data_Stream *ds)
1478{
1479 free(ds);
1480} /* eet_data_stream_flush */
1481
1482static inline void
1483eet_data_stream_write(Eet_Data_Stream *ds,
1484 const void *data,
1485 int size)
1486{
1487 char *p;
1488
1489 if ((ds->pos + size) > ds->size)
1490 {
1491 ds->data = realloc(ds->data, ds->size + size + 512);
1492 if (!ds->data)
1493 {
1494 ds->pos = 0;
1495 ds->size = 0;
1496 return;
1497 }
1498
1499 ds->size = ds->size + size + 512;
1500 }
1501
1502 p = ds->data;
1503 memcpy(p + ds->pos, data, size);
1504 ds->pos += size;
1505} /* eet_data_stream_write */
1506
1507static void
1508eet_data_chunk_put(Eet_Dictionary *ed,
1509 Eet_Data_Chunk *chnk,
1510 Eet_Data_Stream *ds)
1511{
1512 int *size;
1513 void *string;
1514 int s;
1515 int size_ret = 0;
1516 int string_ret = 0;
1517 unsigned char buf[4] = "CHK";
1518
1519 /* disable this check - it will allow empty chunks to be written. this is
1520 * right for corner-cases when y have a struct with empty fields (empty
1521 * strings or empty list ptrs etc.) */
1522 /* if (!chnk->data && chnk->type != EET_T_NULL) return; */
1523 /* chunk head */
1524
1525/* eet_data_stream_write(ds, "CHnK", 4);*/
1526 if (chnk->type != EET_T_UNKNOW)
1527 {
1528 if (chnk->group_type != EET_G_UNKNOWN)
1529 {
1530 int type = EET_I_LIMIT + chnk->group_type - EET_G_UNKNOWN;
1531
1532 switch (chnk->type)
1533 {
1534 /* Only make sense with pointer type. */
1535#define EET_MATCH_TYPE(Type) \
1536case EET_T_ ## Type: type += EET_I_ ## Type; break;
1537
1538 EET_MATCH_TYPE(STRING);
1539 EET_MATCH_TYPE(INLINED_STRING);
1540 EET_MATCH_TYPE(NULL);
1541
1542 default:
1543 return;
1544 } /* switch */
1545
1546 buf[3] = type;
1547 }
1548 else
1549 buf[3] = chnk->type;
1550 }
1551 else
1552 buf[3] = chnk->group_type;
1553
1554 string = eet_data_put_string(ed, &chnk->name, &string_ret);
1555 if (!string)
1556 return;
1557
1558 /* size of chunk payload data + name */
1559 s = chnk->size + string_ret;
1560 size = eet_data_put_int(ed, &s, &size_ret);
1561
1562 /* FIXME: If something goes wrong the resulting file will be corrupted. */
1563 if (!size)
1564 goto on_error;
1565
1566 eet_data_stream_write(ds, buf, 4);
1567
1568 /* write chunk length */
1569 eet_data_stream_write(ds, size, size_ret);
1570
1571 /* write chunk name */
1572 eet_data_stream_write(ds, string, string_ret);
1573
1574 /* write payload */
1575 if (chnk->data)
1576 eet_data_stream_write(ds, chnk->data, chnk->size);
1577
1578 free(string);
1579on_error:
1580 free(size);
1581} /* eet_data_chunk_put */
1582
1583/*---*/
1584
1585static void
1586_eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
1587{
1588 int i;
1589
1590 edd->elements.hash.size = 1 << 6;
1591 edd->elements.hash.buckets = calloc(
1592 1,
1593 sizeof(Eet_Data_Descriptor_Hash) *
1594 edd->elements.hash.size);
1595 for (i = 0; i < edd->elements.num; i++)
1596 {
1597 Eet_Data_Element *ede;
1598 int hash;
1599
1600 ede = &(edd->elements.set[i]);
1601 hash = _eet_hash_gen((char *)ede->name, 6);
1602 if (!edd->elements.hash.buckets[hash].element)
1603 edd->elements.hash.buckets[hash].element = ede;
1604 else
1605 {
1606 Eet_Data_Descriptor_Hash *bucket;
1607
1608 bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash));
1609 bucket->element = ede;
1610 bucket->next = edd->elements.hash.buckets[hash].next;
1611 edd->elements.hash.buckets[hash].next = bucket;
1612 }
1613 }
1614} /* _eet_descriptor_hash_new */
1615
1616static void
1617_eet_descriptor_hash_free(Eet_Data_Descriptor *edd)
1618{
1619 int i;
1620
1621 for (i = 0; i < edd->elements.hash.size; i++)
1622 {
1623 Eet_Data_Descriptor_Hash *bucket, *pbucket;
1624
1625 bucket = edd->elements.hash.buckets[i].next;
1626 while (bucket)
1627 {
1628 pbucket = bucket;
1629 bucket = bucket->next;
1630 free(pbucket);
1631 }
1632 }
1633 if (edd->elements.hash.buckets)
1634 free(edd->elements.hash.buckets);
1635} /* _eet_descriptor_hash_free */
1636
1637static Eet_Data_Element *
1638_eet_descriptor_hash_find(Eet_Data_Descriptor *edd,
1639 char *name,
1640 int hash)
1641{
1642 Eet_Data_Descriptor_Hash *bucket;
1643
1644 if (hash < 0)
1645 hash = _eet_hash_gen(name, 6);
1646 else
1647 hash &= 0x3f;
1648
1649 if (!edd->elements.hash.buckets[hash].element)
1650 return NULL; /*
1651 When we use the dictionary as a source for chunk name, we will always
1652 have the same pointer in name. It's a good idea to just compare pointer
1653 instead of running strcmp on both string.
1654 */
1655
1656 if (edd->elements.hash.buckets[hash].element->directory_name_ptr == name)
1657 return edd->elements.hash.buckets[hash].element;
1658
1659 if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
1660 {
1661 edd->elements.hash.buckets[hash].element->directory_name_ptr = name;
1662 return edd->elements.hash.buckets[hash].element;
1663 }
1664
1665 bucket = edd->elements.hash.buckets[hash].next;
1666 while (bucket)
1667 {
1668 if (bucket->element->directory_name_ptr == name)
1669 return bucket->element;
1670
1671 if (!strcmp(bucket->element->name, name))
1672 {
1673 bucket->element->directory_name_ptr = name;
1674 return bucket->element;
1675 }
1676
1677 bucket = bucket->next;
1678 }
1679 return NULL;
1680} /* _eet_descriptor_hash_find */
1681
1682static void *
1683_eet_mem_alloc(size_t size)
1684{
1685 return calloc(1, size);
1686} /* _eet_mem_alloc */
1687
1688static void
1689_eet_mem_free(void *mem)
1690{
1691 free(mem);
1692} /* _eet_mem_free */
1693
1694static char *
1695_eet_str_alloc(const char *str)
1696{
1697 return strdup(str);
1698} /* _eet_str_alloc */
1699
1700static void
1701_eet_str_free(const char *str)
1702{
1703 free((char *)str);
1704} /* _eet_str_free */
1705
1706static Eina_Hash *
1707_eet_eina_hash_add_alloc(Eina_Hash *hash,
1708 const char *key,
1709 void *data)
1710{
1711 if (!hash)
1712 hash = eina_hash_string_small_new(NULL);
1713
1714 if (!hash)
1715 return NULL;
1716
1717 eina_hash_add(hash, key, data);
1718 return hash;
1719} /* _eet_eina_hash_add_alloc */
1720
1721static Eina_Hash *
1722_eet_eina_hash_direct_add_alloc(Eina_Hash *hash,
1723 const char *key,
1724 void *data)
1725{
1726 if (!hash)
1727 hash = eina_hash_string_small_new(NULL);
1728
1729 if (!hash)
1730 return NULL;
1731
1732 eina_hash_direct_add(hash, key, data);
1733 return hash;
1734} /* _eet_eina_hash_direct_add_alloc */
1735
1736static char *
1737_eet_str_direct_alloc(const char *str)
1738{
1739 return (char *)str;
1740} /* _eet_str_direct_alloc */
1741
1742static void
1743_eet_str_direct_free(const char *str __UNUSED__)
1744{
1745} /* _eet_str_direct_free */
1746
1747static void
1748_eet_eina_hash_foreach(void *hash,
1749 Eina_Hash_Foreach cb,
1750 void *fdata)
1751{
1752 if (hash)
1753 eina_hash_foreach(hash, cb, fdata);
1754} /* _eet_eina_hash_foreach */
1755
1756static void
1757_eet_eina_hash_free(void *hash)
1758{
1759 if (hash)
1760 eina_hash_free(hash);
1761} /* _eet_eina_hash_free */
1762
1763/*---*/
1764EAPI Eina_Bool
1765eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1766 /* When we change the structure content in the future, we need to handle old structure type too */
1767 unsigned int eddc_size,
1768 const char *name,
1769 int size)
1770{
1771 if (!eddc || !name || eddc_size != sizeof (Eet_Data_Descriptor_Class))
1772 return EINA_FALSE;
1773
1774 eddc->name = name;
1775 eddc->size = size;
1776 eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
1777
1778 eddc->func.mem_alloc = _eet_mem_alloc;
1779 eddc->func.mem_free = _eet_mem_free;
1780 eddc->func.str_alloc = (char *(*)(const char *))eina_stringshare_add;
1781 eddc->func.str_free = eina_stringshare_del;
1782 eddc->func.list_next = (void *(*)(void *))eina_list_next;
1783 eddc->func.list_append = (void *(*)(void *, void *))eina_list_append;
1784 eddc->func.list_data = (void *(*)(void *))eina_list_data_get;
1785 eddc->func.list_free = (void *(*)(void *))eina_list_free;
1786 eddc->func.hash_foreach = (void (*)(void *, int (*)(void *, const char *, void *, void *), void *))_eet_eina_hash_foreach;
1787 eddc->func.hash_add = (void *(*)(void *, const char *, void *))_eet_eina_hash_add_alloc;
1788 eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
1789
1790 /* This will cause an ABI incompatibility */
1791 eddc->func.array_alloc = _eet_mem_alloc;
1792 eddc->func.array_free = _eet_mem_free;
1793
1794 return EINA_TRUE;
1795} /* eet_eina_stream_data_descriptor_class_set */
1796
1797EAPI Eina_Bool
1798eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
1799 /* When we change the structure content in the future, we need to handle old structure type too */
1800 unsigned int eddc_size,
1801 const char *name,
1802 int size)
1803{
1804 if (!eet_eina_stream_data_descriptor_class_set(eddc, eddc_size, name, size))
1805 return EINA_FALSE;
1806
1807 eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
1808
1809 eddc->func.hash_add = (void *(*)(void *, const char *, void *))_eet_eina_hash_direct_add_alloc;
1810 eddc->func.str_direct_alloc = _eet_str_direct_alloc;
1811 eddc->func.str_direct_free = _eet_str_direct_free;
1812
1813 return EINA_TRUE;
1814} /* eet_eina_file_data_descriptor_class_set */
1815
1816static Eet_Data_Descriptor *
1817_eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc,
1818 int version)
1819{
1820 Eet_Data_Descriptor *edd;
1821
1822 if (!eddc)
1823 return NULL;
1824
1825 edd = calloc(1, sizeof (Eet_Data_Descriptor));
1826 if (!edd)
1827 return NULL;
1828
1829 edd->name = eddc->name;
1830 edd->ed = NULL;
1831 edd->size = eddc->size;
1832 edd->func.mem_alloc = _eet_mem_alloc;
1833 edd->func.mem_free = _eet_mem_free;
1834 edd->func.str_alloc = _eet_str_alloc;
1835 edd->func.str_free = _eet_str_free;
1836 if (eddc->func.mem_alloc)
1837 edd->func.mem_alloc = eddc->func.mem_alloc;
1838
1839 if (eddc->func.mem_free)
1840 edd->func.mem_free = eddc->func.mem_free;
1841
1842 if (eddc->func.str_alloc)
1843 edd->func.str_alloc = eddc->func.str_alloc;
1844
1845 if (eddc->func.str_free)
1846 edd->func.str_free = eddc->func.str_free;
1847
1848 edd->func.list_next = eddc->func.list_next;
1849 edd->func.list_append = eddc->func.list_append;
1850 edd->func.list_data = eddc->func.list_data;
1851 edd->func.list_free = eddc->func.list_free;
1852 edd->func.hash_foreach = eddc->func.hash_foreach;
1853 edd->func.hash_add = eddc->func.hash_add;
1854 edd->func.hash_free = eddc->func.hash_free;
1855
1856 if (eddc->version > 1 && version > 1)
1857 {
1858 edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
1859 edd->func.str_direct_free = eddc->func.str_direct_free;
1860 }
1861
1862 if (eddc->version > 2)
1863 {
1864 edd->func.type_get = eddc->func.type_get;
1865 edd->func.type_set = eddc->func.type_set;
1866 }
1867
1868 if (eddc->version > 3)
1869 {
1870 edd->func.array_alloc = eddc->func.array_alloc;
1871 edd->func.array_free = eddc->func.array_free;
1872 }
1873
1874 return edd;
1875} /* _eet_data_descriptor_new */
1876
1877EAPI Eet_Data_Descriptor *
1878eet_data_descriptor_new(const char *name,
1879 int size,
1880 Eet_Descriptor_List_Next_Callback func_list_next,
1881 Eet_Descriptor_List_Append_Callback func_list_append,
1882 Eet_Descriptor_List_Data_Callback func_list_data,
1883 Eet_Descriptor_List_Free_Callback func_list_free,
1884 Eet_Descriptor_Hash_Foreach_Callback func_hash_foreach,
1885 Eet_Descriptor_Hash_Add_Callback func_hash_add,
1886 Eet_Descriptor_Hash_Free_Callback func_hash_free)
1887{
1888 Eet_Data_Descriptor_Class eddc;
1889
1890 if (!name)
1891 return NULL;
1892
1893 memset(&eddc, 0, sizeof (Eet_Data_Descriptor_Class));
1894
1895 eddc.name = name;
1896 eddc.size = size;
1897 eddc.version = 0;
1898
1899 eddc.func.list_next = func_list_next;
1900 eddc.func.list_append = func_list_append;
1901 eddc.func.list_data = func_list_data;
1902 eddc.func.list_free = func_list_free;
1903 eddc.func.hash_foreach = func_hash_foreach;
1904 eddc.func.hash_add = func_hash_add;
1905 eddc.func.hash_free = func_hash_free;
1906
1907 return _eet_data_descriptor_new(&eddc, 0);
1908} /* eet_data_descriptor_new */
1909
1910EAPI Eet_Data_Descriptor *
1911eet_data_descriptor2_new(const Eet_Data_Descriptor_Class *eddc)
1912{
1913 return _eet_data_descriptor_new(eddc, 1);
1914} /* eet_data_descriptor2_new */
1915
1916EAPI Eet_Data_Descriptor *
1917eet_data_descriptor3_new(const Eet_Data_Descriptor_Class *eddc)
1918{
1919 return _eet_data_descriptor_new(eddc, 2);
1920} /* eet_data_descriptor3_new */
1921
1922EAPI Eet_Data_Descriptor *
1923eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
1924{
1925 return _eet_data_descriptor_new(eddc, 1);
1926} /* eet_data_descriptor_stream_new */
1927
1928EAPI Eet_Data_Descriptor *
1929eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
1930{
1931 return _eet_data_descriptor_new(eddc, 2);
1932} /* eet_data_descriptor_file_new */
1933
1934EAPI void
1935eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1936{
1937 if (!edd)
1938 return;
1939
1940 _eet_descriptor_hash_free(edd);
1941 if (edd->elements.set)
1942 free(edd->elements.set);
1943
1944 free(edd);
1945} /* eet_data_descriptor_free */
1946
1947EAPI void
1948eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
1949 const char *name,
1950 int type,
1951 int group_type,
1952 int offset,
1953 int count,
1954/* int counter_offset, */
1955 const char *counter_name /* FIXME: Useless should go on a major release */,
1956 Eet_Data_Descriptor *subtype)
1957{
1958 Eet_Data_Element *ede;
1959 Eet_Data_Element *tmp;
1960
1961 /* UNION, VARIANT type would not work with simple type, we need a way to map the type. */
1962 if ((group_type == EET_G_UNION
1963 || group_type == EET_G_VARIANT)
1964 &&
1965 (type != EET_T_UNKNOW
1966 || !subtype
1967 || !subtype->func.type_get
1968 || !subtype->func.type_set))
1969 return;
1970
1971 /* VARIANT type will only work if the map only contains EET_G_*, but not UNION, VARIANT and ARRAY. */
1972 if (group_type == EET_G_VARIANT)
1973 {
1974 int i;
1975
1976 for (i = 0; i < subtype->elements.num; ++i)
1977 if (subtype->elements.set[i].type != EET_T_UNKNOW
1978 && subtype->elements.set[i].group_type > EET_G_VAR_ARRAY
1979 && subtype->elements.set[i].group_type < EET_G_UNION)
1980 return;
1981
1982 subtype->unified_type = EINA_TRUE;
1983 }
1984
1985 if (subtype
1986 && subtype->unified_type
1987 && (type != EET_T_UNKNOW
1988 || group_type < EET_G_UNION))
1989 return;
1990
1991 /* Sanity check done, let allocate ! */
1992 edd->elements.num++;
1993 tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1994 if (!tmp)
1995 return;
1996
1997 edd->elements.set = tmp;
1998 ede = &(edd->elements.set[edd->elements.num - 1]);
1999 ede->name = name;
2000 ede->directory_name_ptr = NULL;
2001
2002 /*
2003 * We do a special case when we do list,hash or whatever group of simple type.
2004 * Instead of handling it in encode/decode/dump/undump, we create an
2005 * implicit structure with only the simple type.
2006 */
2007 if ((group_type > EET_G_UNKNOWN)
2008 && (group_type < EET_G_LAST)
2009 && (((type > EET_T_UNKNOW) && (type < EET_T_STRING))
2010 || ((type > EET_T_NULL) && (type < EET_T_LAST)))
2011 && (!subtype))
2012 {
2013 subtype = calloc(1, sizeof (Eet_Data_Descriptor));
2014 if (!subtype)
2015 return;
2016
2017 subtype->name = "implicit";
2018 subtype->size = eet_basic_codec[type - 1].size;
2019 memcpy(&subtype->func, &edd->func, sizeof(subtype->func));
2020
2021 eet_data_descriptor_element_add(subtype,
2022 eet_basic_codec[type - 1].name,
2023 type,
2024 EET_G_UNKNOWN,
2025 0,
2026 0,
2027 /* 0, */ NULL,
2028 NULL);
2029 type = EET_T_UNKNOW;
2030 }
2031
2032 ede->type = type;
2033 ede->group_type = group_type;
2034 ede->offset = offset;
2035 ede->count = count;
2036 /* FIXME: For the time being, VAR_ARRAY, UNION and VARIANT will put the counter_offset in count. */
2037 ede->counter_offset = count;
2038/* ede->counter_offset = counter_offset; */
2039 ede->counter_name = counter_name;
2040
2041 ede->subtype = subtype;
2042} /* eet_data_descriptor_element_add */
2043
2044EAPI void *
2045eet_data_read_cipher(Eet_File *ef,
2046 Eet_Data_Descriptor *edd,
2047 const char *name,
2048 const char *cipher_key)
2049{
2050 const Eet_Dictionary *ed = NULL;
2051 const void *data = NULL;
2052 void *data_dec;
2053 Eet_Free_Context context;
2054 int required_free = 0;
2055 int size;
2056
2057 ed = eet_dictionary_get(ef);
2058
2059 if (!cipher_key)
2060 data = eet_read_direct(ef, name, &size);
2061
2062 if (!data)
2063 {
2064 required_free = 1;
2065 data = eet_read_cipher(ef, name, &size, cipher_key);
2066 if (!data)
2067 return NULL;
2068 }
2069
2070 eet_free_context_init(&context);
2071 data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, NULL, 0);
2072 eet_free_context_shutdown(&context);
2073
2074 if (required_free)
2075 free((void *)data);
2076
2077 return data_dec;
2078} /* eet_data_read_cipher */
2079
2080EAPI Eet_Node *
2081eet_data_node_read_cipher(Eet_File *ef,
2082 const char *name,
2083 const char *cipher_key)
2084{
2085 const Eet_Dictionary *ed = NULL;
2086 const void *data = NULL;
2087 Eet_Node *result;
2088 Eet_Free_Context context;
2089 int required_free = 0;
2090 int size;
2091
2092 ed = eet_dictionary_get(ef);
2093
2094 if (!cipher_key)
2095 data = eet_read_direct(ef, name, &size);
2096
2097 if (!data)
2098 {
2099 required_free = 1;
2100 data = eet_read_cipher(ef, name, &size, cipher_key);
2101 if (!data)
2102 return NULL;
2103 }
2104
2105 eet_free_context_init(&context);
2106 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0);
2107 eet_free_context_shutdown(&context);
2108
2109 if (required_free)
2110 free((void *)data);
2111
2112 return result;
2113} /* eet_data_node_read_cipher */
2114
2115EAPI void *
2116eet_data_read(Eet_File *ef,
2117 Eet_Data_Descriptor *edd,
2118 const char *name)
2119{
2120 return eet_data_read_cipher(ef, edd, name, NULL);
2121} /* eet_data_read */
2122
2123EAPI int
2124eet_data_write_cipher(Eet_File *ef,
2125 Eet_Data_Descriptor *edd,
2126 const char *name,
2127 const char *cipher_key,
2128 const void *data,
2129 int compress)
2130{
2131 Eet_Dictionary *ed;
2132 void *data_enc;
2133 int size;
2134 int val;
2135
2136 ed = eet_dictionary_get(ef);
2137
2138 data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
2139 if (!data_enc)
2140 return 0;
2141
2142 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
2143 free(data_enc);
2144 return val;
2145} /* eet_data_write_cipher */
2146
2147EAPI int
2148eet_data_write(Eet_File *ef,
2149 Eet_Data_Descriptor *edd,
2150 const char *name,
2151 const void *data,
2152 int compress)
2153{
2154 return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
2155} /* eet_data_write */
2156
2157static void
2158eet_free_context_init(Eet_Free_Context *context)
2159{
2160 unsigned int i = 0;
2161
2162 memset(context, 0, sizeof (Eet_Free_Context));
2163 for (i = 0; i < EET_FREE_COUNT; ++i)
2164 {
2165 eina_array_step_set(&context->freelist.list[i],
2166 sizeof (context->freelist.list[i]),
2167 32);
2168 eina_array_step_set(&context->freelist_array.list[i],
2169 sizeof (context->freelist.list[i]),
2170 32);
2171 eina_array_step_set(&context->freelist_list.list[i],
2172 sizeof (context->freelist.list[i]),
2173 32);
2174 eina_array_step_set(&context->freelist_hash.list[i],
2175 sizeof (context->freelist.list[i]),
2176 32);
2177 eina_array_step_set(&context->freelist_str.list[i],
2178 sizeof (context->freelist.list[i]),
2179 32);
2180 eina_array_step_set(&context->freelist_direct_str.list[i],
2181 sizeof (context->freelist.list[i]),
2182 32);
2183 }
2184}
2185
2186static void
2187eet_free_context_shutdown(Eet_Free_Context *context)
2188{
2189 unsigned int i = 0;
2190
2191 for (i = 0; i < EET_FREE_COUNT; ++i)
2192 {
2193 eina_array_flush(&context->freelist.list[i]);
2194 eina_array_flush(&context->freelist_array.list[i]);
2195 eina_array_flush(&context->freelist_list.list[i]);
2196 eina_array_flush(&context->freelist_hash.list[i]);
2197 eina_array_flush(&context->freelist_str.list[i]);
2198 eina_array_flush(&context->freelist_direct_str.list[i]);
2199 }
2200}
2201
2202static int
2203_eet_free_hash(void *data)
2204{
2205#ifdef _WIN64
2206 __int64 ptr = (UINT_PTR)data;
2207#else /* ifdef _WIN64 */
2208 unsigned long ptr = (unsigned long)(data);
2209#endif /* ifdef _WIN64 */
2210 int hash;
2211
2212 hash = ptr;
2213 hash ^= ptr >> 8;
2214 hash ^= ptr >> 16;
2215 hash ^= ptr >> 24;
2216
2217#if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32))
2218 hash ^= ptr >> 32;
2219 hash ^= ptr >> 40;
2220 hash ^= ptr >> 48;
2221 hash ^= ptr >> 56;
2222#endif /* if defined (_WIN64) || ((!defined (_WIN32)) && (LONG_BIT != 32)) */
2223
2224 return hash & 0xFF;
2225} /* _eet_free_hash */
2226
2227static void
2228_eet_free_add(Eet_Free *ef,
2229 void *data)
2230{
2231 void *track;
2232 Eina_Array_Iterator it;
2233 unsigned int i;
2234 int hash;
2235
2236 hash = _eet_free_hash(data);
2237
2238 EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it)
2239 if (track == data)
2240 return;
2241
2242 eina_array_push(&ef->list[hash], data);
2243} /* _eet_free_add */
2244
2245#if 0
2246static void
2247_eet_free_del(Eet_Free *ef,
2248 void *data)
2249{
2250 void *track;
2251 Eina_Array_Iterator it;
2252 unsigned int i;
2253 int hash;
2254
2255 hash = _eet_free_hash(data);
2256
2257 EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it)
2258 if (track == data)
2259 {
2260 eina_array_data_set(&ef->list[hash], i, NULL);
2261 return;
2262 }
2263}
2264
2265#endif
2266
2267static void
2268_eet_free_reset(Eet_Free *ef)
2269{
2270 unsigned int i;
2271
2272 if (ef->ref > 0)
2273 return;
2274
2275 for (i = 0; i < EET_FREE_COUNT; ++i)
2276 eina_array_clean(&ef->list[i]);
2277} /* _eet_free_reset */
2278
2279static void
2280_eet_free_ref(Eet_Free *ef)
2281{
2282 ef->ref++;
2283} /* _eet_free_ref */
2284
2285static void
2286_eet_free_unref(Eet_Free *ef)
2287{
2288 ef->ref--;
2289} /* _eet_free_unref */
2290
2291#define _eet_freelist_add(Ctx, Data) _eet_free_add(&Ctx->freelist, Data);
2292#define _eet_freelist_del(Ctx, Data) _eet_free_del(&Ctx->freelist, Data);
2293#define _eet_freelist_reset(Ctx) _eet_free_reset(&Ctx->freelist);
2294#define _eet_freelist_ref(Ctx) _eet_free_ref(&Ctx->freelist);
2295#define _eet_freelist_unref(Ctx) _eet_free_unref(&Ctx->freelist);
2296
2297static void
2298_eet_freelist_free(Eet_Free_Context *context,
2299 Eet_Data_Descriptor *edd)
2300{
2301 void *track;
2302 Eina_Array_Iterator it;
2303 unsigned int j;
2304 unsigned int i;
2305
2306 if (context->freelist.ref > 0)
2307 return;
2308
2309 for (j = 0; j < EET_FREE_COUNT; ++j)
2310 EINA_ARRAY_ITER_NEXT(&context->freelist.list[j], i, track, it)
2311 if (track)
2312 {
2313 if (edd)
2314 edd->func.mem_free(track);
2315 else
2316 free(track);
2317 }
2318 _eet_free_reset(&context->freelist);
2319} /* _eet_freelist_free */
2320
2321#define _eet_freelist_array_add(Ctx, Data) _eet_free_add(&Ctx->freelist_array, Data);
2322#define _eet_freelist_array_del(Ctx, Data) _eet_free_del(&Ctx->freelist_array, Data);
2323#define _eet_freelist_array_reset(Ctx) _eet_free_reset(&Ctx->freelist_array);
2324#define _eet_freelist_array_ref(Ctx) _eet_free_ref(&Ctx->freelist_array);
2325#define _eet_freelist_array_unref(Ctx) _eet_free_unref(&Ctx->freelist_array);
2326
2327static void
2328_eet_freelist_array_free(Eet_Free_Context *context,
2329 Eet_Data_Descriptor *edd)
2330{
2331 void *track;
2332 Eina_Array_Iterator it;
2333 unsigned int j;
2334 unsigned int i;
2335
2336 if (context->freelist_array.ref > 0)
2337 return;
2338
2339 for (j = 0; j < EET_FREE_COUNT; ++j)
2340 EINA_ARRAY_ITER_NEXT(&context->freelist_array.list[j], i, track, it)
2341 if (track)
2342 {
2343 if (edd)
2344 {
2345 if (edd->func.array_free)
2346 edd->func.array_free(track);
2347 else
2348 edd->func.mem_free(track);
2349 }
2350 else
2351 free(track);
2352 }
2353 _eet_free_reset(&context->freelist_array);
2354} /* _eet_freelist_array_free */
2355
2356#define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
2357#define _eet_freelist_list_del(Ctx, Data) _eet_free_del(&Ctx->freelist_list, Data);
2358#define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
2359#define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
2360#define _eet_freelist_list_unref(Ctx) _eet_free_unref(&Ctx->freelist_list);
2361
2362static void
2363_eet_freelist_list_free(Eet_Free_Context *context,
2364 Eet_Data_Descriptor *edd)
2365{
2366 void *track;
2367 Eina_Array_Iterator it;
2368 unsigned int j;
2369 unsigned int i;
2370
2371 if (context->freelist_list.ref > 0)
2372 return;
2373
2374 for (j = 0; j < EET_FREE_COUNT; ++j)
2375 EINA_ARRAY_ITER_NEXT(&context->freelist_list.list[j], i, track, it)
2376 if (track)
2377 {
2378 if (edd)
2379 edd->func.list_free(*((void **)(track)));
2380 }
2381 _eet_free_reset(&context->freelist_list);
2382} /* _eet_freelist_list_free */
2383
2384#define _eet_freelist_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_str, Data);
2385#define _eet_freelist_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_str, Data);
2386#define _eet_freelist_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_str);
2387#define _eet_freelist_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_str);
2388#define _eet_freelist_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_str);
2389
2390static void
2391_eet_freelist_str_free(Eet_Free_Context *context,
2392 Eet_Data_Descriptor *edd)
2393{
2394 void *track;
2395 Eina_Array_Iterator it;
2396 unsigned int j;
2397 unsigned int i;
2398
2399 if (context->freelist_str.ref > 0)
2400 return;
2401
2402 for (j = 0; j < EET_FREE_COUNT; ++j)
2403 EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it)
2404 if (track)
2405 {
2406 if (edd)
2407 edd->func.str_free(track);
2408 else
2409 free(track);
2410 }
2411 _eet_free_reset(&context->freelist_str);
2412} /* _eet_freelist_str_free */
2413
2414#define _eet_freelist_direct_str_add(Ctx, Data) _eet_free_add(&Ctx->freelist_direct_str, Data);
2415#define _eet_freelist_direct_str_del(Ctx, Data) _eet_free_del(&Ctx->freelist_direct_str, Data);
2416#define _eet_freelist_direct_str_reset(Ctx) _eet_free_reset(&Ctx->freelist_direct_str);
2417#define _eet_freelist_direct_str_ref(Ctx) _eet_free_ref(&Ctx->freelist_direct_str);
2418#define _eet_freelist_direct_str_unref(Ctx) _eet_free_unref(&Ctx->freelist_direct_str);
2419
2420static void
2421_eet_freelist_direct_str_free(Eet_Free_Context *context,
2422 Eet_Data_Descriptor *edd)
2423{
2424 void *track;
2425 Eina_Array_Iterator it;
2426 unsigned int j;
2427 unsigned int i;
2428
2429 if (context->freelist_direct_str.ref > 0)
2430 return;
2431
2432 for (j = 0; j < EET_FREE_COUNT; ++j)
2433 EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it)
2434 if (track)
2435 {
2436 if (edd)
2437 edd->func.str_direct_free(track);
2438 else
2439 free(track);
2440 }
2441 _eet_free_reset(&context->freelist_direct_str);
2442} /* _eet_freelist_direct_str_free */
2443
2444#define _eet_freelist_hash_add(Ctx, Data) _eet_free_add(&Ctx->freelist_hash, Data);
2445#define _eet_freelist_hash_del(Ctx, Data) _eet_free_del(&Ctx->freelist_hash, Data);
2446#define _eet_freelist_hash_reset(Ctx) _eet_free_reset(&Ctx->freelist_hash);
2447#define _eet_freelist_hash_ref(Ctx) _eet_free_ref(&Ctx->freelist_hash);
2448#define _eet_freelist_hash_unref(Ctx) _eet_free_unref(&Ctx->freelist_hash);
2449
2450static void
2451_eet_freelist_hash_free(Eet_Free_Context *context,
2452 Eet_Data_Descriptor *edd)
2453{
2454 void *track;
2455 Eina_Array_Iterator it;
2456 unsigned int j;
2457 unsigned int i;
2458
2459 if (context->freelist_hash.ref > 0)
2460 return;
2461
2462 for (j = 0; j < EET_FREE_COUNT; ++j)
2463 EINA_ARRAY_ITER_NEXT(&context->freelist_hash.list[j], i, track, it)
2464 if (track)
2465 {
2466 if (edd)
2467 edd->func.hash_free(track);
2468 else
2469 free(track);
2470 }
2471 _eet_free_reset(&context->freelist_hash);
2472} /* _eet_freelist_hash_free */
2473
2474static void
2475_eet_freelist_all_ref(Eet_Free_Context *freelist_context)
2476{
2477 _eet_freelist_ref(freelist_context);
2478 _eet_freelist_str_ref(freelist_context);
2479 _eet_freelist_list_ref(freelist_context);
2480 _eet_freelist_hash_ref(freelist_context);
2481 _eet_freelist_direct_str_ref(freelist_context);
2482} /* _eet_freelist_all_ref */
2483
2484static void
2485_eet_freelist_all_unref(Eet_Free_Context *freelist_context)
2486{
2487 _eet_freelist_unref(freelist_context);
2488 _eet_freelist_str_unref(freelist_context);
2489 _eet_freelist_list_unref(freelist_context);
2490 _eet_freelist_hash_unref(freelist_context);
2491 _eet_freelist_direct_str_unref(freelist_context);
2492} /* _eet_freelist_all_unref */
2493
2494static int
2495eet_data_descriptor_encode_hash_cb(void *hash __UNUSED__,
2496 const char *cipher_key,
2497 void *hdata,
2498 void *fdata)
2499{
2500 Eet_Dictionary *ed;
2501 Eet_Data_Encode_Hash_Info *edehi;
2502 Eet_Data_Stream *ds;
2503 Eet_Data_Element *ede;
2504 Eet_Data_Chunk *echnk;
2505 void *data = NULL;
2506 int size;
2507
2508 edehi = fdata;
2509 ede = edehi->ede;
2510 ds = edehi->ds;
2511 ed = edehi->ed;
2512
2513 /* Store key */
2514 data = eet_data_put_type(ed,
2515 EET_T_STRING,
2516 &cipher_key,
2517 &size);
2518 if (data)
2519 {
2520 echnk = eet_data_chunk_new(data,
2521 size,
2522 ede->name,
2523 ede->type,
2524 ede->group_type);
2525 eet_data_chunk_put(ed, echnk, ds);
2526 eet_data_chunk_free(echnk);
2527 free(data);
2528 data = NULL;
2529 }
2530
2531 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)), return );
2532
2533 /* Store data */
2534 if (ede->type >= EET_T_STRING)
2535 eet_data_put_unknown(ed, NULL, ede, ds, &hdata);
2536 else
2537 {
2538 if (ede->subtype)
2539 data = _eet_data_descriptor_encode(ed,
2540 ede->subtype,
2541 hdata,
2542 &size);
2543
2544 if (data)
2545 {
2546 echnk = eet_data_chunk_new(data,
2547 size,
2548 ede->name,
2549 ede->type,
2550 ede->group_type);
2551 eet_data_chunk_put(ed, echnk, ds);
2552 eet_data_chunk_free(echnk);
2553 free(data);
2554 data = NULL;
2555 }
2556 }
2557
2558 return 1;
2559} /* eet_data_descriptor_encode_hash_cb */
2560
2561static char *
2562_eet_data_dump_token_get(const char *src,
2563 int *len)
2564{
2565 const char *p;
2566 char *tok = NULL;
2567 int in_token = 0;
2568 int in_quote = 0;
2569 int tlen = 0, tsize = 0;
2570
2571#define TOK_ADD(x) \
2572 do { \
2573 tlen++; \
2574 if (tlen >= tsize) \
2575 { \
2576 tsize += 32; \
2577 tok = realloc(tok, tsize); \
2578 } \
2579 tok[tlen - 1] = x; \
2580 } while (0)
2581
2582 for (p = src; *len > 0; p++, (*len)--)
2583 {
2584 if (in_token)
2585 {
2586 if (in_quote)
2587 {
2588 if ((p[0] == '\"') && (p > src) && (p[-1] != '\\'))
2589 in_quote = 0;
2590 else if ((p[0] == '\\') && (*len > 1) &&
2591 (p[1] == '\"'))
2592 {
2593/* skip */
2594 }
2595 else if ((p[0] == '\\') && (p > src) && (p[-1] == '\\'))
2596 {
2597/* skip */
2598 }
2599 else if ((p[0] == '\\') && (*len > 1) && (p[1] == 'n'))
2600 {
2601/* skip */
2602 }
2603 else if ((p[0] == 'n') && (p > src) && (p[-1] == '\\'))
2604 TOK_ADD('\n');
2605 else
2606 TOK_ADD(p[0]);
2607 }
2608 else
2609 {
2610 if (p[0] == '\"')
2611 in_quote = 1;
2612 else
2613 {
2614 if ((isspace(p[0])) || (p[0] == ';')) /* token ends here */
2615 {
2616 TOK_ADD(0);
2617 (*len)--;
2618 return tok;
2619 }
2620 else
2621 TOK_ADD(p[0]);
2622 }
2623 }
2624 }
2625 else if (!((isspace(p[0])) || (p[0] == ';')))
2626 {
2627 in_token = 1;
2628 (*len)++;
2629 p--;
2630 }
2631 }
2632 if (in_token)
2633 {
2634 TOK_ADD(0);
2635 return tok;
2636 }
2637
2638 if (tok)
2639 free(tok);
2640
2641 return NULL;
2642} /* _eet_data_dump_token_get */
2643
2644static void
2645eet_data_encode(Eet_Dictionary *ed,
2646 Eet_Data_Stream *ds,
2647 void *data,
2648 const char *name,
2649 int size,
2650 int type,
2651 int group_type)
2652{
2653 Eet_Data_Chunk *echnk;
2654
2655 if (!data)
2656 type = EET_T_NULL;
2657
2658 if (group_type != EET_G_UNKNOWN)
2659 if (type >= EET_T_LAST)
2660 type = EET_T_UNKNOW;
2661
2662 echnk = eet_data_chunk_new(data, size, name, type, group_type);
2663 eet_data_chunk_put(ed, echnk, ds);
2664 eet_data_chunk_free(echnk);
2665 free(data);
2666} /* eet_data_encode */
2667
2668static void *
2669_eet_data_dump_encode(int parent_type,
2670 Eet_Dictionary *ed,
2671 Eet_Node *node,
2672 int *size_ret)
2673{
2674 Eet_Data_Chunk *chnk = NULL;
2675 Eet_Data_Stream *ds;
2676 void *cdata, *data;
2677 int csize, size;
2678 int count;
2679 int child_type;
2680 Eet_Node *n;
2681
2682 if (_eet_data_words_bigendian == -1)
2683 {
2684 unsigned long int v;
2685
2686 v = htonl(0x12345678);
2687 if (v == 0x12345678)
2688 _eet_data_words_bigendian = 1;
2689 else
2690 _eet_data_words_bigendian = 0;
2691 }
2692
2693 if (!node)
2694 return NULL;
2695
2696 ds = eet_data_stream_new();
2697 if (!ds)
2698 return NULL;
2699
2700 switch (node->type)
2701 {
2702 case EET_G_UNKNOWN:
2703 for (n = node->values; n; n = n->next)
2704 {
2705 data = _eet_data_dump_encode(node->type, ed, n, &size);
2706 if (data)
2707 {
2708 eet_data_stream_write(ds, data, size);
2709 free(data);
2710 }
2711 }
2712 break;
2713
2714 case EET_G_ARRAY:
2715 case EET_G_VAR_ARRAY:
2716 for (child_type = EET_T_NULL, n = node->values; n; n = n->next)
2717 {
2718 if (n->type != EET_T_NULL)
2719 {
2720 child_type = n->type;
2721 break;
2722 }
2723 }
2724
2725 data = eet_data_put_type(ed,
2726 EET_T_INT,
2727 &node->count,
2728 &size);
2729 eet_data_encode(ed,
2730 ds,
2731 data,
2732 node->name,
2733 size,
2734 child_type,
2735 node->type);
2736
2737 count = node->count;
2738
2739 for (n = node->values; n; n = n->next)
2740 {
2741 int pos = ds->pos;
2742
2743 switch (n->type)
2744 {
2745 case EET_T_STRING:
2746 case EET_T_INLINED_STRING:
2747 data = eet_data_put_type(ed,
2748 n->type,
2749 &(n->data.value.str),
2750 &size);
2751 if (data)
2752 eet_data_encode(ed,
2753 ds,
2754 data,
2755 node->name,
2756 size,
2757 n->type,
2758 node->type);
2759
2760 break;
2761
2762 case EET_T_NULL:
2763 continue;
2764
2765 default:
2766 data = _eet_data_dump_encode(n->type, ed, n, &size);
2767 eet_data_encode(ed,
2768 ds,
2769 data,
2770 node->name,
2771 size,
2772 n->type,
2773 node->type);
2774 break;
2775 } /* switch */
2776 if (ds->pos != pos)
2777 count--;
2778 }
2779
2780 for (; count; count--)
2781 {
2782 eet_data_encode(ed,
2783 ds,
2784 NULL,
2785 node->name,
2786 0,
2787 EET_T_NULL,
2788 node->type);
2789 }
2790
2791 /* Array is somekind of special case, so we should embed it inside another chunk. */
2792 *size_ret = ds->pos;
2793 cdata = ds->data;
2794
2795 ds->data = NULL;
2796 ds->size = 0;
2797 eet_data_stream_free(ds);
2798
2799 return cdata;
2800 break;
2801
2802 case EET_G_LIST:
2803 for (n = node->values; n; n = n->next)
2804 {
2805 switch (n->type)
2806 {
2807 case EET_T_STRING:
2808 case EET_T_INLINED_STRING:
2809 data = eet_data_put_type(ed,
2810 n->type,
2811 &(n->data.value.str),
2812 &size);
2813 if (data)
2814 eet_data_encode(ed,
2815 ds,
2816 data,
2817 node->name,
2818 size,
2819 n->type,
2820 node->type);
2821
2822 break;
2823
2824 case EET_T_NULL:
2825 continue;
2826
2827 default:
2828 data = _eet_data_dump_encode(node->type, ed, n, &size);
2829 eet_data_encode(ed,
2830 ds,
2831 data,
2832 node->name,
2833 size,
2834 n->type,
2835 node->type);
2836 } /* switch */
2837 }
2838
2839 /* List is another somekind of special case, every chunk is embed inside a list chunk. */
2840 *size_ret = ds->pos;
2841 cdata = ds->data;
2842
2843 ds->data = NULL;
2844 ds->size = 0;
2845 eet_data_stream_free(ds);
2846
2847 return cdata;
2848 break;
2849
2850 case EET_G_HASH:
2851 if (node->key)
2852 {
2853 data = eet_data_put_type(ed,
2854 EET_T_STRING,
2855 &node->key,
2856 &size);
2857 eet_data_encode(ed,
2858 ds,
2859 data,
2860 node->name,
2861 size,
2862 node->type,
2863 node->type);
2864 }
2865 else
2866 /* A Hash without key will not decode correctly. */
2867 return NULL;
2868
2869 for (n = node->values; n; n = n->next)
2870 {
2871 switch (n->type)
2872 {
2873 case EET_T_STRING:
2874 case EET_T_INLINED_STRING:
2875 data = eet_data_put_type(ed,
2876 n->type,
2877 &(n->data.value.str),
2878 &size);
2879 if (data)
2880 eet_data_encode(ed,
2881 ds,
2882 data,
2883 node->name,
2884 size,
2885 n->type,
2886 node->type);
2887
2888 break;
2889
2890 case EET_T_NULL:
2891 continue;
2892
2893 default:
2894 data = _eet_data_dump_encode(node->type, ed, n, &size);
2895 eet_data_encode(ed,
2896 ds,
2897 data,
2898 node->name,
2899 size,
2900 n->type,
2901 node->type);
2902 } /* switch */
2903 }
2904
2905 /* Hash is somekind of special case, so we should embed it inside another chunk. */
2906 *size_ret = ds->pos;
2907 cdata = ds->data;
2908
2909 eet_data_stream_flush(ds);
2910
2911 return cdata;
2912
2913 case EET_T_NULL:
2914 break;
2915
2916#define EET_DATA_NODE_ENCODE(Eet_Type, Type) \
2917case Eet_Type: \
2918 data = eet_data_put_type(ed, node->type, &(node->data.value.Type), &size); \
2919 if (data) \
2920 { \
2921 eet_data_encode(ed, \
2922 ds, \
2923 data, \
2924 node->name, \
2925 size, \
2926 node->type, \
2927 parent_type); \
2928 cdata = ds->data; \
2929 *size_ret = ds->pos; \
2930 eet_data_stream_flush(ds); \
2931 return cdata; \
2932 } /* switch */ \
2933 break;
2934
2935 EET_DATA_NODE_ENCODE(EET_T_CHAR, c);
2936 EET_DATA_NODE_ENCODE(EET_T_SHORT, s);
2937 EET_DATA_NODE_ENCODE(EET_T_INT, i);
2938 EET_DATA_NODE_ENCODE(EET_T_LONG_LONG, l);
2939 EET_DATA_NODE_ENCODE(EET_T_FLOAT, f);
2940 EET_DATA_NODE_ENCODE(EET_T_DOUBLE, d);
2941 EET_DATA_NODE_ENCODE(EET_T_UCHAR, uc);
2942 EET_DATA_NODE_ENCODE(EET_T_USHORT, us);
2943 EET_DATA_NODE_ENCODE(EET_T_UINT, ui);
2944 EET_DATA_NODE_ENCODE(EET_T_ULONG_LONG, ul);
2945 EET_DATA_NODE_ENCODE(EET_T_INLINED_STRING, str);
2946 EET_DATA_NODE_ENCODE(EET_T_STRING, str);
2947
2948 default:
2949 break;
2950 }
2951
2952 if ((node->type >= EET_G_UNKNOWN) && (node->type < EET_G_LAST))
2953 chnk = eet_data_chunk_new(ds->data,
2954 ds->pos,
2955 node->name,
2956 EET_T_UNKNOW,
2957 node->type);
2958 else
2959 chnk = eet_data_chunk_new(ds->data,
2960 ds->pos,
2961 node->name,
2962 node->type,
2963 EET_G_UNKNOWN);
2964
2965 eet_data_stream_flush(ds);
2966
2967 ds = eet_data_stream_new();
2968 eet_data_chunk_put(ed, chnk, ds);
2969 cdata = ds->data;
2970 csize = ds->pos;
2971
2972 eet_data_stream_flush(ds);
2973 *size_ret = csize;
2974
2975 free(chnk->data);
2976 eet_data_chunk_free(chnk);
2977
2978 return cdata;
2979} /* _eet_data_dump_encode */
2980
2981static void *
2982_eet_data_dump_parse(Eet_Dictionary *ed,
2983 int *size_ret,
2984 const char *src,
2985 int size)
2986{
2987 void *cdata = NULL;
2988 const char *p = NULL;
2989#define M_NONE 0
2990#define M_STRUCT 1
2991#define M_ 2
2992 int left, jump;
2993 Eet_Node *node_base = NULL;
2994 Eet_Node *node = NULL;
2995 Eet_Node *n = NULL, *nn = NULL;
2996
2997 /* FIXME; handle parse errors */
2998#define TOK_GET(t) \
2999 jump = left; t = _eet_data_dump_token_get(p, &left); p += jump - left;
3000 left = size;
3001 for (p = src; p < (src + size); )
3002 {
3003 char *tok1, *tok2, *tok3, *tok4;
3004
3005 TOK_GET(tok1);
3006 if (tok1)
3007 {
3008 if (!strcmp(tok1, "group"))
3009 {
3010 TOK_GET(tok2);
3011 if (tok2)
3012 {
3013 TOK_GET(tok3);
3014 if (tok3)
3015 {
3016 TOK_GET(tok4);
3017 if (tok4)
3018 {
3019 if (!strcmp(tok4, "{"))
3020 {
3021/* we have 'group NAM TYP {' */
3022 n = eet_node_new();
3023 if (n)
3024 {
3025 n->parent = node;
3026 if (!node_base)
3027 node_base = n;
3028
3029 if (node)
3030 {
3031/* append node */
3032 if (!node->values)
3033 node->values = n;
3034 else
3035 for (nn = node->values; nn;
3036 nn = nn->next)
3037 {
3038 if (!nn->next)
3039 {
3040 nn->next = n;
3041 break;
3042 }
3043 }
3044 }
3045
3046 n->name = eina_stringshare_add(tok2);
3047 if (!strcmp(tok3, "struct"))
3048 n->type = EET_G_UNKNOWN;
3049 else if (!strcmp(tok3, "array"))
3050 n->type = EET_G_ARRAY;
3051 else if (!strcmp(tok3, "var_array"))
3052 n->type = EET_G_VAR_ARRAY;
3053 else if (!strcmp(tok3, "list"))
3054 n->type = EET_G_LIST;
3055 else if (!strcmp(tok3, "hash"))
3056 n->type = EET_G_HASH;
3057 else
3058 ERR(
3059 "ERROR: group type '%s' invalid.",
3060 tok3);
3061
3062 node = n;
3063 }
3064 }
3065
3066 free(tok4);
3067 }
3068
3069 free(tok3);
3070 }
3071
3072 free(tok2);
3073 }
3074 }
3075 else if (!strcmp(tok1, "value"))
3076 {
3077 TOK_GET(tok2);
3078 if (tok2)
3079 {
3080 TOK_GET(tok3);
3081 if (tok3)
3082 {
3083 TOK_GET(tok4);
3084 if (tok4)
3085 {
3086/* we have 'value NAME TYP XXX' */
3087 if (node_base)
3088 {
3089 n = eet_node_new();
3090 if (n)
3091 {
3092 n->parent = node;
3093/* append node */
3094 if (!node->values)
3095 node->values = n;
3096 else
3097 for (nn = node->values; nn;
3098 nn = nn->next)
3099 {
3100 if (!nn->next)
3101 {
3102 nn->next = n;
3103 break;
3104 }
3105 }
3106
3107 n->name = eina_stringshare_add(tok2);
3108 if (!strcmp(tok3, "char:"))
3109 {
3110 n->type = EET_T_CHAR;
3111 sscanf(tok4, FMT_CHAR,
3112 &(n->data.value.c));
3113 }
3114 else if (!strcmp(tok3, "short:"))
3115 {
3116 n->type = EET_T_SHORT;
3117 sscanf(tok4, "%hi",
3118 &(n->data.value.s));
3119 }
3120 else if (!strcmp(tok3, "int:"))
3121 {
3122 n->type = EET_T_INT;
3123 sscanf(tok4, "%i",
3124 &(n->data.value.i));
3125 }
3126 else if (!strcmp(tok3, "long_long:"))
3127 {
3128 n->type = EET_T_LONG_LONG;
3129 sscanf(tok4, FMT_LONG_LONG,
3130 &(n->data.value.l));
3131 }
3132 else if (!strcmp(tok3, "float:"))
3133 {
3134 n->type = EET_T_FLOAT;
3135 sscanf(tok4, "%f",
3136 &(n->data.value.f));
3137 }
3138 else if (!strcmp(tok3, "double:"))
3139 {
3140 n->type = EET_T_DOUBLE;
3141 sscanf(tok4, "%lf",
3142 &(n->data.value.d));
3143 }
3144 else if (!strcmp(tok3, "uchar:"))
3145 {
3146 n->type = EET_T_UCHAR;
3147 sscanf(tok4, FMT_UCHAR,
3148 &(n->data.value.uc));
3149 }
3150 else if (!strcmp(tok3, "ushort:"))
3151 {
3152 n->type = EET_T_USHORT;
3153 sscanf(tok4, "%hu",
3154 &(n->data.value.us));
3155 }
3156 else if (!strcmp(tok3, "uint:"))
3157 {
3158 n->type = EET_T_UINT;
3159 sscanf(tok4, "%u",
3160 &(n->data.value.ui));
3161 }
3162 else if (!strcmp(tok3, "ulong_long:"))
3163 {
3164 n->type = EET_T_ULONG_LONG;
3165 sscanf(tok4, FMT_ULONG_LONG,
3166 &(n->data.value.ul));
3167 }
3168 else if (!strcmp(tok3, "string:"))
3169 {
3170 n->type = EET_T_STRING;
3171 n->data.value.str =
3172 eina_stringshare_add(tok4);
3173 }
3174 else if (!strcmp(tok3, "inlined:"))
3175 {
3176 n->type = EET_T_INLINED_STRING;
3177 n->data.value.str =
3178 eina_stringshare_add(tok4);
3179 }
3180 else if (!strcmp(tok3, "null"))
3181 {
3182 n->type = EET_T_NULL;
3183 n->data.value.str = NULL;
3184 }
3185 else
3186 ERR(
3187 "ERROR: value type '%s' invalid.",
3188 tok4);
3189 }
3190 }
3191
3192 free(tok4);
3193 }
3194
3195 free(tok3);
3196 }
3197
3198 free(tok2);
3199 }
3200 }
3201 else if (!strcmp(tok1, "key"))
3202 {
3203 TOK_GET(tok2);
3204 if (tok2)
3205 {
3206/* we have 'key NAME' */
3207 if (node)
3208 node->key = eina_stringshare_add(tok2);
3209
3210 free(tok2);
3211 }
3212 }
3213 else if (!strcmp(tok1, "count"))
3214 {
3215 TOK_GET(tok2);
3216 if (tok2)
3217 {
3218/* we have a 'count COUNT' */
3219 if (node)
3220 sscanf(tok2, "%i", &(node->count));
3221
3222 free(tok2);
3223 }
3224 }
3225 else if (!strcmp(tok1, "}"))
3226 /* we have an end of the group */
3227 if (node)
3228 node = node->parent;
3229
3230 free(tok1);
3231 }
3232 }
3233
3234 if (node_base)
3235 {
3236 cdata = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node_base, size_ret);
3237 eet_node_del(node_base);
3238 }
3239
3240 return cdata;
3241} /* _eet_data_dump_parse */
3242
3243#define NEXT_CHUNK(P, Size, Echnk, Ed) \
3244 { \
3245 int __tmp; \
3246 __tmp = Ed ? (int)(sizeof(int) * 2) : Echnk.len + 4; \
3247 P += (4 + Echnk.size + __tmp); \
3248 Size -= (4 + Echnk.size + __tmp); \
3249 }
3250
3251static void *
3252_eet_data_descriptor_decode(Eet_Free_Context *context,
3253 const Eet_Dictionary *ed,
3254 Eet_Data_Descriptor *edd,
3255 const void *data_in,
3256 int size_in,
3257 void *data_out,
3258 int size_out)
3259{
3260 Eet_Node *result = NULL;
3261 void *data = NULL;
3262 char *p;
3263 int size, i;
3264 Eet_Data_Chunk chnk;
3265
3266 if (_eet_data_words_bigendian == -1)
3267 {
3268 unsigned long int v;
3269
3270 v = htonl(0x12345678);
3271 if (v == 0x12345678)
3272 _eet_data_words_bigendian = 1;
3273 else
3274 _eet_data_words_bigendian = 0;
3275 }
3276
3277 if (edd)
3278 {
3279 if (data_out)
3280 {
3281 if (size_out <= edd->size)
3282 data = data_out;
3283 }
3284 else
3285 {
3286 data = edd->func.mem_alloc(edd->size);
3287 }
3288
3289 if (!data)
3290 return NULL;
3291
3292 if (edd->ed != ed)
3293 {
3294 for (i = 0; i < edd->elements.num; i++)
3295 edd->elements.set[i].directory_name_ptr = NULL;
3296 edd->ed = ed;
3297 }
3298 }
3299
3300 _eet_freelist_all_ref(context);
3301 if (data && !data_out)
3302 _eet_freelist_add(context, data);
3303
3304 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
3305 eet_data_chunk_get(ed, &chnk, data_in, size_in);
3306 if (!chnk.name)
3307 goto error;
3308
3309 if (edd)
3310 if (strcmp(chnk.name, edd->name))
3311 goto error;
3312
3313 p = chnk.data;
3314 if (ed)
3315 size = size_in - (4 + sizeof(int) * 2);
3316 else
3317 size = size_in - (4 + 4 + chnk.len);
3318
3319 if (edd)
3320 {
3321 if (!edd->elements.hash.buckets)
3322 _eet_descriptor_hash_new(edd);
3323 }
3324 else
3325 {
3326 switch (chnk.group_type)
3327 {
3328 case EET_G_UNKNOWN:
3329 switch (chnk.type)
3330 {
3331 case EET_T_STRING:
3332 return eet_node_string_new(chnk.name, chnk.data);
3333
3334 case EET_T_INLINED_STRING:
3335 return eet_node_inlined_string_new(chnk.name, chnk.data);
3336
3337 case EET_T_NULL:
3338 return eet_node_null_new(chnk.name);
3339
3340 default:
3341 result = eet_node_struct_new(chnk.name, NULL);
3342 } /* switch */
3343 break;
3344
3345 case EET_G_VAR_ARRAY:
3346 return eet_node_var_array_new(chnk.name, NULL);
3347
3348 case EET_G_LIST:
3349 case EET_G_HASH:
3350 case EET_G_ARRAY:
3351 case EET_G_UNION:
3352 case EET_G_VARIANT:
3353 default:
3354 goto error;
3355 } /* switch */
3356 }
3357
3358 while (size > 0)
3359 {
3360 Eet_Data_Chunk echnk;
3361 Eet_Data_Element *ede = NULL;
3362 Eet_Node *child = NULL;
3363 int group_type = EET_G_UNKNOWN, type = EET_T_UNKNOW;
3364 int ret = 0;
3365
3366 /* get next data chunk */
3367 memset(&echnk, 0, sizeof(Eet_Data_Chunk));
3368 eet_data_chunk_get(ed, &echnk, p, size);
3369 if (!echnk.name)
3370 goto error; /* FIXME: don't REPLY on edd - work without */
3371
3372 if (edd)
3373 {
3374 ede = _eet_descriptor_hash_find(edd, echnk.name, echnk.hash);
3375 if (ede)
3376 {
3377 group_type = ede->group_type;
3378 type = ede->type;
3379 if ((echnk.type == 0) && (echnk.group_type == 0))
3380 {
3381 type = ede->type;
3382 group_type = ede->group_type;
3383 }
3384 else
3385 {
3386 if (IS_SIMPLE_TYPE(echnk.type) &&
3387 eet_data_type_match(echnk.type, ede->type))
3388/* Needed when converting on the fly from FP to Float */
3389 type = ede->type;
3390 else if ((echnk.group_type > EET_G_UNKNOWN) &&
3391 (echnk.group_type < EET_G_LAST) &&
3392 (echnk.group_type == ede->group_type))
3393 group_type = echnk.group_type;
3394 }
3395 }
3396 }
3397 /*...... dump to node */
3398 else
3399 {
3400 type = echnk.type;
3401 group_type = echnk.group_type;
3402 }
3403
3404 if (!edd && group_type == EET_G_UNKNOWN && IS_SIMPLE_TYPE(type))
3405 {
3406 unsigned char dd[128];
3407
3408 ret = eet_data_get_type(ed,
3409 type,
3410 echnk.data,
3411 ((char *)echnk.data) + echnk.size,
3412 dd);
3413 if (ret <= 0)
3414 goto error;
3415
3416 child = eet_data_node_simple_type(type, echnk.name, dd);
3417
3418 eet_node_struct_append(result, echnk.name, child);
3419 }
3420 else
3421 {
3422 ret = eet_group_codec[group_type - 100].get(
3423 context,
3424 ed,
3425 edd,
3426 ede,
3427 &echnk,
3428 type,
3429 group_type,
3430 ede ? (void *)(((char *)data) + ede->offset) : (void **)&result,
3431 &p,
3432 &size);
3433
3434 if (ret <= 0)
3435 goto error;
3436 }
3437
3438 /* advance to next chunk */
3439 NEXT_CHUNK(p, size, echnk, ed);
3440 }
3441
3442 _eet_freelist_all_unref(context);
3443 if (!edd)
3444 {
3445 _eet_freelist_str_free(context, edd);
3446 _eet_freelist_direct_str_free(context, edd);
3447 _eet_freelist_list_free(context, edd);
3448 _eet_freelist_hash_free(context, edd);
3449 _eet_freelist_array_free(context, edd);
3450 _eet_freelist_free(context, edd);
3451 }
3452 else
3453 {
3454 _eet_freelist_reset(context);
3455 _eet_freelist_str_reset(context);
3456 _eet_freelist_list_reset(context);
3457 _eet_freelist_hash_reset(context);
3458 _eet_freelist_direct_str_reset(context);
3459 _eet_freelist_array_reset(context);
3460 }
3461
3462 if (!edd)
3463 return result;
3464
3465 return data;
3466
3467error:
3468 eet_node_del(result);
3469
3470 _eet_freelist_all_unref(context);
3471 _eet_freelist_str_free(context, edd);
3472 _eet_freelist_direct_str_free(context, edd);
3473 _eet_freelist_list_free(context, edd);
3474 _eet_freelist_hash_free(context, edd);
3475 _eet_freelist_array_free(context, edd);
3476 _eet_freelist_free(context, edd);
3477
3478 /* FIXME: Warn that something goes wrong here. */
3479 return NULL;
3480} /* _eet_data_descriptor_decode */
3481
3482static int
3483eet_data_get_list(Eet_Free_Context *context,
3484 const Eet_Dictionary *ed,
3485 Eet_Data_Descriptor *edd,
3486 Eet_Data_Element *ede,
3487 Eet_Data_Chunk *echnk,
3488 int type,
3489 int group_type __UNUSED__,
3490 void *data,
3491 char **p,
3492 int *size)
3493{
3494 Eet_Data_Descriptor *subtype = NULL;
3495 void *list = NULL;
3496 void **ptr;
3497 void *data_ret;
3498
3499 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3500
3501 if (ede)
3502 {
3503 subtype = ede->subtype;
3504
3505 if (type != ede->type)
3506 return 0;
3507 }
3508
3509 ptr = (void **)data;
3510 list = *ptr;
3511 data_ret = NULL;
3512
3513 if (IS_POINTER_TYPE(type))
3514 POINTER_TYPE_DECODE(context,
3515 ed,
3516 edd,
3517 ede,
3518 echnk,
3519 type,
3520 &data_ret,
3521 p,
3522 size,
3523 on_error);
3524 else
3525 STRUCT_TYPE_DECODE(data_ret,
3526 context,
3527 ed,
3528 subtype,
3529 echnk->data,
3530 echnk->size,
3531 -1,
3532 on_error);
3533
3534 if (edd)
3535 {
3536 list = edd->func.list_append(list, data_ret);
3537 *ptr = list;
3538 _eet_freelist_list_add(context, ptr);
3539 }
3540 else
3541 eet_node_list_append(*((Eet_Node **)data), echnk->name, data_ret);
3542
3543 return 1;
3544
3545on_error:
3546 return 0;
3547} /* eet_data_get_list */
3548
3549static int
3550eet_data_get_hash(Eet_Free_Context *context,
3551 const Eet_Dictionary *ed,
3552 Eet_Data_Descriptor *edd,
3553 Eet_Data_Element *ede,
3554 Eet_Data_Chunk *echnk,
3555 int type,
3556 int group_type __UNUSED__,
3557 void *data,
3558 char **p,
3559 int *size)
3560{
3561 void **ptr;
3562 void *hash = NULL;
3563 char *key = NULL;
3564 void *data_ret = NULL;
3565 int ret = 0;
3566
3567 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3568
3569 ptr = (void **)data;
3570 hash = *ptr;
3571
3572 /* Read key */
3573 ret = eet_data_get_type(ed,
3574 EET_T_STRING,
3575 echnk->data,
3576 ((char *)echnk->data) + echnk->size,
3577 &key);
3578 if (ret <= 0)
3579 goto on_error;
3580
3581 if (!key)
3582 goto on_error;
3583
3584 /* Advance to next chunk */
3585 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3586 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3587
3588 /* Read value */
3589 eet_data_chunk_get(ed, echnk, *p, *size);
3590 if (!echnk->name)
3591 goto on_error;
3592
3593 if (ede)
3594 if ((ede->group_type != echnk->group_type)
3595 || (ede->type != echnk->type))
3596 goto on_error;
3597
3598 if (IS_POINTER_TYPE(echnk->type))
3599 POINTER_TYPE_DECODE(context,
3600 ed,
3601 edd,
3602 ede,
3603 echnk,
3604 echnk->type,
3605 &data_ret,
3606 p,
3607 size,
3608 on_error);
3609 else
3610 STRUCT_TYPE_DECODE(data_ret,
3611 context,
3612 ed,
3613 ede ? ede->subtype : NULL,
3614 echnk->data,
3615 echnk->size,
3616 -1,
3617 on_error);
3618
3619 if (edd)
3620 {
3621 hash = edd->func.hash_add(hash, key, data_ret);
3622 *ptr = hash;
3623 _eet_freelist_hash_add(context, hash);
3624 }
3625 else
3626 eet_node_hash_add(*((Eet_Node **)data), echnk->name, key, data_ret);
3627
3628 return 1;
3629
3630on_error:
3631 return 0;
3632} /* eet_data_get_hash */
3633
3634/* var arrays and fixed arrays have to
3635 * get all chunks at once. for fixed arrays
3636 * we can get each chunk and increment a
3637 * counter stored on the element itself but
3638 * it wont be thread safe. for var arrays
3639 * we still need a way to get the number of
3640 * elements from the data, so storing the
3641 * number of elements and the element data on
3642 * each chunk is pointless.
3643 */
3644static int
3645eet_data_get_array(Eet_Free_Context *context,
3646 const Eet_Dictionary *ed,
3647 Eet_Data_Descriptor *edd,
3648 Eet_Data_Element *ede,
3649 Eet_Data_Chunk *echnk,
3650 int type,
3651 int group_type,
3652 void *data,
3653 char **p,
3654 int *size)
3655{
3656 Eina_List *childs = NULL;
3657 const char *name;
3658 Eet_Node *tmp;
3659 void *ptr;
3660 int count;
3661 int ret;
3662 int subsize = 0;
3663 int i;
3664
3665 EET_ASSERT(!((type > EET_T_UNKNOW) && (type < EET_T_STRING)), return 0);
3666
3667 ptr = data;
3668 /* read the number of elements */
3669 ret = eet_data_get_type(ed,
3670 EET_T_INT,
3671 echnk->data,
3672 ((char *)echnk->data) + echnk->size,
3673 &count);
3674 if (ret <= 0)
3675 return ret;
3676
3677 name = echnk->name;
3678
3679 if (ede)
3680 {
3681 if (IS_POINTER_TYPE(type))
3682 subsize = eet_basic_codec[ede->type].size;
3683 else
3684 subsize = ede->subtype->size;
3685
3686 if (group_type == EET_G_VAR_ARRAY)
3687 {
3688 /* store the number of elements
3689 * on the counter offset */
3690 *(int *)(((char *)data) + ede->count - ede->offset) = count;
3691 /* allocate space for the array of elements */
3692 if (edd->func.array_alloc)
3693 *(void **)ptr = edd->func.array_alloc(count * subsize);
3694 else
3695 *(void **)ptr = edd->func.mem_alloc(count * subsize);
3696
3697 if (!*(void **)ptr)
3698 return 0;
3699
3700 memset(*(void **)ptr, 0, count * subsize);
3701
3702 _eet_freelist_array_add(context, *(void **)ptr);
3703 }
3704 }
3705
3706 /* get all array elements */
3707 for (i = 0; i < count; i++)
3708 {
3709 void *dst = NULL;
3710
3711 /* Advance to next chunk */
3712 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3713 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3714
3715 eet_data_chunk_get(ed, echnk, *p, *size);
3716 if (!echnk->name || strcmp(echnk->name, name) != 0)
3717 goto on_error; /* get the data */
3718
3719 if ((echnk->group_type != group_type)
3720 || ((echnk->type != type) && (echnk->type != EET_T_NULL)))
3721 goto on_error;
3722
3723 if (ede)
3724 if ((ede->group_type != echnk->group_type)
3725 || ((echnk->type != ede->type) && (echnk->type != EET_T_NULL)))
3726 goto on_error;
3727
3728 /* get the destination pointer */
3729 if (ede)
3730 {
3731 if (group_type == EET_G_ARRAY)
3732 dst = (char *)ptr + (subsize * i);
3733 else
3734 dst = *(char **)ptr + (subsize * i);
3735 }
3736
3737 if (IS_POINTER_TYPE(echnk->type))
3738 {
3739 void *data_ret = NULL;
3740
3741 POINTER_TYPE_DECODE(context,
3742 ed,
3743 edd,
3744 ede,
3745 echnk,
3746 echnk->type,
3747 &data_ret,
3748 p,
3749 size,
3750 on_error);
3751 if (dst)
3752 memcpy(dst, &data_ret, subsize);
3753
3754 if (!edd)
3755 childs = eina_list_append(childs, data_ret);
3756 }
3757 else
3758 {
3759 STRUCT_TYPE_DECODE(dst,
3760 context,
3761 ed,
3762 ede ? ede->subtype : NULL,
3763 echnk->data,
3764 echnk->size,
3765 subsize,
3766 on_error);
3767
3768 if (!edd)
3769 childs = eina_list_append(childs, dst);
3770 }
3771 }
3772
3773 if (!edd)
3774 {
3775 Eet_Node *parent = *((Eet_Node **)data);
3776 Eet_Node *array;
3777
3778 if (group_type == EET_G_ARRAY)
3779 array = eet_node_array_new(name, count, childs);
3780 else
3781 array = eet_node_var_array_new(name, childs);
3782
3783 if (!array)
3784 goto on_error;
3785
3786 eet_node_struct_append(parent, name, array);
3787 }
3788
3789 return 1;
3790
3791on_error:
3792 EINA_LIST_FREE(childs, tmp)
3793 eet_node_del(tmp);
3794
3795 return 0;
3796} /* eet_data_get_array */
3797
3798static void
3799eet_data_put_union(Eet_Dictionary *ed,
3800 Eet_Data_Descriptor *edd __UNUSED__,
3801 Eet_Data_Element *ede,
3802 Eet_Data_Stream *ds,
3803 void *data_in)
3804{
3805 const char *union_type;
3806 int i;
3807
3808 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3809
3810 union_type = ede->subtype->func.type_get(
3811 ((char *)data_in) + ede->count - ede->offset,
3812 NULL);
3813
3814 if (!union_type)
3815 return;
3816
3817 /* Search the structure of the union to encode. */
3818 for (i = 0; i < ede->subtype->elements.num; ++i)
3819 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3820 {
3821 Eet_Data_Element *sede;
3822 void *data;
3823 int size;
3824
3825 /* Yeah we found it ! */
3826 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3827 if (data)
3828 eet_data_encode(ed,
3829 ds,
3830 data,
3831 ede->name,
3832 size,
3833 ede->type,
3834 ede->group_type);
3835
3836 sede = &(ede->subtype->elements.set[i]);
3837 data = _eet_data_descriptor_encode(ed,
3838 sede->subtype,
3839 data_in,
3840 &size);
3841 if (data)
3842 eet_data_encode(ed,
3843 ds,
3844 data,
3845 ede->name,
3846 size,
3847 ede->type,
3848 ede->group_type);
3849
3850 break;
3851 }
3852} /* eet_data_put_union */
3853
3854static int
3855eet_data_get_union(Eet_Free_Context *context,
3856 const Eet_Dictionary *ed,
3857 Eet_Data_Descriptor *edd __UNUSED__,
3858 Eet_Data_Element *ede,
3859 Eet_Data_Chunk *echnk,
3860 int type,
3861 int group_type,
3862 void *data,
3863 char **p,
3864 int *size)
3865{
3866 const char *union_type;
3867 void *data_ret = NULL;
3868 int ret = 0;
3869 int i;
3870
3871 /* Read type */
3872 ret = eet_data_get_type(ed,
3873 EET_T_STRING,
3874 echnk->data,
3875 ((char *)echnk->data) + echnk->size,
3876 &union_type);
3877 if (ret <= 0)
3878 goto on_error;
3879
3880 /* Advance to next chunk */
3881 NEXT_CHUNK((*p), (*size), (*echnk), ed);
3882 memset(echnk, 0, sizeof(Eet_Data_Chunk));
3883
3884 /* Read value */
3885 eet_data_chunk_get(ed, echnk, *p, *size);
3886 if (!echnk->name)
3887 goto on_error;
3888
3889 if (ede)
3890 {
3891 EET_ASSERT(!(ede->group_type != group_type || ede->type != type),
3892 goto on_error);
3893
3894 /* Search the structure of the union to decode */
3895 for (i = 0; i < ede->subtype->elements.num; ++i)
3896 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
3897 {
3898 Eet_Data_Element *sede;
3899 char *ut;
3900
3901 /* Yeah we found it ! */
3902 sede = &(ede->subtype->elements.set[i]);
3903 EET_ASSERT(sede->subtype, goto on_error);
3904
3905 data_ret = _eet_data_descriptor_decode(context,
3906 ed,
3907 sede->subtype,
3908 echnk->data,
3909 echnk->size,
3910 data,
3911 sede->subtype->size);
3912 if (!data_ret)
3913 goto on_error;
3914
3915 /* Set union type. */
3916 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
3917 {
3918 ut = ede->subtype->func.str_alloc(union_type);
3919 _eet_freelist_str_add(context, ut);
3920 }
3921 else
3922 {
3923 ut = ede->subtype->func.str_direct_alloc(union_type);
3924 _eet_freelist_direct_str_add(context, ut);
3925 }
3926
3927 ede->subtype->func.type_set(
3928 ut,
3929 ((char *)data) + ede->count -
3930 ede->offset,
3931 EINA_FALSE);
3932
3933 break;
3934 }
3935 }
3936 else
3937 {
3938 /* FIXME: generate node structure. */
3939 data_ret = _eet_data_descriptor_decode(context,
3940 ed, NULL,
3941 echnk->data, echnk->size,
3942 NULL, 0);
3943 goto on_error;
3944 }
3945
3946 return 1;
3947
3948on_error:
3949 return 0;
3950} /* eet_data_get_union */
3951
3952static void
3953eet_data_put_variant(Eet_Dictionary *ed,
3954 Eet_Data_Descriptor *edd __UNUSED__,
3955 Eet_Data_Element *ede,
3956 Eet_Data_Stream *ds,
3957 void *data_in)
3958{
3959 const char *union_type;
3960 void *data;
3961 Eina_Bool unknow = EINA_FALSE;
3962 int size;
3963 int i;
3964
3965 EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
3966
3967 union_type = ede->subtype->func.type_get(
3968 ((char *)data_in) + ede->count - ede->offset,
3969 &unknow);
3970
3971 if (!union_type && unknow == EINA_FALSE)
3972 return;
3973
3974 if (unknow)
3975 {
3976 /* Handle opaque internal representation */
3977 Eet_Variant_Unknow *evu;
3978
3979 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
3980 if (data)
3981 eet_data_encode(ed,
3982 ds,
3983 data,
3984 ede->name,
3985 size,
3986 ede->type,
3987 ede->group_type);
3988
3989 evu = (Eet_Variant_Unknow *)data_in;
3990 if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT))
3991 eet_data_encode(ed,
3992 ds,
3993 evu->data,
3994 ede->name,
3995 evu->size,
3996 ede->type,
3997 ede->group_type);
3998 }
3999 else
4000 /* Search the structure of the union to encode. */
4001 for (i = 0; i < ede->subtype->elements.num; ++i)
4002 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
4003 {
4004 Eet_Data_Element *sede;
4005
4006 /* Yeah we found it ! */
4007 data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
4008 if (data)
4009 eet_data_encode(ed,
4010 ds,
4011 data,
4012 ede->name,
4013 size,
4014 ede->type,
4015 ede->group_type);
4016
4017 sede = &(ede->subtype->elements.set[i]);
4018
4019 if (sede->group_type != EET_G_UNKNOWN)
4020 {
4021 Eet_Data_Stream *lds;
4022
4023 lds = eet_data_stream_new();
4024 eet_group_codec[sede->group_type - 100].put(ed,
4025 sede->subtype,
4026 sede,
4027 lds,
4028 data_in);
4029 if (lds->size != 0)
4030 {
4031 eet_data_encode(ed, ds, lds->data, ede->name, lds->pos,
4032 ede->type, ede->group_type);
4033
4034 lds->data = NULL;
4035 lds->size = 0;
4036 }
4037 else
4038 eet_data_encode(ed, ds, NULL, ede->name, 0,
4039 EET_T_NULL, ede->group_type);
4040
4041 eet_data_stream_free(lds);
4042 }
4043 else
4044 {
4045 data = _eet_data_descriptor_encode(ed,
4046 sede->subtype,
4047 *(void **)data_in,
4048 &size);
4049 if (data)
4050 eet_data_encode(ed,
4051 ds,
4052 data,
4053 ede->name,
4054 size,
4055 ede->type,
4056 ede->group_type);
4057 }
4058
4059 break;
4060 }
4061} /* eet_data_put_variant */
4062
4063static int
4064eet_data_get_variant(Eet_Free_Context *context,
4065 const Eet_Dictionary *ed,
4066 Eet_Data_Descriptor *edd __UNUSED__,
4067 Eet_Data_Element *ede,
4068 Eet_Data_Chunk *echnk,
4069 int type __UNUSED__,
4070 int group_type __UNUSED__,
4071 void *data,
4072 char **p,
4073 int *size)
4074{
4075 const char *union_type;
4076 void *data_ret = NULL;
4077 int ret = 0;
4078 int i;
4079
4080 /* Read type */
4081 ret = eet_data_get_type(ed,
4082 EET_T_STRING,
4083 echnk->data,
4084 ((char *)echnk->data) + echnk->size,
4085 &union_type);
4086 if (ret <= 0)
4087 goto on_error;
4088
4089 /* Advance to next chunk */
4090 NEXT_CHUNK((*p), (*size), (*echnk), ed);
4091 memset(echnk, 0, sizeof(Eet_Data_Chunk));
4092
4093 /* Read value */
4094 eet_data_chunk_get(ed, echnk, *p, *size);
4095 if (!echnk->name)
4096 goto on_error;
4097
4098 if (ede)
4099 {
4100 char *ut;
4101
4102 EET_ASSERT(ede->subtype, goto on_error);
4103
4104 if ((!ed) || (!ede->subtype->func.str_direct_alloc))
4105 {
4106 ut = ede->subtype->func.str_alloc(union_type);
4107 _eet_freelist_str_add(context, ut);
4108 }
4109 else
4110 {
4111 ut = ede->subtype->func.str_direct_alloc(union_type);
4112 _eet_freelist_direct_str_add(context, ut);
4113 }
4114
4115 /* Search the structure of the union to decode */
4116 for (i = 0; i < ede->subtype->elements.num; ++i)
4117 if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
4118 {
4119 Eet_Data_Element *sede;
4120
4121 /* Yeah we found it ! */
4122 sede = &(ede->subtype->elements.set[i]);
4123
4124 if (sede->group_type != EET_G_UNKNOWN)
4125 {
4126 Eet_Data_Chunk chnk;
4127 char *p2;
4128 int size2;
4129
4130 p2 = echnk->data;
4131 size2 = echnk->size;
4132
4133 /* Didn't find a proper way to provide this
4134 without duplicating code */
4135 while (size2 > 0)
4136 {
4137 memset(&chnk, 0, sizeof(Eet_Data_Chunk));
4138 eet_data_chunk_get(ed, &chnk, p2, size2);
4139
4140 if (!chnk.name)
4141 goto on_error;
4142
4143 ret = eet_group_codec[sede->group_type - 100].get
4144 (context, ed, sede->subtype, sede, &chnk, sede->type,
4145 sede->group_type, data, &p2, &size2);
4146
4147 if (ret <= 0)
4148 goto on_error;
4149
4150/* advance to next chunk */
4151 NEXT_CHUNK(p2, size2, chnk, ed);
4152 }
4153
4154 /* Put garbage so that we will not put eet_variant_unknow in it */
4155 data_ret = (void *)data;
4156
4157 /* Set variant type. */
4158 ede->subtype->func.type_set
4159 (ut, ((char *)data) + ede->count - ede->offset,
4160 EINA_FALSE);
4161 break;
4162 }
4163
4164 data_ret = _eet_data_descriptor_decode(context,
4165 ed,
4166 sede->subtype,
4167 echnk->data,
4168 echnk->size,
4169 NULL, 0);
4170 if (!data_ret)
4171 break;
4172
4173 /* And point to the variant data. */
4174 *(void **)data = data_ret;
4175
4176 /* Set variant type. */
4177 ede->subtype->func.type_set
4178 (ut, ((char *)data) + ede->count - ede->offset, EINA_FALSE);
4179 break;
4180 }
4181
4182 if (!data_ret)
4183 {
4184 Eet_Variant_Unknow *evu;
4185
4186 evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1);
4187 if (!evu)
4188 goto on_error;
4189
4190 evu->size = echnk->size;
4191 memcpy(evu->data, echnk->data, evu->size);
4192 EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT);
4193
4194 /* And point to the opaque internal data scructure */
4195 *(void **)data = evu;
4196
4197 /* Set variant type. */
4198 ede->subtype->func.type_set
4199 (ut, ((char *)data) + ede->count - ede->offset, EINA_TRUE);
4200 }
4201 }
4202 else
4203 {
4204 /* FIXME: dump node structure. */
4205 data_ret = _eet_data_descriptor_decode(context,
4206 ed, NULL,
4207 echnk->data, echnk->size,
4208 NULL, 0);
4209 goto on_error;
4210 }
4211
4212 return 1;
4213
4214on_error:
4215 return 0;
4216} /* eet_data_get_variant */
4217
4218static Eet_Node *
4219eet_data_node_simple_type(int type,
4220 const char *name,
4221 void *dd)
4222{
4223#ifdef EET_T_TYPE
4224# undef EET_T_TYPE
4225#endif /* ifdef EET_T_TYPE */
4226
4227#define EET_T_TYPE(Eet_Type, Eet_Node_Type, Type) \
4228case Eet_Type: \
4229 return eet_node_ ## Eet_Node_Type ## _new(name, *((Type *)dd)); \
4230
4231 switch (type)
4232 {
4233 EET_T_TYPE(EET_T_CHAR, char, char);
4234 EET_T_TYPE(EET_T_SHORT, short, short);
4235 EET_T_TYPE(EET_T_INT, int, int);
4236 EET_T_TYPE(EET_T_LONG_LONG, long_long, long long);
4237 EET_T_TYPE(EET_T_FLOAT, float, float);
4238 EET_T_TYPE(EET_T_DOUBLE, double, double);
4239 EET_T_TYPE(EET_T_UCHAR, unsigned_char, unsigned char);
4240 EET_T_TYPE(EET_T_USHORT, unsigned_short, unsigned short);
4241 EET_T_TYPE(EET_T_UINT, unsigned_int, unsigned int);
4242 EET_T_TYPE(EET_T_ULONG_LONG, unsigned_long_long, unsigned long long);
4243 EET_T_TYPE(EET_T_STRING, string, char *);
4244 EET_T_TYPE(EET_T_INLINED_STRING, inlined_string, char *);
4245
4246 case EET_T_NULL:
4247 return eet_node_null_new(name);
4248
4249 default:
4250 ERR("Unknow type passed to eet_data_node_simple_type");
4251 return NULL;
4252 } /* switch */
4253} /* eet_data_node_simple_type */
4254
4255static int
4256eet_data_get_unknown(Eet_Free_Context *context,
4257 const Eet_Dictionary *ed,
4258 Eet_Data_Descriptor *edd,
4259 Eet_Data_Element *ede,
4260 Eet_Data_Chunk *echnk,
4261 int type,
4262 int group_type __UNUSED__,
4263 void *data,
4264 char **p __UNUSED__,
4265 int *size __UNUSED__)
4266{
4267 int ret;
4268 void *data_ret;
4269
4270 if (IS_SIMPLE_TYPE(type))
4271 {
4272 unsigned char dd[128];
4273
4274 ret = eet_data_get_type(ed,
4275 type,
4276 echnk->data,
4277 ((char *)echnk->data) + echnk->size,
4278 edd ? (char *)data : (char *)dd);
4279 if (ret <= 0)
4280 return ret;
4281
4282 if (!edd)
4283 {
4284 Eet_Node **parent = data;
4285 Eet_Node *node;
4286
4287 node = eet_data_node_simple_type(type, echnk->name, dd);
4288
4289 if (*parent)
4290 eet_node_struct_append(*parent, echnk->name, node);
4291 else
4292 *parent = node;
4293 }
4294 else
4295 {
4296 if (type == EET_T_STRING)
4297 {
4298 char **str;
4299
4300 str = (char **)(((char *)data));
4301 if (*str)
4302 {
4303 if ((!ed) || (!edd->func.str_direct_alloc))
4304 {
4305 *str = edd->func.str_alloc(*str);
4306 _eet_freelist_str_add(context, *str);
4307 }
4308 else
4309 {
4310 *str = edd->func.str_direct_alloc(*str);
4311 _eet_freelist_direct_str_add(context, *str);
4312 }
4313 }
4314 }
4315 else if (edd && type == EET_T_INLINED_STRING)
4316 {
4317 char **str;
4318
4319 str = (char **)(((char *)data));
4320 if (*str)
4321 {
4322 *str = edd->func.str_alloc(*str);
4323 _eet_freelist_str_add(context, *str);
4324 }
4325 }
4326 }
4327 }
4328 else
4329 {
4330 Eet_Data_Descriptor *subtype;
4331
4332 subtype = ede ? ede->subtype : NULL;
4333
4334 if (subtype || !edd)
4335 {
4336 Eet_Node **parent = data;
4337 void **ptr;
4338
4339 data_ret = _eet_data_descriptor_decode(context,
4340 ed,
4341 subtype,
4342 echnk->data,
4343 echnk->size,
4344 NULL, 0);
4345 if (!data_ret)
4346 return 0;
4347
4348 if (edd)
4349 {
4350 ptr = (void **)(((char *)data));
4351 *ptr = (void *)data_ret;
4352 }
4353 else
4354 {
4355 Eet_Node *node = data_ret;
4356
4357 if (*parent)
4358 {
4359 node = eet_node_struct_child_new(echnk->name, node);
4360 eet_node_struct_append(*parent, echnk->name, node);
4361 }
4362 else
4363 *parent = node;
4364 }
4365 }
4366 }
4367
4368 return 1;
4369} /* eet_data_get_unknown */
4370
4371static void
4372eet_data_put_array(Eet_Dictionary *ed,
4373 Eet_Data_Descriptor *edd __UNUSED__,
4374 Eet_Data_Element *ede,
4375 Eet_Data_Stream *ds,
4376 void *data_in)
4377{
4378 void *data;
4379 int offset = 0;
4380 int subsize;
4381 int count;
4382 int size;
4383 int j;
4384
4385 EET_ASSERT(!((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING)),
4386 return );
4387
4388 if (ede->group_type == EET_G_ARRAY)
4389 count = ede->counter_offset;
4390 else
4391 count = *(int *)(((char *)data_in) + ede->count - ede->offset);
4392
4393 if (count <= 0)
4394 return; /* Store number of elements */
4395
4396 data = eet_data_put_type(ed, EET_T_INT, &count, &size);
4397 if (data)
4398 eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
4399
4400 if (IS_POINTER_TYPE(ede->type))
4401 subsize = eet_basic_codec[ede->type].size;
4402 else
4403 subsize = ede->subtype->size;
4404
4405 for (j = 0; j < count; j++)
4406 {
4407 void *d;
4408 int pos = ds->pos;
4409
4410 if (ede->group_type == EET_G_ARRAY)
4411 d = (void *)(((char *)data_in) + offset);
4412 else
4413 d = *(((char **)data_in)) + offset;
4414
4415 if (IS_POINTER_TYPE(ede->type))
4416 {
4417 if (*(char **)d)
4418 eet_data_put_unknown(ed, NULL, ede, ds, d);
4419 }
4420 else
4421 {
4422 data = _eet_data_descriptor_encode(ed, ede->subtype, d, &size);
4423 if (data)
4424 eet_data_encode(ed,
4425 ds,
4426 data,
4427 ede->name,
4428 size,
4429 ede->type,
4430 ede->group_type);
4431 }
4432
4433 if (pos == ds->pos)
4434 /* Add a NULL element just to have the correct array layout. */
4435 eet_data_encode(ed,
4436 ds,
4437 NULL,
4438 ede->name,
4439 0,
4440 EET_T_NULL,
4441 ede->group_type);
4442
4443 offset += subsize;
4444 }
4445} /* eet_data_put_array */
4446
4447static void
4448eet_data_put_unknown(Eet_Dictionary *ed,
4449 Eet_Data_Descriptor *edd __UNUSED__,
4450 Eet_Data_Element *ede,
4451 Eet_Data_Stream *ds,
4452 void *data_in)
4453{
4454 void *data = NULL;
4455 int size;
4456
4457 if (IS_SIMPLE_TYPE(ede->type))
4458 data = eet_data_put_type(ed, ede->type, data_in, &size);
4459 else if (ede->subtype)
4460 if (*((char **)data_in))
4461 data = _eet_data_descriptor_encode(ed,
4462 ede->subtype,
4463 *((char **)((char *)(data_in))),
4464 &size);
4465
4466 if (data)
4467 eet_data_encode(ed,
4468 ds,
4469 data,
4470 ede->name,
4471 size,
4472 ede->type,
4473 ede->group_type);
4474} /* eet_data_put_unknown */
4475
4476static void
4477eet_data_put_list(Eet_Dictionary *ed,
4478 Eet_Data_Descriptor *edd,
4479 Eet_Data_Element *ede,
4480 Eet_Data_Stream *ds,
4481 void *data_in)
4482{
4483 void *data;
4484 void *l;
4485 int size;
4486
4487 EET_ASSERT(!(((ede->type > EET_T_UNKNOW) && (ede->type < EET_T_STRING))
4488 || ((ede->type > EET_T_NULL) && (ede->type < EET_T_LAST))),
4489 return );
4490
4491 l = *((void **)(((char *)data_in)));
4492 for (; l; l = edd->func.list_next(l))
4493 {
4494 if (IS_POINTER_TYPE(ede->type))
4495 {
4496 const void *str = edd->func.list_data(l);
4497 eet_data_put_unknown(ed, NULL, ede, ds, &str);
4498 }
4499 else
4500 {
4501 data = _eet_data_descriptor_encode(ed,
4502 ede->subtype,
4503 edd->func.list_data(l),
4504 &size);
4505 if (data)
4506 eet_data_encode(ed,
4507 ds,
4508 data,
4509 ede->name,
4510 size,
4511 ede->type,
4512 ede->group_type);
4513 }
4514 }
4515} /* eet_data_put_list */
4516
4517static void
4518eet_data_put_hash(Eet_Dictionary *ed,
4519 Eet_Data_Descriptor *edd,
4520 Eet_Data_Element *ede,
4521 Eet_Data_Stream *ds,
4522 void *data_in)
4523{
4524 Eet_Data_Encode_Hash_Info fdata;
4525 void *l;
4526
4527 l = *((void **)(((char *)data_in)));
4528 fdata.ds = ds;
4529 fdata.ede = ede;
4530 fdata.ed = ed;
4531 edd->func.hash_foreach(l, eet_data_descriptor_encode_hash_cb, &fdata);
4532} /* eet_data_put_hash */
4533
4534EAPI int
4535eet_data_dump_cipher(Eet_File *ef,
4536 const char *name,
4537 const char *cipher_key,
4538 Eet_Dump_Callback dumpfunc,
4539 void *dumpdata)
4540{
4541 const Eet_Dictionary *ed = NULL;
4542 const void *data = NULL;
4543 Eet_Node *result;
4544 Eet_Free_Context context;
4545 int required_free = 0;
4546 int size;
4547
4548 ed = eet_dictionary_get(ef);
4549
4550 if (!cipher_key)
4551 data = eet_read_direct(ef, name, &size);
4552
4553 if (!data)
4554 {
4555 required_free = 1;
4556 data = eet_read_cipher(ef, name, &size, cipher_key);
4557 if (!data)
4558 return 0;
4559 }
4560
4561 eet_free_context_init(&context);
4562 result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0);
4563 eet_free_context_shutdown(&context);
4564
4565 eet_node_dump(result, 0, dumpfunc, dumpdata);
4566
4567 eet_node_del(result);
4568
4569 if (required_free)
4570 free((void *)data);
4571
4572 return result ? 1 : 0;
4573} /* eet_data_dump_cipher */
4574
4575EAPI int
4576eet_data_dump(Eet_File *ef,
4577 const char *name,
4578 Eet_Dump_Callback dumpfunc,
4579 void *dumpdata)
4580{
4581 return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
4582} /* eet_data_dump */
4583
4584EAPI int
4585eet_data_text_dump_cipher(const void *data_in,
4586 const char *cipher_key,
4587 int size_in,
4588 Eet_Dump_Callback dumpfunc,
4589 void *dumpdata)
4590{
4591 void *ret = NULL;
4592 Eet_Node *result;
4593 Eet_Free_Context context;
4594 unsigned int ret_len = 0;
4595
4596 if (!data_in)
4597 return 0;
4598
4599 if (cipher_key)
4600 {
4601 if (eet_decipher(data_in, size_in, cipher_key,
4602 strlen(cipher_key), &ret, &ret_len))
4603 {
4604 if (ret)
4605 free(ret);
4606
4607 return 0;
4608 }
4609 }
4610 else
4611 {
4612 ret = (void *)data_in;
4613 ret_len = size_in;
4614 }
4615
4616 eet_free_context_init(&context);
4617 result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len, NULL, 0);
4618 eet_free_context_shutdown(&context);
4619
4620 eet_node_dump(result, 0, dumpfunc, dumpdata);
4621
4622 eet_node_del(result);
4623 if (cipher_key)
4624 free(ret);
4625
4626 return result ? 1 : 0;
4627} /* eet_data_text_dump_cipher */
4628
4629EAPI int
4630eet_data_text_dump(const void *data_in,
4631 int size_in,
4632 Eet_Dump_Callback dumpfunc,
4633 void *dumpdata)
4634{
4635 return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
4636} /* eet_data_text_dump */
4637
4638EAPI void *
4639eet_data_text_undump_cipher(const char *text,
4640 const char *cipher_key,
4641 int textlen,
4642 int *size_ret)
4643{
4644 void *ret = NULL;
4645
4646 ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
4647 if (ret && cipher_key)
4648 {
4649 void *ciphered = NULL;
4650 unsigned int ciphered_len;
4651
4652 if (eet_cipher(ret, *size_ret, cipher_key,
4653 strlen(cipher_key), &ciphered, &ciphered_len))
4654 {
4655 if (ciphered)
4656 free(ciphered);
4657
4658 size_ret = 0;
4659 free(ret);
4660 return NULL;
4661 }
4662
4663 free(ret);
4664 *size_ret = ciphered_len;
4665 ret = ciphered;
4666 }
4667
4668 return ret;
4669} /* eet_data_text_undump_cipher */
4670
4671EAPI void *
4672eet_data_text_undump(const char *text,
4673 int textlen,
4674 int *size_ret)
4675{
4676 return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
4677} /* eet_data_text_undump */
4678
4679EAPI int
4680eet_data_undump_cipher(Eet_File *ef,
4681 const char *name,
4682 const char *cipher_key,
4683 const char *text,
4684 int textlen,
4685 int compress)
4686{
4687 Eet_Dictionary *ed;
4688 void *data_enc;
4689 int size;
4690 int val;
4691
4692 ed = eet_dictionary_get(ef);
4693
4694 data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
4695 if (!data_enc)
4696 return 0;
4697
4698 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4699 free(data_enc);
4700 return val;
4701} /* eet_data_undump_cipher */
4702
4703EAPI int
4704eet_data_undump(Eet_File *ef,
4705 const char *name,
4706 const char *text,
4707 int textlen,
4708 int compress)
4709{
4710 return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
4711} /* eet_data_undump */
4712
4713EAPI void *
4714eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
4715 const void *data_in,
4716 const char *cipher_key,
4717 int size_in)
4718{
4719 void *deciphered = (void *)data_in;
4720 void *ret;
4721 Eet_Free_Context context;
4722 unsigned int deciphered_len = size_in;
4723
4724 if (cipher_key && data_in)
4725 if (eet_decipher(data_in, size_in, cipher_key,
4726 strlen(cipher_key), &deciphered, &deciphered_len))
4727 {
4728 if (deciphered)
4729 free(deciphered);
4730
4731 return NULL;
4732 }
4733
4734 eet_free_context_init(&context);
4735 ret = _eet_data_descriptor_decode(&context,
4736 NULL,
4737 edd,
4738 deciphered,
4739 deciphered_len,
4740 NULL, 0);
4741 eet_free_context_shutdown(&context);
4742
4743 if (data_in != deciphered)
4744 free(deciphered);
4745
4746 return ret;
4747} /* eet_data_descriptor_decode_cipher */
4748
4749EAPI void *
4750eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
4751 const void *data_in,
4752 int size_in)
4753{
4754 return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
4755} /* eet_data_descriptor_decode */
4756
4757EAPI Eet_Node *
4758eet_data_node_decode_cipher(const void *data_in,
4759 const char *cipher_key,
4760 int size_in)
4761{
4762 void *deciphered = (void *)data_in;
4763 Eet_Node *ret;
4764 Eet_Free_Context context;
4765 unsigned int deciphered_len = size_in;
4766
4767 if (cipher_key && data_in)
4768 if (eet_decipher(data_in, size_in, cipher_key,
4769 strlen(cipher_key), &deciphered, &deciphered_len))
4770 {
4771 if (deciphered)
4772 free(deciphered);
4773
4774 return NULL;
4775 }
4776
4777 eet_free_context_init(&context);
4778 ret = _eet_data_descriptor_decode(&context,
4779 NULL,
4780 NULL,
4781 deciphered,
4782 deciphered_len,
4783 NULL, 0);
4784 eet_free_context_shutdown(&context);
4785
4786 if (data_in != deciphered)
4787 free(deciphered);
4788
4789 return ret;
4790} /* eet_data_node_decode_cipher */
4791
4792static void *
4793_eet_data_descriptor_encode(Eet_Dictionary *ed,
4794 Eet_Data_Descriptor *edd,
4795 const void *data_in,
4796 int *size_ret)
4797{
4798 Eet_Data_Stream *ds;
4799 Eet_Data_Chunk *chnk;
4800 void *cdata;
4801 int csize;
4802 int i;
4803
4804 if (_eet_data_words_bigendian == -1)
4805 {
4806 unsigned long int v;
4807
4808 v = htonl(0x12345678);
4809 if (v == 0x12345678)
4810 _eet_data_words_bigendian = 1;
4811 else
4812 _eet_data_words_bigendian = 0;
4813 }
4814
4815 ds = eet_data_stream_new();
4816 for (i = 0; i < edd->elements.num; i++)
4817 {
4818 Eet_Data_Element *ede;
4819
4820 ede = &(edd->elements.set[i]);
4821 eet_group_codec[ede->group_type - 100].put(
4822 ed,
4823 edd,
4824 ede,
4825 ds,
4826 ((char *)data_in) +
4827 ede->offset);
4828 }
4829 chnk = eet_data_chunk_new(ds->data,
4830 ds->pos,
4831 edd->name,
4832 EET_T_UNKNOW,
4833 EET_G_UNKNOWN);
4834 ds->data = NULL;
4835 ds->size = 0;
4836 eet_data_stream_free(ds);
4837
4838 ds = eet_data_stream_new();
4839 eet_data_chunk_put(ed, chnk, ds);
4840 cdata = ds->data;
4841 csize = ds->pos;
4842
4843 ds->data = NULL;
4844 ds->size = 0;
4845 eet_data_stream_free(ds);
4846 *size_ret = csize;
4847
4848 free(chnk->data);
4849 eet_data_chunk_free(chnk);
4850
4851 return cdata;
4852} /* _eet_data_descriptor_encode */
4853
4854EAPI int
4855eet_data_node_write_cipher(Eet_File *ef,
4856 const char *name,
4857 const char *cipher_key,
4858 Eet_Node *node,
4859 int compress)
4860{
4861 Eet_Dictionary *ed;
4862 void *data_enc;
4863 int size;
4864 int val;
4865
4866 ed = eet_dictionary_get(ef);
4867
4868 data_enc = _eet_data_dump_encode(EET_G_UNKNOWN, ed, node, &size);
4869 if (!data_enc)
4870 return 0;
4871
4872 val = eet_write_cipher(ef, name, data_enc, size, compress, cipher_key);
4873 free(data_enc);
4874 return val;
4875} /* eet_data_node_write_cipher */
4876
4877EAPI void *
4878eet_data_node_encode_cipher(Eet_Node *node,
4879 const char *cipher_key,
4880 int *size_ret)
4881{
4882 void *ret = NULL;
4883 void *ciphered = NULL;
4884 unsigned int ciphered_len = 0;
4885 int size;
4886
4887 ret = _eet_data_dump_encode(EET_G_UNKNOWN, NULL, node, &size);
4888 if (cipher_key && ret)
4889 {
4890 if (eet_cipher(ret, size, cipher_key,
4891 strlen(cipher_key), &ciphered, &ciphered_len))
4892 {
4893 if (ciphered)
4894 free(ciphered);
4895
4896 if (size_ret)
4897 *size_ret = 0;
4898
4899 free(ret);
4900 return NULL;
4901 }
4902
4903 free(ret);
4904 size = (int)ciphered_len;
4905 ret = ciphered;
4906 }
4907
4908 if (size_ret)
4909 *size_ret = size;
4910
4911 return ret;
4912} /* eet_data_node_encode_cipher */
4913
4914EAPI void *
4915eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
4916 const void *data_in,
4917 const char *cipher_key,
4918 int *size_ret)
4919{
4920 void *ret = NULL;
4921 void *ciphered = NULL;
4922 unsigned int ciphered_len = 0;
4923 int size;
4924
4925 ret = _eet_data_descriptor_encode(NULL, edd, data_in, &size);
4926 if (cipher_key && ret)
4927 {
4928 if (eet_cipher(ret, size, cipher_key,
4929 strlen(cipher_key), &ciphered, &ciphered_len))
4930 {
4931 if (ciphered)
4932 free(ciphered);
4933
4934 if (size_ret)
4935 *size_ret = 0;
4936
4937 free(ret);
4938 return NULL;
4939 }
4940
4941 free(ret);
4942 size = ciphered_len;
4943 ret = ciphered;
4944 }
4945
4946 if (size_ret)
4947 *size_ret = size;
4948
4949 return ret;
4950} /* eet_data_descriptor_encode_cipher */
4951
4952EAPI void *
4953eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
4954 const void *data_in,
4955 int *size_ret)
4956{
4957 return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);
4958} /* eet_data_descriptor_encode */
4959
4960EAPI void *
4961eet_data_xattr_cipher_get(const char *filename,
4962 const char *attribute,
4963 Eet_Data_Descriptor *edd,
4964 const char *cipher_key)
4965{
4966 void *blob;
4967 void *ret;
4968 ssize_t size;
4969
4970 blob = eina_xattr_get(filename, attribute, &size);
4971 if (!blob) return NULL;
4972
4973 ret = eet_data_descriptor_decode_cipher(edd, blob, cipher_key, size);
4974 free(blob);
4975
4976 return ret;
4977}
4978
4979EAPI Eina_Bool
4980eet_data_xattr_cipher_set(const char *filename,
4981 const char *attribute,
4982 Eet_Data_Descriptor *edd,
4983 const char *cipher_key,
4984 const void *data,
4985 Eina_Xattr_Flags flags)
4986{
4987 void *blob;
4988 int size;
4989 Eina_Bool ret;
4990
4991 blob = eet_data_descriptor_encode_cipher(edd, data, cipher_key, &size);
4992 if (!blob) return EINA_FALSE;
4993
4994 ret = eina_xattr_set(filename, attribute, blob, size, flags);
4995 free(blob);
4996
4997 return ret;
4998}
4999
diff --git a/libraries/eet/src/lib/eet_dictionary.c b/libraries/eet/src/lib/eet_dictionary.c
new file mode 100644
index 0000000..60d0ec1
--- /dev/null
+++ b/libraries/eet/src/lib/eet_dictionary.c
@@ -0,0 +1,439 @@
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
9#include <Eina.h>
10
11#include "Eet.h"
12#include "Eet_private.h"
13
14Eet_Dictionary *
15eet_dictionary_add(void)
16{
17 Eet_Dictionary *new;
18
19 new = calloc(1, sizeof (Eet_Dictionary));
20 if (!new)
21 return NULL;
22
23 memset(new->hash, -1, sizeof (int) * 256);
24
25 return new;
26} /* eet_dictionary_add */
27
28void
29eet_dictionary_free(Eet_Dictionary *ed)
30{
31 if (ed)
32 {
33 int i;
34
35 for (i = 0; i < ed->count; ++i)
36 if (ed->all[i].allocated)
37 eina_stringshare_del(ed->all[i].str);
38
39 if (ed->all)
40 free(ed->all);
41
42 if (ed->converts) eina_hash_free(ed->converts);
43
44 free(ed);
45 }
46} /* eet_dictionary_free */
47
48static int
49_eet_dictionary_lookup(Eet_Dictionary *ed,
50 const char *string,
51 int len,
52 int hash)
53{
54 Eina_Bool found = EINA_FALSE;
55 int prev = -1;
56 int current;
57
58 current = ed->hash[hash];
59
60 while (current != -1)
61 {
62 if (ed->all[current].len == len)
63 {
64 if (ed->all[current].str &&
65 (ed->all[current].str == string || strcmp(ed->all[current].str, string) == 0))
66 {
67 found = EINA_TRUE;
68 break;
69 }
70 }
71
72 prev = current;
73 current = ed->all[current].next;
74 }
75
76 if (current == -1 && found)
77 return prev;
78
79 return current;
80} /* _eet_dictionary_lookup */
81
82int
83eet_dictionary_string_add(Eet_Dictionary *ed,
84 const char *string)
85{
86 Eet_String *current;
87 const char *str;
88 int hash;
89 int idx;
90 int len;
91
92 if (!ed)
93 return -1;
94
95 hash = _eet_hash_gen(string, 8);
96 len = strlen(string) + 1;
97
98 idx = _eet_dictionary_lookup(ed, string, len, hash);
99
100 if (idx != -1)
101 {
102 if (ed->all[idx].str && (ed->all[idx].str == string || strcmp(ed->all[idx].str, string) == 0))
103 return idx;
104 }
105
106 if (ed->total == ed->count)
107 {
108 Eet_String *new;
109 int total;
110
111 total = ed->total + 8;
112
113 new = realloc(ed->all, sizeof (Eet_String) * total);
114 if (!new)
115 return -1;
116
117 ed->all = new;
118 ed->total = total;
119 }
120
121 str = eina_stringshare_add(string);
122 if (!str)
123 return -1;
124
125 current = ed->all + ed->count;
126
127 current->allocated = EINA_TRUE;
128
129 current->hash = hash;
130
131 current->str = str;
132 current->len = len;
133
134 if (idx == -1)
135 {
136 current->next = ed->hash[hash];
137 current->prev = -1;
138 ed->hash[hash] = ed->count;
139 }
140 else
141 {
142 current->next = idx;
143 current->prev = ed->all[idx].prev;
144
145 if (current->next != -1)
146 ed->all[current->next].prev = ed->count;
147
148 if (current->prev != -1)
149 ed->all[current->prev].next = ed->count;
150 else
151 ed->hash[hash] = ed->count;
152 }
153
154 return ed->count++;
155} /* eet_dictionary_string_add */
156
157int
158eet_dictionary_string_get_size(const Eet_Dictionary *ed,
159 int idx)
160{
161 if (!ed)
162 return 0;
163
164 if (idx < 0)
165 return 0;
166
167 if (idx < ed->count)
168 return ed->all[idx].len;
169
170 return 0;
171} /* eet_dictionary_string_get_size */
172
173int
174eet_dictionary_string_get_hash(const Eet_Dictionary *ed,
175 int idx)
176{
177 if (!ed)
178 return -1;
179
180 if (idx < 0)
181 return -1;
182
183 if (idx < ed->count)
184 return ed->all[idx].hash;
185
186 return -1;
187} /* eet_dictionary_string_get_hash */
188
189const char *
190eet_dictionary_string_get_char(const Eet_Dictionary *ed,
191 int idx)
192{
193 if (!ed)
194 return NULL;
195
196 if (idx < 0)
197 return NULL;
198
199 if (idx < ed->count)
200 {
201#ifdef _WIN32
202 /* Windows file system could change the mmaped file when replacing a file. So we need to copy all string in memory to avoid bugs. */
203 if (!ed->all[idx].allocated)
204 {
205 ed->all[idx].str = eina_stringshare_add(ed->all[idx].str);
206 ed->all[idx].allocated = EINA_TRUE;
207 }
208#endif /* ifdef _WIN32 */
209 return ed->all[idx].str;
210 }
211
212 return NULL;
213} /* eet_dictionary_string_get_char */
214
215static inline Eina_Bool
216_eet_dictionary_string_get_me_cache(const char *s,
217 int len,
218 int *mantisse,
219 int *exponent)
220{
221 if ((len == 6) && (s[0] == '0') && (s[1] == 'x') && (s[3] == 'p'))
222 {
223 *mantisse = (s[2] >= 'a') ? (s[2] - 'a' + 10) : (s[2] - '0');
224 *exponent = (s[5] - '0');
225
226 return EINA_TRUE;
227 }
228
229 return EINA_FALSE;
230} /* _eet_dictionary_string_get_me_cache */
231
232static inline Eina_Bool
233_eet_dictionary_string_get_float_cache(const char *s,
234 int len,
235 float *result)
236{
237 int mantisse;
238 int exponent;
239
240 if (_eet_dictionary_string_get_me_cache(s, len, &mantisse, &exponent))
241 {
242 if (s[4] == '+')
243 *result = (float)(mantisse << exponent);
244 else
245 *result = (float)mantisse / (float)(1 << exponent);
246
247 return EINA_TRUE;
248 }
249
250 return EINA_FALSE;
251} /* _eet_dictionary_string_get_float_cache */
252
253static inline Eina_Bool
254_eet_dictionary_string_get_double_cache(const char *s,
255 int len,
256 double *result)
257{
258 int mantisse;
259 int exponent;
260
261 if (_eet_dictionary_string_get_me_cache(s, len, &mantisse, &exponent))
262 {
263 if (s[4] == '+')
264 *result = (double)(mantisse << exponent);
265 else
266 *result = (double)mantisse / (float)(1 << exponent);
267
268 return EINA_TRUE;
269 }
270
271 return EINA_FALSE;
272} /* _eet_dictionary_string_get_double_cache */
273
274static inline Eina_Bool
275_eet_dictionary_test(const Eet_Dictionary *ed,
276 int idx,
277 void *result)
278{
279 if (!result)
280 return EINA_FALSE;
281
282 if (!ed)
283 return EINA_FALSE;
284
285 if (idx < 0)
286 return EINA_FALSE;
287
288 if (!(idx < ed->count))
289 return EINA_FALSE;
290
291 return EINA_TRUE;
292} /* _eet_dictionary_test */
293
294static Eet_Convert *
295eet_dictionary_convert_get(const Eet_Dictionary *ed,
296 int idx,
297 const char **str)
298{
299 Eet_Convert *result;
300
301 *str = ed->all[idx].str;
302
303 if (!ed->converts)
304 {
305 ((Eet_Dictionary *)ed)->converts = eina_hash_int32_new(free);
306
307 goto add_convert;
308 }
309
310 result = eina_hash_find(ed->converts, &idx);
311 if (result) return result;
312
313add_convert:
314 result = calloc(1, sizeof (Eet_Convert));
315
316 eina_hash_add(ed->converts, &idx, result);
317 return result;
318}
319
320Eina_Bool
321eet_dictionary_string_get_float(const Eet_Dictionary *ed,
322 int idx,
323 float *result)
324{
325 Eet_Convert *convert;
326 const char *str;
327
328 if (!_eet_dictionary_test(ed, idx, result))
329 return EINA_FALSE;
330
331 convert = eet_dictionary_convert_get(ed, idx, &str);
332 if (!convert) return EINA_FALSE;
333
334 if (!(convert->type & EET_D_FLOAT))
335 {
336 if (!_eet_dictionary_string_get_float_cache(str, ed->all[idx].len,
337 &convert->f))
338 {
339 long long mantisse = 0;
340 long exponent = 0;
341
342 if (eina_convert_atod(str, ed->all[idx].len, &mantisse,
343 &exponent) == EINA_FALSE)
344 return EINA_FALSE;
345
346 convert->f = ldexpf((float)mantisse, exponent);
347 }
348
349 convert->type |= EET_D_FLOAT;
350 }
351
352 *result = convert->f;
353 return EINA_TRUE;
354} /* eet_dictionary_string_get_float */
355
356Eina_Bool
357eet_dictionary_string_get_double(const Eet_Dictionary *ed,
358 int idx,
359 double *result)
360{
361 Eet_Convert *convert;
362 const char *str;
363
364 if (!_eet_dictionary_test(ed, idx, result))
365 return EINA_FALSE;
366
367 convert = eet_dictionary_convert_get(ed, idx, &str);
368 if (!convert) return EINA_FALSE;
369
370 if (!(convert->type & EET_D_DOUBLE))
371 {
372 if (!_eet_dictionary_string_get_double_cache(str, ed->all[idx].len,
373 &convert->d))
374 {
375 long long mantisse = 0;
376 long exponent = 0;
377
378 if (eina_convert_atod(str, ed->all[idx].len, &mantisse,
379 &exponent) == EINA_FALSE)
380 return EINA_FALSE;
381
382 convert->d = ldexp((double)mantisse, exponent);
383 }
384
385 convert->type |= EET_D_DOUBLE;
386 }
387
388 *result = convert->d;
389 return EINA_TRUE;
390} /* eet_dictionary_string_get_double */
391
392Eina_Bool
393eet_dictionary_string_get_fp(const Eet_Dictionary *ed,
394 int idx,
395 Eina_F32p32 *result)
396{
397 Eet_Convert *convert;
398 const char *str;
399
400 if (!_eet_dictionary_test(ed, idx, result))
401 return EINA_FALSE;
402
403 convert = eet_dictionary_convert_get(ed, idx, &str);
404 if (!convert) return EINA_FALSE;
405
406 if (!(convert->type & EET_D_FIXED_POINT))
407 {
408 Eina_F32p32 fp;
409
410 if (!eina_convert_atofp(str, ed->all[idx].len, &fp))
411 return EINA_FALSE;
412
413 convert->fp = fp;
414 convert->type |= EET_D_FIXED_POINT;
415 }
416
417 *result = convert->fp;
418 return EINA_TRUE;
419} /* eet_dictionary_string_get_fp */
420
421EAPI int
422eet_dictionary_string_check(Eet_Dictionary *ed,
423 const char *string)
424{
425 int i;
426
427 if ((!ed) || (!string))
428 return 0;
429
430 if ((ed->start <= string) && (string < ed->end))
431 return 1;
432
433 for (i = 0; i < ed->count; ++i)
434 if ((ed->all[i].allocated) && ed->all[i].str == string)
435 return 1;
436
437 return 0;
438} /* eet_dictionary_string_check */
439
diff --git a/libraries/eet/src/lib/eet_image.c b/libraries/eet/src/lib/eet_image.c
new file mode 100644
index 0000000..79f6f90
--- /dev/null
+++ b/libraries/eet/src/lib/eet_image.c
@@ -0,0 +1,1820 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif /* ifdef HAVE_CONFIG_H */
4
5#ifdef HAVE_ALLOCA_H
6# include <alloca.h>
7#elif defined __GNUC__
8# define alloca __builtin_alloca
9#elif defined _AIX
10# define alloca __alloca
11#elif defined _MSC_VER
12# include <malloc.h>
13# define alloca _alloca
14#else /* ifdef HAVE_ALLOCA_H */
15# include <stddef.h>
16# ifdef __cplusplus
17extern "C"
18# endif /* ifdef __cplusplus */
19void *alloca(size_t);
20#endif /* ifdef HAVE_ALLOCA_H */
21
22#ifdef HAVE_NETINET_IN_H
23# ifdef __OpenBSD__
24# include <sys/types.h>
25# endif /* ifdef __OpenBSD__ */
26# include <netinet/in.h>
27#endif /* ifdef HAVE_NETINET_IN_H */
28
29#ifdef _WIN32
30# include <winsock2.h>
31# define HAVE_BOOLEAN
32#endif /* ifdef _WIN32 */
33
34#include <stdio.h>
35#include <string.h>
36#include <setjmp.h>
37#include <zlib.h>
38#include <jpeglib.h>
39
40#include "Eet.h"
41#include "Eet_private.h"
42
43/*---*/
44
45typedef struct _JPEG_error_mgr *emptr;
46
47/*---*/
48
49struct _JPEG_error_mgr
50{
51 struct jpeg_error_mgr pub;
52 jmp_buf setjmp_buffer;
53};
54
55struct jpeg_membuf_src
56{
57 struct jpeg_source_mgr pub;
58
59 const unsigned char *buf;
60 size_t len;
61 struct jpeg_membuf_src *self;
62};
63
64static void
65_eet_jpeg_membuf_src_init(j_decompress_ptr cinfo)
66{
67 /* FIXME: Use attribute unused */
68 (void)cinfo;
69} /* _eet_jpeg_membuf_src_init */
70
71static boolean
72_eet_jpeg_membuf_src_fill(j_decompress_ptr cinfo)
73{
74 static const JOCTET jpeg_eoi[2] = { 0xFF, JPEG_EOI };
75 struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
76
77 src->pub.bytes_in_buffer = sizeof(jpeg_eoi);
78 src->pub.next_input_byte = jpeg_eoi;
79
80 return TRUE;
81} /* _eet_jpeg_membuf_src_fill */
82
83static void
84_eet_jpeg_membuf_src_skip(j_decompress_ptr cinfo,
85 long num_bytes)
86{
87 struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
88
89 src->pub.bytes_in_buffer -= num_bytes;
90 src->pub.next_input_byte += num_bytes;
91} /* _eet_jpeg_membuf_src_skip */
92
93static void
94_eet_jpeg_membuf_src_term(j_decompress_ptr cinfo)
95{
96 struct jpeg_membuf_src *src = ((struct jpeg_membuf_src *)cinfo->src)->self;
97
98 free(src);
99 cinfo->src = NULL;
100} /* _eet_jpeg_membuf_src_term */
101
102static int
103eet_jpeg_membuf_src(j_decompress_ptr cinfo,
104 const void *buf,
105 size_t len)
106{
107 struct jpeg_membuf_src *src;
108
109 src = calloc(1, sizeof(*src));
110 if (!src)
111 return -1;
112
113 src->self = src;
114
115 cinfo->src = &src->pub;
116 src->buf = buf;
117 src->len = len;
118 src->pub.init_source = _eet_jpeg_membuf_src_init;
119 src->pub.fill_input_buffer = _eet_jpeg_membuf_src_fill;
120 src->pub.skip_input_data = _eet_jpeg_membuf_src_skip;
121 src->pub.resync_to_restart = jpeg_resync_to_restart;
122 src->pub.term_source = _eet_jpeg_membuf_src_term;
123 src->pub.bytes_in_buffer = src->len;
124 src->pub.next_input_byte = src->buf;
125
126 return 0;
127} /* eet_jpeg_membuf_src */
128
129struct jpeg_membuf_dst
130{
131 struct jpeg_destination_mgr pub;
132
133 void **dst_buf;
134 size_t *dst_len;
135
136 unsigned char *buf;
137 size_t len;
138 int failed;
139 struct jpeg_membuf_dst *self;
140};
141
142static void
143_eet_jpeg_membuf_dst_init(j_compress_ptr cinfo)
144{
145 /* FIXME: Use eina attribute */
146 (void)cinfo;
147} /* _eet_jpeg_membuf_dst_init */
148
149static boolean
150_eet_jpeg_membuf_dst_flush(j_compress_ptr cinfo)
151{
152 struct jpeg_membuf_dst *dst = (struct jpeg_membuf_dst *)cinfo->dest;
153 unsigned char *buf;
154
155 if (dst->len >= 0x40000000 ||
156 !(buf = realloc(dst->buf, dst->len * 2)))
157 {
158 dst->failed = 1;
159 dst->pub.next_output_byte = dst->buf;
160 dst->pub.free_in_buffer = dst->len;
161 return TRUE;
162 }
163
164 dst->pub.next_output_byte =
165 buf + ((unsigned char *)dst->pub.next_output_byte - dst->buf);
166 dst->buf = buf;
167 dst->pub.free_in_buffer += dst->len;
168 dst->len *= 2;
169
170 return FALSE;
171} /* _eet_jpeg_membuf_dst_flush */
172
173static void
174_eet_jpeg_membuf_dst_term(j_compress_ptr cinfo)
175{
176 struct jpeg_membuf_dst *dst = ((struct jpeg_membuf_dst *)cinfo->dest)->self;
177
178 if (dst->failed)
179 {
180 *dst->dst_buf = NULL;
181 *dst->dst_len = 0;
182 free(dst->buf);
183 }
184 else
185 {
186 *dst->dst_buf = dst->buf;
187 *dst->dst_len = (unsigned char *)dst->pub.next_output_byte - dst->buf;
188 }
189
190 free(dst);
191 cinfo->dest = NULL;
192} /* _eet_jpeg_membuf_dst_term */
193
194static int
195eet_jpeg_membuf_dst(j_compress_ptr cinfo,
196 void **buf,
197 size_t *len)
198{
199 struct jpeg_membuf_dst *dst;
200
201 dst = calloc(1, sizeof(*dst));
202 if (!dst)
203 return -1;
204
205 dst->buf = malloc(32768);
206 if (!dst->buf)
207 {
208 free(dst);
209 return -1;
210 }
211
212 dst->self = dst;
213 dst->len = 32768;
214
215 cinfo->dest = &dst->pub;
216 dst->pub.init_destination = _eet_jpeg_membuf_dst_init;
217 dst->pub.empty_output_buffer = _eet_jpeg_membuf_dst_flush;
218 dst->pub.term_destination = _eet_jpeg_membuf_dst_term;
219 dst->pub.free_in_buffer = dst->len;
220 dst->pub.next_output_byte = dst->buf;
221 dst->dst_buf = buf;
222 dst->dst_len = len;
223 dst->failed = 0;
224
225 return 0;
226} /* eet_jpeg_membuf_dst */
227
228/*---*/
229
230static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
231static void _JPEGErrorHandler(j_common_ptr cinfo);
232static void _JPEGErrorHandler2(j_common_ptr cinfo,
233 int msg_level);
234
235static int
236eet_data_image_jpeg_header_decode(const void *data,
237 int size,
238 unsigned int *w,
239 unsigned int *h);
240static int
241eet_data_image_jpeg_rgb_decode(const void *data,
242 int size,
243 unsigned int src_x,
244 unsigned int src_y,
245 unsigned int *d,
246 unsigned int w,
247 unsigned int h,
248 unsigned int row_stride);
249static void *
250eet_data_image_jpeg_alpha_decode(const void *data,
251 int size,
252 unsigned int src_x,
253 unsigned int src_y,
254 unsigned int *d,
255 unsigned int w,
256 unsigned int h,
257 unsigned int row_stride);
258static void *
259eet_data_image_lossless_convert(int *size,
260 const void *data,
261 unsigned int w,
262 unsigned int h,
263 int alpha);
264static void *
265eet_data_image_lossless_compressed_convert(int *size,
266 const void *data,
267 unsigned int w,
268 unsigned int h,
269 int alpha,
270 int compression);
271static void *
272eet_data_image_jpeg_convert(int *size,
273 const void *data,
274 unsigned int w,
275 unsigned int h,
276 int alpha,
277 int quality);
278static void *
279eet_data_image_jpeg_alpha_convert(int *size,
280 const void *data,
281 unsigned int w,
282 unsigned int h,
283 int alpha,
284 int quality);
285
286/*---*/
287
288static int _eet_image_words_bigendian = -1;
289
290/*---*/
291
292#define SWAP64(x) (x) = \
293 ((((unsigned long long)(x) & 0x00000000000000ffULL) << 56) | \
294 (((unsigned long long)(x) & 0x000000000000ff00ULL) << 40) | \
295 (((unsigned long long)(x) & 0x0000000000ff0000ULL) << 24) | \
296 (((unsigned long long)(x) & 0x00000000ff000000ULL) << 8) | \
297 (((unsigned long long)(x) & 0x000000ff00000000ULL) >> 8) | \
298 (((unsigned long long)(x) & 0x0000ff0000000000ULL) >> 24) | \
299 (((unsigned long long)(x) & 0x00ff000000000000ULL) >> 40) | \
300 (((unsigned long long)(x) & 0xff00000000000000ULL) >> 56))
301#define SWAP32(x) (x) = \
302 ((((int)(x) & 0x000000ff) << 24) | \
303 (((int)(x) & 0x0000ff00) << 8) | \
304 (((int)(x) & 0x00ff0000) >> 8) | \
305 (((int)(x) & 0xff000000) >> 24))
306#define SWAP16(x) (x) = \
307 ((((short)(x) & 0x00ff) << 8) | \
308 (((short)(x) & 0xff00) >> 8))
309
310#ifdef CONV8
311# undef CONV8
312#endif /* ifdef CONV8 */
313#ifdef CONV16
314# undef CONV16
315#endif /* ifdef CONV16 */
316#ifdef CONV32
317# undef CONV32
318#endif /* ifdef CONV32 */
319#ifdef CONV64
320# undef CONV64
321#endif /* ifdef CONV64 */
322
323#define CONV8(x)
324#define CONV16(x) {if (_eet_image_words_bigendian) {SWAP16(x); }}
325#define CONV32(x) {if (_eet_image_words_bigendian) {SWAP32(x); }}
326#define CONV64(x) {if (_eet_image_words_bigendian) {SWAP64(x); }}
327
328/*---*/
329
330static void
331_JPEGFatalErrorHandler(j_common_ptr cinfo)
332{
333 emptr errmgr;
334
335 errmgr = (emptr)cinfo->err;
336 /* cinfo->err->output_message(cinfo);*/
337 longjmp(errmgr->setjmp_buffer, 1);
338 return;
339} /* _JPEGFatalErrorHandler */
340
341static void
342_JPEGErrorHandler(j_common_ptr cinfo __UNUSED__)
343{
344 /* emptr errmgr; */
345
346 /* errmgr = (emptr) cinfo->err; */
347 /* cinfo->err->output_message(cinfo);*/
348 /* longjmp(errmgr->setjmp_buffer, 1);*/
349 return;
350} /* _JPEGErrorHandler */
351
352static void
353_JPEGErrorHandler2(j_common_ptr cinfo __UNUSED__,
354 int msg_level __UNUSED__)
355{
356 /* emptr errmgr; */
357
358 /* errmgr = (emptr) cinfo->err; */
359 /* cinfo->err->output_message(cinfo);*/
360 /* longjmp(errmgr->setjmp_buffer, 1);*/
361 return;
362} /* _JPEGErrorHandler2 */
363
364static int
365eet_data_image_jpeg_header_decode(const void *data,
366 int size,
367 unsigned int *w,
368 unsigned int *h)
369{
370 struct jpeg_decompress_struct cinfo;
371 struct _JPEG_error_mgr jerr;
372
373 memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct));
374
375 cinfo.err = jpeg_std_error(&(jerr.pub));
376 jerr.pub.error_exit = _JPEGFatalErrorHandler;
377 jerr.pub.emit_message = _JPEGErrorHandler2;
378 jerr.pub.output_message = _JPEGErrorHandler;
379 if (setjmp(jerr.setjmp_buffer))
380 return 0;
381
382 jpeg_create_decompress(&cinfo);
383
384 if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
385 {
386 jpeg_destroy_decompress(&cinfo);
387 return 0;
388 }
389
390 jpeg_read_header(&cinfo, TRUE);
391 cinfo.do_fancy_upsampling = FALSE;
392 cinfo.do_block_smoothing = FALSE;
393 jpeg_start_decompress(&cinfo);
394
395 /* head decoding */
396 *w = cinfo.output_width;
397 *h = cinfo.output_height;
398
399 free(cinfo.src);
400 cinfo.src = NULL;
401
402 jpeg_destroy_decompress(&cinfo);
403
404 if ((*w < 1) || (*h < 1) || (*w > 8192) || (*h > 8192))
405 return 0;
406
407 return 1;
408} /* eet_data_image_jpeg_header_decode */
409
410static int
411eet_data_image_jpeg_rgb_decode(const void *data,
412 int size,
413 unsigned int src_x,
414 unsigned int src_y,
415 unsigned int *d,
416 unsigned int w,
417 unsigned int h,
418 unsigned int row_stride)
419{
420 struct jpeg_decompress_struct cinfo;
421 struct _JPEG_error_mgr jerr;
422 unsigned char *ptr, *line[16], *tdata = NULL;
423 unsigned int *ptr2, *tmp;
424 unsigned int iw, ih;
425 unsigned int x, y, l, scans;
426 unsigned int i;
427
428 /* FIXME: handle src_x, src_y and row_stride correctly */
429 if (!d)
430 return 0;
431
432 memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct));
433
434 cinfo.err = jpeg_std_error(&(jerr.pub));
435 jerr.pub.error_exit = _JPEGFatalErrorHandler;
436 jerr.pub.emit_message = _JPEGErrorHandler2;
437 jerr.pub.output_message = _JPEGErrorHandler;
438 if (setjmp(jerr.setjmp_buffer))
439 return 0;
440
441 jpeg_create_decompress(&cinfo);
442
443 if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
444 {
445 jpeg_destroy_decompress(&cinfo);
446 return 0;
447 }
448
449 jpeg_read_header(&cinfo, TRUE);
450 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
451 cinfo.do_fancy_upsampling = FALSE;
452 cinfo.do_block_smoothing = FALSE;
453 jpeg_start_decompress(&cinfo);
454
455 /* head decoding */
456 iw = cinfo.output_width;
457 ih = cinfo.output_height;
458 if ((iw != w) || (ih != h))
459 {
460 free(cinfo.src);
461 cinfo.src = NULL;
462
463 jpeg_destroy_decompress(&cinfo);
464 return 0;
465 }
466
467 /* end head decoding */
468 /* data decoding */
469 if (cinfo.rec_outbuf_height > 16)
470 {
471 free(cinfo.src);
472 cinfo.src = NULL;
473
474 jpeg_destroy_decompress(&cinfo);
475 return 0;
476 }
477
478 tdata = alloca((iw) * 16 * 3);
479 ptr2 = d;
480
481 if (cinfo.output_components == 3)
482 {
483 for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++)
484 line[i] = tdata + (i * (iw) * 3);
485 for (l = 0; l < ih; l += cinfo.rec_outbuf_height)
486 {
487 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
488 scans = cinfo.rec_outbuf_height;
489 if ((ih - l) < scans)
490 scans = ih - l;
491
492 ptr = tdata;
493
494 if (l + scans >= src_y && l < src_y + h)
495 {
496 y = src_y - l;
497 if (src_y < l)
498 y = 0;
499
500 for (ptr += 3 * iw * y; y < scans && (y + l) < (src_y + h);
501 y++)
502 {
503 tmp = ptr2;
504 ptr += 3 * src_x;
505 for (x = 0; x < w; x++)
506 {
507 *ptr2 =
508 (0xff000000) |
509 ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
510 ptr += 3;
511 ptr2++;
512 }
513 ptr += 3 * (iw - w);
514 ptr2 = tmp + row_stride / 4;
515 }
516 }
517 }
518 }
519 else if (cinfo.output_components == 1)
520 {
521 for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++)
522 line[i] = tdata + (i * (iw));
523 for (l = 0; l < (ih); l += cinfo.rec_outbuf_height)
524 {
525 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
526 scans = cinfo.rec_outbuf_height;
527 if (((ih) - l) < scans)
528 scans = (ih) - l;
529
530 ptr = tdata;
531
532 if (l >= src_y && l < src_y + h)
533 {
534 y = src_y - l;
535 if (src_y < l)
536 y = 0;
537
538 for (ptr += iw * y; y < scans && (y + l) < (src_y + h); y++)
539 {
540 tmp = ptr2;
541 ptr += src_x;
542 for (x = 0; x < w; x++)
543 {
544 *ptr2 =
545 (0xff000000) |
546 ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]);
547 ptr++;
548 ptr2++;
549 }
550 ptr += iw - w;
551 ptr2 = tmp + row_stride / 4;
552 }
553 }
554 }
555 }
556
557 /* end data decoding */
558 jpeg_finish_decompress(&cinfo);
559 jpeg_destroy_decompress(&cinfo);
560 return 1;
561} /* eet_data_image_jpeg_rgb_decode */
562
563static void *
564eet_data_image_jpeg_alpha_decode(const void *data,
565 int size,
566 unsigned int src_x,
567 unsigned int src_y,
568 unsigned int *d,
569 unsigned int w,
570 unsigned int h,
571 unsigned int row_stride)
572{
573 struct jpeg_decompress_struct cinfo;
574 struct _JPEG_error_mgr jerr;
575 unsigned char *ptr, *line[16], *tdata = NULL;
576 unsigned int *ptr2, *tmp;
577 unsigned int x, y, l, scans;
578 unsigned int i, iw;
579
580 memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct));
581
582 cinfo.err = jpeg_std_error(&(jerr.pub));
583 jerr.pub.error_exit = _JPEGFatalErrorHandler;
584 jerr.pub.emit_message = _JPEGErrorHandler2;
585 jerr.pub.output_message = _JPEGErrorHandler;
586 if (setjmp(jerr.setjmp_buffer))
587 return NULL;
588
589 jpeg_create_decompress(&cinfo);
590
591 if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
592 {
593 jpeg_destroy_decompress(&cinfo);
594 return NULL;
595 }
596
597 jpeg_read_header(&cinfo, TRUE);
598 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
599 cinfo.do_fancy_upsampling = FALSE;
600 cinfo.do_block_smoothing = FALSE;
601 jpeg_start_decompress(&cinfo);
602
603 /* head decoding */
604 iw = cinfo.output_width;
605 if (w != cinfo.output_width
606 || h != cinfo.output_height)
607 {
608 free(cinfo.src);
609 cinfo.src = NULL;
610
611 jpeg_destroy_decompress(&cinfo);
612 return NULL;
613 }
614
615 /* end head decoding */
616 /* data decoding */
617 if (cinfo.rec_outbuf_height > 16)
618 {
619 free(cinfo.src);
620 cinfo.src = NULL;
621
622 jpeg_destroy_decompress(&cinfo);
623 return NULL;
624 }
625
626 tdata = alloca(w * 16 * 3);
627 ptr2 = d;
628 if (cinfo.output_components == 1)
629 {
630 for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++)
631 line[i] = tdata + (i * w);
632 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
633 {
634 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
635 scans = cinfo.rec_outbuf_height;
636 if ((h - l) < scans)
637 scans = h - l;
638
639 ptr = tdata;
640
641 if (l >= src_y && l < src_y + h)
642 {
643 y = src_y - l;
644 if (src_y < l)
645 y = 0;
646
647 for (ptr += iw * y; y < scans && (y + l) < (src_y + h); y++)
648 {
649 tmp = ptr2;
650 ptr += src_x;
651 for (x = 0; x < w; x++)
652 {
653 *ptr2 =
654 ((*ptr2) & 0x00ffffff) |
655 ((ptr[0]) << 24);
656 ptr++;
657 ptr2++;
658 }
659 ptr += iw - w;
660 ptr2 = tmp + row_stride / 4;
661 }
662 }
663 }
664 }
665
666 /* end data decoding */
667 jpeg_finish_decompress(&cinfo);
668 jpeg_destroy_decompress(&cinfo);
669 return d;
670} /* eet_data_image_jpeg_alpha_decode */
671
672static void *
673eet_data_image_lossless_convert(int *size,
674 const void *data,
675 unsigned int w,
676 unsigned int h,
677 int alpha)
678{
679 if (_eet_image_words_bigendian == -1)
680 {
681 unsigned long int v;
682
683 v = htonl(0x12345678);
684 if (v == 0x12345678)
685 _eet_image_words_bigendian = 1;
686 else
687 _eet_image_words_bigendian = 0;
688 }
689
690 {
691 unsigned char *d;
692 int *header;
693
694 d = malloc((w * h * 4) + (8 * 4));
695 if (!d)
696 return NULL;
697
698 header = (int *)d;
699 memset(d, 0, 32);
700
701 header[0] = 0xac1dfeed;
702 header[1] = w;
703 header[2] = h;
704 header[3] = alpha;
705
706 memcpy(d + 32, data, w * h * 4);
707
708 if (_eet_image_words_bigendian)
709 {
710 unsigned int i;
711
712 for (i = 0; i < ((w * h) + 8); i++) SWAP32(header[i]);
713 }
714
715 *size = ((w * h * 4) + (8 * 4));
716 return d;
717 }
718} /* eet_data_image_lossless_convert */
719
720static void *
721eet_data_image_lossless_compressed_convert(int *size,
722 const void *data,
723 unsigned int w,
724 unsigned int h,
725 int alpha,
726 int compression)
727{
728 if (_eet_image_words_bigendian == -1)
729 {
730 unsigned long int v;
731
732 v = htonl(0x12345678);
733 if (v == 0x12345678)
734 _eet_image_words_bigendian = 1;
735 else
736 _eet_image_words_bigendian = 0;
737 }
738
739 {
740 unsigned char *d;
741 unsigned char *comp;
742 int *header;
743 int ret;
744 uLongf buflen;
745
746 d = malloc((w * h * 4) + (8 * 4));
747 if (!d)
748 return NULL;
749
750 buflen = (((w * h * 101) / 100) + 3) * 4;
751 comp = malloc(buflen);
752 if (!comp)
753 {
754 free(d);
755 return NULL;
756 }
757
758 header = (int *)d;
759 memset(d, 0, 32);
760
761 header[0] = 0xac1dfeed;
762 header[1] = w;
763 header[2] = h;
764 header[3] = alpha;
765 header[4] = compression;
766 memcpy(d + 32, data, w * h * 4);
767
768 if (_eet_image_words_bigendian)
769 {
770 unsigned int i;
771
772 for (i = 0; i < ((w * h) + 8); i++) SWAP32(header[i]);
773 }
774
775 ret = compress2((Bytef *)comp, &buflen,
776 (Bytef *)(d + 32),
777 (uLong)(w * h * 4),
778 compression);
779 if (ret != Z_OK || buflen > (w * h * 4))
780 {
781 free(comp);
782 free(d);
783 *size = -1;
784 return NULL;
785 }
786
787 memcpy(d + 32, comp, buflen);
788 *size = (8 * 4) + buflen;
789 free(comp);
790 return d;
791 }
792} /* eet_data_image_lossless_compressed_convert */
793
794static void *
795eet_data_image_jpeg_convert(int *size,
796 const void *data,
797 unsigned int w,
798 unsigned int h,
799 int alpha,
800 int quality)
801{
802 struct jpeg_compress_struct cinfo;
803 struct _JPEG_error_mgr jerr;
804 const int *ptr;
805 void *d = NULL;
806 size_t sz = 0;
807 JSAMPROW *jbuf;
808 unsigned char *buf;
809
810 (void)alpha; /* unused */
811
812 buf = alloca(3 * w);
813
814 memset(&cinfo, 0, sizeof (struct jpeg_compress_struct));
815
816 cinfo.err = jpeg_std_error(&(jerr.pub));
817 jerr.pub.error_exit = _JPEGFatalErrorHandler;
818 jerr.pub.emit_message = _JPEGErrorHandler2;
819 jerr.pub.output_message = _JPEGErrorHandler;
820 if (setjmp(jerr.setjmp_buffer))
821 return NULL;
822
823 jpeg_create_compress(&cinfo);
824
825 if (eet_jpeg_membuf_dst(&cinfo, &d, &sz))
826 {
827 jpeg_destroy_compress(&cinfo);
828 return NULL;
829 }
830
831 cinfo.image_width = w;
832 cinfo.image_height = h;
833 cinfo.input_components = 3;
834 cinfo.in_color_space = JCS_RGB;
835 cinfo.optimize_coding = FALSE;
836 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
837 if (quality < 60) cinfo.dct_method = JDCT_IFAST;
838 jpeg_set_defaults(&cinfo);
839 jpeg_set_quality(&cinfo, quality, TRUE);
840
841 if (quality >= 90)
842 {
843 cinfo.comp_info[0].h_samp_factor = 1;
844 cinfo.comp_info[0].v_samp_factor = 1;
845 cinfo.comp_info[1].h_samp_factor = 1;
846 cinfo.comp_info[1].v_samp_factor = 1;
847 cinfo.comp_info[2].h_samp_factor = 1;
848 cinfo.comp_info[2].v_samp_factor = 1;
849 }
850
851 jpeg_start_compress(&cinfo, TRUE);
852
853 while (cinfo.next_scanline < cinfo.image_height)
854 {
855 unsigned int i, j;
856
857 /* convert scaline from ARGB to RGB packed */
858 ptr = ((const int *)data) + cinfo.next_scanline * w;
859 for (j = 0, i = 0; i < w; i++)
860 {
861 buf[j++] = ((*ptr) >> 16) & 0xff;
862 buf[j++] = ((*ptr) >> 8) & 0xff;
863 buf[j++] = ((*ptr)) & 0xff;
864 ptr++;
865 }
866 jbuf = (JSAMPROW *)(&buf);
867 jpeg_write_scanlines(&cinfo, jbuf, 1);
868 }
869
870 jpeg_finish_compress(&cinfo);
871 jpeg_destroy_compress(&cinfo);
872
873 *size = sz;
874 return d;
875} /* eet_data_image_jpeg_convert */
876
877static void *
878eet_data_image_jpeg_alpha_convert(int *size,
879 const void *data,
880 unsigned int w,
881 unsigned int h,
882 int alpha,
883 int quality)
884{
885 unsigned char *d1, *d2;
886 unsigned char *d;
887 int *header;
888 int sz1, sz2;
889
890 (void)alpha; /* unused */
891
892 if (_eet_image_words_bigendian == -1)
893 {
894 unsigned long int v;
895
896 v = htonl(0x12345678);
897 if (v == 0x12345678)
898 _eet_image_words_bigendian = 1;
899 else
900 _eet_image_words_bigendian = 0;
901 }
902
903 {
904 const int *ptr;
905 void *dst = NULL;
906 size_t sz = 0;
907 struct _JPEG_error_mgr jerr;
908 JSAMPROW *jbuf;
909 struct jpeg_compress_struct cinfo;
910 unsigned char *buf;
911
912 buf = alloca(3 * w);
913
914 cinfo.err = jpeg_std_error(&(jerr.pub));
915 jerr.pub.error_exit = _JPEGFatalErrorHandler;
916 jerr.pub.emit_message = _JPEGErrorHandler2;
917 jerr.pub.output_message = _JPEGErrorHandler;
918 if (setjmp(jerr.setjmp_buffer))
919 return NULL;
920
921 jpeg_create_compress(&cinfo);
922 if (eet_jpeg_membuf_dst(&cinfo, &dst, &sz))
923 {
924 jpeg_destroy_compress(&cinfo);
925 return NULL;
926 }
927
928 cinfo.image_width = w;
929 cinfo.image_height = h;
930 cinfo.input_components = 3;
931 cinfo.in_color_space = JCS_RGB;
932 cinfo.optimize_coding = FALSE;
933 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
934 if (quality < 60) cinfo.dct_method = JDCT_IFAST;
935 jpeg_set_defaults(&cinfo);
936 jpeg_set_quality(&cinfo, quality, TRUE);
937 if (quality >= 90)
938 {
939 cinfo.comp_info[0].h_samp_factor = 1;
940 cinfo.comp_info[0].v_samp_factor = 1;
941 cinfo.comp_info[1].h_samp_factor = 1;
942 cinfo.comp_info[1].v_samp_factor = 1;
943 cinfo.comp_info[2].h_samp_factor = 1;
944 cinfo.comp_info[2].v_samp_factor = 1;
945 }
946
947 jpeg_start_compress(&cinfo, TRUE);
948
949 while (cinfo.next_scanline < cinfo.image_height)
950 {
951 unsigned int i, j;
952
953 ptr = ((const int *)data) + cinfo.next_scanline * w;
954 /* convert scaline from ARGB to RGB packed */
955 for (j = 0, i = 0; i < w; i++)
956 {
957 buf[j++] = ((*ptr) >> 16) & 0xff;
958 buf[j++] = ((*ptr) >> 8) & 0xff;
959 buf[j++] = ((*ptr)) & 0xff;
960 ptr++;
961 }
962 jbuf = (JSAMPROW *)(&buf);
963 jpeg_write_scanlines(&cinfo, jbuf, 1);
964 }
965
966 jpeg_finish_compress(&cinfo);
967 jpeg_destroy_compress(&cinfo);
968
969 d1 = dst;
970 sz1 = sz;
971 }
972 {
973 const int *ptr;
974 void *dst = NULL;
975 size_t sz = 0;
976 struct _JPEG_error_mgr jerr;
977 JSAMPROW *jbuf;
978 struct jpeg_compress_struct cinfo;
979 unsigned char *buf;
980
981 buf = alloca(3 * w);
982
983 cinfo.err = jpeg_std_error(&(jerr.pub));
984 jerr.pub.error_exit = _JPEGFatalErrorHandler;
985 jerr.pub.emit_message = _JPEGErrorHandler2;
986 jerr.pub.output_message = _JPEGErrorHandler;
987 if (setjmp(jerr.setjmp_buffer))
988 {
989 free(d1);
990 return NULL;
991 }
992
993 jpeg_create_compress(&cinfo);
994 if (eet_jpeg_membuf_dst(&cinfo, &dst, &sz))
995 {
996 jpeg_destroy_compress(&cinfo);
997 free(d1);
998 return NULL;
999 }
1000
1001 cinfo.image_width = w;
1002 cinfo.image_height = h;
1003 cinfo.input_components = 1;
1004 cinfo.in_color_space = JCS_GRAYSCALE;
1005 jpeg_set_defaults(&cinfo);
1006 jpeg_set_quality(&cinfo, quality, TRUE);
1007 if (quality >= 90)
1008 {
1009 cinfo.comp_info[0].h_samp_factor = 1;
1010 cinfo.comp_info[0].v_samp_factor = 1;
1011 cinfo.comp_info[1].h_samp_factor = 1;
1012 cinfo.comp_info[1].v_samp_factor = 1;
1013 cinfo.comp_info[2].h_samp_factor = 1;
1014 cinfo.comp_info[2].v_samp_factor = 1;
1015 }
1016
1017 jpeg_start_compress(&cinfo, TRUE);
1018
1019 while (cinfo.next_scanline < cinfo.image_height)
1020 {
1021 unsigned int i, j;
1022
1023 ptr = ((const int *)data) + cinfo.next_scanline * w;
1024 /* convert scaline from ARGB to RGB packed */
1025 for (j = 0, i = 0; i < w; i++)
1026 {
1027 buf[j++] = ((*ptr) >> 24) & 0xff;
1028 ptr++;
1029 }
1030 jbuf = (JSAMPROW *)(&buf);
1031 jpeg_write_scanlines(&cinfo, jbuf, 1);
1032 }
1033
1034 jpeg_finish_compress(&cinfo);
1035 jpeg_destroy_compress(&cinfo);
1036
1037 d2 = dst;
1038 sz2 = sz;
1039 }
1040 d = malloc(12 + sz1 + sz2);
1041 if (!d)
1042 {
1043 free(d1);
1044 free(d2);
1045 return NULL;
1046 }
1047
1048 header = (int *)d;
1049 header[0] = 0xbeeff00d;
1050 header[1] = sz1;
1051 header[2] = sz2;
1052 if (_eet_image_words_bigendian)
1053 {
1054 int i;
1055
1056 for (i = 0; i < 3; i++) SWAP32(header[i]);
1057 }
1058
1059 memcpy(d + 12, d1, sz1);
1060 memcpy(d + 12 + sz1, d2, sz2);
1061
1062 free(d1);
1063 free(d2);
1064 *size = 12 + sz1 + sz2;
1065 return d;
1066} /* eet_data_image_jpeg_alpha_convert */
1067
1068EAPI int
1069eet_data_image_write_cipher(Eet_File *ef,
1070 const char *name,
1071 const char *cipher_key,
1072 const void *data,
1073 unsigned int w,
1074 unsigned int h,
1075 int alpha,
1076 int comp,
1077 int quality,
1078 int lossy)
1079{
1080 void *d = NULL;
1081 int size = 0;
1082
1083 d = eet_data_image_encode(data, &size, w, h, alpha, comp, quality, lossy);
1084 if (d)
1085 {
1086 int v;
1087
1088 v = eet_write_cipher(ef, name, d, size, 0, cipher_key);
1089 free(d);
1090 return v;
1091 }
1092
1093 return 0;
1094} /* eet_data_image_write_cipher */
1095
1096EAPI int
1097eet_data_image_write(Eet_File *ef,
1098 const char *name,
1099 const void *data,
1100 unsigned int w,
1101 unsigned int h,
1102 int alpha,
1103 int comp,
1104 int quality,
1105 int lossy)
1106{
1107 return eet_data_image_write_cipher(ef,
1108 name,
1109 NULL,
1110 data,
1111 w,
1112 h,
1113 alpha,
1114 comp,
1115 quality,
1116 lossy);
1117} /* eet_data_image_write */
1118
1119EAPI void *
1120eet_data_image_read_cipher(Eet_File *ef,
1121 const char *name,
1122 const char *cipher_key,
1123 unsigned int *w,
1124 unsigned int *h,
1125 int *alpha,
1126 int *comp,
1127 int *quality,
1128 int *lossy)
1129{
1130 unsigned int *d = NULL;
1131 void *data = NULL;
1132 int free_data = 0;
1133 int size;
1134
1135 if (!cipher_key)
1136 data = (void *)eet_read_direct(ef, name, &size);
1137
1138 if (!data)
1139 {
1140 data = eet_read_cipher(ef, name, &size, cipher_key);
1141 free_data = 1;
1142 if (!data)
1143 return NULL;
1144 }
1145
1146 d = eet_data_image_decode(data, size, w, h, alpha, comp, quality, lossy);
1147
1148 if (free_data)
1149 free(data);
1150
1151 return d;
1152} /* eet_data_image_read_cipher */
1153
1154EAPI void *
1155eet_data_image_read(Eet_File *ef,
1156 const char *name,
1157 unsigned int *w,
1158 unsigned int *h,
1159 int *alpha,
1160 int *comp,
1161 int *quality,
1162 int *lossy)
1163{
1164 return eet_data_image_read_cipher(ef, name, NULL, w, h, alpha,
1165 comp, quality, lossy);
1166} /* eet_data_image_read */
1167
1168EAPI int
1169eet_data_image_read_to_surface_cipher(Eet_File *ef,
1170 const char *name,
1171 const char *cipher_key,
1172 unsigned int src_x,
1173 unsigned int src_y,
1174 unsigned int *d,
1175 unsigned int w,
1176 unsigned int h,
1177 unsigned int row_stride,
1178 int *alpha,
1179 int *comp,
1180 int *quality,
1181 int *lossy)
1182{
1183 void *data = NULL;
1184 int free_data = 0;
1185 int res = 1;
1186 int size;
1187
1188 if (!cipher_key)
1189 data = (void *)eet_read_direct(ef, name, &size);
1190
1191 if (!data)
1192 {
1193 data = eet_read_cipher(ef, name, &size, cipher_key);
1194 free_data = 1;
1195 if (!data)
1196 return 0;
1197 }
1198
1199 res = eet_data_image_decode_to_surface(data, size, src_x, src_y, d,
1200 w, h, row_stride, alpha,
1201 comp, quality, lossy);
1202
1203 if (free_data)
1204 free(data);
1205
1206 return res;
1207} /* eet_data_image_read_to_surface_cipher */
1208
1209EAPI int
1210eet_data_image_read_to_surface(Eet_File *ef,
1211 const char *name,
1212 unsigned int src_x,
1213 unsigned int src_y,
1214 unsigned int *d,
1215 unsigned int w,
1216 unsigned int h,
1217 unsigned int row_stride,
1218 int *alpha,
1219 int *comp,
1220 int *quality,
1221 int *lossy)
1222{
1223 return eet_data_image_read_to_surface_cipher(ef, name, NULL,
1224 src_x, src_y, d,
1225 w, h, row_stride,
1226 alpha, comp, quality,
1227 lossy);
1228} /* eet_data_image_read_to_surface */
1229
1230EAPI int
1231eet_data_image_header_read_cipher(Eet_File *ef,
1232 const char *name,
1233 const char *cipher_key,
1234 unsigned int *w,
1235 unsigned int *h,
1236 int *alpha,
1237 int *comp,
1238 int *quality,
1239 int *lossy)
1240{
1241 void *data = NULL;
1242 int size = 0;
1243 int free_data = 0;
1244 int d;
1245
1246 if (!cipher_key)
1247 data = (void *)eet_read_direct(ef, name, &size);
1248
1249 if (!data)
1250 {
1251 data = eet_read_cipher(ef, name, &size, cipher_key);
1252 free_data = 1;
1253 if (!data)
1254 return 0;
1255 }
1256
1257 d = eet_data_image_header_decode(data, size, w, h, alpha,
1258 comp, quality, lossy);
1259 if (free_data)
1260 free(data);
1261
1262 return d;
1263} /* eet_data_image_header_read_cipher */
1264
1265EAPI int
1266eet_data_image_header_read(Eet_File *ef,
1267 const char *name,
1268 unsigned int *w,
1269 unsigned int *h,
1270 int *alpha,
1271 int *comp,
1272 int *quality,
1273 int *lossy)
1274{
1275 return eet_data_image_header_read_cipher(ef, name, NULL,
1276 w, h, alpha,
1277 comp, quality, lossy);
1278} /* eet_data_image_header_read */
1279
1280EAPI void *
1281eet_data_image_encode_cipher(const void *data,
1282 const char *cipher_key,
1283 unsigned int w,
1284 unsigned int h,
1285 int alpha,
1286 int comp,
1287 int quality,
1288 int lossy,
1289 int *size_ret)
1290{
1291 void *d = NULL;
1292 void *ciphered_d = NULL;
1293 unsigned int ciphered_sz = 0;
1294 int size = 0;
1295
1296 if (lossy == 0)
1297 {
1298 if (comp > 0)
1299 d = eet_data_image_lossless_compressed_convert(&size, data,
1300 w, h, alpha, comp);
1301
1302 /* eet_data_image_lossless_compressed_convert will refuse to compress something
1303 if the result is bigger than the entry. */
1304 if (comp <= 0 || !d)
1305 d = eet_data_image_lossless_convert(&size, data, w, h, alpha);
1306 }
1307 else
1308 {
1309 if (!alpha)
1310 d = eet_data_image_jpeg_convert(&size, data, w, h, alpha, quality);
1311 else
1312 d = eet_data_image_jpeg_alpha_convert(&size, data,
1313 w, h, alpha, quality);
1314 }
1315
1316 if (cipher_key)
1317 {
1318 if(!eet_cipher(d, size, cipher_key, strlen(cipher_key), &ciphered_d,
1319 &ciphered_sz))
1320 {
1321 if (d)
1322 free(d);
1323
1324 d = ciphered_d;
1325 size = ciphered_sz;
1326 }
1327 else
1328 if (ciphered_d)
1329 free(ciphered_d);
1330 }
1331
1332 if (size_ret)
1333 *size_ret = size;
1334
1335 return d;
1336} /* eet_data_image_encode_cipher */
1337
1338EAPI void *
1339eet_data_image_encode(const void *data,
1340 int *size_ret,
1341 unsigned int w,
1342 unsigned int h,
1343 int alpha,
1344 int comp,
1345 int quality,
1346 int lossy)
1347{
1348 return eet_data_image_encode_cipher(data, NULL, w, h, alpha,
1349 comp, quality, lossy, size_ret);
1350} /* eet_data_image_encode */
1351
1352EAPI int
1353eet_data_image_header_decode_cipher(const void *data,
1354 const char *cipher_key,
1355 int size,
1356 unsigned int *w,
1357 unsigned int *h,
1358 int *alpha,
1359 int *comp,
1360 int *quality,
1361 int *lossy)
1362{
1363 int header[8];
1364 void *deciphered_d = NULL;
1365 unsigned int deciphered_sz = 0;
1366
1367 if (cipher_key)
1368 {
1369 if (!eet_decipher(data, size, cipher_key, strlen(cipher_key),
1370 &deciphered_d, &deciphered_sz))
1371 {
1372 data = deciphered_d;
1373 size = deciphered_sz;
1374 }
1375 else
1376 if (deciphered_d)
1377 free(deciphered_d);
1378 }
1379
1380 if (_eet_image_words_bigendian == -1)
1381 {
1382 unsigned long int v;
1383
1384 v = htonl(0x12345678);
1385 if (v == 0x12345678)
1386 _eet_image_words_bigendian = 1;
1387 else
1388 _eet_image_words_bigendian = 0;
1389 }
1390
1391 if (size < 32)
1392 return 0;
1393
1394 memcpy(header, data, 32);
1395 if (_eet_image_words_bigendian)
1396 {
1397 int i;
1398
1399 for (i = 0; i < 8; i++) SWAP32(header[i]);
1400 }
1401
1402 if ((unsigned)header[0] == 0xac1dfeed)
1403 {
1404 int iw, ih, al, cp;
1405
1406 iw = header[1];
1407 ih = header[2];
1408 al = header[3];
1409 cp = header[4];
1410 if ((iw < 1) || (ih < 1) || (iw > 8192) || (ih > 8192))
1411 return 0;
1412
1413 if ((cp == 0) && (size < ((iw * ih * 4) + 32)))
1414 return 0;
1415
1416 if (w)
1417 *w = iw;
1418
1419 if (h)
1420 *h = ih;
1421
1422 if (alpha)
1423 *alpha = al ? 1 : 0;
1424
1425 if (comp)
1426 *comp = cp;
1427
1428 if (lossy)
1429 *lossy = 0;
1430
1431 if (quality)
1432 *quality = 100;
1433
1434 return 1;
1435 }
1436 else if ((unsigned)header[0] == 0xbeeff00d)
1437 {
1438 unsigned int iw = 0, ih = 0;
1439 unsigned const char *dt;
1440 int sz1;
1441 int ok;
1442
1443 sz1 = header[1];
1444/* sz2 = header[2]; */
1445 dt = data;
1446 dt += 12;
1447 ok = eet_data_image_jpeg_header_decode(dt, sz1, &iw, &ih);
1448 if (ok)
1449 {
1450 if (w)
1451 *w = iw;
1452
1453 if (h)
1454 *h = ih;
1455
1456 if (alpha)
1457 *alpha = 1;
1458
1459 if (comp)
1460 *comp = 0;
1461
1462 if (lossy)
1463 *lossy = 1;
1464
1465 if (quality)
1466 *quality = 75;
1467
1468 return 1;
1469 }
1470 }
1471 else
1472 {
1473 unsigned int iw = 0, ih = 0;
1474 int ok;
1475
1476 ok = eet_data_image_jpeg_header_decode(data, size, &iw, &ih);
1477 if (ok)
1478 {
1479 if (w)
1480 *w = iw;
1481
1482 if (h)
1483 *h = ih;
1484
1485 if (alpha)
1486 *alpha = 0;
1487
1488 if (comp)
1489 *comp = 0;
1490
1491 if (lossy)
1492 *lossy = 1;
1493
1494 if (quality)
1495 *quality = 75;
1496
1497 return 1;
1498 }
1499 }
1500
1501 return 0;
1502} /* eet_data_image_header_decode_cipher */
1503
1504EAPI int
1505eet_data_image_header_decode(const void *data,
1506 int size,
1507 unsigned int *w,
1508 unsigned int *h,
1509 int *alpha,
1510 int *comp,
1511 int *quality,
1512 int *lossy)
1513{
1514 return eet_data_image_header_decode_cipher(data,
1515 NULL,
1516 size,
1517 w,
1518 h,
1519 alpha,
1520 comp,
1521 quality,
1522 lossy);
1523} /* eet_data_image_header_decode */
1524
1525static void
1526_eet_data_image_copy_buffer(const unsigned int *src,
1527 unsigned int src_x,
1528 unsigned int src_y,
1529 unsigned int src_w,
1530 unsigned int *dst,
1531 unsigned int w,
1532 unsigned int h,
1533 unsigned int row_stride)
1534{
1535 src += src_x + src_y * src_w;
1536
1537 if (row_stride == src_w * 4 && w == src_w)
1538 memcpy(dst, src, row_stride * h);
1539 else
1540 {
1541 unsigned int *over = dst;
1542 unsigned int y;
1543
1544 for (y = 0; y < h; ++y, src += src_w, over += row_stride)
1545 memcpy(over, src, w * 4);
1546 }
1547} /* _eet_data_image_copy_buffer */
1548
1549static int
1550_eet_data_image_decode_inside(const void *data,
1551 int size,
1552 unsigned int src_x,
1553 unsigned int src_y,
1554 unsigned int src_w,
1555 unsigned int src_h,
1556 unsigned int *d,
1557 unsigned int w,
1558 unsigned int h,
1559 unsigned int row_stride,
1560 int alpha,
1561 int comp,
1562 int quality,
1563 int lossy)
1564{
1565 if (lossy == 0 && quality == 100)
1566 {
1567 unsigned int *body;
1568
1569 body = ((unsigned int *)data) + 8;
1570 if (!comp)
1571 _eet_data_image_copy_buffer(body, src_x, src_y, src_w, d,
1572 w, h, row_stride);
1573 else
1574 {
1575 if (src_h == h && src_w == w && row_stride == src_w * 4)
1576 {
1577 uLongf dlen;
1578
1579 dlen = w * h * 4;
1580 uncompress((Bytef *)d, &dlen, (Bytef *)body,
1581 (uLongf)(size - 32));
1582 }
1583 else
1584 {
1585 Bytef *dtmp;
1586 uLongf dlen = src_w * src_h * 4;
1587
1588 /* FIXME: This could create a huge alloc. So compressed
1589 data and tile could not always work. */
1590 dtmp = malloc(dlen);
1591 if (!dtmp)
1592 return 0;
1593
1594 uncompress(dtmp, &dlen, (Bytef *)body, (uLongf)(size - 32));
1595
1596 _eet_data_image_copy_buffer((unsigned int *)dtmp,
1597 src_x, src_y, src_w, d,
1598 w, h, row_stride);
1599
1600 free(dtmp);
1601 }
1602 }
1603
1604 /* Fix swapiness. */
1605 if (_eet_image_words_bigendian)
1606 {
1607 unsigned int x;
1608
1609 for (x = 0; x < (w * h); x++) SWAP32(d[x]);
1610 }
1611 }
1612 else if (comp == 0 && lossy == 1)
1613 {
1614 if (alpha)
1615 {
1616 unsigned const char *dt;
1617 int header[8];
1618 int sz1, sz2;
1619
1620 memcpy(header, data, 32);
1621 if (_eet_image_words_bigendian)
1622 {
1623 int i;
1624
1625 for (i = 0; i < 8; i++) SWAP32(header[i]);
1626 }
1627
1628 sz1 = header[1];
1629 sz2 = header[2];
1630 dt = data;
1631 dt += 12;
1632
1633 if (eet_data_image_jpeg_rgb_decode(dt, sz1, src_x, src_y, d, w, h,
1634 row_stride))
1635 {
1636 dt += sz1;
1637 if (!eet_data_image_jpeg_alpha_decode(dt, sz2, src_x, src_y,
1638 d, w, h, row_stride))
1639 return 0;
1640 }
1641 }
1642 else if (!eet_data_image_jpeg_rgb_decode(data, size, src_x, src_y, d, w,
1643 h, row_stride))
1644 return 0;
1645 }
1646 else
1647 abort();
1648
1649 return 1;
1650} /* _eet_data_image_decode_inside */
1651
1652EAPI void *
1653eet_data_image_decode_cipher(const void *data,
1654 const char *cipher_key,
1655 int size,
1656 unsigned int *w,
1657 unsigned int *h,
1658 int *alpha,
1659 int *comp,
1660 int *quality,
1661 int *lossy)
1662{
1663 unsigned int *d = NULL;
1664 unsigned int iw, ih;
1665 int ialpha, icompress, iquality, ilossy;
1666 void *deciphered_d = NULL;
1667 unsigned int deciphered_sz = 0;
1668
1669 if (cipher_key)
1670 {
1671 if (!eet_decipher(data, size, cipher_key, strlen(cipher_key),
1672 &deciphered_d, &deciphered_sz))
1673 {
1674 data = deciphered_d;
1675 size = deciphered_sz;
1676 }
1677 else
1678 if (deciphered_d)
1679 free(deciphered_d);
1680 }
1681
1682 /* All check are done during header decode, this simplify the code a lot. */
1683 if (!eet_data_image_header_decode(data, size, &iw, &ih, &ialpha, &icompress,
1684 &iquality, &ilossy))
1685 return NULL;
1686
1687 d = malloc(iw * ih * 4);
1688 if (!d)
1689 return NULL;
1690
1691 if (!_eet_data_image_decode_inside(data, size, 0, 0, iw, ih, d, iw, ih, iw *
1692 4, ialpha, icompress, iquality, ilossy))
1693 {
1694 free(d);
1695 return NULL;
1696 }
1697
1698 if (w)
1699 *w = iw;
1700
1701 if (h)
1702 *h = ih;
1703
1704 if (alpha)
1705 *alpha = ialpha;
1706
1707 if (comp)
1708 *comp = icompress;
1709
1710 if (quality)
1711 *quality = iquality;
1712
1713 if (lossy)
1714 *lossy = ilossy;
1715
1716 return d;
1717} /* eet_data_image_decode_cipher */
1718
1719EAPI void *
1720eet_data_image_decode(const void *data,
1721 int size,
1722 unsigned int *w,
1723 unsigned int *h,
1724 int *alpha,
1725 int *comp,
1726 int *quality,
1727 int *lossy)
1728{
1729 return eet_data_image_decode_cipher(data, NULL, size, w, h,
1730 alpha, comp, quality, lossy);
1731} /* eet_data_image_decode */
1732
1733EAPI int
1734eet_data_image_decode_to_surface_cipher(const void *data,
1735 const char *cipher_key,
1736 int size,
1737 unsigned int src_x,
1738 unsigned int src_y,
1739 unsigned int *d,
1740 unsigned int w,
1741 unsigned int h,
1742 unsigned int row_stride,
1743 int *alpha,
1744 int *comp,
1745 int *quality,
1746 int *lossy)
1747{
1748 unsigned int iw, ih;
1749 int ialpha, icompress, iquality, ilossy;
1750 void *deciphered_d = NULL;
1751 unsigned int deciphered_sz = 0;
1752
1753 if (cipher_key)
1754 {
1755 if (!eet_decipher(data, size, cipher_key, strlen(cipher_key),
1756 &deciphered_d, &deciphered_sz))
1757 {
1758 data = deciphered_d;
1759 size = deciphered_sz;
1760 }
1761 else
1762 if (deciphered_d)
1763 free(deciphered_d);
1764 }
1765
1766 /* All check are done during header decode, this simplify the code a lot. */
1767 if (!eet_data_image_header_decode(data, size, &iw, &ih, &ialpha, &icompress,
1768 &iquality, &ilossy))
1769 return 0;
1770
1771 if (!d)
1772 return 0;
1773
1774 if (w * 4 > row_stride)
1775 return 0;
1776
1777 if (w > iw || h > ih)
1778 return 0;
1779
1780 if (!_eet_data_image_decode_inside(data, size, src_x, src_y, iw, ih, d, w, h,
1781 row_stride, ialpha, icompress, iquality,
1782 ilossy))
1783 return 0;
1784
1785 if (alpha)
1786 *alpha = ialpha;
1787
1788 if (comp)
1789 *comp = icompress;
1790
1791 if (quality)
1792 *quality = iquality;
1793
1794 if (lossy)
1795 *lossy = ilossy;
1796
1797 return 1;
1798} /* eet_data_image_decode_to_surface_cipher */
1799
1800EAPI int
1801eet_data_image_decode_to_surface(const void *data,
1802 int size,
1803 unsigned int src_x,
1804 unsigned int src_y,
1805 unsigned int *d,
1806 unsigned int w,
1807 unsigned int h,
1808 unsigned int row_stride,
1809 int *alpha,
1810 int *comp,
1811 int *quality,
1812 int *lossy)
1813{
1814 return eet_data_image_decode_to_surface_cipher(data, NULL, size,
1815 src_x, src_y, d,
1816 w, h, row_stride,
1817 alpha, comp, quality,
1818 lossy);
1819} /* eet_data_image_decode_to_surface */
1820
diff --git a/libraries/eet/src/lib/eet_lib.c b/libraries/eet/src/lib/eet_lib.c
new file mode 100644
index 0000000..a0d6435
--- /dev/null
+++ b/libraries/eet/src/lib/eet_lib.c
@@ -0,0 +1,2648 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif /* ifdef HAVE_CONFIG_H */
4
5#ifdef HAVE_ALLOCA_H
6# include <alloca.h>
7#elif defined __GNUC__
8# define alloca __builtin_alloca
9#elif defined _AIX
10# define alloca __alloca
11#elif defined _MSC_VER
12# include <malloc.h>
13# define alloca _alloca
14#else /* ifdef HAVE_ALLOCA_H */
15# include <stddef.h>
16# ifdef __cplusplus
17extern "C"
18# endif /* ifdef __cplusplus */
19void *alloca(size_t);
20#endif /* ifdef HAVE_ALLOCA_H */
21
22#ifdef _WIN32
23# include <winsock2.h>
24#endif /* ifdef _WIN32 */
25
26#include <stdio.h>
27#include <errno.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <time.h>
31#include <string.h>
32#include <fnmatch.h>
33#include <fcntl.h>
34#include <zlib.h>
35
36#ifdef HAVE_UNISTD_H
37# include <unistd.h>
38#endif /* ifdef HAVE_UNISTD_H */
39
40#ifdef HAVE_NETINET_IN_H
41# include <netinet/in.h>
42#endif /* ifdef HAVE_NETINET_IN_H */
43
44#ifdef HAVE_EVIL
45# include <Evil.h>
46#endif /* ifdef HAVE_EVIL */
47
48#include <Eina.h>
49
50#ifdef HAVE_GNUTLS
51# include <gnutls/gnutls.h>
52# include <gcrypt.h>
53#endif /* ifdef HAVE_GNUTLS */
54
55#ifdef HAVE_OPENSSL
56# include <openssl/err.h>
57# include <openssl/evp.h>
58#endif /* ifdef HAVE_OPENSSL */
59
60#ifdef EINA_HAVE_THREADS
61# ifdef HAVE_GNUTLS
62GCRY_THREAD_OPTION_PTHREAD_IMPL;
63# endif /* ifdef HAVE_GNUTLS */
64#endif /* ifdef EINA_HAVE_THREADS */
65
66#include "Eet.h"
67#include "Eet_private.h"
68
69#ifndef O_BINARY
70# define O_BINARY 0
71#endif
72
73static Eet_Version _version = { VMAJ, VMIN, VMIC, VREV };
74EAPI Eet_Version *eet_version = &_version;
75
76#ifdef HAVE_REALPATH
77# undef HAVE_REALPATH
78#endif /* ifdef HAVE_REALPATH */
79
80#define EET_MAGIC_FILE 0x1ee7ff00
81#define EET_MAGIC_FILE_HEADER 0x1ee7ff01
82
83#define EET_MAGIC_FILE2 0x1ee70f42
84
85typedef struct _Eet_File_Header Eet_File_Header;
86typedef struct _Eet_File_Node Eet_File_Node;
87typedef struct _Eet_File_Directory Eet_File_Directory;
88
89struct _Eet_File
90{
91 char *path;
92 Eina_File *readfp;
93 Eet_File_Header *header;
94 Eet_Dictionary *ed;
95 Eet_Key *key;
96 const unsigned char *data;
97 const void *x509_der;
98 const void *signature;
99 void *sha1;
100
101 Eet_File_Mode mode;
102
103 int magic;
104 int references;
105
106 unsigned long int data_size;
107 int x509_length;
108 unsigned int signature_length;
109 int sha1_length;
110
111 Eina_Lock file_lock;
112
113 unsigned char writes_pending : 1;
114 unsigned char delete_me_now : 1;
115};
116
117struct _Eet_File_Header
118{
119 int magic;
120 Eet_File_Directory *directory;
121};
122
123struct _Eet_File_Directory
124{
125 int size;
126 Eet_File_Node **nodes;
127};
128
129struct _Eet_File_Node
130{
131 char *name;
132 void *data;
133 Eet_File_Node *next; /* FIXME: make buckets linked lists */
134
135 unsigned long int offset;
136 unsigned long int dictionary_offset;
137 unsigned long int name_offset;
138
139 unsigned int name_size;
140 unsigned int size;
141 unsigned int data_size;
142
143 unsigned char free_name : 1;
144 unsigned char compression : 1;
145 unsigned char ciphered : 1;
146 unsigned char alias : 1;
147};
148
149#if 0
150/* Version 2 */
151/* NB: all int's are stored in network byte order on disk */
152/* file format: */
153int magic; /* magic number ie 0x1ee7ff00 */
154int num_directory_entries; /* number of directory entries to follow */
155int bytes_directory_entries; /* bytes of directory entries to follow */
156struct
157{
158 int offset; /* bytes offset into file for data chunk */
159 int flags; /* flags - for now 0 = uncompressed and clear, 1 = compressed and clear, 2 = uncompressed and ciphered, 3 = compressed and ciphered */
160 int size; /* size of the data chunk */
161 int data_size; /* size of the (uncompressed) data chunk */
162 int name_size; /* length in bytes of the name field */
163 char name[name_size]; /* name string (variable length) and \0 terminated */
164} directory[num_directory_entries];
165/* and now startes the data stream... */
166#endif /* if 0 */
167
168#if 0
169/* Version 3 */
170/* NB: all int's are stored in network byte order on disk */
171/* file format: */
172int magic; /* magic number ie 0x1ee70f42 */
173int num_directory_entries; /* number of directory entries to follow */
174int num_dictionary_entries; /* number of dictionary entries to follow */
175struct
176{
177 int data_offset; /* bytes offset into file for data chunk */
178 int size; /* size of the data chunk */
179 int data_size; /* size of the (uncompressed) data chunk */
180 int name_offset; /* bytes offset into file for name string */
181 int name_size; /* length in bytes of the name field */
182 int flags; /* bit flags - for now:
183 bit 0 => compresion on/off
184 bit 1 => ciphered on/off
185 bit 2 => alias
186 */
187} directory[num_directory_entries];
188struct
189{
190 int hash;
191 int offset;
192 int size;
193 int prev;
194 int next;
195} dictionary[num_dictionary_entries];
196/* now start the string stream. */
197/* and right after them the data stream. */
198int magic_sign; /* Optional, only if the eet file is signed. */
199int signature_length; /* Signature length. */
200int x509_length; /* Public certificate that signed the file. */
201char signature[signature_length]; /* The signature. */
202char x509[x509_length]; /* The public certificate. */
203#endif /* if 0 */
204
205#define EET_FILE2_HEADER_COUNT 3
206#define EET_FILE2_DIRECTORY_ENTRY_COUNT 6
207#define EET_FILE2_DICTIONARY_ENTRY_COUNT 5
208
209#define EET_FILE2_HEADER_SIZE (sizeof(int) * \
210 EET_FILE2_HEADER_COUNT)
211#define EET_FILE2_DIRECTORY_ENTRY_SIZE (sizeof(int) * \
212 EET_FILE2_DIRECTORY_ENTRY_COUNT)
213#define EET_FILE2_DICTIONARY_ENTRY_SIZE (sizeof(int) * \
214 EET_FILE2_DICTIONARY_ENTRY_COUNT)
215
216/* prototypes of internal calls */
217static Eet_File *
218eet_cache_find(const char *path,
219 Eet_File **cache,
220 int cache_num);
221static void
222eet_cache_add(Eet_File *ef,
223 Eet_File ***cache,
224 int *cache_num,
225 int *cache_alloc);
226static void
227eet_cache_del(Eet_File *ef,
228 Eet_File ***cache,
229 int *cache_num,
230 int *cache_alloc);
231static int
232eet_string_match(const char *s1,
233 const char *s2);
234#if 0 /* Unused */
235static Eet_Error
236eet_flush(Eet_File *ef);
237#endif /* if 0 */
238static Eet_Error
239 eet_flush2(Eet_File *ef);
240static Eet_File_Node *
241 find_node_by_name(Eet_File *ef,
242 const char *name);
243static int
244read_data_from_disk(Eet_File *ef,
245 Eet_File_Node *efn,
246 void *buf,
247 int len);
248
249static Eet_Error
250eet_internal_close(Eet_File *ef,
251 Eina_Bool locked);
252
253static Eina_Lock eet_cache_lock;
254
255#define LOCK_CACHE eina_lock_take(&eet_cache_lock)
256#define UNLOCK_CACHE eina_lock_release(&eet_cache_lock)
257
258#define INIT_FILE(File) eina_lock_new(&File->file_lock)
259#define LOCK_FILE(File) eina_lock_take(&File->file_lock)
260#define UNLOCK_FILE(File) eina_lock_release(&File->file_lock)
261#define DESTROY_FILE(File) eina_lock_free(&File->file_lock)
262
263/* cache. i don't expect this to ever be large, so arrays will do */
264static int eet_writers_num = 0;
265static int eet_writers_alloc = 0;
266static Eet_File **eet_writers = NULL;
267static int eet_readers_num = 0;
268static int eet_readers_alloc = 0;
269static Eet_File **eet_readers = NULL;
270static int eet_init_count = 0;
271
272/* log domain variable */
273int _eet_log_dom_global = -1;
274
275/* Check to see its' an eet file pointer */
276static inline int
277eet_check_pointer(const Eet_File *ef)
278{
279 if ((!ef) || (ef->magic != EET_MAGIC_FILE))
280 return 1;
281
282 return 0;
283} /* eet_check_pointer */
284
285static inline int
286eet_check_header(const Eet_File *ef)
287{
288 if (!ef->header)
289 return 1;
290
291 if (!ef->header->directory)
292 return 1;
293
294 return 0;
295} /* eet_check_header */
296
297static inline int
298eet_test_close(int test,
299 Eet_File *ef)
300{
301 if (test)
302 {
303 ef->delete_me_now = 1;
304 eet_internal_close(ef, EINA_TRUE);
305 }
306
307 return test;
308} /* eet_test_close */
309
310/* find an eet file in the currently in use cache */
311static Eet_File *
312eet_cache_find(const char *path,
313 Eet_File **cache,
314 int cache_num)
315{
316 int i;
317
318 /* walk list */
319 for (i = 0; i < cache_num; i++)
320 {
321 /* if matches real path - return it */
322 if (eet_string_match(cache[i]->path, path))
323 if (!cache[i]->delete_me_now)
324 return cache[i];
325 }
326
327 /* not found */
328 return NULL;
329} /* eet_cache_find */
330
331/* add to end of cache */
332/* this should only be called when the cache lock is already held */
333static void
334eet_cache_add(Eet_File *ef,
335 Eet_File ***cache,
336 int *cache_num,
337 int *cache_alloc)
338{
339 Eet_File **new_cache;
340 int new_cache_num;
341 int new_cache_alloc;
342
343 new_cache_num = *cache_num;
344 if (new_cache_num >= 64) /* avoid fd overruns - limit to 128 (most recent) in the cache */
345 {
346 Eet_File *del_ef = NULL;
347 int i;
348
349 new_cache = *cache;
350 for (i = 0; i < new_cache_num; i++)
351 {
352 if (new_cache[i]->references == 0)
353 {
354 del_ef = new_cache[i];
355 break;
356 }
357 }
358
359 if (del_ef)
360 {
361 del_ef->delete_me_now = 1;
362 eet_internal_close(del_ef, EINA_TRUE);
363 }
364 }
365
366 new_cache = *cache;
367 new_cache_num = *cache_num;
368 new_cache_alloc = *cache_alloc;
369 new_cache_num++;
370 if (new_cache_num > new_cache_alloc)
371 {
372 new_cache_alloc += 16;
373 new_cache = realloc(new_cache, new_cache_alloc * sizeof(Eet_File *));
374 if (!new_cache)
375 {
376 CRIT("BAD ERROR! Eet realloc of cache list failed. Abort");
377 abort();
378 }
379 }
380
381 new_cache[new_cache_num - 1] = ef;
382 *cache = new_cache;
383 *cache_num = new_cache_num;
384 *cache_alloc = new_cache_alloc;
385} /* eet_cache_add */
386
387/* delete from cache */
388/* this should only be called when the cache lock is already held */
389static void
390eet_cache_del(Eet_File *ef,
391 Eet_File ***cache,
392 int *cache_num,
393 int *cache_alloc)
394{
395 Eet_File **new_cache;
396 int new_cache_num, new_cache_alloc;
397 int i, j;
398
399 new_cache = *cache;
400 new_cache_num = *cache_num;
401 new_cache_alloc = *cache_alloc;
402 if (new_cache_num <= 0)
403 return;
404
405 for (i = 0; i < new_cache_num; i++)
406 {
407 if (new_cache[i] == ef)
408 break;
409 }
410
411 if (i >= new_cache_num)
412 return;
413
414 new_cache_num--;
415 for (j = i; j < new_cache_num; j++)
416 new_cache[j] = new_cache[j + 1];
417
418 if (new_cache_num <= (new_cache_alloc - 16))
419 {
420 new_cache_alloc -= 16;
421 if (new_cache_num > 0)
422 {
423 new_cache = realloc(new_cache, new_cache_alloc * sizeof(Eet_File *));
424 if (!new_cache)
425 {
426 CRIT("BAD ERROR! Eet realloc of cache list failed. Abort");
427 abort();
428 }
429 }
430 else
431 {
432 free(new_cache);
433 new_cache = NULL;
434 }
435 }
436
437 *cache = new_cache;
438 *cache_num = new_cache_num;
439 *cache_alloc = new_cache_alloc;
440} /* eet_cache_del */
441
442/* internal string match. null friendly, catches same ptr */
443static int
444eet_string_match(const char *s1,
445 const char *s2)
446{
447 /* both null- no match */
448 if ((!s1) || (!s2))
449 return 0;
450
451 if (s1 == s2)
452 return 1;
453
454 return !strcmp(s1, s2);
455} /* eet_string_match */
456
457/* flush out writes to a v2 eet file */
458static Eet_Error
459eet_flush2(Eet_File *ef)
460{
461 Eet_File_Node *efn;
462 FILE *fp;
463 Eet_Error error = EET_ERROR_NONE;
464 int head[EET_FILE2_HEADER_COUNT];
465 int num_directory_entries = 0;
466 int num_dictionary_entries = 0;
467 int bytes_directory_entries = 0;
468 int bytes_dictionary_entries = 0;
469 int bytes_strings = 0;
470 int data_offset = 0;
471 int strings_offset = 0;
472 int num;
473 int i;
474 int j;
475
476 if (eet_check_pointer(ef))
477 return EET_ERROR_BAD_OBJECT;
478
479 if (eet_check_header(ef))
480 return EET_ERROR_EMPTY;
481
482 if (!ef->writes_pending)
483 return EET_ERROR_NONE;
484
485 if ((ef->mode == EET_FILE_MODE_READ_WRITE)
486 || (ef->mode == EET_FILE_MODE_WRITE))
487 {
488 int fd;
489
490 /* opening for write - delete old copy of file right away */
491 unlink(ef->path);
492 fd = open(ef->path, O_CREAT | O_TRUNC | O_RDWR | O_BINARY, S_IRUSR | S_IWUSR);
493 fp = fdopen(fd, "wb");
494 if (!fp)
495 return EET_ERROR_NOT_WRITABLE;
496
497 fcntl(fileno(fp), F_SETFD, FD_CLOEXEC);
498 }
499 else
500 return EET_ERROR_NOT_WRITABLE;
501
502 /* calculate string base offset and data base offset */
503 num = (1 << ef->header->directory->size);
504 for (i = 0; i < num; ++i)
505 {
506 for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
507 {
508 num_directory_entries++;
509 bytes_strings += strlen(efn->name) + 1;
510 }
511 }
512 if (ef->ed)
513 {
514 num_dictionary_entries = ef->ed->count;
515
516 for (i = 0; i < num_dictionary_entries; ++i)
517 bytes_strings += ef->ed->all[i].len;
518 }
519
520 /* calculate section bytes size */
521 bytes_directory_entries = EET_FILE2_DIRECTORY_ENTRY_SIZE *
522 num_directory_entries + EET_FILE2_HEADER_SIZE;
523 bytes_dictionary_entries = EET_FILE2_DICTIONARY_ENTRY_SIZE *
524 num_dictionary_entries;
525
526 /* calculate per entry offset */
527 strings_offset = bytes_directory_entries + bytes_dictionary_entries;
528 data_offset = bytes_directory_entries + bytes_dictionary_entries +
529 bytes_strings;
530
531 for (i = 0; i < num; ++i)
532 {
533 for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
534 {
535 efn->offset = data_offset;
536 data_offset += efn->size;
537
538 efn->name_offset = strings_offset;
539 strings_offset += efn->name_size;
540 }
541 }
542
543 /* calculate dictionary strings offset */
544 if (ef->ed)
545 ef->ed->offset = strings_offset;
546
547 /* go thru and write the header */
548 head[0] = (int)htonl((unsigned int)EET_MAGIC_FILE2);
549 head[1] = (int)htonl((unsigned int)num_directory_entries);
550 head[2] = (int)htonl((unsigned int)num_dictionary_entries);
551
552 fseek(fp, 0, SEEK_SET);
553 if (fwrite(head, sizeof (head), 1, fp) != 1)
554 goto write_error;
555
556 /* write directories entry */
557 for (i = 0; i < num; i++)
558 {
559 for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
560 {
561 unsigned int flag;
562 int ibuf[EET_FILE2_DIRECTORY_ENTRY_COUNT];
563
564 flag = (efn->alias << 2) | (efn->ciphered << 1) | efn->compression;
565
566 ibuf[0] = (int)htonl((unsigned int)efn->offset);
567 ibuf[1] = (int)htonl((unsigned int)efn->size);
568 ibuf[2] = (int)htonl((unsigned int)efn->data_size);
569 ibuf[3] = (int)htonl((unsigned int)efn->name_offset);
570 ibuf[4] = (int)htonl((unsigned int)efn->name_size);
571 ibuf[5] = (int)htonl((unsigned int)flag);
572
573 if (fwrite(ibuf, sizeof(ibuf), 1, fp) != 1)
574 goto write_error;
575 }
576 }
577
578 /* write dictionary */
579 if (ef->ed)
580 {
581 int offset = strings_offset;
582
583 for (j = 0; j < ef->ed->count; ++j)
584 {
585 int sbuf[EET_FILE2_DICTIONARY_ENTRY_COUNT];
586
587 sbuf[0] = (int)htonl((unsigned int)ef->ed->all[j].hash);
588 sbuf[1] = (int)htonl((unsigned int)offset);
589 sbuf[2] = (int)htonl((unsigned int)ef->ed->all[j].len);
590 sbuf[3] = (int)htonl((unsigned int)ef->ed->all[j].prev);
591 sbuf[4] = (int)htonl((unsigned int)ef->ed->all[j].next);
592
593 offset += ef->ed->all[j].len;
594
595 if (fwrite(sbuf, sizeof (sbuf), 1, fp) != 1)
596 goto write_error;
597 }
598 }
599
600 /* write directories name */
601 for (i = 0; i < num; i++)
602 {
603 for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
604 {
605 if (fwrite(efn->name, efn->name_size, 1, fp) != 1)
606 goto write_error;
607 }
608 }
609
610 /* write strings */
611 if (ef->ed)
612 for (j = 0; j < ef->ed->count; ++j)
613 {
614 if (fwrite(ef->ed->all[j].str, ef->ed->all[j].len, 1, fp) != 1)
615 goto write_error;
616 }
617
618 /* write data */
619 for (i = 0; i < num; i++)
620 {
621 for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
622 {
623 if (fwrite(efn->data, efn->size, 1, fp) != 1)
624 goto write_error;
625 }
626 }
627
628 /* flush all write to the file. */
629 fflush(fp);
630// this is going to really cause trouble. if ANYTHING this needs to go into a
631// thread spawned off - but even then...
632// in this case... ext4 is "wrong". (yes we can jump up and down and point posix
633// manual pages at eachother, but ext4 broke behavior that has been in place
634// for decades and that 1000's of apps rely on daily - that is that one operation
635// to disk is committed to disk BEFORE following operations, so the fs retains
636// a consistent state
637// fsync(fileno(fp));
638
639 /* append signature if required */
640 if (ef->key)
641 {
642 error = eet_identity_sign(fp, ef->key);
643 if (error != EET_ERROR_NONE)
644 goto sign_error;
645 }
646
647 /* no more writes pending */
648 ef->writes_pending = 0;
649
650 fclose(fp);
651
652 return EET_ERROR_NONE;
653
654write_error:
655 if (ferror(fp))
656 {
657 switch (errno)
658 {
659 case EFBIG: error = EET_ERROR_WRITE_ERROR_FILE_TOO_BIG; break;
660
661 case EIO: error = EET_ERROR_WRITE_ERROR_IO_ERROR; break;
662
663 case ENOSPC: error = EET_ERROR_WRITE_ERROR_OUT_OF_SPACE; break;
664
665 case EPIPE: error = EET_ERROR_WRITE_ERROR_FILE_CLOSED; break;
666
667 default: error = EET_ERROR_WRITE_ERROR; break;
668 } /* switch */
669 }
670
671sign_error:
672 fclose(fp);
673 return error;
674} /* eet_flush2 */
675
676EAPI int
677eet_init(void)
678{
679 if (++eet_init_count != 1)
680 return eet_init_count;
681
682 if (!eina_init())
683 {
684 fprintf(stderr, "Eet: Eina init failed");
685 return --eet_init_count;
686 }
687
688 _eet_log_dom_global = eina_log_domain_register("eet", EET_DEFAULT_LOG_COLOR);
689 if (_eet_log_dom_global < 0)
690 {
691 EINA_LOG_ERR("Eet Can not create a general log domain.");
692 goto shutdown_eina;
693 }
694
695 eina_lock_new(&eet_cache_lock);
696
697 if (!eet_node_init())
698 {
699 EINA_LOG_ERR("Eet: Eet_Node mempool creation failed");
700 goto unregister_log_domain;
701 }
702
703#ifdef HAVE_GNUTLS
704 /* Before the library can be used, it must initialize itself if needed. */
705 if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
706 {
707 gcry_check_version(NULL);
708 /* Disable warning messages about problems with the secure memory subsystem.
709 This command should be run right after gcry_check_version. */
710 if (gcry_control(GCRYCTL_DISABLE_SECMEM_WARN))
711 goto shutdown_eet; /* This command is used to allocate a pool of secure memory and thus
712 enabling the use of secure memory. It also drops all extra privileges the
713 process has (i.e. if it is run as setuid (root)). If the argument nbytes
714 is 0, secure memory will be disabled. The minimum amount of secure memory
715 allocated is currently 16384 bytes; you may thus use a value of 1 to
716 request that default size. */
717
718 if (gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0))
719 WRN(
720 "BIG FAT WARNING: I AM UNABLE TO REQUEST SECMEM, Cryptographic operation are at risk !");
721 }
722
723# ifdef EINA_HAVE_THREADS
724 if (gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread))
725 WRN(
726 "YOU ARE USING PTHREADS, BUT I CANNOT INITIALIZE THREADSAFE GCRYPT OPERATIONS!");
727
728# endif /* ifdef EINA_HAVE_THREADS */
729 if (gnutls_global_init())
730 goto shutdown_eet;
731
732#endif /* ifdef HAVE_GNUTLS */
733#ifdef HAVE_OPENSSL
734 ERR_load_crypto_strings();
735 OpenSSL_add_all_algorithms();
736#endif /* ifdef HAVE_OPENSSL */
737
738 return eet_init_count;
739
740#ifdef HAVE_GNUTLS
741shutdown_eet:
742#endif
743 eet_node_shutdown();
744unregister_log_domain:
745 eina_log_domain_unregister(_eet_log_dom_global);
746 _eet_log_dom_global = -1;
747shutdown_eina:
748 eina_shutdown();
749 return --eet_init_count;
750} /* eet_init */
751
752EAPI int
753eet_shutdown(void)
754{
755 if (--eet_init_count != 0)
756 return eet_init_count;
757
758 eet_clearcache();
759 eet_node_shutdown();
760
761 eina_lock_free(&eet_cache_lock);
762
763#ifdef HAVE_GNUTLS
764 gnutls_global_deinit();
765#endif /* ifdef HAVE_GNUTLS */
766#ifdef HAVE_OPENSSL
767 EVP_cleanup();
768 ERR_free_strings();
769#endif /* ifdef HAVE_OPENSSL */
770 eina_log_domain_unregister(_eet_log_dom_global);
771 _eet_log_dom_global = -1;
772 eina_shutdown();
773
774 return eet_init_count;
775} /* eet_shutdown */
776
777EAPI Eet_Error
778eet_sync(Eet_File *ef)
779{
780 Eet_Error ret;
781
782 if (eet_check_pointer(ef))
783 return EET_ERROR_BAD_OBJECT;
784
785 if ((ef->mode != EET_FILE_MODE_WRITE) &&
786 (ef->mode != EET_FILE_MODE_READ_WRITE))
787 return EET_ERROR_NOT_WRITABLE;
788
789 if (!ef->writes_pending)
790 return EET_ERROR_NONE;
791
792 LOCK_FILE(ef);
793
794 ret = eet_flush2(ef);
795
796 UNLOCK_FILE(ef);
797 return ret;
798} /* eet_sync */
799
800EAPI void
801eet_clearcache(void)
802{
803 int num = 0;
804 int i;
805
806 /*
807 * We need to compute the list of eet file to close separately from the cache,
808 * due to eet_close removing them from the cache after each call.
809 */
810 LOCK_CACHE;
811 for (i = 0; i < eet_writers_num; i++)
812 {
813 if (eet_writers[i]->references <= 0)
814 num++;
815 }
816
817 for (i = 0; i < eet_readers_num; i++)
818 {
819 if (eet_readers[i]->references <= 0)
820 num++;
821 }
822
823 if (num > 0)
824 {
825 Eet_File **closelist = NULL;
826
827 closelist = alloca(num * sizeof(Eet_File *));
828 num = 0;
829 for (i = 0; i < eet_writers_num; i++)
830 {
831 if (eet_writers[i]->references <= 0)
832 {
833 closelist[num] = eet_writers[i];
834 eet_writers[i]->delete_me_now = 1;
835 num++;
836 }
837 }
838
839 for (i = 0; i < eet_readers_num; i++)
840 {
841 if (eet_readers[i]->references <= 0)
842 {
843 closelist[num] = eet_readers[i];
844 eet_readers[i]->delete_me_now = 1;
845 num++;
846 }
847 }
848
849 for (i = 0; i < num; i++)
850 {
851 eet_internal_close(closelist[i], EINA_TRUE);
852 }
853 }
854
855 UNLOCK_CACHE;
856} /* eet_clearcache */
857
858/* FIXME: MMAP race condition in READ_WRITE_MODE */
859static Eet_File *
860eet_internal_read2(Eet_File *ef)
861{
862 const int *data = (const int *)ef->data;
863 const char *start = (const char *)ef->data;
864 int idx = 0;
865 unsigned long int bytes_directory_entries;
866 unsigned long int bytes_dictionary_entries;
867 unsigned long int signature_base_offset;
868 unsigned long int num_directory_entries;
869 unsigned long int num_dictionary_entries;
870 unsigned int i;
871
872 idx += sizeof(int);
873 if (eet_test_close((int)ntohl(*data) != EET_MAGIC_FILE2, ef))
874 return NULL;
875
876 data++;
877
878#define GET_INT(Value, Pointer, Index) \
879 { \
880 Value = ntohl(*Pointer); \
881 Pointer++; \
882 Index += sizeof(int); \
883 }
884
885 /* get entries count and byte count */
886 GET_INT(num_directory_entries, data, idx);
887 /* get dictionary count and byte count */
888 GET_INT(num_dictionary_entries, data, idx);
889
890 bytes_directory_entries = EET_FILE2_DIRECTORY_ENTRY_SIZE *
891 num_directory_entries + EET_FILE2_HEADER_SIZE;
892 bytes_dictionary_entries = EET_FILE2_DICTIONARY_ENTRY_SIZE *
893 num_dictionary_entries;
894
895 /* we can't have > 0x7fffffff values here - invalid */
896 if (eet_test_close((num_directory_entries > 0x7fffffff), ef))
897 return NULL;
898
899 /* we can't have more bytes directory and bytes in dictionaries than the size of the file */
900 if (eet_test_close((bytes_directory_entries + bytes_dictionary_entries) >
901 ef->data_size, ef))
902 return NULL;
903
904 /* allocate header */
905 ef->header = calloc(1, sizeof(Eet_File_Header));
906 if (eet_test_close(!ef->header, ef))
907 return NULL;
908
909 ef->header->magic = EET_MAGIC_FILE_HEADER;
910
911 /* allocate directory block in ram */
912 ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
913 if (eet_test_close(!ef->header->directory, ef))
914 return NULL;
915
916 /* 8 bit hash table (256 buckets) */
917 ef->header->directory->size = 8;
918 /* allocate base hash table */
919 ef->header->directory->nodes =
920 calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size));
921 if (eet_test_close(!ef->header->directory->nodes, ef))
922 return NULL;
923
924 signature_base_offset = 0;
925 if (num_directory_entries == 0)
926 {
927 signature_base_offset = ef->data_size;
928 }
929
930 /* actually read the directory block - all of it, into ram */
931 for (i = 0; i < num_directory_entries; ++i)
932 {
933 const char *name;
934 Eet_File_Node *efn;
935 unsigned long int name_offset;
936 unsigned long int name_size;
937 int hash;
938 int flag;
939
940 /* out directory block is inconsistent - we have overrun our */
941 /* dynamic block buffer before we finished scanning dir entries */
942 efn = malloc(sizeof(Eet_File_Node));
943 if (eet_test_close(!efn, ef))
944 {
945 if (efn) free(efn); /* yes i know - we only get here if
946 * efn is null/0 -> trying to shut up
947 * warning tools like cppcheck */
948 return NULL;
949 }
950
951 /* get entrie header */
952 GET_INT(efn->offset, data, idx);
953 GET_INT(efn->size, data, idx);
954 GET_INT(efn->data_size, data, idx);
955 GET_INT(name_offset, data, idx);
956 GET_INT(name_size, data, idx);
957 GET_INT(flag, data, idx);
958
959 efn->compression = flag & 0x1 ? 1 : 0;
960 efn->ciphered = flag & 0x2 ? 1 : 0;
961 efn->alias = flag & 0x4 ? 1 : 0;
962
963#define EFN_TEST(Test, Ef, Efn) \
964 if (eet_test_close(Test, Ef)) \
965 { \
966 free(Efn); \
967 return NULL; \
968 }
969
970 /* check data pointer position */
971 EFN_TEST(!((efn->size > 0)
972 && (efn->offset + efn->size <= ef->data_size)
973 && (efn->offset > bytes_dictionary_entries +
974 bytes_directory_entries)), ef, efn);
975
976 /* check name position */
977 EFN_TEST(!((name_size > 0)
978 && (name_offset + name_size < ef->data_size)
979 && (name_offset >= bytes_dictionary_entries +
980 bytes_directory_entries)), ef, efn);
981
982 name = start + name_offset;
983
984 /* check '\0' at the end of name string */
985 EFN_TEST(name[name_size - 1] != '\0', ef, efn);
986
987 efn->free_name = 0;
988 efn->name = (char *)name;
989 efn->name_size = name_size;
990
991 hash = _eet_hash_gen(efn->name, ef->header->directory->size);
992 efn->next = ef->header->directory->nodes[hash];
993 ef->header->directory->nodes[hash] = efn;
994
995 /* read-only mode, so currently we have no data loaded */
996 if (ef->mode == EET_FILE_MODE_READ)
997 efn->data = NULL; /* read-write mode - read everything into ram */
998 else
999 {
1000 efn->data = malloc(efn->size);
1001 if (efn->data)
1002 memcpy(efn->data, ef->data + efn->offset, efn->size);
1003 }
1004
1005 /* compute the possible position of a signature */
1006 if (signature_base_offset < efn->offset + efn->size)
1007 signature_base_offset = efn->offset + efn->size;
1008 }
1009
1010 ef->ed = NULL;
1011
1012 if (num_dictionary_entries)
1013 {
1014 const int *dico = (const int *)ef->data +
1015 EET_FILE2_DIRECTORY_ENTRY_COUNT * num_directory_entries +
1016 EET_FILE2_HEADER_COUNT;
1017 int j;
1018
1019 if (eet_test_close((num_dictionary_entries *
1020 (int)EET_FILE2_DICTIONARY_ENTRY_SIZE + idx) >
1021 (bytes_dictionary_entries + bytes_directory_entries),
1022 ef))
1023 return NULL;
1024
1025 ef->ed = calloc(1, sizeof (Eet_Dictionary));
1026 if (eet_test_close(!ef->ed, ef))
1027 return NULL;
1028
1029 ef->ed->all = calloc(num_dictionary_entries, sizeof (Eet_String));
1030 if (eet_test_close(!ef->ed->all, ef))
1031 return NULL;
1032
1033 ef->ed->count = num_dictionary_entries;
1034 ef->ed->total = num_dictionary_entries;
1035 ef->ed->start = start + bytes_dictionary_entries +
1036 bytes_directory_entries;
1037 ef->ed->end = ef->ed->start;
1038
1039 for (j = 0; j < ef->ed->count; ++j)
1040 {
1041 unsigned int offset;
1042 int hash;
1043
1044 GET_INT(hash, dico, idx);
1045 GET_INT(offset, dico, idx);
1046 GET_INT(ef->ed->all[j].len, dico, idx);
1047 GET_INT(ef->ed->all[j].prev, dico, idx);
1048 GET_INT(ef->ed->all[j].next, dico, idx);
1049
1050 /* Hash value could be stored on 8bits data, but this will break alignment of all the others data.
1051 So stick to int and check the value. */
1052 if (eet_test_close(hash & 0xFFFFFF00, ef))
1053 return NULL;
1054
1055 /* Check string position */
1056 if (eet_test_close(!((ef->ed->all[j].len > 0)
1057 && (offset >
1058 (bytes_dictionary_entries +
1059 bytes_directory_entries))
1060 && (offset + ef->ed->all[j].len <
1061 ef->data_size)), ef))
1062 return NULL;
1063
1064 ef->ed->all[j].str = start + offset;
1065
1066 if (ef->ed->all[j].str + ef->ed->all[j].len > ef->ed->end)
1067 ef->ed->end = ef->ed->all[j].str + ef->ed->all[j].len;
1068
1069 /* Check '\0' at the end of the string */
1070 if (eet_test_close(ef->ed->all[j].str[ef->ed->all[j].len - 1] !=
1071 '\0', ef))
1072 return NULL;
1073
1074 ef->ed->all[j].hash = hash;
1075 if (ef->ed->all[j].prev == -1)
1076 ef->ed->hash[hash] = j;
1077
1078 /* compute the possible position of a signature */
1079 if (signature_base_offset < offset + ef->ed->all[j].len)
1080 signature_base_offset = offset + ef->ed->all[j].len;
1081 }
1082 }
1083
1084 /* Check if the file is signed */
1085 ef->x509_der = NULL;
1086 ef->x509_length = 0;
1087 ef->signature = NULL;
1088 ef->signature_length = 0;
1089
1090 if (signature_base_offset < ef->data_size)
1091 {
1092#ifdef HAVE_SIGNATURE
1093 const unsigned char *buffer = ((const unsigned char *)ef->data) +
1094 signature_base_offset;
1095 ef->x509_der = eet_identity_check(ef->data,
1096 signature_base_offset,
1097 &ef->sha1,
1098 &ef->sha1_length,
1099 buffer,
1100 ef->data_size - signature_base_offset,
1101 &ef->signature,
1102 &ef->signature_length,
1103 &ef->x509_length);
1104
1105 if (eet_test_close(!ef->x509_der, ef))
1106 return NULL;
1107
1108#else /* ifdef HAVE_SIGNATURE */
1109 ERR(
1110 "This file could be signed but you didn't compile the necessary code to check the signature.");
1111#endif /* ifdef HAVE_SIGNATURE */
1112 }
1113
1114 return ef;
1115} /* eet_internal_read2 */
1116
1117#if EET_OLD_EET_FILE_FORMAT
1118static Eet_File *
1119eet_internal_read1(Eet_File *ef)
1120{
1121 const unsigned char *dyn_buf = NULL;
1122 const unsigned char *p = NULL;
1123 unsigned long int byte_entries;
1124 unsigned long int num_entries;
1125 unsigned int i;
1126 int idx = 0;
1127
1128 WRN(
1129 "EET file format of '%s' is deprecated. You should just open it one time with mode == EET_FILE_MODE_READ_WRITE to solve this issue.",
1130 ef->path);
1131
1132 /* build header table if read mode */
1133 /* geat header */
1134 idx += sizeof(int);
1135 if (eet_test_close((int)ntohl(*((int *)ef->data)) != EET_MAGIC_FILE, ef))
1136 return NULL;
1137
1138#define EXTRACT_INT(Value, Pointer, Index) \
1139 { \
1140 int tmp; \
1141 memcpy(&tmp, Pointer + Index, sizeof(int)); \
1142 Value = ntohl(tmp); \
1143 Index += sizeof(int); \
1144 }
1145
1146 /* get entries count and byte count */
1147 EXTRACT_INT(num_entries, ef->data, idx);
1148 EXTRACT_INT(byte_entries, ef->data, idx);
1149
1150 /* we can't have <= 0 values here - invalid */
1151 if (eet_test_close((num_entries > 0x7fffffff) ||
1152 (byte_entries > 0x7fffffff), ef))
1153 return NULL;
1154
1155 /* we can't have more entires than minimum bytes for those! invalid! */
1156 if (eet_test_close((num_entries * 20) > byte_entries, ef))
1157 return NULL;
1158
1159 /* check we will not outrun the file limit */
1160 if (eet_test_close(((byte_entries + (int)(sizeof(int) * 3)) >
1161 ef->data_size), ef))
1162 return NULL;
1163
1164 /* allocate header */
1165 ef->header = calloc(1, sizeof(Eet_File_Header));
1166 if (eet_test_close(!ef->header, ef))
1167 return NULL;
1168
1169 ef->header->magic = EET_MAGIC_FILE_HEADER;
1170
1171 /* allocate directory block in ram */
1172 ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
1173 if (eet_test_close(!ef->header->directory, ef))
1174 return NULL;
1175
1176 /* 8 bit hash table (256 buckets) */
1177 ef->header->directory->size = 8;
1178 /* allocate base hash table */
1179 ef->header->directory->nodes =
1180 calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size));
1181 if (eet_test_close(!ef->header->directory->nodes, ef))
1182 return NULL;
1183
1184 /* actually read the directory block - all of it, into ram */
1185 dyn_buf = ef->data + idx;
1186
1187 /* parse directory block */
1188 p = dyn_buf;
1189
1190 for (i = 0; i < num_entries; i++)
1191 {
1192 Eet_File_Node *efn;
1193 void *data = NULL;
1194 int indexn = 0;
1195 int name_size;
1196 int hash;
1197 int k;
1198
1199#define HEADER_SIZE (sizeof(int) * 5)
1200
1201 /* out directory block is inconsistent - we have overrun our */
1202 /* dynamic block buffer before we finished scanning dir entries */
1203 if (eet_test_close(p + HEADER_SIZE >= (dyn_buf + byte_entries), ef))
1204 return NULL;
1205
1206 /* allocate all the ram needed for this stored node accounting */
1207 efn = malloc (sizeof(Eet_File_Node));
1208 if (eet_test_close(!efn, ef))
1209 {
1210 if (efn) free(efn); /* yes i know - we only get here if
1211 * efn is null/0 -> trying to shut up
1212 * warning tools like cppcheck */
1213 return NULL;
1214 }
1215
1216 /* get entrie header */
1217 EXTRACT_INT(efn->offset, p, indexn);
1218 EXTRACT_INT(efn->compression, p, indexn);
1219 EXTRACT_INT(efn->size, p, indexn);
1220 EXTRACT_INT(efn->data_size, p, indexn);
1221 EXTRACT_INT(name_size, p, indexn);
1222
1223 efn->name_size = name_size;
1224 efn->ciphered = 0;
1225 efn->alias = 0;
1226
1227 /* invalid size */
1228 if (eet_test_close(efn->size <= 0, ef))
1229 {
1230 free(efn);
1231 return NULL;
1232 }
1233
1234 /* invalid name_size */
1235 if (eet_test_close(name_size <= 0, ef))
1236 {
1237 free(efn);
1238 return NULL;
1239 }
1240
1241 /* reading name would mean falling off end of dyn_buf - invalid */
1242 if (eet_test_close((p + 16 + name_size) > (dyn_buf + byte_entries), ef))
1243 {
1244 free(efn);
1245 return NULL;
1246 }
1247
1248 /* This code is useless if we dont want backward compatibility */
1249 for (k = name_size;
1250 k > 0 && ((unsigned char)*(p + HEADER_SIZE + k)) != 0; --k)
1251 ;
1252
1253 efn->free_name = ((unsigned char)*(p + HEADER_SIZE + k)) != 0;
1254
1255 if (efn->free_name)
1256 {
1257 efn->name = malloc(sizeof(char) * name_size + 1);
1258 if (eet_test_close(!efn->name, ef))
1259 {
1260 free(efn);
1261 return NULL;
1262 }
1263
1264 strncpy(efn->name, (char *)p + HEADER_SIZE, name_size);
1265 efn->name[name_size] = 0;
1266
1267 WRN(
1268 "File: %s is not up to date for key \"%s\" - needs rebuilding sometime",
1269 ef->path,
1270 efn->name);
1271 }
1272 else
1273 /* The only really useful peace of code for efn->name (no backward compatibility) */
1274 efn->name = (char *)((unsigned char *)(p + HEADER_SIZE));
1275
1276 /* get hash bucket it should go in */
1277 hash = _eet_hash_gen(efn->name, ef->header->directory->size);
1278 efn->next = ef->header->directory->nodes[hash];
1279 ef->header->directory->nodes[hash] = efn;
1280
1281 /* read-only mode, so currently we have no data loaded */
1282 if (ef->mode == EET_FILE_MODE_READ)
1283 efn->data = NULL; /* read-write mode - read everything into ram */
1284 else
1285 {
1286 data = malloc(efn->size);
1287 if (data)
1288 memcpy(data, ef->data + efn->offset, efn->size);
1289
1290 efn->data = data;
1291 }
1292
1293 /* advance */
1294 p += HEADER_SIZE + name_size;
1295 }
1296 return ef;
1297} /* eet_internal_read1 */
1298
1299#endif /* if EET_OLD_EET_FILE_FORMAT */
1300
1301/*
1302 * this should only be called when the cache lock is already held
1303 * (We could drop this restriction if we add a parameter to eet_test_close
1304 * that indicates if the lock is held or not. For now it is easiest
1305 * to just require that it is always held.)
1306 */
1307static Eet_File *
1308eet_internal_read(Eet_File *ef)
1309{
1310 const int *data = (const int *)ef->data;
1311
1312 if (eet_test_close((ef->data == (void *)-1) || (!ef->data), ef))
1313 return NULL;
1314
1315 if (eet_test_close(ef->data_size < (int)sizeof(int) * 3, ef))
1316 return NULL;
1317
1318 switch (ntohl(*data))
1319 {
1320#if EET_OLD_EET_FILE_FORMAT
1321 case EET_MAGIC_FILE:
1322 return eet_internal_read1(ef);
1323
1324#endif /* if EET_OLD_EET_FILE_FORMAT */
1325 case EET_MAGIC_FILE2:
1326 return eet_internal_read2(ef);
1327
1328 default:
1329 ef->delete_me_now = 1;
1330 eet_internal_close(ef, EINA_TRUE);
1331 break;
1332 } /* switch */
1333
1334 return NULL;
1335} /* eet_internal_read */
1336
1337static Eet_Error
1338eet_internal_close(Eet_File *ef,
1339 Eina_Bool locked)
1340{
1341 Eet_Error err;
1342
1343 /* check to see its' an eet file pointer */
1344 if (eet_check_pointer(ef))
1345 return EET_ERROR_BAD_OBJECT;
1346
1347 if (!locked)
1348 LOCK_CACHE;
1349
1350 /* deref */
1351 ef->references--;
1352 /* if its still referenced - dont go any further */
1353 if (ef->references > 0)
1354 {
1355 /* flush any writes */
1356 if ((ef->mode == EET_FILE_MODE_WRITE) ||
1357 (ef->mode == EET_FILE_MODE_READ_WRITE))
1358 eet_sync(ef);
1359 goto on_error;
1360 }
1361
1362 err = eet_flush2(ef);
1363
1364 eet_identity_unref(ef->key);
1365 ef->key = NULL;
1366
1367 /* if not urgent to delete it - dont free it - leave it in cache */
1368 if ((!ef->delete_me_now) && (ef->mode == EET_FILE_MODE_READ))
1369 goto on_error;
1370
1371 /* remove from cache */
1372 if (ef->mode == EET_FILE_MODE_READ)
1373 eet_cache_del(ef, &eet_readers, &eet_readers_num, &eet_readers_alloc);
1374 else if ((ef->mode == EET_FILE_MODE_WRITE) ||
1375 (ef->mode == EET_FILE_MODE_READ_WRITE))
1376 eet_cache_del(ef, &eet_writers, &eet_writers_num, &eet_writers_alloc);
1377
1378 /* we can unlock the cache now */
1379 if (!locked)
1380 UNLOCK_CACHE;
1381
1382 DESTROY_FILE(ef);
1383
1384 /* free up data */
1385 if (ef->header)
1386 {
1387 if (ef->header->directory)
1388 {
1389 if (ef->header->directory->nodes)
1390 {
1391 int i, num;
1392
1393 num = (1 << ef->header->directory->size);
1394 for (i = 0; i < num; i++)
1395 {
1396 Eet_File_Node *efn;
1397
1398 while ((efn = ef->header->directory->nodes[i]))
1399 {
1400 if (efn->data)
1401 free(efn->data);
1402
1403 ef->header->directory->nodes[i] = efn->next;
1404
1405 if (efn->free_name)
1406 free(efn->name);
1407
1408 free(efn);
1409 }
1410 }
1411 free(ef->header->directory->nodes);
1412 }
1413
1414 free(ef->header->directory);
1415 }
1416
1417 free(ef->header);
1418 }
1419
1420 eet_dictionary_free(ef->ed);
1421
1422 if (ef->sha1)
1423 free(ef->sha1);
1424
1425 if (ef->readfp)
1426 {
1427 if (ef->data)
1428 eina_file_map_free(ef->readfp, (void *)ef->data);
1429
1430 eina_file_close(ef->readfp);
1431 }
1432
1433 /* zero out ram for struct - caution tactic against stale memory use */
1434 memset(ef, 0, sizeof(Eet_File));
1435
1436 /* free it */
1437 free(ef);
1438 return err;
1439
1440on_error:
1441 if (!locked)
1442 UNLOCK_CACHE;
1443
1444 return EET_ERROR_NONE;
1445} /* eet_internal_close */
1446
1447EAPI Eet_File *
1448eet_memopen_read(const void *data,
1449 size_t size)
1450{
1451 Eet_File *ef;
1452
1453 if (!data || size == 0)
1454 return NULL;
1455
1456 ef = malloc (sizeof (Eet_File));
1457 if (!ef)
1458 return NULL;
1459
1460 INIT_FILE(ef);
1461 ef->ed = NULL;
1462 ef->path = NULL;
1463 ef->key = NULL;
1464 ef->magic = EET_MAGIC_FILE;
1465 ef->references = 1;
1466 ef->mode = EET_FILE_MODE_READ;
1467 ef->header = NULL;
1468 ef->delete_me_now = 1;
1469 ef->readfp = NULL;
1470 ef->data = data;
1471 ef->data_size = size;
1472 ef->sha1 = NULL;
1473 ef->sha1_length = 0;
1474
1475 /* eet_internal_read expects the cache lock to be held when it is called */
1476 LOCK_CACHE;
1477 ef = eet_internal_read(ef);
1478 UNLOCK_CACHE;
1479 return ef;
1480} /* eet_memopen_read */
1481
1482EAPI Eet_File *
1483eet_open(const char *file,
1484 Eet_File_Mode mode)
1485{
1486 Eina_File *fp;
1487 Eet_File *ef;
1488 int file_len;
1489 unsigned long int size;
1490
1491 if (!file)
1492 return NULL;
1493
1494 /* find the current file handle in cache*/
1495 ef = NULL;
1496 LOCK_CACHE;
1497 if (mode == EET_FILE_MODE_READ)
1498 {
1499 ef = eet_cache_find((char *)file, eet_writers, eet_writers_num);
1500 if (ef)
1501 {
1502 eet_sync(ef);
1503 ef->references++;
1504 ef->delete_me_now = 1;
1505 eet_internal_close(ef, EINA_TRUE);
1506 }
1507
1508 ef = eet_cache_find((char *)file, eet_readers, eet_readers_num);
1509 }
1510 else if ((mode == EET_FILE_MODE_WRITE) ||
1511 (mode == EET_FILE_MODE_READ_WRITE))
1512 {
1513 ef = eet_cache_find((char *)file, eet_readers, eet_readers_num);
1514 if (ef)
1515 {
1516 ef->delete_me_now = 1;
1517 ef->references++;
1518 eet_internal_close(ef, EINA_TRUE);
1519 }
1520
1521 ef = eet_cache_find((char *)file, eet_writers, eet_writers_num);
1522 }
1523
1524 /* try open the file based on mode */
1525 if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
1526 {
1527 /* Prevent garbage in futur comparison. */
1528 fp = eina_file_open(file, EINA_FALSE);
1529 if (!fp)
1530 goto open_error;
1531
1532 size = eina_file_size_get(fp);
1533
1534 if (size < ((int)sizeof(int) * 3))
1535 {
1536 eina_file_close(fp);
1537 fp = NULL;
1538
1539 size = 0;
1540
1541 goto open_error;
1542 }
1543
1544open_error:
1545 if (!fp && mode == EET_FILE_MODE_READ)
1546 goto on_error;
1547 }
1548 else
1549 {
1550 if (mode != EET_FILE_MODE_WRITE)
1551 return NULL;
1552
1553 size = 0;
1554
1555 fp = NULL;
1556 }
1557
1558 /* We found one */
1559 if (ef && ef->readfp != fp)
1560 {
1561 ef->delete_me_now = 1;
1562 ef->references++;
1563 eet_internal_close(ef, EINA_TRUE);
1564 ef = NULL;
1565 }
1566
1567 if (ef)
1568 {
1569 /* reference it up and return it */
1570 if (fp)
1571 eina_file_close(fp);
1572
1573 ef->references++;
1574 UNLOCK_CACHE;
1575 return ef;
1576 }
1577
1578 file_len = strlen(file) + 1;
1579
1580 /* Allocate struct for eet file and have it zero'd out */
1581 ef = malloc(sizeof(Eet_File) + file_len);
1582 if (!ef)
1583 goto on_error;
1584
1585 /* fill some of the members */
1586 INIT_FILE(ef);
1587 ef->key = NULL;
1588 ef->readfp = fp;
1589 ef->path = ((char *)ef) + sizeof(Eet_File);
1590 memcpy(ef->path, file, file_len);
1591 ef->magic = EET_MAGIC_FILE;
1592 ef->references = 1;
1593 ef->mode = mode;
1594 ef->header = NULL;
1595 ef->writes_pending = 0;
1596 ef->delete_me_now = 0;
1597 ef->data = NULL;
1598 ef->data_size = 0;
1599 ef->sha1 = NULL;
1600 ef->sha1_length = 0;
1601
1602 ef->ed = (mode == EET_FILE_MODE_WRITE)
1603 || (!ef->readfp && mode == EET_FILE_MODE_READ_WRITE) ?
1604 eet_dictionary_add() : NULL;
1605
1606 if (!ef->readfp &&
1607 (mode == EET_FILE_MODE_READ_WRITE || mode == EET_FILE_MODE_WRITE))
1608 goto empty_file;
1609
1610 /* if we can't open - bail out */
1611 if (eet_test_close(!ef->readfp, ef))
1612 goto on_error;
1613
1614 /* if we opened for read or read-write */
1615 if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
1616 {
1617 ef->data_size = size;
1618 ef->data = eina_file_map_all(fp, EINA_FILE_SEQUENTIAL);
1619 if (eet_test_close((ef->data == NULL), ef))
1620 goto on_error;
1621
1622 ef = eet_internal_read(ef);
1623 if (!ef)
1624 goto on_error;
1625 }
1626
1627empty_file:
1628 /* add to cache */
1629 if (ef->references == 1)
1630 {
1631 if (ef->mode == EET_FILE_MODE_READ)
1632 eet_cache_add(ef, &eet_readers, &eet_readers_num, &eet_readers_alloc);
1633 else if ((ef->mode == EET_FILE_MODE_WRITE) ||
1634 (ef->mode == EET_FILE_MODE_READ_WRITE))
1635 eet_cache_add(ef, &eet_writers, &eet_writers_num, &eet_writers_alloc);
1636 }
1637
1638 UNLOCK_CACHE;
1639 return ef;
1640
1641on_error:
1642 UNLOCK_CACHE;
1643 return NULL;
1644} /* eet_open */
1645
1646EAPI Eet_File_Mode
1647eet_mode_get(Eet_File *ef)
1648{
1649 /* check to see its' an eet file pointer */
1650 if ((!ef) || (ef->magic != EET_MAGIC_FILE))
1651 return EET_FILE_MODE_INVALID;
1652 else
1653 return ef->mode;
1654} /* eet_mode_get */
1655
1656EAPI const void *
1657eet_identity_x509(Eet_File *ef,
1658 int *der_length)
1659{
1660 if (!ef->x509_der)
1661 return NULL;
1662
1663 if (der_length)
1664 *der_length = ef->x509_length;
1665
1666 return ef->x509_der;
1667} /* eet_identity_x509 */
1668
1669EAPI const void *
1670eet_identity_signature(Eet_File *ef,
1671 int *signature_length)
1672{
1673 if (!ef->signature)
1674 return NULL;
1675
1676 if (signature_length)
1677 *signature_length = ef->signature_length;
1678
1679 return ef->signature;
1680} /* eet_identity_signature */
1681
1682EAPI const void *
1683eet_identity_sha1(Eet_File *ef,
1684 int *sha1_length)
1685{
1686 if (!ef->sha1)
1687 ef->sha1 = eet_identity_compute_sha1(ef->data,
1688 ef->data_size,
1689 &ef->sha1_length);
1690
1691 if (sha1_length)
1692 *sha1_length = ef->sha1_length;
1693
1694 return ef->sha1;
1695} /* eet_identity_sha1 */
1696
1697EAPI Eet_Error
1698eet_identity_set(Eet_File *ef,
1699 Eet_Key *key)
1700{
1701 Eet_Key *tmp;
1702
1703 if (!ef)
1704 return EET_ERROR_BAD_OBJECT;
1705
1706 tmp = ef->key;
1707 ef->key = key;
1708 eet_identity_ref(ef->key);
1709 eet_identity_unref(tmp);
1710
1711 /* flags that writes are pending */
1712 ef->writes_pending = 1;
1713
1714 return EET_ERROR_NONE;
1715} /* eet_identity_set */
1716
1717EAPI Eet_Error
1718eet_close(Eet_File *ef)
1719{
1720 return eet_internal_close(ef, EINA_FALSE);
1721} /* eet_close */
1722
1723EAPI void *
1724eet_read_cipher(Eet_File *ef,
1725 const char *name,
1726 int *size_ret,
1727 const char *cipher_key)
1728{
1729 Eet_File_Node *efn;
1730 char *data = NULL;
1731 unsigned long int size = 0;
1732
1733 if (size_ret)
1734 *size_ret = 0;
1735
1736 /* check to see its' an eet file pointer */
1737 if (eet_check_pointer(ef))
1738 return NULL;
1739
1740 if (!name)
1741 return NULL;
1742
1743 if ((ef->mode != EET_FILE_MODE_READ) &&
1744 (ef->mode != EET_FILE_MODE_READ_WRITE))
1745 return NULL;
1746
1747 /* no header, return NULL */
1748 if (eet_check_header(ef))
1749 return NULL;
1750
1751 LOCK_FILE(ef);
1752
1753 /* hunt hash bucket */
1754 efn = find_node_by_name(ef, name);
1755 if (!efn)
1756 goto on_error;
1757
1758 /* get size (uncompressed, if compressed at all) */
1759 size = efn->data_size;
1760
1761 /* allocate data */
1762 data = malloc(size);
1763 if (!data)
1764 goto on_error;
1765
1766 /* uncompressed data */
1767 if (efn->compression == 0)
1768 {
1769 void *data_deciphered = NULL;
1770 unsigned int data_deciphered_sz = 0;
1771 /* if we already have the data in ram... copy that */
1772
1773 if (efn->ciphered && efn->size > size)
1774 {
1775 size = efn->size;
1776 data = realloc(data, efn->size);
1777 }
1778
1779 if (efn->data)
1780 memcpy(data, efn->data, size);
1781 else
1782 if (!read_data_from_disk(ef, efn, data, size))
1783 goto on_error;
1784
1785 if (efn->ciphered && cipher_key)
1786 {
1787 if (eet_decipher(data, efn->size, cipher_key, strlen(cipher_key),
1788 &data_deciphered, &data_deciphered_sz))
1789 {
1790 if (data_deciphered)
1791 free(data_deciphered);
1792
1793 goto on_error;
1794 }
1795
1796 free(data);
1797 data = data_deciphered;
1798 size = data_deciphered_sz;
1799 }
1800 }
1801 /* compressed data */
1802 else
1803 {
1804 void *tmp_data = NULL;
1805 void *data_deciphered = NULL;
1806 unsigned int data_deciphered_sz = 0;
1807 int free_tmp = 0;
1808 int compr_size = efn->size;
1809 uLongf dlen;
1810
1811 /* if we already have the data in ram... copy that */
1812 if (efn->data)
1813 tmp_data = efn->data;
1814 else
1815 {
1816 tmp_data = malloc(compr_size);
1817 if (!tmp_data)
1818 goto on_error;
1819
1820 free_tmp = 1;
1821
1822 if (!read_data_from_disk(ef, efn, tmp_data, compr_size))
1823 {
1824 free(tmp_data);
1825 goto on_error;
1826 }
1827 }
1828
1829 if (efn->ciphered && cipher_key)
1830 {
1831 if (eet_decipher(tmp_data, compr_size, cipher_key,
1832 strlen(cipher_key), &data_deciphered,
1833 &data_deciphered_sz))
1834 {
1835 if (free_tmp)
1836 free(tmp_data);
1837
1838 if (data_deciphered)
1839 free(data_deciphered);
1840
1841 goto on_error;
1842 }
1843
1844 if (free_tmp)
1845 free(tmp_data);
1846 free_tmp = 1;
1847 tmp_data = data_deciphered;
1848 compr_size = data_deciphered_sz;
1849 }
1850
1851 /* decompress it */
1852 dlen = size;
1853 if (uncompress((Bytef *)data, &dlen,
1854 tmp_data, (uLongf)compr_size))
1855 {
1856 if (free_tmp)
1857 free(tmp_data);
1858 goto on_error;
1859 }
1860
1861 if (free_tmp)
1862 free(tmp_data);
1863 }
1864
1865 UNLOCK_FILE(ef);
1866
1867 /* handle alias */
1868 if (efn->alias)
1869 {
1870 void *tmp;
1871
1872 if (data[size - 1] != '\0')
1873 goto on_error;
1874
1875 tmp = eet_read_cipher(ef, data, size_ret, cipher_key);
1876
1877 free(data);
1878
1879 data = tmp;
1880 }
1881 else
1882 /* fill in return values */
1883 if (size_ret)
1884 *size_ret = size;
1885
1886 return data;
1887
1888on_error:
1889 UNLOCK_FILE(ef);
1890 free(data);
1891 return NULL;
1892} /* eet_read_cipher */
1893
1894EAPI void *
1895eet_read(Eet_File *ef,
1896 const char *name,
1897 int *size_ret)
1898{
1899 return eet_read_cipher(ef, name, size_ret, NULL);
1900} /* eet_read */
1901
1902EAPI const void *
1903eet_read_direct(Eet_File *ef,
1904 const char *name,
1905 int *size_ret)
1906{
1907 Eet_File_Node *efn;
1908 const char *data = NULL;
1909 int size = 0;
1910
1911 if (size_ret)
1912 *size_ret = 0;
1913
1914 /* check to see its' an eet file pointer */
1915 if (eet_check_pointer(ef))
1916 return NULL;
1917
1918 if (!name)
1919 return NULL;
1920
1921 if ((ef->mode != EET_FILE_MODE_READ) &&
1922 (ef->mode != EET_FILE_MODE_READ_WRITE))
1923 return NULL;
1924
1925 /* no header, return NULL */
1926 if (eet_check_header(ef))
1927 return NULL;
1928
1929 LOCK_FILE(ef);
1930
1931 /* hunt hash bucket */
1932 efn = find_node_by_name(ef, name);
1933 if (!efn)
1934 goto on_error;
1935
1936 /* trick to detect data in memory instead of mmaped from disk */
1937 if (efn->offset > ef->data_size && !efn->data)
1938 goto on_error;
1939
1940 /* get size (uncompressed, if compressed at all) */
1941 size = efn->data_size;
1942
1943 if (efn->alias)
1944 {
1945 data = efn->data ? efn->data : ef->data + efn->offset;
1946
1947 /* handle alias case */
1948 if (efn->compression)
1949 {
1950 char *tmp;
1951 int compr_size = efn->size;
1952 uLongf dlen;
1953
1954 tmp = alloca(sizeof (compr_size));
1955 dlen = size;
1956
1957 if (uncompress((Bytef *)tmp, &dlen, (Bytef *)data,
1958 (uLongf)compr_size))
1959 goto on_error;
1960
1961 if (tmp[compr_size - 1] != '\0')
1962 goto on_error;
1963
1964 UNLOCK_FILE(ef);
1965
1966 return eet_read_direct(ef, tmp, size_ret);
1967 }
1968
1969 if (!data)
1970 goto on_error;
1971
1972 if (data[size - 1] != '\0')
1973 goto on_error;
1974
1975 UNLOCK_FILE(ef);
1976
1977 return eet_read_direct(ef, data, size_ret);
1978 }
1979 else
1980 /* uncompressed data */
1981 if (efn->compression == 0
1982 && efn->ciphered == 0)
1983 data = efn->data ? efn->data : ef->data + efn->offset; /* compressed data */
1984 else
1985 data = NULL;
1986
1987 /* fill in return values */
1988 if (size_ret)
1989 *size_ret = size;
1990
1991 UNLOCK_FILE(ef);
1992
1993 return data;
1994
1995on_error:
1996 UNLOCK_FILE(ef);
1997 return NULL;
1998} /* eet_read_direct */
1999
2000EAPI const char *
2001eet_alias_get(Eet_File *ef,
2002 const char *name)
2003{
2004 Eet_File_Node *efn;
2005 const char *data = NULL;
2006 int size = 0;
2007
2008 /* check to see its' an eet file pointer */
2009 if (eet_check_pointer(ef))
2010 return NULL;
2011
2012 if (!name)
2013 return NULL;
2014
2015 if ((ef->mode != EET_FILE_MODE_READ) &&
2016 (ef->mode != EET_FILE_MODE_READ_WRITE))
2017 return NULL;
2018
2019 /* no header, return NULL */
2020 if (eet_check_header(ef))
2021 return NULL;
2022
2023 LOCK_FILE(ef);
2024
2025 /* hunt hash bucket */
2026 efn = find_node_by_name(ef, name);
2027 if (!efn)
2028 goto on_error;
2029
2030 /* trick to detect data in memory instead of mmaped from disk */
2031 if (efn->offset > ef->data_size && !efn->data)
2032 goto on_error;
2033
2034 /* get size (uncompressed, if compressed at all) */
2035 size = efn->data_size;
2036
2037 if (!efn->alias) return NULL;
2038 data = efn->data ? efn->data : ef->data + efn->offset;
2039
2040 /* handle alias case */
2041 if (efn->compression)
2042 {
2043 char *tmp;
2044 int compr_size = efn->size;
2045 uLongf dlen;
2046
2047 tmp = alloca(sizeof (compr_size));
2048 dlen = size;
2049
2050 if (uncompress((Bytef *)tmp, &dlen, (Bytef *)data,
2051 (uLongf)compr_size))
2052 goto on_error;
2053
2054 if (tmp[compr_size - 1] != '\0')
2055 goto on_error;
2056
2057 UNLOCK_FILE(ef);
2058
2059 return eina_stringshare_add(tmp);
2060 }
2061
2062 if (!data)
2063 goto on_error;
2064
2065 if (data[size - 1] != '\0')
2066 goto on_error;
2067
2068 UNLOCK_FILE(ef);
2069
2070 return eina_stringshare_add(data);
2071
2072on_error:
2073 UNLOCK_FILE(ef);
2074 return NULL;
2075}
2076
2077EAPI Eina_Bool
2078eet_alias(Eet_File *ef,
2079 const char *name,
2080 const char *destination,
2081 int comp)
2082{
2083 Eet_File_Node *efn;
2084 void *data2;
2085 Eina_Bool exists_already = EINA_FALSE;
2086 int data_size;
2087 int hash;
2088
2089 /* check to see its' an eet file pointer */
2090 if (eet_check_pointer(ef))
2091 return EINA_FALSE;
2092
2093 if ((!name) || (!destination))
2094 return EINA_FALSE;
2095
2096 if ((ef->mode != EET_FILE_MODE_WRITE) &&
2097 (ef->mode != EET_FILE_MODE_READ_WRITE))
2098 return EINA_FALSE;
2099
2100 LOCK_FILE(ef);
2101
2102 if (!ef->header)
2103 {
2104 /* allocate header */
2105 ef->header = calloc(1, sizeof(Eet_File_Header));
2106 if (!ef->header)
2107 goto on_error;
2108
2109 ef->header->magic = EET_MAGIC_FILE_HEADER;
2110 /* allocate directory block in ram */
2111 ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
2112 if (!ef->header->directory)
2113 {
2114 free(ef->header);
2115 ef->header = NULL;
2116 goto on_error;
2117 }
2118
2119 /* 8 bit hash table (256 buckets) */
2120 ef->header->directory->size = 8;
2121 /* allocate base hash table */
2122 ef->header->directory->nodes =
2123 calloc(1, sizeof(Eet_File_Node *) *
2124 (1 << ef->header->directory->size));
2125 if (!ef->header->directory->nodes)
2126 {
2127 free(ef->header->directory);
2128 ef->header = NULL;
2129 goto on_error;
2130 }
2131 }
2132
2133 /* figure hash bucket */
2134 hash = _eet_hash_gen(name, ef->header->directory->size);
2135
2136 data_size = comp ?
2137 12 + (((strlen(destination) + 1) * 101) / 100)
2138 : strlen(destination) + 1;
2139
2140 data2 = malloc(data_size);
2141 if (!data2)
2142 goto on_error;
2143
2144 /* if we want to compress */
2145 if (comp)
2146 {
2147 uLongf buflen;
2148
2149 /* compress the data with max compression */
2150 buflen = (uLongf)data_size;
2151 if (compress2((Bytef *)data2, &buflen, (Bytef *)destination,
2152 (uLong)strlen(destination) + 1,
2153 Z_BEST_COMPRESSION) != Z_OK)
2154 {
2155 free(data2);
2156 goto on_error;
2157 }
2158
2159 /* record compressed chunk size */
2160 data_size = (int)buflen;
2161 if (data_size < 0 || data_size >= (int)(strlen(destination) + 1))
2162 {
2163 comp = 0;
2164 data_size = strlen(destination) + 1;
2165 }
2166 else
2167 {
2168 void *data3;
2169
2170 data3 = realloc(data2, data_size);
2171 if (data3)
2172 data2 = data3;
2173 }
2174 }
2175
2176 if (!comp)
2177 memcpy(data2, destination, data_size);
2178
2179 /* Does this node already exist? */
2180 for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next)
2181 {
2182 /* if it matches */
2183 if ((efn->name) && (eet_string_match(efn->name, name)))
2184 {
2185 free(efn->data);
2186 efn->alias = 1;
2187 efn->ciphered = 0;
2188 efn->compression = !!comp;
2189 efn->size = data_size;
2190 efn->data_size = strlen(destination) + 1;
2191 efn->data = data2;
2192 /* Put the offset above the limit to avoid direct access */
2193 efn->offset = ef->data_size + 1;
2194 exists_already = EINA_TRUE;
2195
2196 break;
2197 }
2198 }
2199 if (!exists_already)
2200 {
2201 efn = malloc(sizeof(Eet_File_Node));
2202 if (!efn)
2203 {
2204 free(data2);
2205 goto on_error;
2206 }
2207
2208 efn->name = strdup(name);
2209 efn->name_size = strlen(efn->name) + 1;
2210 efn->free_name = 1;
2211
2212 efn->next = ef->header->directory->nodes[hash];
2213 ef->header->directory->nodes[hash] = efn;
2214 /* Put the offset above the limit to avoid direct access */
2215 efn->offset = ef->data_size + 1;
2216 efn->alias = 1;
2217 efn->ciphered = 0;
2218 efn->compression = !!comp;
2219 efn->size = data_size;
2220 efn->data_size = strlen(destination) + 1;
2221 efn->data = data2;
2222 }
2223
2224 /* flags that writes are pending */
2225 ef->writes_pending = 1;
2226
2227 UNLOCK_FILE(ef);
2228 return EINA_TRUE;
2229
2230on_error:
2231 UNLOCK_FILE(ef);
2232 return EINA_FALSE;
2233} /* eet_alias */
2234
2235EAPI int
2236eet_write_cipher(Eet_File *ef,
2237 const char *name,
2238 const void *data,
2239 int size,
2240 int comp,
2241 const char *cipher_key)
2242{
2243 Eet_File_Node *efn;
2244 void *data2 = NULL;
2245 int exists_already = 0;
2246 int data_size;
2247 int hash;
2248
2249 /* check to see its' an eet file pointer */
2250 if (eet_check_pointer(ef))
2251 return 0;
2252
2253 if ((!name) || (!data) || (size <= 0))
2254 return 0;
2255
2256 if ((ef->mode != EET_FILE_MODE_WRITE) &&
2257 (ef->mode != EET_FILE_MODE_READ_WRITE))
2258 return 0;
2259
2260 LOCK_FILE(ef);
2261
2262 if (!ef->header)
2263 {
2264 /* allocate header */
2265 ef->header = calloc(1, sizeof(Eet_File_Header));
2266 if (!ef->header)
2267 goto on_error;
2268
2269 ef->header->magic = EET_MAGIC_FILE_HEADER;
2270 /* allocate directory block in ram */
2271 ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
2272 if (!ef->header->directory)
2273 {
2274 free(ef->header);
2275 ef->header = NULL;
2276 goto on_error;
2277 }
2278
2279 /* 8 bit hash table (256 buckets) */
2280 ef->header->directory->size = 8;
2281 /* allocate base hash table */
2282 ef->header->directory->nodes =
2283 calloc(1, sizeof(Eet_File_Node *) *
2284 (1 << ef->header->directory->size));
2285 if (!ef->header->directory->nodes)
2286 {
2287 free(ef->header->directory);
2288 ef->header = NULL;
2289 goto on_error;
2290 }
2291 }
2292
2293 /* figure hash bucket */
2294 hash = _eet_hash_gen(name, ef->header->directory->size);
2295
2296 data_size = comp ? 12 + ((size * 101) / 100) : size;
2297
2298 if (comp || !cipher_key)
2299 {
2300 data2 = malloc(data_size);
2301 if (!data2)
2302 goto on_error;
2303 }
2304
2305 /* if we want to compress */
2306 if (comp)
2307 {
2308 uLongf buflen;
2309
2310 /* compress the data with max compression */
2311 buflen = (uLongf)data_size;
2312 if (compress2((Bytef *)data2, &buflen, (Bytef *)data,
2313 (uLong)size, Z_BEST_COMPRESSION) != Z_OK)
2314 {
2315 free(data2);
2316 goto on_error;
2317 }
2318
2319 /* record compressed chunk size */
2320 data_size = (int)buflen;
2321 if (data_size < 0 || data_size >= size)
2322 {
2323 comp = 0;
2324 data_size = size;
2325 }
2326 else
2327 {
2328 void *data3;
2329
2330 data3 = realloc(data2, data_size);
2331 if (data3)
2332 data2 = data3;
2333 }
2334 }
2335
2336 if (cipher_key)
2337 {
2338 void *data_ciphered = NULL;
2339 unsigned int data_ciphered_sz = 0;
2340 const void *tmp;
2341
2342 tmp = comp ? data2 : data;
2343 if (!eet_cipher(tmp, data_size, cipher_key, strlen(cipher_key),
2344 &data_ciphered, &data_ciphered_sz))
2345 {
2346 if (data2)
2347 free(data2);
2348
2349 data2 = data_ciphered;
2350 data_size = data_ciphered_sz;
2351 }
2352 else
2353 {
2354 if (data_ciphered)
2355 free(data_ciphered);
2356
2357 cipher_key = NULL;
2358 }
2359 }
2360 else
2361 if (!comp)
2362 memcpy(data2, data, size);
2363
2364 /* Does this node already exist? */
2365 for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next)
2366 {
2367 /* if it matches */
2368 if ((efn->name) && (eet_string_match(efn->name, name)))
2369 {
2370 free(efn->data);
2371 efn->alias = 0;
2372 efn->ciphered = cipher_key ? 1 : 0;
2373 efn->compression = !!comp;
2374 efn->size = data_size;
2375 efn->data_size = size;
2376 efn->data = data2;
2377 /* Put the offset above the limit to avoid direct access */
2378 efn->offset = ef->data_size + 1;
2379 exists_already = 1;
2380 break;
2381 }
2382 }
2383 if (!exists_already)
2384 {
2385 efn = malloc(sizeof(Eet_File_Node));
2386 if (!efn)
2387 {
2388 free(data2);
2389 goto on_error;
2390 }
2391
2392 efn->name = strdup(name);
2393 efn->name_size = strlen(efn->name) + 1;
2394 efn->free_name = 1;
2395
2396 efn->next = ef->header->directory->nodes[hash];
2397 ef->header->directory->nodes[hash] = efn;
2398 /* Put the offset above the limit to avoid direct access */
2399 efn->offset = ef->data_size + 1;
2400 efn->alias = 0;
2401 efn->ciphered = cipher_key ? 1 : 0;
2402 efn->compression = !!comp;
2403 efn->size = data_size;
2404 efn->data_size = size;
2405 efn->data = data2;
2406 }
2407
2408 /* flags that writes are pending */
2409 ef->writes_pending = 1;
2410 UNLOCK_FILE(ef);
2411 return data_size;
2412
2413on_error:
2414 UNLOCK_FILE(ef);
2415 return 0;
2416} /* eet_write_cipher */
2417
2418EAPI int
2419eet_write(Eet_File *ef,
2420 const char *name,
2421 const void *data,
2422 int size,
2423 int comp)
2424{
2425 return eet_write_cipher(ef, name, data, size, comp, NULL);
2426} /* eet_write */
2427
2428EAPI int
2429eet_delete(Eet_File *ef,
2430 const char *name)
2431{
2432 Eet_File_Node *efn;
2433 Eet_File_Node *pefn;
2434 int hash;
2435 int exists_already = 0;
2436
2437 /* check to see its' an eet file pointer */
2438 if (eet_check_pointer(ef))
2439 return 0;
2440
2441 if (!name)
2442 return 0;
2443
2444 /* deleting keys is only possible in RW or WRITE mode */
2445 if (ef->mode == EET_FILE_MODE_READ)
2446 return 0;
2447
2448 if (eet_check_header(ef))
2449 return 0;
2450
2451 LOCK_FILE(ef);
2452
2453 /* figure hash bucket */
2454 hash = _eet_hash_gen(name, ef->header->directory->size);
2455
2456 /* Does this node already exist? */
2457 for (pefn = NULL, efn = ef->header->directory->nodes[hash];
2458 efn;
2459 pefn = efn, efn = efn->next)
2460 {
2461 /* if it matches */
2462 if (eet_string_match(efn->name, name))
2463 {
2464 if (efn->data)
2465 free(efn->data);
2466
2467 if (!pefn)
2468 ef->header->directory->nodes[hash] = efn->next;
2469 else
2470 pefn->next = efn->next;
2471
2472 if (efn->free_name)
2473 free(efn->name);
2474
2475 free(efn);
2476 exists_already = 1;
2477 break;
2478 }
2479 }
2480 /* flags that writes are pending */
2481 if (exists_already)
2482 ef->writes_pending = 1;
2483
2484 UNLOCK_FILE(ef);
2485
2486 /* update access time */
2487 return exists_already;
2488} /* eet_delete */
2489
2490EAPI Eet_Dictionary *
2491eet_dictionary_get(Eet_File *ef)
2492{
2493 if (eet_check_pointer(ef))
2494 return NULL;
2495
2496 return ef->ed;
2497} /* eet_dictionary_get */
2498
2499EAPI char **
2500eet_list(Eet_File *ef,
2501 const char *glob,
2502 int *count_ret)
2503{
2504 Eet_File_Node *efn;
2505 char **list_ret = NULL;
2506 int list_count = 0;
2507 int list_count_alloc = 0;
2508 int i, num;
2509
2510 /* check to see its' an eet file pointer */
2511 if (eet_check_pointer(ef) || eet_check_header(ef) ||
2512 (!glob) ||
2513 ((ef->mode != EET_FILE_MODE_READ) &&
2514 (ef->mode != EET_FILE_MODE_READ_WRITE)))
2515 {
2516 if (count_ret)
2517 *count_ret = 0;
2518
2519 return NULL;
2520 }
2521
2522 if (!strcmp(glob, "*"))
2523 glob = NULL;
2524
2525 LOCK_FILE(ef);
2526
2527 /* loop through all entries */
2528 num = (1 << ef->header->directory->size);
2529 for (i = 0; i < num; i++)
2530 {
2531 for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
2532 {
2533 /* if the entry matches the input glob
2534 * check for * explicitly, because on some systems, * isn't well
2535 * supported
2536 */
2537 if ((!glob) || !fnmatch(glob, efn->name, 0))
2538 {
2539 /* add it to our list */
2540 list_count++;
2541
2542 /* only realloc in 32 entry chunks */
2543 if (list_count > list_count_alloc)
2544 {
2545 char **new_list = NULL;
2546
2547 list_count_alloc += 64;
2548 new_list =
2549 realloc(list_ret, list_count_alloc * (sizeof(char *)));
2550 if (!new_list)
2551 {
2552 free(list_ret);
2553
2554 goto on_error;
2555 }
2556
2557 list_ret = new_list;
2558 }
2559
2560 /* put pointer of name string in */
2561 list_ret[list_count - 1] = efn->name;
2562 }
2563 }
2564 }
2565
2566 UNLOCK_FILE(ef);
2567
2568 /* return count and list */
2569 if (count_ret)
2570 *count_ret = list_count;
2571
2572 return list_ret;
2573
2574on_error:
2575 UNLOCK_FILE(ef);
2576
2577 if (count_ret)
2578 *count_ret = 0;
2579
2580 return NULL;
2581} /* eet_list */
2582
2583EAPI int
2584eet_num_entries(Eet_File *ef)
2585{
2586 int i, num, ret = 0;
2587 Eet_File_Node *efn;
2588
2589 /* check to see its' an eet file pointer */
2590 if (eet_check_pointer(ef) || eet_check_header(ef) ||
2591 ((ef->mode != EET_FILE_MODE_READ) &&
2592 (ef->mode != EET_FILE_MODE_READ_WRITE)))
2593 return -1;
2594
2595 LOCK_FILE(ef);
2596
2597 /* loop through all entries */
2598 num = (1 << ef->header->directory->size);
2599 for (i = 0; i < num; i++)
2600 {
2601 for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
2602 ret++;
2603 }
2604
2605 UNLOCK_FILE(ef);
2606
2607 return ret;
2608} /* eet_num_entries */
2609
2610static Eet_File_Node *
2611find_node_by_name(Eet_File *ef,
2612 const char *name)
2613{
2614 Eet_File_Node *efn;
2615 int hash;
2616
2617 /* get hash bucket this should be in */
2618 hash = _eet_hash_gen(name, ef->header->directory->size);
2619
2620 for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next)
2621 {
2622 if (eet_string_match(efn->name, name))
2623 return efn;
2624 }
2625
2626 return NULL;
2627} /* find_node_by_name */
2628
2629static int
2630read_data_from_disk(Eet_File *ef,
2631 Eet_File_Node *efn,
2632 void *buf,
2633 int len)
2634{
2635 if (efn->offset > ef->data_size)
2636 return 0;
2637
2638 if (!ef->data)
2639 return 0;
2640
2641 if ((efn->offset + len) > ef->data_size)
2642 return 0;
2643
2644 memcpy(buf, ef->data + efn->offset, len);
2645
2646 return len;
2647} /* read_data_from_disk */
2648
diff --git a/libraries/eet/src/lib/eet_node.c b/libraries/eet/src/lib/eet_node.c
new file mode 100644
index 0000000..d90ef83
--- /dev/null
+++ b/libraries/eet/src/lib/eet_node.c
@@ -0,0 +1,797 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif /* ifdef HAVE_CONFIG_H */
4
5#include <string.h>
6#include <stdio.h>
7
8#ifdef HAVE_EVIL
9# include <Evil.h>
10#endif /* ifdef HAVE_EVIL */
11
12#include <Eina.h>
13
14#include "Eet.h"
15#include "Eet_private.h"
16
17static Eina_Mempool *_eet_node_mp = NULL;
18
19Eet_Node *
20eet_node_new(void)
21{
22 Eet_Node *result;
23
24 result = eina_mempool_malloc(_eet_node_mp, sizeof (Eet_Node));
25 if (!result)
26 return NULL;
27
28 memset(result, 0, sizeof (Eet_Node));
29 return result;
30} /* eet_node_new */
31
32void
33eet_node_free(Eet_Node *node)
34{
35 eina_mempool_free(_eet_node_mp, node);
36} /* eet_node_free */
37
38static Eet_Node *
39_eet_node_new(const char *name,
40 int type)
41{
42 Eet_Node *n;
43
44 n = eet_node_new();
45 if (!n)
46 return NULL;
47
48 n->type = type;
49 n->name = eina_stringshare_add(name);
50
51 return n;
52} /* _eet_node_new */
53
54static void
55_eet_node_append(Eet_Node *n,
56 Eina_List *nodes)
57{
58 Eet_Node *value;
59 Eina_List *l;
60
61 EINA_LIST_REVERSE_FOREACH(nodes, l, value)
62 {
63 value->next = n->values;
64 n->values = value;
65 }
66} /* _eet_node_append */
67
68#define EET_NODE_NEW(Eet_type, Name, Value, Type) \
69 EAPI Eet_Node * \
70 eet_node_ ## Name ## _new(const char *name, Type Value) \
71 { \
72 Eet_Node *n; \
73 \
74 n = _eet_node_new(name, Eet_type); \
75 if (!n) { return NULL; } \
76 \
77 n->data.value.Value = Value; \
78 \
79 return n; \
80 }
81
82#define EET_NODE_STR_NEW(Eet_type, Name, Value, Type) \
83 EAPI Eet_Node * \
84 eet_node_ ## Name ## _new(const char *name, Type Value) \
85 { \
86 Eet_Node *n; \
87 \
88 n = _eet_node_new(name, Eet_type); \
89 if (!n) { return NULL; } \
90 \
91 n->data.value.Value = eina_stringshare_add(Value); \
92 \
93 return n; \
94 }
95
96EET_NODE_NEW(EET_T_CHAR, char, c, char)
97EET_NODE_NEW(EET_T_SHORT, short, s, short)
98EET_NODE_NEW(EET_T_INT, int, i, int)
99EET_NODE_NEW(EET_T_LONG_LONG, long_long, l, long long)
100EET_NODE_NEW(EET_T_FLOAT, float, f, float)
101EET_NODE_NEW(EET_T_DOUBLE, double, d, double)
102EET_NODE_NEW(EET_T_UCHAR, unsigned_char, uc, unsigned char)
103EET_NODE_NEW(EET_T_USHORT, unsigned_short, us, unsigned short)
104EET_NODE_NEW(EET_T_UINT, unsigned_int, ui, unsigned int)
105EET_NODE_NEW(EET_T_ULONG_LONG, unsigned_long_long, ul, unsigned long long)
106EET_NODE_STR_NEW(EET_T_STRING, string, str, const char *)
107EET_NODE_STR_NEW(EET_T_INLINED_STRING, inlined_string, str, const char *)
108
109Eet_Node *
110eet_node_null_new(const char *name)
111{
112 Eet_Node *n;
113
114 n = _eet_node_new(name, EET_T_NULL);
115 if (!n)
116 return NULL;
117
118 n->data.value.str = NULL;
119
120 return n;
121}
122
123Eet_Node *
124eet_node_list_new(const char *name,
125 Eina_List *nodes)
126{
127 Eet_Node *n;
128
129 n = _eet_node_new(name, EET_G_LIST);
130 if (!n)
131 return NULL;
132
133 _eet_node_append(n, nodes);
134
135 return n;
136} /* eet_node_list_new */
137
138Eet_Node *
139eet_node_array_new(const char *name,
140 int count,
141 Eina_List *nodes)
142{
143 Eet_Node *n;
144
145 n = _eet_node_new(name, EET_G_ARRAY);
146 if (!n)
147 return NULL;
148
149 n->count = count;
150
151 _eet_node_append(n, nodes);
152
153 return n;
154} /* eet_node_array_new */
155
156Eet_Node *
157eet_node_var_array_new(const char *name,
158 Eina_List *nodes)
159{
160 Eet_Node *n;
161
162 n = _eet_node_new(name, EET_G_VAR_ARRAY);
163 if (!n)
164 return NULL;
165
166 n->count = eina_list_count(nodes);
167
168 _eet_node_append(n, nodes);
169
170 return n;
171} /* eet_node_var_array_new */
172
173Eet_Node *
174eet_node_hash_new(const char *name,
175 const char *key,
176 Eet_Node *node)
177{
178 Eina_List *nodes;
179 Eet_Node *n;
180
181 if (!node)
182 return NULL;
183
184 n = _eet_node_new(name, EET_G_HASH);
185 if (!n)
186 return NULL;
187
188 n->key = eina_stringshare_add(key);
189 nodes = eina_list_append(NULL, node);
190
191 _eet_node_append(n, nodes);
192
193 return n;
194} /* eet_node_hash_new */
195
196Eet_Node *
197eet_node_struct_new(const char *name,
198 Eina_List *nodes)
199{
200 Eet_Node *n;
201
202 n = _eet_node_new(name, EET_G_UNKNOWN);
203 if (!n)
204 return NULL;
205
206 _eet_node_append(n, nodes);
207
208 return n;
209} /* eet_node_struct_new */
210
211Eet_Node *
212eet_node_struct_child_new(const char *parent,
213 Eet_Node *child)
214{
215 Eet_Node *n;
216
217 if (!child) return NULL;
218
219 if (child->type != EET_G_UNKNOWN)
220 return child;
221
222 n = _eet_node_new(parent, EET_G_UNKNOWN);
223 if (!n)
224 return NULL;
225
226 _eet_node_append(n, eina_list_prepend(NULL, child));
227
228 return n;
229} /* eet_node_struct_child_new */
230
231Eet_Node *
232eet_node_children_get(Eet_Node *node)
233{
234 if (!node) return NULL;
235 return node->values;
236}
237
238Eet_Node *
239eet_node_next_get(Eet_Node *node)
240{
241 if (!node) return NULL;
242 return node->next;
243}
244
245Eet_Node *
246eet_node_parent_get(Eet_Node *node)
247{
248 if (!node) return NULL;
249 return node->parent;
250}
251
252void
253eet_node_list_append(Eet_Node *parent,
254 const char *name,
255 Eet_Node *child)
256{
257 const char *tmp;
258 Eet_Node *nn;
259
260 if ((!parent) || (!child)) return;
261 tmp = eina_stringshare_add(name);
262
263 for (nn = parent->values; nn; nn = nn->next)
264 if (nn->name == tmp && nn->type == EET_G_LIST)
265 {
266 Eet_Node *n;
267
268 if (!nn->values)
269 nn->values = child;
270 else
271 {
272 for (n = nn->values; n->next; n = n->next)
273 ;
274 n->next = child;
275 }
276
277 child->next = NULL;
278
279 eina_stringshare_del(tmp);
280
281 return;
282 }
283
284 /* No list found, so create it. */
285 nn = eet_node_list_new(tmp, eina_list_append(NULL, child));
286
287 /* And add it to the parent. */
288 nn->next = parent->values;
289 parent->values = nn;
290
291 eina_stringshare_del(tmp);
292} /* eet_node_list_append */
293
294void
295eet_node_struct_append(Eet_Node *parent,
296 const char *name,
297 Eet_Node *child)
298{
299 const char *tmp;
300 Eet_Node *prev;
301 Eet_Node *nn;
302
303 if ((!parent) || (!child)) return;
304 if (parent->type != EET_G_UNKNOWN)
305 {
306 ERR("[%s] is not a structure. Will not insert [%s] in it",
307 parent->name,
308 name);
309 eet_node_del(child);
310 return;
311 }
312
313 tmp = eina_stringshare_add(name);
314
315 for (prev = NULL, nn = parent->values; nn; prev = nn, nn = nn->next)
316 if (nn->name == tmp && nn->type == child->type)
317 {
318 if (prev)
319 prev->next = nn->next;
320 else
321 parent->values = nn->next;
322
323 nn->next = NULL;
324 eet_node_del(nn);
325
326 break;
327 }
328
329 if (prev)
330 {
331 prev->next = child;
332 child->next = NULL;
333 }
334 else
335 {
336 child->next = NULL;
337 parent->values = child;
338 }
339
340 eina_stringshare_del(tmp);
341} /* eet_node_struct_append */
342
343void
344eet_node_hash_add(Eet_Node *parent,
345 const char *name,
346 const char *key,
347 Eet_Node *child)
348{
349 Eet_Node *nn;
350
351 if ((!parent) || (!child)) return;
352
353 /* No list found, so create it. */
354 nn = eet_node_hash_new(name, key, child);
355
356 /* And add it to the parent. */
357 nn->next = parent->values;
358 parent->values = nn;
359} /* eet_node_hash_add */
360
361int
362eet_node_type_get(Eet_Node *node)
363{
364 if (!node) return EET_T_UNKNOW;
365 return node->type;
366}
367
368Eet_Node_Data *
369eet_node_value_get(Eet_Node *node)
370{
371 if (!node) return NULL;
372 return &node->data;
373}
374
375const char *
376eet_node_name_get(Eet_Node *node)
377{
378 if (!node) return NULL;
379 return node->name;
380}
381
382void
383eet_node_del(Eet_Node *n)
384{
385 Eet_Node *nn;
386 Eet_Node *tmp;
387
388 if (!n)
389 return;
390
391 switch (n->type)
392 {
393 case EET_G_HASH:
394 eina_stringshare_del(n->key);
395
396 case EET_G_UNKNOWN:
397 case EET_G_VAR_ARRAY:
398 case EET_G_ARRAY:
399 case EET_G_LIST:
400 for (nn = n->values; nn; )
401 {
402 tmp = nn;
403 nn = nn->next;
404 eet_node_del(tmp);
405 }
406 break;
407
408 case EET_T_STRING:
409 case EET_T_INLINED_STRING:
410 eina_stringshare_del(n->data.value.str);
411 break;
412
413 case EET_T_CHAR:
414 case EET_T_SHORT:
415 case EET_T_INT:
416 case EET_T_LONG_LONG:
417 case EET_T_FLOAT:
418 case EET_T_DOUBLE:
419 case EET_T_UCHAR:
420 case EET_T_USHORT:
421 case EET_T_UINT:
422 break;
423 } /* switch */
424
425 eina_stringshare_del(n->name);
426 eet_node_free(n);
427} /* eet_node_del */
428
429static const char *eet_node_dump_g_name[6] = {
430 "struct",
431 "array",
432 "var_array",
433 "list",
434 "hash",
435 "???"
436};
437
438static const char *eet_node_dump_t_name[14][2] = {
439 { "???: ", "???" },
440 { "char: ", "%hhi" },
441 { "short: ", "%hi" },
442 { "int: ", "%i" },
443 { "long_long: ", "%lli" },
444 { "float: ", "%1.25f" },
445 { "double: ", "%1.25f" },
446 { "uchar: ", "%hhu" },
447 { "ushort: ", "%i" },
448 { "uint: ", "%u" },
449 { "ulong_long: ", "%llu" },
450 { "null", "" }
451};
452
453static void
454eet_node_dump_level(int level,
455 Eet_Dump_Callback dumpfunc,
456 void *dumpdata)
457{
458 int i;
459
460 for (i = 0; i < level; i++) dumpfunc(dumpdata, " ");
461} /* eet_node_dump_level */
462
463static char *
464eet_node_string_escape(const char *str)
465{
466 char *s, *sp;
467 const char *strp;
468 int sz = 0;
469
470 for (strp = str; *strp; strp++)
471 {
472 if (*strp == '\"')
473 sz += 2;
474 else if (*strp == '\\')
475 sz += 2;
476 else if (*strp == '\n')
477 sz += 2;
478 else
479 sz += 1;
480 }
481 s = malloc(sz + 1);
482 if (!s)
483 return NULL;
484
485 for (strp = str, sp = s; *strp; strp++, sp++)
486 {
487 if (*strp == '\"'
488 || *strp == '\\'
489 || *strp == '\n')
490 {
491 *sp = '\\';
492 sp++;
493 }
494
495 if (*strp == '\n')
496 *sp = 'n';
497 else
498 *sp = *strp;
499 }
500 *sp = 0;
501 return s;
502} /* eet_node_string_escape */
503
504static void
505eet_node_dump_string_escape(void *dumpdata,
506 Eet_Dump_Callback dumpfunc,
507 const char *str)
508{
509 char *s;
510
511 s = eet_node_string_escape(str);
512 if (!s)
513 return;
514
515 dumpfunc(dumpdata, s);
516 free(s);
517} /* eet_node_dump_string_escape */
518
519static void
520eet_node_dump_simple_type(Eet_Node *n,
521 int level,
522 Eet_Dump_Callback dumpfunc,
523 void *dumpdata)
524{
525 const char *type_name = NULL;
526 char tbuf[256];
527
528 eet_node_dump_level(level, dumpfunc, dumpdata);
529 dumpfunc(dumpdata, "value \"");
530 eet_node_dump_string_escape(dumpdata, dumpfunc, n->name);
531 dumpfunc(dumpdata, "\" ");
532
533#ifdef EET_T_TYPE
534# undef EET_T_TYPE
535#endif /* ifdef EET_T_TYPE */
536
537#define EET_T_TYPE(Eet_Type, Type) \
538case Eet_Type: \
539{ \
540 dumpfunc(dumpdata, eet_node_dump_t_name[Eet_Type][0]); \
541 snprintf(tbuf, \
542 sizeof (tbuf), \
543 eet_node_dump_t_name[Eet_Type][1], \
544 n->data.value.Type); \
545 dumpfunc(dumpdata, tbuf); \
546 break; \
547}
548
549 switch (n->type)
550 {
551 EET_T_TYPE(EET_T_CHAR, c);
552 EET_T_TYPE(EET_T_SHORT, s);
553 EET_T_TYPE(EET_T_INT, i);
554 EET_T_TYPE(EET_T_LONG_LONG, l);
555 EET_T_TYPE(EET_T_FLOAT, f);
556 EET_T_TYPE(EET_T_DOUBLE, d);
557 EET_T_TYPE(EET_T_UCHAR, uc);
558 EET_T_TYPE(EET_T_USHORT, us);
559 EET_T_TYPE(EET_T_UINT, ui);
560 EET_T_TYPE(EET_T_ULONG_LONG, ul);
561
562 case EET_T_INLINED_STRING:
563 type_name = "inlined: \"";
564
565 case EET_T_STRING:
566 if (!type_name)
567 type_name = "string: \"";
568
569 dumpfunc(dumpdata, type_name);
570 eet_node_dump_string_escape(dumpdata, dumpfunc, n->data.value.str);
571 dumpfunc(dumpdata, "\"");
572 break;
573
574 case EET_T_NULL:
575 dumpfunc(dumpdata, "null");
576 break;
577
578 default:
579 dumpfunc(dumpdata, "???: ???");
580 break;
581 } /* switch */
582
583 dumpfunc(dumpdata, ";\n");
584} /* eet_node_dump_simple_type */
585
586static void
587eet_node_dump_group_start(int level,
588 Eet_Dump_Callback dumpfunc,
589 void *dumpdata,
590 int group_type,
591 const char *name)
592{
593 int chnk_type;
594
595 chnk_type = (group_type >= EET_G_UNKNOWN && group_type <= EET_G_HASH) ?
596 group_type : EET_G_LAST;
597
598 eet_node_dump_level(level, dumpfunc, dumpdata);
599 dumpfunc(dumpdata, "group \"");
600 eet_node_dump_string_escape(dumpdata, dumpfunc, name);
601 dumpfunc(dumpdata, "\" ");
602
603 dumpfunc(dumpdata, eet_node_dump_g_name[chnk_type - EET_G_UNKNOWN]);
604 dumpfunc(dumpdata, " {\n");
605} /* eet_node_dump_group_start */
606
607static void
608eet_node_dump_group_end(int level,
609 Eet_Dump_Callback dumpfunc,
610 void *dumpdata)
611{
612 eet_node_dump_level(level, dumpfunc, dumpdata);
613 dumpfunc(dumpdata, "}\n");
614} /* eet_node_dump_group_end */
615
616void
617eet_node_dump(Eet_Node *n,
618 int dumplevel,
619 Eet_Dump_Callback dumpfunc,
620 void *dumpdata)
621{
622 Eet_Node *it;
623
624 if (!n)
625 return;
626
627 switch (n->type)
628 {
629 case EET_G_VAR_ARRAY:
630 case EET_G_ARRAY:
631 case EET_G_UNKNOWN:
632 case EET_G_HASH:
633 case EET_G_LIST:
634 eet_node_dump_group_start(dumplevel,
635 dumpfunc,
636 dumpdata,
637 n->type,
638 n->name);
639
640 if (n->type == EET_G_VAR_ARRAY
641 || n->type == EET_G_ARRAY)
642 {
643 char tbuf[256];
644
645 eet_node_dump_level(dumplevel, dumpfunc, dumpdata);
646 dumpfunc(dumpdata, " count ");
647 eina_convert_itoa(n->count, tbuf);
648 dumpfunc(dumpdata, tbuf);
649 dumpfunc(dumpdata, ";\n");
650 }
651 else if (n->type == EET_G_HASH)
652 {
653 eet_node_dump_level(dumplevel, dumpfunc, dumpdata);
654 dumpfunc(dumpdata, " key \"");
655 eet_node_dump_string_escape(dumpdata, dumpfunc, n->key);
656 dumpfunc(dumpdata, "\";\n");
657 }
658
659 for (it = n->values; it; it = it->next)
660 eet_node_dump(it, dumplevel + 2, dumpfunc, dumpdata);
661
662 eet_node_dump_group_end(dumplevel, dumpfunc, dumpdata);
663 break;
664
665 case EET_T_STRING:
666 case EET_T_INLINED_STRING:
667 case EET_T_CHAR:
668 case EET_T_SHORT:
669 case EET_T_INT:
670 case EET_T_LONG_LONG:
671 case EET_T_FLOAT:
672 case EET_T_DOUBLE:
673 case EET_T_UCHAR:
674 case EET_T_USHORT:
675 case EET_T_UINT:
676 case EET_T_ULONG_LONG:
677 eet_node_dump_simple_type(n, dumplevel, dumpfunc, dumpdata);
678 break;
679 } /* switch */
680} /* eet_node_dump */
681
682void *
683eet_node_walk(void *parent,
684 const char *name,
685 Eet_Node *root,
686 Eet_Node_Walk *cb,
687 void *user_data)
688{
689 Eet_Node *it;
690 void *me = NULL;
691 int i;
692
693 if (!root)
694 {
695 if (parent)
696 cb->struct_add(parent, name, NULL, user_data);
697
698 return NULL;
699 }
700
701 switch (root->type)
702 {
703 case EET_G_UNKNOWN:
704 me = cb->struct_alloc(root->name, user_data);
705
706 for (it = root->values; it; it = it->next)
707 eet_node_walk(me, it->name, it, cb, user_data);
708
709 break;
710
711 case EET_G_VAR_ARRAY:
712 case EET_G_ARRAY:
713 me = cb->array(root->type == EET_G_VAR_ARRAY ? EINA_TRUE : EINA_FALSE,
714 root->name, root->count, user_data);
715
716 for (i = 0, it = root->values; it; it = it->next)
717 cb->insert(me, i++, eet_node_walk(NULL,
718 NULL,
719 it,
720 cb,
721 user_data), user_data);
722
723 break;
724
725 case EET_G_LIST:
726 me = cb->list(root->name, user_data);
727
728 for (it = root->values; it; it = it->next)
729 cb->append(me, eet_node_walk(NULL,
730 NULL,
731 it,
732 cb,
733 user_data), user_data);
734
735 break;
736
737 case EET_G_HASH:
738 if (!parent)
739 return NULL;
740
741 return cb->hash(parent, root->name, root->key,
742 eet_node_walk(NULL,
743 NULL,
744 root->values,
745 cb,
746 user_data), user_data);
747
748 case EET_T_STRING:
749 case EET_T_INLINED_STRING:
750 case EET_T_CHAR:
751 case EET_T_SHORT:
752 case EET_T_INT:
753 case EET_T_LONG_LONG:
754 case EET_T_FLOAT:
755 case EET_T_DOUBLE:
756 case EET_T_UCHAR:
757 case EET_T_USHORT:
758 case EET_T_UINT:
759 case EET_T_ULONG_LONG:
760 me = cb->simple(root->type, &root->data, user_data);
761 break;
762 } /* switch */
763
764 if (parent)
765 cb->struct_add(parent, name, me, user_data);
766
767 return me;
768} /* eet_node_walk */
769
770int
771eet_node_init(void)
772{
773 const char *choice;
774 const char *tmp;
775
776#ifdef EINA_DEFAULT_MEMPOOL
777 choice = "pass_through";
778#else
779 choice = "chained_mempool";
780#endif
781 tmp = getenv("EET_MEMPOOL");
782 if (tmp && tmp[0])
783 choice = tmp;
784
785 _eet_node_mp =
786 eina_mempool_add(choice, "eet-node-alloc", NULL, sizeof(Eet_Node), 1024);
787
788 return _eet_node_mp ? 1 : 0;
789} /* eet_node_init */
790
791void
792eet_node_shutdown(void)
793{
794 eina_mempool_del(_eet_node_mp);
795 _eet_node_mp = NULL;
796} /* eet_node_shutdown */
797
diff --git a/libraries/eet/src/lib/eet_utils.c b/libraries/eet/src/lib/eet_utils.c
new file mode 100644
index 0000000..8e591a2
--- /dev/null
+++ b/libraries/eet/src/lib/eet_utils.c
@@ -0,0 +1,36 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif /* ifdef HAVE_CONFIG_H */
4
5#include <stdio.h>
6#include <math.h>
7
8#include "Eet.h"
9#include "Eet_private.h"
10
11int
12_eet_hash_gen(const char *key,
13 int hash_size)
14{
15 int hash_num = 0;
16 int value, i;
17 int mask;
18 unsigned char *ptr;
19
20 /* no string - index 0 */
21 if (!key)
22 return 0;
23
24 /* calc hash num */
25 for (i = 0, ptr = (unsigned char *)key, value = (int)(*ptr);
26 value;
27 ptr++, i++, value = (int)(*ptr))
28 hash_num ^= (value | (value << 8)) >> (i & 0x7);
29
30 /* mask it */
31 mask = (1 << hash_size) - 1;
32 hash_num &= mask;
33 /* return it */
34 return hash_num;
35} /* _eet_hash_gen */
36