add ecore_strlcat for symmetry

add ecore_strbuf, an auto-expanding string buffer for building long strings whose length isn't easily determinable beforehand. for now just supports append.


SVN revision: 28379
This commit is contained in:
rephorm 2007-02-16 23:49:55 +00:00 committed by rephorm
parent d6dff9cb77
commit b8df6783e3
4 changed files with 165 additions and 0 deletions

View File

@ -60,6 +60,9 @@ extern "C" {
typedef struct _ecore_list_node Ecore_List_Node;
# define ECORE_LIST_NODE(node) ((Ecore_List_Node *)node)
typedef struct _ecore_strbuf Ecore_Strbuf;
# define ECORE_STRBUF(buf) ((Ecore_Strbuf *)buf)
struct _ecore_list_node {
void *data;
@ -476,6 +479,14 @@ extern "C" {
/* Add a function to free the data stored in nodes */
EAPI int ecore_tree_set_free_cb(Ecore_Tree * tree, Ecore_Free_Cb free_func);
Ecore_Strbuf * ecore_strbuf_new(void);
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);
const char * ecore_strbuf_string_get(Ecore_Strbuf *buf);
#ifdef __cplusplus
}
#endif

View File

@ -25,6 +25,7 @@ ecore_plugin.c \
ecore_sheap.c \
ecore_signal.c \
ecore_str.c \
ecore_strbuf.c \
ecore_strings.c \
ecore_time.c \
ecore_timer.c \

View File

@ -60,6 +60,42 @@ ecore_strlcpy(char *dst, const char *src, size_t siz)
#endif
}
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}
int
ecore_str_has_prefix(const char *str, const char *prefix)
{

View File

@ -0,0 +1,117 @@
#include "ecore_private.h"
#include "Ecore.h"
#include "Ecore_Data.h"
#include "Ecore_Str.h"
#define ECORE_STRBUF_INIT_SIZE 32
#define ECORE_STRBUF_INIT_STEP 32
#define ECORE_STRBUF_MAX_STEP 4096
struct _ecore_strbuf
{
char *buf;
int len;
int size;
int step;
};
/**
* Create a new string buffer
*/
Ecore_Strbuf *
ecore_strbuf_new(void)
{
Ecore_Strbuf *buf;
buf = malloc(sizeof(Ecore_Strbuf));
if (!buf) return NULL;
buf->len = 0;
buf->size = ECORE_STRBUF_INIT_SIZE;
buf->step = ECORE_STRBUF_INIT_STEP;
buf->buf = malloc(buf->size);
buf->buf[0] = '\0';
return buf;
}
/**
* Free a string buffer
* @param buf the buffer to free
*/
void
ecore_strbuf_free(Ecore_Strbuf *buf)
{
CHECK_PARAM_POINTER("buf", buf);
free(buf->buf);
free(buf);
}
/**
* Append a string to a buffer, reallocating as necessary.
* @param buf the Ecore_Strbuf to append to
* @param str the string to append
*/
void
ecore_strbuf_append(Ecore_Strbuf *buf, const char *str)
{
CHECK_PARAM_POINTER("buf", buf);
CHECK_PARAM_POINTER("str", str);
int l;
int off = 0;
l = ecore_strlcpy(buf->buf + buf->len, str, buf->size - buf->len);
while (l > buf->size - buf->len)
{
/* we successfully appended this much */
off += buf->size - buf->len - 1;
buf->len = buf->size - 1;
buf->size += buf->step;
if (buf->step < ECORE_STRBUF_MAX_STEP)
buf->step *= 2;
buf->buf = realloc(buf->buf, buf->size);
*(buf->buf + buf->len) = '\0';
l = ecore_strlcpy(buf->buf + buf->len, str + off, buf->size - buf->len);
}
buf->len += l;
}
/**
* Append a character to a string buffer, reallocating as necessary.
* @param buf the Ecore_Strbuf to append to
* @param c the char to append
*/
void
ecore_strbuf_append_char(Ecore_Strbuf *buf, char c)
{
CHECK_PARAM_POINTER("buf", buf);
if (buf->len >= buf->size - 1)
{
buf->size += buf->step;
if (buf->step < ECORE_STRBUF_MAX_STEP)
buf->step *= 2;
buf->buf = realloc(buf->buf, buf->size);
}
buf->buf[(buf->len)++] = c;
buf->buf[buf->len] = '\0';
}
/**
* Retrieve a pointer to the contents of a string buffer
* @param buf the buffer
*
* This pointer must not be modified, and will no longer be valid if
* the Ecore_Strbuf is modified.
*/
const char *
ecore_strbuf_string_get(Ecore_Strbuf *buf)
{
CHECK_PARAM_POINTER_RETURN("buf", buf, NULL);
return buf->buf;
}