eina_strbuf: introduce change last occurrence function

Reviewers: cedric, woohyun, bowonryu

Reviewed By: cedric

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Maniphest Tasks: T8757

Differential Revision: https://phab.enlightenment.org/D11990
This commit is contained in:
Ali Alzyod 2020-06-22 17:31:54 +09:00 committed by WooHyun Jung
parent fd24fb568e
commit c501d09c3a
3 changed files with 73 additions and 1 deletions

View File

@ -608,6 +608,19 @@ EAPI Eina_Bool eina_strbuf_replace(Eina_Strbuf *buf, const char *str, const char
*/
#define eina_strbuf_replace_first(buf, str, with) eina_strbuf_replace(buf, str, with, 1)
/**
* @brief Replaces the last occurrence of a substring with another string.
*
* @param[in,out] buf The string buffer.
* @param[in] str The text to match.
* @param[in] with The replacement string.
* @return #EINA_TRUE on success, #EINA_FALSE on failure.
*
* This function replaces the last occurrence of @p str in @p buf with
* @p with.
*/
EAPI Eina_Bool eina_strbuf_replace_last(Eina_Strbuf *buf, const char *str, const char *with) EINA_ARG_NONNULL(1, 2, 3);
/**
* @brief Replaces all matching substrings with another string.
*

View File

@ -980,6 +980,61 @@ eina_strbuf_replace(Eina_Strbuf *buf,
return EINA_TRUE;
}
EAPI Eina_Bool
eina_strbuf_replace_last(Eina_Strbuf *buf,
const char *str,
const char *with)
{
size_t len1, len2;
char *spos, *spos_next;
size_t pos;
EINA_SAFETY_ON_NULL_RETURN_VAL( str, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(with, EINA_FALSE);
EINA_MAGIC_CHECK_STRBUF(buf, 0);
spos = NULL;
spos_next = strstr(buf->buf, str);
while (spos_next && *spos_next)
{
spos = spos_next;
spos_next = strstr(spos + 1, str);
}
if (!spos) return EINA_FALSE;
pos = spos - (const char *)buf->buf;
len1 = strlen(str);
len2 = strlen(with);
/* This is a read only buffer which need change to be made */
if (buf->ro)
{
char *dest;
dest = malloc(buf->size);
if (!dest) return 0;
memcpy(dest, buf->buf, buf->len);
buf->buf = dest;
}
if (len1 != len2)
{
/* resize the buffer if necessary */
if (EINA_UNLIKELY(!_eina_strbuf_common_grow(_STRBUF_CSIZE, buf,
buf->len - len1 + len2)))
return EINA_FALSE; /* move the existing text */
memmove(((unsigned char *)(buf->buf)) + pos + len2,
((unsigned char *)(buf->buf)) + pos + len1,
buf->len - pos - len1);
}
/* and now insert the given string */
memcpy(((unsigned char *)(buf->buf)) + pos, with, len2);
buf->len += len2 - len1;
memset(((unsigned char *)(buf->buf)) + buf->len, 0, 1);
return EINA_TRUE;
}
EAPI int
eina_strbuf_replace_all(Eina_Strbuf *buf, const char *str, const char *with)
{

View File

@ -303,8 +303,12 @@ EFL_START_TEST(eina_test_strbuf_replace)
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "baaaab"));
fail_if(eina_strbuf_replace_last(buf, "a", "x") == 0);
fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
fail_if(strcmp(eina_strbuf_string_get(buf), "baaaxb"));
fail_if(eina_strbuf_replace_first(buf, "a", "b") == 0);
fail_if(strcmp(eina_strbuf_string_get(buf), "bbaaab"));
fail_if(strcmp(eina_strbuf_string_get(buf), "bbaaxb"));
eina_strbuf_free(buf);