parent
4e30cb2411
commit
6df28268ca
|
@ -389,3 +389,8 @@
|
|||
|
||||
* On Windows 64, long is of size 32 bits and not 64 bits. Also
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param ef A valid eet file handle.
|
||||
|
|
|
@ -146,6 +146,7 @@ struct _Eet_File_Node
|
|||
unsigned char free_name : 1;
|
||||
unsigned char compression : 1;
|
||||
unsigned char ciphered : 1;
|
||||
unsigned char alias : 1;
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
@ -181,7 +182,11 @@ struct
|
|||
int data_size; /* size of the (uncompressed) data chunk */
|
||||
int name_offset; /* bytes offset into file for name string */
|
||||
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];
|
||||
struct
|
||||
{
|
||||
|
@ -521,7 +526,7 @@ eet_flush2(Eet_File *ef)
|
|||
unsigned int flag;
|
||||
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[1] = (int) htonl ((unsigned int) efn->size);
|
||||
|
@ -889,6 +894,7 @@ eet_internal_read2(Eet_File *ef)
|
|||
|
||||
efn->compression = flag & 0x1 ? 1 : 0;
|
||||
efn->ciphered = flag & 0x2 ? 1 : 0;
|
||||
efn->alias = flag & 0x4 ? 1 : 0;
|
||||
|
||||
#define EFN_TEST(Test, Ef, Efn) \
|
||||
if (eet_test_close(Test, Ef)) \
|
||||
|
@ -1120,6 +1126,7 @@ eet_internal_read1(Eet_File *ef)
|
|||
|
||||
efn->name_size = name_size;
|
||||
efn->ciphered = 0;
|
||||
efn->alias = 0;
|
||||
|
||||
/* invalid size */
|
||||
if (eet_test_close(efn->size <= 0, ef))
|
||||
|
@ -1570,9 +1577,9 @@ eet_close(Eet_File *ef)
|
|||
EAPI void *
|
||||
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)
|
||||
*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;
|
||||
unsigned int data_deciphered_sz = 0;
|
||||
/* if we alreayd have the data in ram... copy that */
|
||||
|
||||
if (efn->data)
|
||||
memcpy(data, efn->data, efn->size);
|
||||
else
|
||||
|
@ -1677,12 +1685,27 @@ eet_read_cipher(Eet_File *ef, const char *name, int *size_ret, const char *ciphe
|
|||
free(tmp_data);
|
||||
}
|
||||
|
||||
/* fill in return values */
|
||||
if (size_ret)
|
||||
*size_ret = size;
|
||||
|
||||
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 */
|
||||
if (size_ret)
|
||||
*size_ret = size;
|
||||
|
||||
return data;
|
||||
|
||||
on_error:
|
||||
|
@ -1700,9 +1723,9 @@ eet_read(Eet_File *ef, const char *name, int *size_ret)
|
|||
EAPI const void *
|
||||
eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
|
||||
{
|
||||
const void *data = NULL;
|
||||
int size = 0;
|
||||
Eet_File_Node *efn;
|
||||
const char *data = NULL;
|
||||
int size = 0;
|
||||
|
||||
if (size_ret)
|
||||
*size_ret = 0;
|
||||
|
@ -1732,13 +1755,42 @@ eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
|
|||
/* get size (uncompressed, if compressed at all) */
|
||||
size = efn->data_size;
|
||||
|
||||
/* uncompressed data */
|
||||
if (efn->compression == 0
|
||||
&& efn->ciphered == 0)
|
||||
data = efn->data ? efn->data : ef->data + efn->offset;
|
||||
/* compressed data */
|
||||
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
|
||||
data = NULL;
|
||||
/* uncompressed data */
|
||||
if (efn->compression == 0
|
||||
&& efn->ciphered == 0)
|
||||
data = efn->data ? efn->data : ef->data + efn->offset;
|
||||
/* compressed data */
|
||||
else
|
||||
data = NULL;
|
||||
|
||||
/* fill in return values */
|
||||
if (size_ret)
|
||||
|
@ -1753,6 +1805,150 @@ eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
|
|||
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
|
||||
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)
|
||||
{
|
||||
free(data2);
|
||||
return 0;
|
||||
goto on_error;
|
||||
}
|
||||
/* record compressed chunk size */
|
||||
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)))
|
||||
{
|
||||
free(efn->data);
|
||||
efn->alias = 0;
|
||||
efn->ciphered = cipher_key ? 1 : 0;
|
||||
efn->compression = !!comp;
|
||||
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];
|
||||
ef->header->directory->nodes[hash] = efn;
|
||||
efn->offset = -1;
|
||||
efn->alias = 0;
|
||||
efn->ciphered = cipher_key ? 1 : 0;
|
||||
efn->compression = !!comp;
|
||||
efn->size = data_size;
|
||||
|
|
|
@ -364,7 +364,7 @@ _eet_build_ex_descriptor(Eet_Data_Descriptor *edd)
|
|||
static Eet_Test_Ex_Type*
|
||||
_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) return NULL;
|
||||
|
@ -671,6 +671,8 @@ START_TEST(eet_file_simple_write)
|
|||
fail_if(!ef);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -689,8 +691,14 @@ START_TEST(eet_file_simple_write)
|
|||
|
||||
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_num_entries(ef) != 1);
|
||||
fail_if(eet_num_entries(ef) != 3);
|
||||
|
||||
eet_close(ef);
|
||||
|
||||
|
@ -1324,7 +1332,7 @@ static int pass_get(char *pass, int size, __UNUSED__ int rwflags, __UNUSED__ voi
|
|||
{
|
||||
memset(pass, 0, size);
|
||||
|
||||
if (strlen("password") > size)
|
||||
if ((int) strlen("password") > size)
|
||||
return 0;
|
||||
snprintf(pass, size, "%s", "password");
|
||||
return strlen(pass);
|
||||
|
@ -1334,7 +1342,7 @@ static int badpass_get(char *pass, int size, __UNUSED__ int rwflags, __UNUSED__
|
|||
{
|
||||
memset(pass, 0, size);
|
||||
|
||||
if (strlen("bad password") > size)
|
||||
if ((int) strlen("bad password") > size)
|
||||
return 0;
|
||||
snprintf(pass, size, "%s", "bad password");
|
||||
return strlen(pass);
|
||||
|
|
Loading…
Reference in New Issue