forked from enlightenment/efl
- add ecore_strbuf_replace() and ecore_strbuf_replace_all()
- some formating and minor things SVN revision: 28573
This commit is contained in:
parent
c972ad1f83
commit
d879ceda5c
|
@ -483,14 +483,21 @@ extern "C" {
|
|||
EAPI int ecore_tree_set_free_cb(Ecore_Tree * tree, Ecore_Free_Cb free_func);
|
||||
|
||||
|
||||
Ecore_Strbuf * ecore_strbuf_new(void);
|
||||
void ecore_strbuf_free(Ecore_Strbuf *buf);
|
||||
void ecore_strbuf_append(Ecore_Strbuf *buf, const char *str);
|
||||
void ecore_strbuf_append_char(Ecore_Strbuf *buf, char c);
|
||||
void ecore_strbuf_insert(Ecore_Strbuf *buf, const char *str, size_t pos);
|
||||
#define ecore_strbuf_prepend(buf, str) ecore_strbuf_insert(buf, str, 0)
|
||||
const char * ecore_strbuf_string_get(Ecore_Strbuf *buf);
|
||||
size_t ecore_strbuf_length_get(Ecore_Strbuf *buf);
|
||||
EAPI Ecore_Strbuf * ecore_strbuf_new(void);
|
||||
EAPI void ecore_strbuf_free(Ecore_Strbuf *buf);
|
||||
EAPI void ecore_strbuf_append(Ecore_Strbuf *buf, const char *str);
|
||||
EAPI void ecore_strbuf_append_char(Ecore_Strbuf *buf, char c);
|
||||
EAPI void ecore_strbuf_insert(Ecore_Strbuf *buf, const char *str,
|
||||
size_t pos);
|
||||
# define ecore_strbuf_prepend(buf, str) ecore_strbuf_insert(buf, str, 0)
|
||||
EAPI const char * ecore_strbuf_string_get(Ecore_Strbuf *buf);
|
||||
EAPI size_t ecore_strbuf_length_get(Ecore_Strbuf *buf);
|
||||
EAPI int ecore_strbuf_replace(Ecore_Strbuf *buf, const char *str,
|
||||
const char *with, unsigned int n);
|
||||
# define ecore_strbuf_replace_first(buf, str, with) \
|
||||
ecore_strbuf_replace(buf, str, with, 1)
|
||||
EAPI int ecore_strbuf_replace_all(Ecore_Strbuf *buf, const char *str,
|
||||
const char *with);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -15,10 +15,12 @@ struct _ecore_strbuf
|
|||
size_t step;
|
||||
};
|
||||
|
||||
static int _ecore_strbuf_resize(Ecore_Strbuf *buf, size_t size);
|
||||
|
||||
/**
|
||||
* Create a new string buffer
|
||||
*/
|
||||
Ecore_Strbuf *
|
||||
EAPI Ecore_Strbuf *
|
||||
ecore_strbuf_new(void)
|
||||
{
|
||||
Ecore_Strbuf *buf;
|
||||
|
@ -40,7 +42,7 @@ ecore_strbuf_new(void)
|
|||
* Free a string buffer
|
||||
* @param buf the buffer to free
|
||||
*/
|
||||
void
|
||||
EAPI void
|
||||
ecore_strbuf_free(Ecore_Strbuf *buf)
|
||||
{
|
||||
CHECK_PARAM_POINTER("buf", buf);
|
||||
|
@ -53,7 +55,7 @@ ecore_strbuf_free(Ecore_Strbuf *buf)
|
|||
* @param buf the Ecore_Strbuf to append to
|
||||
* @param str the string to append
|
||||
*/
|
||||
void
|
||||
EAPI void
|
||||
ecore_strbuf_append(Ecore_Strbuf *buf, const char *str)
|
||||
{
|
||||
size_t l;
|
||||
|
@ -80,18 +82,16 @@ ecore_strbuf_append(Ecore_Strbuf *buf, const char *str)
|
|||
buf->len += l;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insert a string to a buffer, reallocating as necessary.
|
||||
* @param buf the Ecore_Strbuf to insert
|
||||
* @param str the string to insert
|
||||
* @param pos the position to insert the string
|
||||
*/
|
||||
void
|
||||
EAPI void
|
||||
ecore_strbuf_insert(Ecore_Strbuf *buf, const char *str, size_t pos)
|
||||
{
|
||||
size_t len;
|
||||
size_t new_size;
|
||||
|
||||
CHECK_PARAM_POINTER("buf", buf);
|
||||
CHECK_PARAM_POINTER("str", str);
|
||||
|
@ -106,23 +106,12 @@ ecore_strbuf_insert(Ecore_Strbuf *buf, const char *str, size_t pos)
|
|||
* resize the buffer if necessary
|
||||
*/
|
||||
len = strlen(str);
|
||||
new_size = buf->size;
|
||||
while (len + buf->len > new_size)
|
||||
{
|
||||
new_size += buf->step;
|
||||
if (buf->step < ECORE_STRBUF_MAX_STEP)
|
||||
buf->step *= 2;
|
||||
}
|
||||
|
||||
if (new_size != buf->size)
|
||||
{
|
||||
buf->size = new_size;
|
||||
buf->buf = realloc(buf->buf, buf->size);
|
||||
}
|
||||
if (!_ecore_strbuf_resize(buf, buf->len + len))
|
||||
return;
|
||||
/* move the existing text */
|
||||
memmove(buf->buf + len + pos, buf->buf + pos, buf->len - pos);
|
||||
/* and now insert the given string */
|
||||
strncpy(buf->buf + pos, str, len);
|
||||
memcpy(buf->buf + pos, str, len);
|
||||
buf->len += len;
|
||||
buf->buf[buf->len] = 0;
|
||||
}
|
||||
|
@ -132,7 +121,7 @@ ecore_strbuf_insert(Ecore_Strbuf *buf, const char *str, size_t pos)
|
|||
* @param buf the Ecore_Strbuf to append to
|
||||
* @param c the char to append
|
||||
*/
|
||||
void
|
||||
EAPI void
|
||||
ecore_strbuf_append_char(Ecore_Strbuf *buf, char c)
|
||||
{
|
||||
CHECK_PARAM_POINTER("buf", buf);
|
||||
|
@ -155,7 +144,7 @@ ecore_strbuf_append_char(Ecore_Strbuf *buf, char c)
|
|||
* This pointer must not be modified, and will no longer be valid if
|
||||
* the Ecore_Strbuf is modified.
|
||||
*/
|
||||
const char *
|
||||
EAPI const char *
|
||||
ecore_strbuf_string_get(Ecore_Strbuf *buf)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("buf", buf, NULL);
|
||||
|
@ -166,10 +155,206 @@ ecore_strbuf_string_get(Ecore_Strbuf *buf)
|
|||
* Retrieve the length of the string buffer content
|
||||
* @param buf the buffer
|
||||
*/
|
||||
size_t
|
||||
EAPI size_t
|
||||
ecore_strbuf_length_get(Ecore_Strbuf *buf)
|
||||
{
|
||||
CHECK_PARAM_POINTER_RETURN("buf", buf, 0);
|
||||
return buf->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the n-th string with an other string.
|
||||
* @param buf the Ecore_Strbuf to work with
|
||||
* @param str the string to replace
|
||||
* @param with the replaceing string
|
||||
* @param n the number of the fitting string
|
||||
*
|
||||
* @return true on success
|
||||
*/
|
||||
EAPI int
|
||||
ecore_strbuf_replace(Ecore_Strbuf *buf, const char *str, const char *with,
|
||||
unsigned int n)
|
||||
{
|
||||
size_t len1, len2;
|
||||
char *spos;
|
||||
size_t pos;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("buf", buf, 0);
|
||||
CHECK_PARAM_POINTER_RETURN("str", str, 0);
|
||||
CHECK_PARAM_POINTER_RETURN("with", with, 0);
|
||||
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
spos = buf->buf;
|
||||
while (n--)
|
||||
{
|
||||
spos = strstr(spos, str);
|
||||
if (!spos || *spos == '\0')
|
||||
return 0;
|
||||
if (n) spos++;
|
||||
}
|
||||
|
||||
pos = spos - buf->buf;
|
||||
len1 = strlen(str);
|
||||
len2 = strlen(with);
|
||||
if (len1 != len2)
|
||||
{
|
||||
/* resize the buffer if necessary */
|
||||
if (!_ecore_strbuf_resize(buf, buf->len - len1 + len2))
|
||||
return 0;
|
||||
/* move the existing text */
|
||||
memmove(buf->buf + pos + len2, buf->buf + pos + len1,
|
||||
buf->len - pos - len1);
|
||||
}
|
||||
/* and now insert the given string */
|
||||
memcpy(buf->buf + pos, with, len2);
|
||||
buf->len += len2 - len1;
|
||||
buf->buf[buf->len] = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all strings with an other string.
|
||||
* @param buf the Ecore_Strbuf to work with
|
||||
* @param str the string to replace
|
||||
* @param with the replaceing string
|
||||
*
|
||||
* @return how often the string was replaced
|
||||
*/
|
||||
EAPI int
|
||||
ecore_strbuf_replace_all(Ecore_Strbuf *buf, const char *str, const char *with)
|
||||
{
|
||||
size_t len1, len2, len;
|
||||
char *tmp_buf = NULL;
|
||||
char *spos;
|
||||
size_t pos, start;
|
||||
size_t pos_tmp, start_tmp;
|
||||
int n = 0;
|
||||
|
||||
CHECK_PARAM_POINTER_RETURN("buf", buf, 0);
|
||||
CHECK_PARAM_POINTER_RETURN("str", str, 0);
|
||||
CHECK_PARAM_POINTER_RETURN("with", with, 0);
|
||||
|
||||
spos = strstr(buf->buf, str);
|
||||
if (!spos || *spos == '\0')
|
||||
return 0;
|
||||
|
||||
len1 = strlen(str);
|
||||
len2 = strlen(with);
|
||||
|
||||
/* if the size of the two string is equal, it is fairly easy to replace them
|
||||
* we don't need to resize the buffer or doing other calculations */
|
||||
if (len1 == len2)
|
||||
{
|
||||
while (spos)
|
||||
{
|
||||
memcpy(spos, with, len2);
|
||||
spos = strstr(spos + len2, str);
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
pos = pos_tmp = spos - buf->buf;
|
||||
tmp_buf = buf->buf;
|
||||
buf->buf = malloc(buf->size);
|
||||
if (!buf->buf)
|
||||
{
|
||||
buf->buf = tmp_buf;
|
||||
return 0;
|
||||
}
|
||||
start = start_tmp = 0;
|
||||
len = buf->len;
|
||||
|
||||
while (spos)
|
||||
{
|
||||
n++;
|
||||
len = (len + len2) - len1;
|
||||
/* resize the buffer if necessary */
|
||||
if (!_ecore_strbuf_resize(buf, len))
|
||||
{
|
||||
/* we have to stop replacing here, because we haven't enough
|
||||
* memory to go on */
|
||||
len = (len + len1) - len2;
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy the untouched text */
|
||||
memcpy(buf->buf + start, tmp_buf + start_tmp, pos - start);
|
||||
/* copy the new string */
|
||||
memcpy(buf->buf + pos, with, len2);
|
||||
|
||||
/* calculate the next positions */
|
||||
start_tmp = pos_tmp + len1;
|
||||
start = pos + len2;
|
||||
spos = strstr(tmp_buf + start_tmp, str);
|
||||
/* this calculations don't make sense if spos == NULL, but the
|
||||
* calculated values won't be used, because the loop will stop
|
||||
* then */
|
||||
pos_tmp = spos - tmp_buf;
|
||||
pos = start + pos_tmp - start_tmp;
|
||||
}
|
||||
/* and now copy the rest of the text */
|
||||
memcpy(buf->buf + start, tmp_buf + start_tmp, len - start);
|
||||
buf->len = len;
|
||||
buf->buf[buf->len] = 0;
|
||||
|
||||
free(tmp_buf);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* resize the buffer
|
||||
* @param buf the buffer to resize
|
||||
* @param size the minimum size of the buffer
|
||||
*/
|
||||
static int
|
||||
_ecore_strbuf_resize(Ecore_Strbuf *buf, size_t size)
|
||||
{
|
||||
char *buffer;
|
||||
size_t new_size;
|
||||
size_t new_step;
|
||||
|
||||
new_size = buf->size;
|
||||
new_step = buf->step;
|
||||
|
||||
/*
|
||||
* first we have to determine the new buffer size
|
||||
*/
|
||||
if (size == buf->size)
|
||||
/* nothing to do */
|
||||
return 1;
|
||||
else if (size > buf->size)
|
||||
{
|
||||
/* enlarge the buffer */
|
||||
while (size > new_size)
|
||||
{
|
||||
new_size += new_step;
|
||||
if (new_step < ECORE_STRBUF_MAX_STEP)
|
||||
new_step *= 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* shrink the buffer */
|
||||
/*
|
||||
* to be done
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* reallocate the buffer to the new size */
|
||||
buffer = realloc(buf->buf, new_size);
|
||||
if (!buffer)
|
||||
return 0;
|
||||
|
||||
buf->buf = buffer;
|
||||
buf->size = new_size;
|
||||
buf->step = new_step;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue