From ddda0a79a93d4fae22b39467b0d095267f5ea66b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Fri, 21 Feb 2014 15:57:26 +0100 Subject: [PATCH] Instanciation of strings returned by mkpath... MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit To facilitate the life of programmers, the functions tzplatform_mkstr, tzplatform_mkpath, tzplatform_mkpath3, tzplatform_mkpath4 now return an unique allocated string that MUST NOT be freed. Change-Id: I0981fdac301ea470d92764e7d927f60f39a75089 Signed-off-by: José Bollo --- src/scratch.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++-- src/tzplatform_config.h | 16 +++------- 2 files changed, 86 insertions(+), 14 deletions(-) diff --git a/src/scratch.c b/src/scratch.c index dc3c918..c5816f8 100644 --- a/src/scratch.c +++ b/src/scratch.c @@ -28,6 +28,7 @@ #endif #include +#include #ifndef INITIAL_SCRATCH_CAPACITY #define INITIAL_SCRATCH_CAPACITY 240 @@ -37,6 +38,16 @@ #error "bad value for INITIAL_SCRATCH_CAPACITY" #endif +#define INSTANCIATE 1 +#if INSTANCIATE +#define SET_CAPACITY 97 +#define HASHCODE_INIT 5381 +#define HASHCODE_NEXT(H,C) (((H) << 5) + (H) + (C)) +#ifndef NOT_MULTI_THREAD_SAFE +#define NOT_MULTI_THREAD_SAFE +#endif +#endif + #ifndef NOT_MULTI_THREAD_SAFE #include static pthread_key_t tlskey; @@ -45,6 +56,59 @@ static int key_initialized = 0; static void *global_scratch = NULL; #endif +#if INSTANCIATE +/* structure for recording items in the hash map */ +struct set_item { + struct set_item *next; /* chain to next item */ + size_t hashcode; /* hash of the string */ + size_t length; /* length of the string including null */ +}; + +/* the array of recorded strings */ +static struct set_item *global_path_set[SET_CAPACITY]; /* initialized to zeros */ + +/* instanciate (or retrieve an instance) of the 'string' that +is granted to have the 'length' including terminating null and a +hash code 'hashcode' */ +static const char *instantiate(const char *string, size_t length, size_t hashcode) +{ + struct set_item **pp, *item; + char *result; + + /* get first item in the table */ + pp = &global_path_set[hashcode % SET_CAPACITY]; + result = 0; + do { + /* inspect the item */ + item = *pp; + if (!item) { + /* no item: create it */ + item = malloc(length + sizeof * item); + if (!item) + return NULL; + /* init it */ + item->next = 0; + item->hashcode = hashcode; + item->length = length; + result = (char *)(item + 1); + memcpy(result, string, length); + /* record it */ + *pp = item; + } else if (item->hashcode == hashcode + && item->length == length + && 0 == strcmp(string, (const char *)(item + 1))) { + /* item found */ + result = (char *)(item + 1); + } else { + /* try the next */ + pp = &item->next; + } + } while (!result); + + return result; +} +#endif + /* CAUTION: in a multitheaded context, it is expected that =========== the function scratchcat is call under a mutex. If it is not the case please check for initializing 'tlskey' @@ -57,6 +121,9 @@ const char *scratchcat( int ispath, const char **strings) size_t length, capacity; const char *instr; char c, pc; +#if INSTANCIATE + size_t hashcode = HASHCODE_INIT; +#endif /* get the recorded pointer on scrtch area */ #ifndef NOT_MULTI_THREAD_SAFE @@ -139,19 +206,32 @@ const char *scratchcat( int ispath, const char **strings) /* append the char */ pc = result[length++] = c; +#if INSTANCIATE + hashcode = HASHCODE_NEXT(hashcode, (size_t)c); +#endif } +#if INSTANCIATE + return instantiate(result, length, hashcode); +#else return result; +#endif } #ifdef TEST_SCRATCH #include int main(int argc, const char**argv) { - int ispath; + int ispath, iter, i; argv++; ispath = argv[0] && argv[0][0] == '-' && argv[0][1] == 'p'; - printf("%s\n",scratchcat(ispath,argv+ispath)); + for (i = 0 ; i < 2 ; i++) { + iter = ispath; + while (iter < argc) { + const char *p = scratchcat(ispath,argv+iter++); + printf("%p: %s\n",p,p); + } + } return 0; } #endif diff --git a/src/tzplatform_config.h b/src/tzplatform_config.h index 2ee948d..490970a 100644 --- a/src/tzplatform_config.h +++ b/src/tzplatform_config.h @@ -78,9 +78,7 @@ int tzplatform_getenv_int(enum tzplatform_variable id); Return the string resulting of the concatenation of string value of the tizen plaform variable 'id' and the given string 'str'. - The returned value is a scratch buffer (unique for the thread) that is - available until the next call to 'tzplatform_mkstr', 'tzplatform_mkpath', - 'tzplatform_mkpath3' or 'tzplatform_mkpath4'. + The returned value is an allocated unique string that MUST not be freed. Can return NULL in case of internal error. @@ -100,9 +98,7 @@ const char* tzplatform_mkstr(enum tzplatform_variable id, const char *str); path-concatenation is the concatenation taking care of / characters. - The returned value is a scratch buffer (unique for the thread) that is - available until the next call to 'tzplatform_mkstr', 'tzplatform_mkpath', - 'tzplatform_mkpath3' or 'tzplatform_mkpath4'. + The returned value is an allocated unique string that MUST not be freed. Can return NULL in case of internal error. @@ -122,9 +118,7 @@ const char* tzplatform_mkpath(enum tzplatform_variable id, const char *path); path-concatenation is the concatenation taking care of / characters. - The returned value is a scratch buffer (unique for the thread) that is - available until the next call to 'tzplatform_mkstr', 'tzplatform_mkpath', - 'tzplatform_mkpath3' or 'tzplatform_mkpath4'. + The returned value is an allocated unique string that MUST not be freed. Can return NULL in case of internal error. @@ -145,9 +139,7 @@ const char* tzplatform_mkpath3(enum tzplatform_variable id, const char *path, path-concatenation is the concatenation taking care of / characters. - The returned value is a scratch buffer (unique for the thread) that is - available until the next call to 'tzplatform_mkstr', 'tzplatform_mkpath', - 'tzplatform_mkpath3' or 'tzplatform_mkpath4'. + The returned value is an allocated unique string that MUST not be freed. Can return NULL in case of internal error. -- 2.7.4