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 <cedric@osg.samsung.com>
This commit is contained in:
Shilpa Singh 2015-11-03 14:01:51 -08:00 committed by Cedric BAIL
parent e45b801577
commit 297ea39a5c
4 changed files with 145 additions and 3 deletions

View File

@ -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;

View File

@ -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;
@ -85,11 +87,39 @@ eina_tmpstr_add_length(const char *str, size_t length)
return s->str;
}
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;
}

View File

@ -237,6 +237,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);
/**
* @}
*/

View File

@ -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);
}