forked from enlightenment/efl
parent
4e30cb2411
commit
6df28268ca
|
@ -389,3 +389,8 @@
|
||||||
|
|
||||||
* On Windows 64, long is of size 32 bits and not 64 bits. Also
|
* On Windows 64, long is of size 32 bits and not 64 bits. Also
|
||||||
LONG_BIT is not defined on Windows.
|
LONG_BIT is not defined on Windows.
|
||||||
|
|
||||||
|
2010-06-29 Cedric BAIL
|
||||||
|
|
||||||
|
* Add eet_alias support.
|
||||||
|
* Fix possible dead lock in eet_write_cipher.
|
||||||
|
|
|
@ -444,6 +444,23 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
EAPI int eet_delete(Eet_File *ef, const char *name);
|
EAPI int eet_delete(Eet_File *ef, const char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias a specific section to another one. Destination may exist or not,
|
||||||
|
* no check are done.
|
||||||
|
* @param ef A valid eet file handle opened for writing.
|
||||||
|
* @param name Name of the entry. eg: "/base/file_i_want".
|
||||||
|
* @param destination Destionation of the alias. eg: "/base/the_real_stuff_i_want".
|
||||||
|
* @param compress Compression flags (1 == compress, 0 = don't compress).
|
||||||
|
* @return EINA_TRUE on success, EINA_FALSE on failure.
|
||||||
|
*
|
||||||
|
* Name and Destination must not be NULL, otherwhise EINA_FALSE will be returned.
|
||||||
|
*
|
||||||
|
* @since 1.3.3
|
||||||
|
* @ingroup Eet_File_Group
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool eet_alias(Eet_File *ef, const char *name, const char *destination, int compress);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all entries in eet file matching shell glob.
|
* List all entries in eet file matching shell glob.
|
||||||
* @param ef A valid eet file handle.
|
* @param ef A valid eet file handle.
|
||||||
|
|
|
@ -146,6 +146,7 @@ struct _Eet_File_Node
|
||||||
unsigned char free_name : 1;
|
unsigned char free_name : 1;
|
||||||
unsigned char compression : 1;
|
unsigned char compression : 1;
|
||||||
unsigned char ciphered : 1;
|
unsigned char ciphered : 1;
|
||||||
|
unsigned char alias : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -181,7 +182,11 @@ struct
|
||||||
int data_size; /* size of the (uncompressed) data chunk */
|
int data_size; /* size of the (uncompressed) data chunk */
|
||||||
int name_offset; /* bytes offset into file for name string */
|
int name_offset; /* bytes offset into file for name string */
|
||||||
int name_size; /* length in bytes of the name field */
|
int name_size; /* length in bytes of the name field */
|
||||||
int flags; /* flags - for now 0 = uncompressed, 1 = compressed */
|
int flags; /* bit flags - for now:
|
||||||
|
bit 0 => compresion on/off
|
||||||
|
bit 1 => ciphered on/off
|
||||||
|
bit 2 => alias
|
||||||
|
*/
|
||||||
} directory[num_directory_entries];
|
} directory[num_directory_entries];
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -521,7 +526,7 @@ eet_flush2(Eet_File *ef)
|
||||||
unsigned int flag;
|
unsigned int flag;
|
||||||
int ibuf[EET_FILE2_DIRECTORY_ENTRY_COUNT];
|
int ibuf[EET_FILE2_DIRECTORY_ENTRY_COUNT];
|
||||||
|
|
||||||
flag = (efn->ciphered << 1) | efn->compression;
|
flag = (efn->alias << 2) | (efn->ciphered << 1) | efn->compression;
|
||||||
|
|
||||||
ibuf[0] = (int) htonl ((unsigned int) efn->offset);
|
ibuf[0] = (int) htonl ((unsigned int) efn->offset);
|
||||||
ibuf[1] = (int) htonl ((unsigned int) efn->size);
|
ibuf[1] = (int) htonl ((unsigned int) efn->size);
|
||||||
|
@ -889,6 +894,7 @@ eet_internal_read2(Eet_File *ef)
|
||||||
|
|
||||||
efn->compression = flag & 0x1 ? 1 : 0;
|
efn->compression = flag & 0x1 ? 1 : 0;
|
||||||
efn->ciphered = flag & 0x2 ? 1 : 0;
|
efn->ciphered = flag & 0x2 ? 1 : 0;
|
||||||
|
efn->alias = flag & 0x4 ? 1 : 0;
|
||||||
|
|
||||||
#define EFN_TEST(Test, Ef, Efn) \
|
#define EFN_TEST(Test, Ef, Efn) \
|
||||||
if (eet_test_close(Test, Ef)) \
|
if (eet_test_close(Test, Ef)) \
|
||||||
|
@ -1120,6 +1126,7 @@ eet_internal_read1(Eet_File *ef)
|
||||||
|
|
||||||
efn->name_size = name_size;
|
efn->name_size = name_size;
|
||||||
efn->ciphered = 0;
|
efn->ciphered = 0;
|
||||||
|
efn->alias = 0;
|
||||||
|
|
||||||
/* invalid size */
|
/* invalid size */
|
||||||
if (eet_test_close(efn->size <= 0, ef))
|
if (eet_test_close(efn->size <= 0, ef))
|
||||||
|
@ -1570,9 +1577,9 @@ eet_close(Eet_File *ef)
|
||||||
EAPI void *
|
EAPI void *
|
||||||
eet_read_cipher(Eet_File *ef, const char *name, int *size_ret, const char *cipher_key)
|
eet_read_cipher(Eet_File *ef, const char *name, int *size_ret, const char *cipher_key)
|
||||||
{
|
{
|
||||||
void *data = NULL;
|
|
||||||
int size = 0;
|
|
||||||
Eet_File_Node *efn;
|
Eet_File_Node *efn;
|
||||||
|
char *data = NULL;
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
if (size_ret)
|
if (size_ret)
|
||||||
*size_ret = 0;
|
*size_ret = 0;
|
||||||
|
@ -1609,6 +1616,7 @@ eet_read_cipher(Eet_File *ef, const char *name, int *size_ret, const char *ciphe
|
||||||
void *data_deciphered = NULL;
|
void *data_deciphered = NULL;
|
||||||
unsigned int data_deciphered_sz = 0;
|
unsigned int data_deciphered_sz = 0;
|
||||||
/* if we alreayd have the data in ram... copy that */
|
/* if we alreayd have the data in ram... copy that */
|
||||||
|
|
||||||
if (efn->data)
|
if (efn->data)
|
||||||
memcpy(data, efn->data, efn->size);
|
memcpy(data, efn->data, efn->size);
|
||||||
else
|
else
|
||||||
|
@ -1677,12 +1685,27 @@ eet_read_cipher(Eet_File *ef, const char *name, int *size_ret, const char *ciphe
|
||||||
free(tmp_data);
|
free(tmp_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UNLOCK_FILE(ef);
|
||||||
|
|
||||||
|
/* handle alias */
|
||||||
|
if (efn->alias)
|
||||||
|
{
|
||||||
|
void *tmp;
|
||||||
|
|
||||||
|
if (data[size - 1] != '\0')
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
tmp = eet_read_cipher(ef, data, size_ret, cipher_key);
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
data = tmp;
|
||||||
|
}
|
||||||
|
else
|
||||||
/* fill in return values */
|
/* fill in return values */
|
||||||
if (size_ret)
|
if (size_ret)
|
||||||
*size_ret = size;
|
*size_ret = size;
|
||||||
|
|
||||||
UNLOCK_FILE(ef);
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
on_error:
|
on_error:
|
||||||
|
@ -1700,9 +1723,9 @@ eet_read(Eet_File *ef, const char *name, int *size_ret)
|
||||||
EAPI const void *
|
EAPI const void *
|
||||||
eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
|
eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
|
||||||
{
|
{
|
||||||
const void *data = NULL;
|
|
||||||
int size = 0;
|
|
||||||
Eet_File_Node *efn;
|
Eet_File_Node *efn;
|
||||||
|
const char *data = NULL;
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
if (size_ret)
|
if (size_ret)
|
||||||
*size_ret = 0;
|
*size_ret = 0;
|
||||||
|
@ -1732,6 +1755,35 @@ eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
|
||||||
/* get size (uncompressed, if compressed at all) */
|
/* get size (uncompressed, if compressed at all) */
|
||||||
size = efn->data_size;
|
size = efn->data_size;
|
||||||
|
|
||||||
|
if (efn->alias)
|
||||||
|
{
|
||||||
|
data = efn->data ? efn->data : ef->data + efn->offset;
|
||||||
|
|
||||||
|
/* handle alias case */
|
||||||
|
if (efn->compression)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
int compr_size = efn->size;
|
||||||
|
uLongf dlen;
|
||||||
|
|
||||||
|
tmp = alloca(sizeof (compr_size));
|
||||||
|
dlen = size;
|
||||||
|
|
||||||
|
if (uncompress((Bytef *)tmp, &dlen, (Bytef *) data, (uLongf)compr_size))
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
if (tmp[compr_size - 1] != '\0')
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
return eet_read_direct(ef, tmp, size_ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data) goto on_error;
|
||||||
|
if (data[size - 1] != '\0') goto on_error;
|
||||||
|
|
||||||
|
return eet_read_direct(ef, data, size_ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
/* uncompressed data */
|
/* uncompressed data */
|
||||||
if (efn->compression == 0
|
if (efn->compression == 0
|
||||||
&& efn->ciphered == 0)
|
&& efn->ciphered == 0)
|
||||||
|
@ -1753,6 +1805,150 @@ eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
eet_alias(Eet_File *ef, const char *name, const char *destination, int comp)
|
||||||
|
{
|
||||||
|
Eet_File_Node *efn;
|
||||||
|
void *data2;
|
||||||
|
Eina_Bool exists_already = EINA_FALSE;
|
||||||
|
int data_size;
|
||||||
|
int hash;
|
||||||
|
|
||||||
|
/* check to see its' an eet file pointer */
|
||||||
|
if (eet_check_pointer(ef))
|
||||||
|
return EINA_FALSE;
|
||||||
|
if ((!name) || (!destination))
|
||||||
|
return EINA_FALSE;
|
||||||
|
if ((ef->mode != EET_FILE_MODE_WRITE) &&
|
||||||
|
(ef->mode != EET_FILE_MODE_READ_WRITE))
|
||||||
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
LOCK_FILE(ef);
|
||||||
|
|
||||||
|
if (!ef->header)
|
||||||
|
{
|
||||||
|
/* allocate header */
|
||||||
|
ef->header = calloc(1, sizeof(Eet_File_Header));
|
||||||
|
if (!ef->header)
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
|
ef->header->magic = EET_MAGIC_FILE_HEADER;
|
||||||
|
/* allocate directory block in ram */
|
||||||
|
ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
|
||||||
|
if (!ef->header->directory)
|
||||||
|
{
|
||||||
|
free(ef->header);
|
||||||
|
ef->header = NULL;
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 8 bit hash table (256 buckets) */
|
||||||
|
ef->header->directory->size = 8;
|
||||||
|
/* allocate base hash table */
|
||||||
|
ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size));
|
||||||
|
if (!ef->header->directory->nodes)
|
||||||
|
{
|
||||||
|
free(ef->header->directory);
|
||||||
|
ef->header = NULL;
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* figure hash bucket */
|
||||||
|
hash = _eet_hash_gen(name, ef->header->directory->size);
|
||||||
|
|
||||||
|
data_size = comp ?
|
||||||
|
12 + (((strlen(destination) + 1) * 101) / 100)
|
||||||
|
: strlen(destination) + 1;
|
||||||
|
|
||||||
|
data2 = malloc(data_size);
|
||||||
|
if (!data2) goto on_error;
|
||||||
|
|
||||||
|
/* if we want to compress */
|
||||||
|
if (comp)
|
||||||
|
{
|
||||||
|
uLongf buflen;
|
||||||
|
|
||||||
|
/* compress the data with max compression */
|
||||||
|
buflen = (uLongf)data_size;
|
||||||
|
if (compress2((Bytef *)data2, &buflen, (Bytef *)destination,
|
||||||
|
(uLong)strlen(destination) + 1, Z_BEST_COMPRESSION) != Z_OK)
|
||||||
|
{
|
||||||
|
free(data2);
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
/* record compressed chunk size */
|
||||||
|
data_size = (int)buflen;
|
||||||
|
if (data_size < 0 || data_size >= (int) (strlen(destination) + 1))
|
||||||
|
{
|
||||||
|
comp = 0;
|
||||||
|
data_size = strlen(destination) + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
void *data3;
|
||||||
|
|
||||||
|
data3 = realloc(data2, data_size);
|
||||||
|
if (data3)
|
||||||
|
data2 = data3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!comp)
|
||||||
|
memcpy(data2, destination, data_size);
|
||||||
|
|
||||||
|
/* Does this node already exist? */
|
||||||
|
for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next)
|
||||||
|
{
|
||||||
|
/* if it matches */
|
||||||
|
if ((efn->name) && (eet_string_match(efn->name, name)))
|
||||||
|
{
|
||||||
|
free(efn->data);
|
||||||
|
efn->alias = 1;
|
||||||
|
efn->ciphered = 0;
|
||||||
|
efn->compression = !!comp;
|
||||||
|
efn->size = data_size;
|
||||||
|
efn->data_size = strlen(destination) + 1;
|
||||||
|
efn->data = data2;
|
||||||
|
efn->offset = -1;
|
||||||
|
exists_already = EINA_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!exists_already)
|
||||||
|
{
|
||||||
|
efn = malloc(sizeof(Eet_File_Node));
|
||||||
|
if (!efn)
|
||||||
|
{
|
||||||
|
free(data2);
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
efn->name = strdup(name);
|
||||||
|
efn->name_size = strlen(efn->name) + 1;
|
||||||
|
efn->free_name = 1;
|
||||||
|
|
||||||
|
efn->next = ef->header->directory->nodes[hash];
|
||||||
|
ef->header->directory->nodes[hash] = efn;
|
||||||
|
efn->offset = -1;
|
||||||
|
efn->alias = 1;
|
||||||
|
efn->ciphered = 0;
|
||||||
|
efn->compression = !!comp;
|
||||||
|
efn->size = data_size;
|
||||||
|
efn->data_size = strlen(destination) + 1;
|
||||||
|
efn->data = data2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* flags that writes are pending */
|
||||||
|
ef->writes_pending = 1;
|
||||||
|
|
||||||
|
UNLOCK_FILE(ef);
|
||||||
|
return EINA_TRUE;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
UNLOCK_FILE(ef);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
EAPI int
|
EAPI int
|
||||||
eet_write_cipher(Eet_File *ef, const char *name, const void *data, int size, int comp, const char *cipher_key)
|
eet_write_cipher(Eet_File *ef, const char *name, const void *data, int size, int comp, const char *cipher_key)
|
||||||
{
|
{
|
||||||
|
@ -1824,7 +2020,7 @@ eet_write_cipher(Eet_File *ef, const char *name, const void *data, int size, int
|
||||||
(uLong)size, Z_BEST_COMPRESSION) != Z_OK)
|
(uLong)size, Z_BEST_COMPRESSION) != Z_OK)
|
||||||
{
|
{
|
||||||
free(data2);
|
free(data2);
|
||||||
return 0;
|
goto on_error;
|
||||||
}
|
}
|
||||||
/* record compressed chunk size */
|
/* record compressed chunk size */
|
||||||
data_size = (int)buflen;
|
data_size = (int)buflen;
|
||||||
|
@ -1874,6 +2070,7 @@ eet_write_cipher(Eet_File *ef, const char *name, const void *data, int size, int
|
||||||
if ((efn->name) && (eet_string_match(efn->name, name)))
|
if ((efn->name) && (eet_string_match(efn->name, name)))
|
||||||
{
|
{
|
||||||
free(efn->data);
|
free(efn->data);
|
||||||
|
efn->alias = 0;
|
||||||
efn->ciphered = cipher_key ? 1 : 0;
|
efn->ciphered = cipher_key ? 1 : 0;
|
||||||
efn->compression = !!comp;
|
efn->compression = !!comp;
|
||||||
efn->size = data_size;
|
efn->size = data_size;
|
||||||
|
@ -1899,6 +2096,7 @@ eet_write_cipher(Eet_File *ef, const char *name, const void *data, int size, int
|
||||||
efn->next = ef->header->directory->nodes[hash];
|
efn->next = ef->header->directory->nodes[hash];
|
||||||
ef->header->directory->nodes[hash] = efn;
|
ef->header->directory->nodes[hash] = efn;
|
||||||
efn->offset = -1;
|
efn->offset = -1;
|
||||||
|
efn->alias = 0;
|
||||||
efn->ciphered = cipher_key ? 1 : 0;
|
efn->ciphered = cipher_key ? 1 : 0;
|
||||||
efn->compression = !!comp;
|
efn->compression = !!comp;
|
||||||
efn->size = data_size;
|
efn->size = data_size;
|
||||||
|
|
|
@ -364,7 +364,7 @@ _eet_build_ex_descriptor(Eet_Data_Descriptor *edd)
|
||||||
static Eet_Test_Ex_Type*
|
static Eet_Test_Ex_Type*
|
||||||
_eet_test_ex_set(Eet_Test_Ex_Type *res, int offset)
|
_eet_test_ex_set(Eet_Test_Ex_Type *res, int offset)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (!res) res = malloc( sizeof(Eet_Test_Ex_Type));
|
if (!res) res = malloc( sizeof(Eet_Test_Ex_Type));
|
||||||
if (!res) return NULL;
|
if (!res) return NULL;
|
||||||
|
@ -671,6 +671,8 @@ START_TEST(eet_file_simple_write)
|
||||||
fail_if(!ef);
|
fail_if(!ef);
|
||||||
|
|
||||||
fail_if(!eet_write(ef, "keys/tests", buffer, strlen(buffer) + 1, 1));
|
fail_if(!eet_write(ef, "keys/tests", buffer, strlen(buffer) + 1, 1));
|
||||||
|
fail_if(!eet_alias(ef, "keys/alias", "keys/tests", 0));
|
||||||
|
fail_if(!eet_alias(ef, "keys/alias2", "keys/alias", 1));
|
||||||
|
|
||||||
fail_if(eet_mode_get(ef) != EET_FILE_MODE_WRITE);
|
fail_if(eet_mode_get(ef) != EET_FILE_MODE_WRITE);
|
||||||
|
|
||||||
|
@ -689,8 +691,14 @@ START_TEST(eet_file_simple_write)
|
||||||
|
|
||||||
fail_if(memcmp(test, buffer, strlen(buffer) + 1) != 0);
|
fail_if(memcmp(test, buffer, strlen(buffer) + 1) != 0);
|
||||||
|
|
||||||
|
test = eet_read(ef, "keys/alias2", &size);
|
||||||
|
fail_if(!test);
|
||||||
|
fail_if(size != (int) strlen(buffer) + 1);
|
||||||
|
|
||||||
|
fail_if(eet_read_direct(ef, "key/alias2", &size));
|
||||||
|
|
||||||
fail_if(eet_mode_get(ef) != EET_FILE_MODE_READ);
|
fail_if(eet_mode_get(ef) != EET_FILE_MODE_READ);
|
||||||
fail_if(eet_num_entries(ef) != 1);
|
fail_if(eet_num_entries(ef) != 3);
|
||||||
|
|
||||||
eet_close(ef);
|
eet_close(ef);
|
||||||
|
|
||||||
|
@ -1324,7 +1332,7 @@ static int pass_get(char *pass, int size, __UNUSED__ int rwflags, __UNUSED__ voi
|
||||||
{
|
{
|
||||||
memset(pass, 0, size);
|
memset(pass, 0, size);
|
||||||
|
|
||||||
if (strlen("password") > size)
|
if ((int) strlen("password") > size)
|
||||||
return 0;
|
return 0;
|
||||||
snprintf(pass, size, "%s", "password");
|
snprintf(pass, size, "%s", "password");
|
||||||
return strlen(pass);
|
return strlen(pass);
|
||||||
|
@ -1334,7 +1342,7 @@ static int badpass_get(char *pass, int size, __UNUSED__ int rwflags, __UNUSED__
|
||||||
{
|
{
|
||||||
memset(pass, 0, size);
|
memset(pass, 0, size);
|
||||||
|
|
||||||
if (strlen("bad password") > size)
|
if ((int) strlen("bad password") > size)
|
||||||
return 0;
|
return 0;
|
||||||
snprintf(pass, size, "%s", "bad password");
|
snprintf(pass, size, "%s", "bad password");
|
||||||
return strlen(pass);
|
return strlen(pass);
|
||||||
|
|
Loading…
Reference in New Issue