cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=297ea39a5cd11d1b0697ded2f46412ecddba63b7

commit 297ea39a5cd11d1b0697ded2f46412ecddba63b7
Author: Shilpa Singh <shilpa.si...@samsung.com>
Date:   Tue Nov 3 14:01:51 2015 -0800

    eina: add eina_tmpstr_manage_new, eina_tmpstr_manage_new_length APIs
    
    Summary:
    Add eina_tmpstr_manage_new, eina_tmpstr_manage_new_length APIs, these APIs 
create new tmpstr but reuse the input string memory.
    
    @feature
    
    Test Plan: Test case and example updated
    
    Reviewers: tasn, cedric
    
    Reviewed By: cedric
    
    Differential Revision: https://phab.enlightenment.org/D3178
    
    Signed-off-by: Cedric BAIL <ced...@osg.samsung.com>
---
 src/examples/eina/eina_tmpstr_01.c | 14 +++++++-
 src/lib/eina/eina_tmpstr.c         | 35 ++++++++++++++++++--
 src/lib/eina/eina_tmpstr.h         | 32 ++++++++++++++++++
 src/tests/eina/eina_test_tmpstr.c  | 67 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 145 insertions(+), 3 deletions(-)

diff --git a/src/examples/eina/eina_tmpstr_01.c 
b/src/examples/eina/eina_tmpstr_01.c
index 36d8c62..68158ca 100644
--- a/src/examples/eina/eina_tmpstr_01.c
+++ b/src/examples/eina/eina_tmpstr_01.c
@@ -8,6 +8,9 @@ int
 main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
 {
    const char *str;
+   char *str2;
+   const char *str3;
+   int len;
    const char *prologe = "The Cylons were created by man. They rebelled. They "
                          "evolved.";
 
@@ -15,9 +18,18 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
 
    str = eina_tmpstr_add_length(prologe, 31);
    printf("%s\n", str);
-   printf("length: %d\n", eina_tmpstr_len(str));
+   len = eina_tmpstr_len(str);
+   printf("length: %d\n", len);
    eina_tmpstr_del(str);
 
+   str2 = (char *)calloc(61, sizeof(char));
+   strcpy(str2, prologe);
+   str3 = eina_tmpstr_manage_new(str2);
+   printf("%s\n", str3);
+   len = eina_tmpstr_len(str3);
+   printf("length: %d\n", len);
+   eina_tmpstr_del(str3);
+
    eina_shutdown();
 
    return 0;
diff --git a/src/lib/eina/eina_tmpstr.c b/src/lib/eina/eina_tmpstr.c
index 43824b7..c7d26ee 100644
--- a/src/lib/eina/eina_tmpstr.c
+++ b/src/lib/eina/eina_tmpstr.c
@@ -47,6 +47,7 @@ struct _Str
    size_t length;
    Str *next;
    char *str;
+   Eina_Bool ma : 1;
 };
 
 static Eina_Lock _mutex;
@@ -78,6 +79,7 @@ eina_tmpstr_add_length(const char *str, size_t length)
    s->str = ((char *)s) + sizeof(Str);
    strncpy(s->str, str, length);
    s->str[length] = '\0';
+   s->ma = EINA_FALSE;
    eina_lock_take(&_mutex);
    s->next = strs;
    strs = s;
@@ -86,10 +88,38 @@ eina_tmpstr_add_length(const char *str, size_t length)
 }
 
 EAPI Eina_Tmpstr *
+eina_tmpstr_manage_new_length(char *str, size_t length)
+{
+   Str *s;
+
+   if (!str || !length) return NULL;
+   s = calloc(1, sizeof(Str));
+   if (!s) return NULL;
+   s->length = length;
+   s->str = str;
+   s->ma = EINA_TRUE;
+   eina_lock_take(&_mutex);
+   s->next = strs;
+   strs = s;
+   eina_lock_release(&_mutex);
+   return s->str;
+}
+
+EAPI Eina_Tmpstr *
+eina_tmpstr_manage_new(char *str)
+{
+   size_t len;
+
+   if (!str) return NULL;
+   len = strlen(str);
+   return eina_tmpstr_manage_new_length(str, len);
+}
+
+EAPI Eina_Tmpstr *
 eina_tmpstr_add(const char *str)
 {
    size_t len;
-   
+
    if (!str) return NULL;
    len = strlen(str);
    return eina_tmpstr_add_length(str, len);
@@ -99,7 +129,7 @@ EAPI void
 eina_tmpstr_del(Eina_Tmpstr *tmpstr)
 {
    Str *s, *sp;
-   
+
    if ((!strs) || (!tmpstr)) return;
    eina_lock_take(&_mutex);
    for (sp = NULL, s = strs; s; sp = s, s = s->next)
@@ -108,6 +138,7 @@ eina_tmpstr_del(Eina_Tmpstr *tmpstr)
           {
              if (sp) sp->next = s->next;
              else strs = s->next;
+             if (s->ma) free(s->str);
              free(s);
              break;
           }
diff --git a/src/lib/eina/eina_tmpstr.h b/src/lib/eina/eina_tmpstr.h
index e516cfd..151fcd1 100644
--- a/src/lib/eina/eina_tmpstr.h
+++ b/src/lib/eina/eina_tmpstr.h
@@ -238,6 +238,38 @@ EAPI size_t eina_tmpstr_len(Eina_Tmpstr *tmpstr);
 EAPI void eina_tmpstr_del(Eina_Tmpstr *tmpstr) EINA_ARG_NONNULL(1);
 
 /**
+ * @brief Add a new temporary string using the passed string. The passed
+ * string is used directly as the buffer. The passed string must be malloced.
+ *
+ * @param str the input string to manage.
+ * @return A pointer to the tmp string that is a standard C string.
+ *
+ * This function creates a new temporary string. On error, @c NULL is
+ * returned. To free the resources, use eina_tmpstr_del().
+ *
+ * @see eina_tmpstr_del()
+ * @since 1.17.0
+ */
+EAPI Eina_Tmpstr *eina_tmpstr_manage_new(char *str) EINA_WARN_UNUSED_RESULT;
+
+/**
+ * @brief Add a new temporary string using the passed string. The passed
+ * string is used directly as the buffer. The passed string must be malloced.
+ *
+ * @param str the input string to manage.
+ * @param length the length of the string.
+ * @return A pointer to the tmp string that is a standard C string.
+ *
+ * This function creates a new temporary string. On error, @c NULL is
+ * returned. To free the resources, use eina_tmpstr_del().
+ *
+ * @see eina_tmpstr_manage_new()
+ * @see eina_tmpstr_del()
+ * @since 1.17.0
+ */
+EAPI Eina_Tmpstr *eina_tmpstr_manage_new_length(char *str, size_t length);
+
+/**
  * @}
  */
 
diff --git a/src/tests/eina/eina_test_tmpstr.c 
b/src/tests/eina/eina_test_tmpstr.c
index 72fb7c8..4959dd3 100644
--- a/src/tests/eina/eina_test_tmpstr.c
+++ b/src/tests/eina/eina_test_tmpstr.c
@@ -60,6 +60,70 @@ START_TEST(tmpstr_simple)
 }
 END_TEST
 
+START_TEST(tmpstr_simple_len)
+{
+   eina_init();
+
+   const int cnt_tmp_strings = 10;
+   const int max_str_len = 255;
+   char buf[max_str_len + 1];
+   Eina_Tmpstr *tmp_strings[cnt_tmp_strings];
+
+   // Add several tmp strings
+   for (int i = 0; i != cnt_tmp_strings; ++i)
+     {
+        snprintf(buf, max_str_len, "Tmp string %d", (i + 1));
+        tmp_strings[i] = eina_tmpstr_add_length(buf, (max_str_len + 1));
+
+        fail_if(strcmp(buf, tmp_strings[i]));
+     }
+
+   // Delete these tmp strings
+   for (int i = 0; i != cnt_tmp_strings; ++i)
+     {
+        snprintf(buf, max_str_len, "Tmp string %d", (cnt_tmp_strings - i - 1 + 
1));
+
+        fail_if(strcmp(buf, tmp_strings[cnt_tmp_strings - i - 1]));
+
+        eina_tmpstr_del(tmp_strings[cnt_tmp_strings - i - 1]);
+        tmp_strings[cnt_tmp_strings - i - 1] = 0;
+     }
+
+   // Delete non tmp string (should do nothing)
+   eina_tmpstr_del("Some non tmp string");
+
+   eina_shutdown();
+}
+END_TEST
+
+START_TEST(tmpstr_manage)
+{
+   eina_init();
+
+   char *buf = malloc(7);
+   strcpy(buf, "tmpstr");
+   Eina_Tmpstr *tstr1 = eina_tmpstr_manage_new(buf);
+   fail_if(strcmp(buf, tstr1));
+   eina_tmpstr_del(tstr1);
+
+   eina_shutdown();
+}
+END_TEST
+
+START_TEST(tmpstr_manage_len)
+{
+   eina_init();
+
+   char *buf = malloc(10);
+   strcpy(buf, "tmpstr");
+   Eina_Tmpstr *tstr1 = eina_tmpstr_manage_new_length(buf, 7);
+   fail_if(strcmp(buf, tstr1));
+   eina_tmpstr_del(tstr1);
+
+   eina_shutdown();
+}
+END_TEST
+
 START_TEST(tmpstr_len)
 {
    eina_init();
@@ -86,5 +150,8 @@ void
 eina_test_tmpstr(TCase *tc)
 {
    tcase_add_test(tc, tmpstr_simple);
+   tcase_add_test(tc, tmpstr_simple_len);
+   tcase_add_test(tc, tmpstr_manage);
+   tcase_add_test(tc, tmpstr_manage_len);
    tcase_add_test(tc, tmpstr_len);
 }

-- 


Reply via email to