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>
 #endif
 
 #include <stdlib.h>
+#include <memory.h>
 
 #ifndef INITIAL_SCRATCH_CAPACITY
 #define INITIAL_SCRATCH_CAPACITY  240
 
 #ifndef INITIAL_SCRATCH_CAPACITY
 #define INITIAL_SCRATCH_CAPACITY  240
 #error "bad value for INITIAL_SCRATCH_CAPACITY"
 #endif
 
 #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;
 #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
 
 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' 
 /* 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;
     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
 
     /* 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;
 
         /* 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;
     return result;
+#endif
 }
 
 
 #ifdef TEST_SCRATCH
 #include <stdio.h>
 int main(int argc, const char**argv) {
 }
 
 
 #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';
     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
     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'.
 
  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.
 
 
  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.
 
 
  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.
 
 
  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.
 
 
  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.
 
 
  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.
 
 
  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.
 
 
  Can return NULL in case of internal error.