Instanciation of strings returned by mkpath... 93/16693/1 accepted/tizen/generic accepted/tizen/ivi accepted/tizen_generic accepted/tizen_ivi_panda accepted/tizen_ivi_release tizen_ivi_release accepted/tizen/generic/20140221.153759 accepted/tizen/generic/20140312.094848 accepted/tizen/ivi/20140221.200115 accepted/tizen/ivi/panda/20140312.112152 accepted/tizen/ivi/release/20140312.105532 accepted/tizen/mobile/20140227.071800 submit/tizen/20140221.153548 submit/tizen/20140312.070646 submit/tizen_ivi_release/20140312.071122
authorJosé Bollo <jose.bollo@open.eurogiciel.org>
Fri, 21 Feb 2014 14:57:26 +0000 (15:57 +0100)
committerJosé Bollo <jose.bollo@open.eurogiciel.org>
Fri, 21 Feb 2014 15:08:46 +0000 (16:08 +0100)
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 <jose.bollo@open.eurogiciel.org>
src/scratch.c
src/tzplatform_config.h

index dc3c918..c5816f8 100644 (file)
@@ -28,6 +28,7 @@
 #endif
 
 #include <stdlib.h>
+#include <memory.h>
 
 #ifndef INITIAL_SCRATCH_CAPACITY
 #define INITIAL_SCRATCH_CAPACITY  240
 #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 <pthread.h>
 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 <stdio.h>
 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
index 2ee948d..490970a 100644 (file)
@@ -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.