forked from enlightenment/efl
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:
parent
d6dff9cb77
commit
b8df6783e3
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue