more documentation

SVN revision: 7248
This commit is contained in:
Carsten Haitzler 2003-07-27 13:12:33 +00:00
parent c388bc2a46
commit 48ccbe5123
2 changed files with 238 additions and 18 deletions

View File

@ -13,6 +13,10 @@ These routines are used for Eet Library interaction
@author Carsten Haitzler <raster@rasterman.com>
@date 2000-2002
@section intro What is Eet?
It is a tiny library designed to write an arbitary set of chunks of data
@ -21,13 +25,160 @@ and allow fast random-access reading of the file later on. It does not
do zip as a zip itself has more complexity than is needed, and it was much
simpler to impliment this once here.
Eet is extremely fast, small and simple. Eet files can be very small and
highly compressed, making them very optimal for just sending across the
internet without having to archive, compress or decompress and install them.
They allow for lightning-fast random-acess reads once created, making them
perfect for storing data that is written once (or rarely) and read many
times, but the program does not want to have to read it all in at once.
It also can encode and decode data structures in memory, as well as image
data for saving to eet files or sending across the network to other
data for saving to Eet files or sending across the network to other
machines, or just writing to arbitary files on the system. All data is
encoded in a platform independant way and can be written and read by any
architecture.
@todo Complete documentation of API
@todo Add fixed and variable array encode/decode support
@section example A simple example on using Eet
Here is a simple example on how to use Eet to save a series of strings to a
file and load them again. The advantage of using Eet over just fprintf() and
fscanf() is that not only can these entries be strings, they need no special
parsing to handle delimiter characters or escaping, they can be binary data,
image data, data structures containing integers, strings, other data
structures, linked lists and much more, without the programmer having to
worry about parsing, and best of all, Eet is very fast.
@code
#include <Eet.h>
int
main(int argc, char **argv)
{
Eet_File *ef;
int i;
char buf[32];
char *ret;
int size;
char **entries =
{
"Entry 1",
"Big text string here compared to others",
"Eet is cool"
};
// blindly open an file for output and write strings with their NUL char
ef = eet_open("test.eet", EET_FILE_MODE_WRITE);
eet_write(ef, "Entry 1", entries[0], strlen(entries[0]) + 1, 0);
eet_write(ef, "Entry 2", entries[1], strlen(entries[1]) + 1, 1);
eet_write(ef, "Entry 3", entries[2], strlen(entries[2]) + 1, 0);
eet_close(ef);
// open the file again and blindly get the entries we wrote
ef = eet_open("test.eet", EET_FILE_MODE_READ);
ret = eet_read(ef, "Entry 1", &size);
printf("%s\n", ret);
ret = eet_read(ef, "Entry 2", &size);
printf("%s\n", ret);
ret = eet_read(ef, "Entry 3", &size);
printf("%s\n", ret);
eet_close(ef);
}
@endcode
@section format What does an Eet file look like?
The file format is very simple. There is a directory block at the start of
the file listing entries and offsets into the file where they are stored,
their sizes, compression flags etc. followed by all the entry data strung one
element after the other.
All Eet files start with t a 4 byte magic number. It is written using network
byte-order (big endian, or from most significant byte first to least
significant byte last) and is 0x1ee7ff00 (or byte by byte 0:1e 1:e7 2:ff
3:00). The next 4 bytes are an integer (in big endian notation) indicating
how many entries are stored in the Eet file. 0 indicates it is empty. This is
a signed integer and thus values less than 0 are invalid, limiting the number
of entries in an Eet file to 0x7fffffff entries at most. The next 4 bytes is
the size of the directory table, in bytes, encoded in big-endian format. This
is a signed integer and cannot be less than 0.
The directory table for the file follows immediately, with a continuous list
of all entries in the Eet file, their offset in the file etc. The order of
these entries is not important, but convention would have them be from first
to last entry in the file. Each directory entry consiste of 5 integers, one
after the other, each stored as a signed, big endian integer. The first is
the offset in the file that the data for this entry is stored at (based from
the very start of the file, not relative to the end of the directory block).
The second integer holds flags for the entry. currently only the least
significant bit (bit 0) holds any useful information, and it is set to 1 if
the entry is compressed using zlib compression calls, or 0 if it is not
compressed. The next integer is the size of the entry in bytes stored in the
file. The next integer is the size of the data when decompressed (if it was
compressed) in bytes. This may be the same as the previous integer if the
entry was not compressed. The final integer is the number of bytes used by
the string identifier for the entry, without the NUL byte terminator, which
is not stored. The next series of bytes is the string name of the entry, with
the number of bytes being the same as specified in the last integer above.
This list of entries continues until there are no more entries left to list.
To read an entry from an Eet file, simply find the appropriate entry in the
directory table, find it's offset and size, and read it into memory. If it is
compressed, decompress it using zlib and then use that data.
Here is a data map of an Eet file. All integers are encoded using big-endian
notation (most significant byte first) and are signed. There is no alignment
of data, so all data types follow immediately on, one after the other. All
compressed data is compressed using the zlib compress2() function, and
decompressed using the zlib uncompress() function. Please see zlib
documentation for more information as to the encoding of compressed data.
@verbatim
HEADER:
[INT] Magic number (0x1ee7ff00)
[INT] Number of entries in the directory table
[INT] The size of the directory table, in bytes
DIRECTORY TABLE ENTRIES (as many as specified in the header):
[INT] Offest from file start at which entry is stored (in bytes)
[INT] Entry flags (1 = compressed, 0 = not compressed)
[INT] Size of data chunk in file (in bytes)
[INT] Size of the data chunk once decompressed (or the same as above, if not)
[INT] The length of the string itendifier, in bytes, without NUL terminator
[STR] Series of bytes for the string identifier, no NUL terminator
... more directory entries
DATA STORED, ONE AFTER ANOTHER:
[DAT] DATA ENTRY 1...
[DAT] DATA ENTRY 2...
[DAT] DATA ENTRY 3...
... more data chunks
@endverbatim
The contents of each entry in an Eet file has no defined format as such. It
is an opaque chunk of data, that is up to the application to deocde, unless
it is an image, ecoded by Eet, or a data structure encoded by Eet. The data
itself for these entries can be encoded and decoded by Eet with extra helper
functions in Eet. eet_data_image_read() and eet_data_image_write() are used
to handle reading and writing image data from a known Eet file entry name.
eet_data_read() and eet_data_write() are used to decode and encode program
data structures from an Eet file, making the loading and saving of program
information stored in data structures a simple 1 function call process.
Please see src/lib/eet_data.c for information on the format of these
specially encoded data entries in an Eet file (for now).
@todo Add hash table, fixed and variable array encode/decode support.
@todo Document data format for images and data structures.
*/

View File

@ -328,8 +328,10 @@ extern "C" {
* @param func_list_next The function to get the next list node.
* @param func_list_append The function to append a member to a list.
* @param func_list_data The function to get the data from a list node.
* @param func_list_free The function to free an entire linked list.
* @param func_hash_foreach The function to iterate through all hash table entries.
* @param func_hash_add The function to add a member to a hash table.
* @param func_hash_free The function to free an entire hash table.
* @return A new empty data descriptor.
*
* This function creates a new data descriptore and returns a handle to the
@ -529,7 +531,7 @@ extern "C" {
* likes. Eet can handle members being added or deleted from the data in
* storage and safely zero-fills unfilled members if they were not found
* in the data. It checks sizes and headers whenever it reads data, allowing
* the programmer ot not worry about corrupt data.
* the programmer to not worry about corrupt data.
*
* Once a data structure has been described by the programmer with the
* fields they wish to save or load, storing or retrieving a data structure
@ -555,25 +557,75 @@ extern "C" {
int eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, char *name, void *data, int compress);
/**
* To be documented.
*
* FIXME: To be fixed.
* Decode a data structure from an arbitary location in memory.
* @param edd The data descriptor to use when decoding.
* @param data_in The pointer to the data to decode into a struct.
* @param size_in The size of the data pointed to in bytes.
* @return NULL on failure, or a valid decoded struct pointer on success.
*
* This function will decode a data structure that has been encoded using
* eet_data_descriptor_encode(), and return a data structure with all its
* elements filled out, if successful, or NULL on failure.
*
* The data to be decoded is stored at the memory pointed to by @p data_in,
* and is described by the descriptor pointed to by @p edd. The data size is
* passed in as the value to @p size_in, ande must be greater than 0 to
* succeed.
*
* This function is useful for decoding data structures delivered to the
* application by means other than an eet file, such as an IPC or socket
* connection, raw files, shared memory etc.
*
* Please see eet_data_read() for more information.
*
*/
void *eet_data_descriptor_decode(Eet_Data_Descriptor *edd, void *data_in, int size_in);
/**
* To be documented.
* Encode a dsata struct to memory and return that encoded data.
* @param edd The data descriptor to use when encoding.
* @param data_in The pointer to the struct to encode into data.
* @param size_ret A pointer to the an int to be filled with the decoded size.
* @return NULL on failure, or a valid encoded data chunk on success.
*
* FIXME: To be fixed.
* This function takes a data structutre in memory and encodes it into a
* serialised chunk of data that can be decoded again by
* eet_data_descriptor_decode(). This is useful for being able to transmit
* data structures across sockets, pipes, IPC or shared file mechanisms,
* without having to worry about memory space, machine type, endianess etc.
*
* The parameter @p edd must point to a valid data descriptor, and
* @p data_in must point to the right data structure to encode. If not, the
* encoding may fail.
*
* On success a non NULL valid pointer is returned and what @p size_ret
* points to is set to the size of this decoded data, in bytes. When the
* encoded data is no longer needed, call free() on it. On failure NULL is
* returned and what @p size_ret points to is set to 0.
*
* Please see eet_data_write() for more information.
*
*/
void *eet_data_descriptor_encode(Eet_Data_Descriptor *edd, void *data_in, int *size_ret);
/**
* To be documented.
*
* FIXME: To be fixed.
* Add a basic data element to a data descriptor.
* @param edd The data descriptor to add the type to.
* @param struct_type The type of the struct.
* @param name The string name to use to encode/decode this member.
* @param member The struct member itself to be encoded.
* @param type The type of the member to encode.
*
* This macro is a convenience macro provided to add a member to the data
* descriptor @p edd. The type of the structure is provided as the
* @p struct_type parameter (for example: struct my_struct). The @p name
* parameter defines a string that will be used to uniquely name that
* member of the struct (it is suggested to use the struct member itself).
* The @p member parameter is the actual struct member itself (for
* example: values), and @p type is the basic data type of the member which
* must be one of: EET_T_CHAR, EET_T_SHORT, EET_T_INT, EET_T_LONG_LONG,
* EET_T_FLOAT, EET_T_DOUBLE, EET_T_UCHAR, EET_T_USHORT, EET_T_UINT,
* EET_T_ULONG_LONG or EET_T_STRING.
*
*/
#define EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, name, member, type) \
@ -586,9 +638,18 @@ extern "C" {
}
/**
* To be documented.
*
* FIXME: To be fixed.
* Add a sub-element type to a data descriptor
* @param edd The data descriptor to add the type to.
* @param struct_type The type of the struct.
* @param name The string name to use to encode/decode this member.
* @param member The struct member itself to be encoded.
* @param subtype The type of sub-type struct to add.
*
* This macro lets you easily add a sub-type (a struct that's pointed to
* by this one). All the parameters are the same as for
* EET_DATA_DESCRIPTOR_ADD_BASIC(), with the @p subtype being the exception.
* This must be the data descriptor of the struct that is pointed to by
* this element.
*
*/
#define EET_DATA_DESCRIPTOR_ADD_SUB(edd, struct_type, name, member, subtype) \
@ -601,9 +662,17 @@ extern "C" {
}
/**
* To be documented.
*
* FIXME: To be fixed.
* Add a linked list type to a data descriptor
* @param edd The data descriptor to add the type to.
* @param struct_type The type of the struct.
* @param name The string name to use to encode/decode this member.
* @param member The struct member itself to be encoded.
* @param subtype The type of linked list member to add.
*
* This macro lets you easily add a linked list of other data types. All the
* parameters are the same as for EET_DATA_DESCRIPTOR_ADD_BASIC(), with the
* @p subtype being the exception. This must be the data descriptor of the
* element that is in each member of the linked list to be stored.
*
*/
#define EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, name, member, subtype) \