Tizen Native API
5.0
|
Functions to create, destroy and do basic manipulation of Eet_File handles.
This section explains how to use the most basic Eet functions, which are used to work with eet files, read data from them, store it back in or take a look at what entries it contains, without making use of the serialization capabilities explained in Eet Data Serialization.
The following example will serve as an introduction to most, if not all, of these functions.
If you are only using Eet, this is the only header you need to include.
#include <Eet.h>
Now let's create ourselves an eet file to play with. The following function shows step by step how to open a file and write some data in it. First, we define our file handler and some other things we'll put in it.
Eet_File *ef; char buf[1024], *ptr; int size, len, i; const char *some_strings[] = { "And some more strings", "spread across several", "elements of an array!" }; const char some_data[] = "\x1e\xe7\x0f\x42\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x35" "\x00\x00\x00\xa0\x00\x00\x00\xa0\x00\x00\x00\x24\x00\x00\x00\x11" "\x00\x00\x00\x00\x2f\x6d\x69\x73\x74\x65\x72\x69\x6f\x75\x73\x2f" "\x64\x61\x74\x61\x00\x41\x6e\x20\x45\x45\x54\x20\x69\x6e\x73\x69" "\x64\x65\x20\x6f\x66\x20\x61\x6e\x20\x45\x45\x54\x21\x0a\x54\x68" "\x69\x73\x20\x77\x61\x73\x6e\x27\x74\x20\x72\x65\x61\x6c\x6c\x79" "\x20\x75\x73\x65\x66\x75\x6c\x20\x62\x75\x74\x20\x69\x74\x20\x68" "\x65\x6c\x70\x65\x64\x20\x74\x6f\x20\x73\x68\x6f\x77\x20\x68\x6f" "\x77\x0a\x74\x6f\x20\x75\x73\x65\x20\x65\x65\x74\x5f\x6d\x65\x6d" "\x6f\x70\x65\x6e\x5f\x72\x65\x61\x64\x28\x29\x20\x74\x6f\x20\x6f" "\x70\x65\x6e\x20\x61\x6e\x20\x65\x65\x74\x20\x66\x69\x6c\x65\x20" "\x66\x72\x6f\x6d\x0a\x64\x61\x74\x61\x20\x61\x6c\x72\x65\x61\x64" "\x79\x20\x6c\x6f\x61\x64\x65\x64\x20\x69\x6e\x20\x6d\x65\x6d\x6f" "\x72\x79\x2e\x0a\x00";
We open a new file in write mode, and if it fails, we just return, since there's not much more we can do about it..
ef = eet_open("/tmp/my_file.eet", EET_FILE_MODE_WRITE); if (!ef) return 0;
Now, we need to write some data in our file. For now, strings will suffice, so let's just dump a bunch of them in there.
strcpy(buf, "Here is a string of data to save!"); size = eet_write(ef, "/key/to_store/at", buf, sizeof(buf), 1); if (!size) { fprintf(stderr, "Error writing data!\n"); eet_close(ef); return 0; }
As you can see, we copied a string into our static buffer, which is a bit bigger than the full length of the string, and then told Eet to write it into the file, compressed, returning the size of the data written into the file. This is all to show that Eet treats data as just data. It doesn't matter what that data represents (for now), it's all just bytes for it. As running the following code will show, we took a string of around 30 bytes and put it in a buffer of 1024 bytes, but the returned size won't be any of those.
len = strlen(buf);
printf("strlen() = %d, eet_write() = %d\n", len, size);
Next, we copy into our buffer our set of strings, including their null terminators and write them into the file. No error checking for the sake of brevity. And a call to eet_sync() to make sure all out data is properly written down to disk, even though we haven't yet closed the file.
ptr = buf; for (i = 0; i < 3; i++) { len = strlen(some_strings[i]) + 1; memcpy(ptr, some_strings[i], len); ptr += len; } eet_write(ef, "/several/strings", buf, sizeof(buf), 1); eet_sync(ef);
One more write, this time our large array of binary data and... well, I couldn't come up with a valid use of the last set of strings we stored, so let's take it out from the file with eet_delete().
eet_write(ef, "/some/mysterious/data", some_data, sizeof(some_data) - 1, 1); eet_delete(ef, "/several/strings");
Finally, we close the file, saving any changes back to disk and return. Notice how, if there's any error closing the file or saving its contents, the return value from the function will be a false one, which later on will make the program exit with an error code.
return eet_close(ef) == EET_ERROR_NONE;
Moving onto our main function, we will open the same file and read it back. Trivial, but it'll show how we can do so in more than one way. We'll skip the variable declarations, as they aren't very different from what we've seen already.
We start from the beginning by initializing Eet so things in general work. Forgetting to do so will result in weird results or crashes when calling any eet function, so if you experience something like that, the first thing to look at is whether eet_init() is missing. Then we call our create_eet_file
function, described above, to make sure we have something to work with. If the function fails it will return 0 and we just exit, since nothing from here onwards will work anyway.
eet_init(); if (!create_eet_file()) return -1;
Let's take a look now at what entries our file has. For this, we use eet_list(), which will return a list of strings, each being the name of one entry. Since we skipped before, it may be worth noting that list
is declared as a char
**. The num
parameter will, of course, have the number of entries contained in our file. If everything's fine, we'll get our list and print it to the screen, and once done with it, we free the list. That's just the list, not its contents, as they are internal strings used by Eet and trying to free them will surely break things.
ef = eet_open("/tmp/my_file.eet", EET_FILE_MODE_READ); if (!ef) return -1; list = eet_list(ef, "*", &num); if (list) { for (i = 0; i < num; i++) printf("Key stored: %s\n", list[i]); free(list); }
Reading back plain data is simple. Just a call to eet_read() with the file to read from, and the name of the entry we are interested in. We get back our data and the passed size
parameter will contain the size of it. If the data was stored compressed, it will decompressed first.
ret = eet_read(ef, "/key/to_store/at", &size); if (ret) { printf("Data read (%i bytes):\n%s\n", size, ret); free(ret); }
Another simple read for the set of strings from before, except those were deleted, so we should get a NULL return and continue normally.
ret = eet_read(ef, "/several/strings", &size); if (ret) { printf("More data read (%i bytes):\n%s\n", size, ret); free(ret); }
Finally, we'll get our binary data in the same way we got the strings. Once again, it makes no difference for Eet what the data is, it's up to us to know how to handle it.
ret = eet_read(ef, "/some/mysterious/data", &size); if (ret) {
Now some cheating, we know that this data is an Eet file because, well... we just know it. So we are going to open it and take a look at its insides. For this, eet_open() won't work, as it needs to have a file on disk to read from and all we have is some data in RAM.
So how do we do? One way would be to create a normal file and write down our data, then open it with eet_open(). Another, faster and more efficient if all we want to do is read the file, is to use eet_memopen_read().
Eet_File *ef2; ef2 = eet_memopen_read(ret, size);
As you can see, the size we got from our previous read was put to good use this time. Unlike the first one where all we had were strings, the size of the data read only serves to demonstrate that we are reading back the entire size of our original buf
variable.
A little peeking to see how many entries the file has and to make an example of eet_num_entries() to get that number when we don't care about their names.
num = eet_num_entries(ef2); printf("Mysterious data has %d entries\n", num);
More cheating follows. Just like we knew this was an Eet file, we also know what key to read from, and ontop of that we know that the data in it is not compressed. Knowing all this allows us to take some shortcuts.
printf("Mysterious data:\n%s\n", (char *)eet_read_direct(ef2, "/mysterious/data", NULL));
That's a direct print of our data, whatever that data is. We don't want to worry about having to free it later, so we just used eet_direct_read() to tell Eet to gives a pointer to the internal data in the file, without duplicating it. Since we said that data was not compressed, we shouldn't worry about printing garbage to the screen (and yes, we also know the data is yet another string). We also don't care about the size of the data as it was stored in the file, so we passed NULL as the size parameter. One very important note about this, however, is that we don't care about the size parameter because the data in the file contains the null terminator for the string. So when using Eet to store strings this way, it's very important to consider whether you will keep that final null byte, or to always get the size read and do the necessary checks and copies. It's up to the user and the particular use cases to decide how this will be done.
With everything done, close this second file and free the data used to open it. And this is important, we can't free that data until we are done with the file, as Eet is using it. When opening with eet_memopen_read(), the data passed to it must be available for as long as the the file is open.
eet_close(ef2); free(ret); }
Finally, we close the first file, shutdown all internal resources used by Eet and leave our main function, thus terminating our program.
eet_close(ef); eet_shutdown(); return 0;
You can look at the full code of the example here.
Functions | |
Eet_File * | eet_open (const char *file, Eet_File_Mode mode) |
Opens an eet file on disk, and returns a handle to it. | |
Eet_File * | eet_mmap (const Eina_File *file) |
Opens an eet file on disk from an Eina_File handle, and returns a handle to it. | |
Eet_File * | eet_memopen_read (const void *data, size_t size) |
Eet_File_Mode | eet_mode_get (Eet_File *ef) |
Gets the mode an Eet_File was opened with. | |
Eet_Error | eet_close (Eet_File *ef) |
Closes an eet file handle and flush pending writes. | |
Eet_Error | eet_sync (Eet_File *ef) |
Syncs content of an eet file handle, flushing pending writes. | |
Eet_Dictionary * | eet_dictionary_get (Eet_File *ef) |
Returns a handle to the shared string dictionary of the Eet file. | |
int | eet_dictionary_string_check (Eet_Dictionary *ed, const char *string) |
Checks if a given string comes from a given dictionary. | |
int | eet_dictionary_count (const Eet_Dictionary *ed) |
Returns the number of strings inside a dictionary. | |
void * | eet_read (Eet_File *ef, const char *name, int *size_ret) |
Reads a specified entry from an eet file and return data. | |
const void * | eet_read_direct (Eet_File *ef, const char *name, int *size_ret) |
Reads a specified entry from an eet file and return data. | |
int | eet_write (Eet_File *ef, const char *name, const void *data, int size, int compress) |
Write a specified entry to an eet file handle. | |
int | eet_delete (Eet_File *ef, const char *name) |
Deletes a specified entry from an Eet file being written or re-written. | |
Eina_Bool | eet_alias (Eet_File *ef, const char *name, const char *destination, int compress) |
Alias a specific section to another one. Destination may exist or not, no checks are done. | |
const char * | eet_file_get (Eet_File *ef) |
Retrieves the filename of an Eet_File. | |
const char * | eet_alias_get (Eet_File *ef, const char *name) |
Retrieves the destination name of an alias. | |
char ** | eet_list (Eet_File *ef, const char *glob, int *count_ret) |
Lists all entries in eet file matching shell glob. | |
Eina_Iterator * | eet_list_entries (Eet_File *ef) |
Returns an iterator that will describe each entry of an Eet_File. | |
int | eet_num_entries (Eet_File *ef) |
Returns the number of entries in the specified eet file. | |
Typedefs | |
typedef enum _Eet_File_Mode | Eet_File_Mode |
typedef struct _Eet_File | Eet_File |
typedef struct _Eet_Dictionary | Eet_Dictionary |
typedef struct _Eet_Entry | Eet_Entry |
Opaque handle that defines a file-backed (mmaped) dictionary of strings.
Eet files may contains multiple Entries per file, this handle describe them. You can get that handle from an iterator given by eet_list_entries().
Opaque handle that defines an Eet file (or memory).
This handle will be returned by the functions eet_open() and eet_memopen_read() and is used by every other function that affects the file in any way. When you are done with it, call eet_close() to close it and, if the file was open for writing, write down to disk any changes made to it.
typedef enum _Eet_File_Mode Eet_File_Mode |
Modes that a file can be opened.
enum _Eet_File_Mode |
Alias a specific section to another one. Destination may exist or not, no checks are done.
ef | A valid eet file handle opened for writing. |
name | Name of the new entry. eg: "/base/file_i_want". |
destination | Actual source of the aliased entry eg: "/base/the_real_stuff_i_want". |
compress | Compression flags (1 == compress, 0 = don't compress). |
Name and Destination must not be NULL, otherwise EINA_FALSE will be returned. The equivalent of this would be calling 'ln -s destination name'
const char* eet_alias_get | ( | Eet_File * | ef, |
const char * | name | ||
) |
Retrieves the destination name of an alias.
ef | A valid eet file handle opened for writing |
name | Name of the entry. eg: "/base/file_i_want" |
Name must not be NULL, otherwise NULL will be returned.
Closes an eet file handle and flush pending writes.
ef | A valid eet file handle. |
This function will flush any pending writes to disk if the eet file was opened for write, and free all data associated with the file handle and file, and close the file. If it was opened for read (or read/write), the file handle may still be held open internally for caching purposes. To flush speculatively held eet file handles use eet_clearcache().
If the eet file handle is not valid nothing will be done.
int eet_delete | ( | Eet_File * | ef, |
const char * | name | ||
) |
Deletes a specified entry from an Eet file being written or re-written.
ef | A valid eet file handle opened for writing. |
name | Name of the entry. eg: "/base/file_i_want". |
This function will delete the specified chunk of data from the eet file and return greater than 0 on success. 0 will be returned on failure.
The eet file handle must be a valid file handle for an eet file opened for writing. If it is not, 0 will be returned and no action will be performed.
Name, must not be NULL, otherwise 0 will be returned.
int eet_dictionary_count | ( | const Eet_Dictionary * | ed | ) |
Returns the number of strings inside a dictionary.
ed | A valid dictionary handle |
Eet_Dictionary* eet_dictionary_get | ( | Eet_File * | ef | ) |
Returns a handle to the shared string dictionary of the Eet file.
ef | A valid eet file handle. |
This function returns a handle to the dictionary of an Eet file whose handle is ef
, if a dictionary exists. NULL is returned otherwise or if the file handle is known to be invalid.
int eet_dictionary_string_check | ( | Eet_Dictionary * | ed, |
const char * | string | ||
) |
Checks if a given string comes from a given dictionary.
ed | A valid dictionary handle |
string | A valid 0 byte terminated C string |
1
if it is in the dictionary, 0
otherwiseThis checks the given dictionary to see if the given string is actually inside that dictionary (i.e. comes from it) and returns 1
if it does. If the dictionary handle is invalid, the string is NULL or the string is not in the dictionary, 0
is returned.
const char* eet_file_get | ( | Eet_File * | ef | ) |
Retrieves the filename of an Eet_File.
ef | A valid eet file handle opened for writing. |
Lists all entries in eet file matching shell glob.
ef | A valid eet file handle. |
glob | A shell glob to match against. |
count_ret | Number of entries found to match. |
This function will list all entries in the eet file matching the supplied shell glob and return an allocated list of their names, if there are any, and if no memory errors occur.
The eet file handle must be valid and glob must not be NULL, or NULL will be returned and count_ret will be filled with 0
.
The calling program must call free() on the array returned, but NOT on the string pointers in the array. They are taken as read-only internals from the eet file handle. They are only valid as long as the file handle is not closed. When it is closed those pointers in the array are now not valid and should not be used.
On success, the array returned will have a list of string pointers that are the names of the entries that matched, and count_ret will have the number of entries in this array placed in it.
Hint: an easy way to list all entries in an eet file is to use a glob value of "*".
Eina_Iterator* eet_list_entries | ( | Eet_File * | ef | ) |
Returns an iterator that will describe each entry of an Eet_File.
ef | A valid eet file handle. |
Eet_File* eet_memopen_read | ( | const void * | data, |
size_t | size | ||
) |
Opens an eet file directly from a memory location. The data is not copied, so you must keep it around as long as the eet file is open. There is currently no cache for this kind of Eet_File, so it's reopened every time you use eet_memopen_read.
data | Address of file in memory. |
size | Size of memory to be read. |
Files opened this way will always be in read-only mode.
Opens an eet file on disk from an Eina_File handle, and returns a handle to it.
file | The Eina_File handle to map to an eet file. |
This function will open an exiting eet file for reading, and build the directory table in memory and return a handle to the file, if it exists and can be read, and no memory errors occur on the way, otherwise NULL will be returned.
This function can't open file for writing only read only mode is supported for now.
If the same file is opened multiple times, then the same file handle will be returned as eet maintains an internal list of all currently open files. That means opening a file for read only looks in the read only set, and returns a handle to that file handle and increments its reference count. You need to close an eet file handle as many times as it has been opened to maintain correct reference counts.
Eet_File_Mode eet_mode_get | ( | Eet_File * | ef | ) |
Gets the mode an Eet_File was opened with.
ef | A valid eet file handle. |
int eet_num_entries | ( | Eet_File * | ef | ) |
Returns the number of entries in the specified eet file.
ef | A valid eet file handle. |
-1
if the number of entries cannot be read due to open mode restrictions.Eet_File* eet_open | ( | const char * | file, |
Eet_File_Mode | mode | ||
) |
Opens an eet file on disk, and returns a handle to it.
file | The file path to the eet file. eg: "/tmp/file.eet" . |
mode | The mode for opening. Either EET_FILE_MODE_READ, EET_FILE_MODE_WRITE or EET_FILE_MODE_READ_WRITE. |
This function will open an exiting eet file for reading, and build the directory table in memory and return a handle to the file, if it exists and can be read, and no memory errors occur on the way, otherwise NULL will be returned.
It will also open an eet file for writing. This will, if successful, delete the original file and replace it with a new empty file, till the eet file handle is closed or flushed. If it cannot be opened for writing or a memory error occurs, NULL is returned.
You can also open the file for read/write. If you then write a key that does not exist it will be created, if the key exists it will be replaced by the new data.
If the same file is opened multiple times, then the same file handle will be returned as eet maintains an internal list of all currently open files. Note that it considers files opened for read only and those opened for read/write and write only as 2 separate sets. Those that do not write to the file and those that do. Eet will allow 2 handles to the same file if they are in the 2 separate lists/groups. That means opening a file for read only looks in the read only set, and returns a handle to that file handle and increments its reference count. If you open a file for read/write or write only it looks in the write set and returns a handle after incrementing the reference count. You need to close an eet file handle as many times as it has been opened to maintain correct reference counts. Files whose modified timestamp or size do not match those of the existing referenced file handles will not be returned and a new handle will be returned instead.
Reads a specified entry from an eet file and return data.
ef | A valid eet file handle opened for reading. |
name | Name of the entry. eg: "/base/file_i_want". |
size_ret | Number of bytes read from entry and returned. |
This function finds an entry in the eet file that is stored under the name specified, and returns that data, decompressed, if successful. NULL is returned if the lookup fails or if memory errors are encountered. It is the job of the calling program to call free() on the returned data. The number of bytes in the returned data chunk are placed in size_ret.
If the eet file handle is not valid NULL is returned and size_ret is filled with 0
.
const void* eet_read_direct | ( | Eet_File * | ef, |
const char * | name, | ||
int * | size_ret | ||
) |
Reads a specified entry from an eet file and return data.
ef | A valid eet file handle opened for reading. |
name | Name of the entry. eg: "/base/file_i_want". |
size_ret | Number of bytes read from entry and returned. |
This function finds an entry in the eet file that is stored under the name specified, and returns that data if not compressed and successful. NULL is returned if the lookup fails or if memory errors are encountered or if the data is compressed. The calling program must never call free() on the returned data. The number of bytes in the returned data chunk are placed in size_ret.
If the eet file handle is not valid NULL is returned and size_ret is filled with 0
.
Syncs content of an eet file handle, flushing pending writes.
ef | A valid eet file handle. |
This function will flush any pending writes to disk. The eet file must be opened for write.
If the eet file handle is not valid nothing will be done.
Write a specified entry to an eet file handle.
ef | A valid eet file handle opened for writing. |
name | Name of the entry. eg: "/base/file_i_want". |
data | Pointer to the data to be stored. |
size | Length in bytes in the data to be stored. |
compress | Compression flags (1 == compress, 0 = don't compress). |
This function will write the specified chunk of data to the eet file and return greater than 0 on success. 0 will be returned on failure.
The eet file handle must be a valid file handle for an eet file opened for writing. If it is not, 0 will be returned and no action will be performed.
Name, and data must not be NULL, and size must be > 0. If these conditions are not met, 0 will be returned.
The data will be copied (and optionally compressed) in ram, pending a flush to disk (it will stay in ram till the eet file handle is closed though).