Move ecore_str and ecore_strbuf to eina
authorenglebass <englebass@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 27 Jan 2010 20:47:47 +0000 (20:47 +0000)
committerenglebass <englebass@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 27 Jan 2010 20:47:47 +0000 (20:47 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eina@45650 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

configure.ac
src/include/Eina.h
src/include/Makefile.am
src/include/eina_str.h [new file with mode: 0644]
src/include/eina_strbuf.h [new file with mode: 0644]
src/lib/Makefile.am
src/lib/eina_str.c [new file with mode: 0644]
src/lib/eina_strbuf.c [new file with mode: 0644]

index 5209834..75c8a6d 100644 (file)
@@ -339,6 +339,7 @@ AC_SUBST(lt_enable_auto_import)
 
 ### Checks for library functions
 AC_FUNC_ALLOCA
+AC_CHECK_FUNCS(strlcpy)
 
 #dlopen and dladdr
 dlopen_libs=""
index c7b921f..ad1876d 100644 (file)
@@ -180,6 +180,8 @@ extern "C" {
 #include "eina_tiler.h"
 #include "eina_hamster.h"
 #include "eina_matrixsparse.h"
+#include "eina_str.h"
+#include "eina_strbuf.h"
 
 #ifdef __cplusplus
 }
index 568ca0b..d7e4b57 100644 (file)
@@ -41,7 +41,9 @@ eina_cpu.h \
 eina_tiler.h \
 eina_hamster.h \
 eina_matrixsparse.h \
-eina_inline_tiler.x
+eina_inline_tiler.x \
+eina_str.h \
+eina_strbuf.h
 
 installed_mainheaderdir = $(includedir)/eina-@VMAJ@
 dist_installed_mainheader_DATA = Eina.h eina_config.h
diff --git a/src/include/eina_str.h b/src/include/eina_str.h
new file mode 100644 (file)
index 0000000..196c513
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef _EINA_STR_H
+#define _EINA_STR_H
+
+#include <stddef.h>
+#include <string.h>
+
+#include "eina_types.h"
+
+/**
+ * @file eina_str.h
+ * @brief Contains useful C string functions.
+ */
+
+/* strlcpy implementation for libc's lacking it */
+EAPI size_t eina_strlcpy(char *dst, const char *src, size_t siz);
+EAPI size_t eina_strlcat(char *dst, const char *src, size_t siz);
+
+EAPI int eina_str_has_prefix(const char *str, const char *prefix);
+
+EAPI int eina_str_has_suffix(const char *str, const char *suffix);
+EAPI int eina_str_has_extension(const char *str, const char *ext);
+
+EAPI char **eina_str_split(const char *string, const char *delimiter, 
+                            int max_tokens);
+
+EAPI size_t eina_str_join_len(char *dst, size_t size, char sep, const char *a, size_t a_len, const char *b, size_t b_len);
+
+
+/**
+ * Join two strings and store the result in @a dst buffer.
+ *
+ * Similar to eina_str_join_len(), but will compute the length of @a
+ * and @a b using strlen().
+ *
+ * @param dst where to store the result.
+ * @param size byte size of dst, will write at most (size - 1)
+ *     characters and then the '\0' (null terminator).
+ * @param sep separator character to use.
+ * @param a first string to use, before @a sep.
+ * @param b second string to use, after @a sep.
+ *
+ * @return the number of characters printed (not including the
+ *     trailing '\0' used to end output to strings). Just like
+ *     snprintf(), it will not write more than @a size bytes, thus a
+ *     return value of @a size or more means that the output was
+ *     truncated.
+ *
+ * @see eina_str_join_len() and eina_str_join_static()
+ */
+static inline size_t eina_str_join(char *dst, size_t size, char sep, const char *a, const char *b)
+{
+   return eina_str_join_len(dst, size, sep, a, strlen(a), b, strlen(b));
+}
+
+/**
+ * Join two static strings and store the result in static @a dst buffer.
+ *
+ * Similar to eina_str_join_len(), but will assume string sizes are
+ * know using sizeof(X).
+ *
+ * @param dst where to store the result.
+ * @param sep separator character to use.
+ * @param a first string to use, before @a sep.
+ * @param b second string to use, after @a sep.
+ *
+ * @return the number of characters printed (not including the
+ *     trailing '\0' used to end output to strings). Just like
+ *     snprintf(), it will not write more than @a size bytes, thus a
+ *     return value of @a size or more means that the output was
+ *     truncated.
+ *
+ * @see eina_str_join() and eina_str_join_static()
+ */
+#define eina_str_join_static(dst, sep, a, b) eina_str_join_len(dst, sizeof(dst), sep, a, (sizeof(a) > 0) ? sizeof(a) - 1 : 0, b, (sizeof(b) > 0) ? sizeof(b) - 1 : 0)
+
+#endif /* EINA_STR_H */
diff --git a/src/include/eina_strbuf.h b/src/include/eina_strbuf.h
new file mode 100644 (file)
index 0000000..e061e8f
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef EINA_STRBUF_H
+#define EINA_STRBUF_H
+
+#include <stddef.h>
+
+#include "eina_types.h"
+
+typedef struct _Eina_Strbuf Eina_Strbuf;
+
+EAPI Eina_Strbuf *eina_strbuf_new(void);
+EAPI void eina_strbuf_free(Eina_Strbuf *buf);
+EAPI void eina_strbuf_append(Eina_Strbuf *buf, const char *str);
+EAPI void eina_strbuf_append_char(Eina_Strbuf *buf, char c);
+EAPI void eina_strbuf_insert(Eina_Strbuf *buf, const char *str, 
+                              size_t pos);
+#define eina_strbuf_prepend(buf, str) eina_strbuf_insert(buf, str, 0)
+EAPI const char *eina_strbuf_string_get(Eina_Strbuf *buf);
+EAPI size_t eina_strbuf_length_get(Eina_Strbuf *buf);
+EAPI int eina_strbuf_replace(Eina_Strbuf *buf, const char *str, 
+                                 const char *with, unsigned int n);
+#define eina_strbuf_replace_first(buf, str, with) \
+       eina_strbuf_replace(buf, str, with, 1)
+EAPI int eina_strbuf_replace_all(Eina_Strbuf *buf, const char *str,
+                                  const char *with);
+
+#endif /* EINA_STRBUF_H */
index f7370e0..787efd2 100644 (file)
@@ -36,7 +36,9 @@ eina_stringshare.c \
 eina_cpu.c \
 eina_tiler.c \
 eina_hamster.c \
-eina_safety_checks.c
+eina_safety_checks.c \
+eina_str.c \
+eina_strbuf.c
 
 if EINA_STATIC_BUILD_CHAINED_POOL
 base_sources += $(top_srcdir)/src/modules/mp/chained_pool/eina_chained_mempool.c
diff --git a/src/lib/eina_str.c b/src/lib/eina_str.c
new file mode 100644 (file)
index 0000000..332721a
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+/* Leave the OpenBSD version below so we can track upstream fixes */
+/*      $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $        */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+static int eina_str_has_suffix_helper(const char *str, const char *suffix,
+               int (*cmp)(const char *, const char *));
+/**
+ * @param dst the destination
+ * @param src the source
+ * @param siz the size of the destination
+ * @return the length of the source string
+ * @brief copy a c-string
+ *
+ * Copy src to string dst of size siz.  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+eina_strlcpy(char *dst, const char *src, size_t siz)
+{
+#ifdef HAVE_STRLCPY
+   return strlcpy(dst, src, siz);
+#else
+   char *d = dst;
+   const char *s = src;
+   size_t n = siz;
+
+   /* Copy as many bytes as will fit */
+   if (n != 0)
+     {
+       while (--n != 0)
+         {
+            if ((*d++ = *s++) == '\0')
+              break;
+         }
+     }
+
+   /* Not enough room in dst, add NUL and traverse rest of src */
+   if (n == 0)
+     {
+       if (siz != 0)
+         *d = '\0';                /* NUL-terminate dst */
+       while (*s++)
+         ;
+     }
+
+   return(s - src - 1);        /* count does not include NUL */
+#endif
+}
+
+/**
+ * @param dst the destination
+ * @param src the source
+ * @param siz the size of the destination
+ * @return the length of the source string plus MIN(siz, strlen(initial dst))
+ * @brief append a c-string
+ *
+ * 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
+eina_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 */
+}
+
+/**
+ * @param str the string to work with
+ * @param prefix the prefix to check for
+ * @return true if str has the given prefix
+ * @brief checks if the string has the given prefix
+ */
+int
+eina_str_has_prefix(const char *str, const char *prefix)
+{
+   size_t str_len;
+   size_t prefix_len;
+
+   str_len = strlen(str);
+   prefix_len = strlen(prefix);
+   if (prefix_len > str_len)
+     return 0;
+
+   return (strncmp(str, prefix, prefix_len) == 0);
+}
+
+/**
+ * @param str the string to work with
+ * @param suffix the suffix to check for
+ * @return true if str has the given suffix
+ * @brief checks if the string has the given suffix
+ */
+int
+eina_str_has_suffix(const char *str, const char *suffix)
+{
+   return eina_str_has_suffix_helper(str, suffix, strcmp);
+}
+
+/**
+ * This function does the same like eina_str_has_suffix(), but with a
+ * case insensitive compare.
+ *
+ * @param str the string to work with
+ * @param ext the  extension to check for
+ * @return true if str has the given extension
+ * @brief checks if the string has the given extension
+ */
+int
+eina_str_has_extension(const char *str, const char *ext)
+{
+   return eina_str_has_suffix_helper(str, ext, strcasecmp);
+}
+
+/*
+ * Internal helper function used by eina_str_has_suffix() and
+ * eina_str_has_extension()
+ */
+static int
+eina_str_has_suffix_helper(const char *str, const char *suffix,
+               int (*cmp)(const char *, const char *))
+{
+   size_t str_len;
+   size_t suffix_len;
+
+   str_len = strlen(str);
+   suffix_len = strlen(suffix);
+   if (suffix_len > str_len)
+     return 0;
+
+   return cmp(str + str_len - suffix_len, suffix) == 0;
+}
+
+/**
+ * Splits a string into a maximum of max_tokens pieces, using the given
+ * delimiter. If max_tokens is reached, the final string in the returned
+ * string array contains the remainder of string.
+ *
+ * @param str         A string to split.
+ * @param delim       A string which specifies the places at which to split the
+ *                    string. The delimiter is not included in any of the
+ *                    resulting strings, unless max_tokens is reached.
+ * @param max_tokens  The maximum number of strings to split string into.
+ *                    If this is less than 1, the string is split completely.
+ * @return            A newly-allocated NULL-terminated array of strings.
+ *                    To free it: free the first element of the array
+ *                    and the array itself.
+ */
+char **
+eina_str_split(const char *str, const char *delim, int max_tokens)
+{
+   char *s, *sep, **str_array;
+   size_t len, dlen;
+   int i;
+
+   if (*delim == '\0')
+     return NULL;
+
+   max_tokens = ((max_tokens <= 0) ? (INT_MAX) : (max_tokens - 1));
+   len = strlen(str);
+   dlen = strlen(delim);
+   s = strdup(str);
+   str_array = malloc(sizeof(char *) * (len + 1));
+   for (i = 0; (i < max_tokens) && (sep = strstr(s, delim)); i++)
+     {
+       str_array[i] = s;
+       s = sep + dlen;
+       *sep = 0;
+     }
+
+   str_array[i++] = s;
+   str_array = realloc(str_array, sizeof(char *) * (i + 1));
+   str_array[i] = NULL;
+
+   return str_array;
+}
+
+/**
+ * Join two strings of known length and store the result in @a dst buffer.
+ *
+ * @param dst where to store the result.
+ * @param size byte size of dst, will write at most (size - 1)
+ *     characters and then the '\0' (null terminator).
+ * @param sep separator character to use.
+ * @param a first string to use, before @a sep.
+ * @param a_len length of @a a, not including '\0' (strlen()-like)
+ * @param b second string to use, after @a sep.
+ * @param b_len length of @a b, not including '\0' (strlen()-like)
+ *
+ * @return the number of characters printed (not including the
+ *     trailing '\0' used to end output to strings). Just like
+ *     snprintf(), it will not write more than @a size bytes, thus a
+ *     return value of @a size or more means that the output was
+ *     truncated.
+ *
+ * @see eina_str_join() and eina_str_join_static()
+ */
+size_t
+eina_str_join_len(char *dst, size_t size, char sep, const char *a, size_t a_len, const char *b, size_t b_len)
+{
+   size_t ret = a_len + b_len + 1;
+   size_t off;
+
+   if (size < 1) return ret;
+
+   if (size <= a_len)
+     {
+       memcpy(dst, a, size - 1);
+       dst[size - 1] = '\0';
+       return ret;
+     }
+
+   memcpy(dst, a, a_len);
+   off = a_len;
+
+   if (size <= off + 1)
+     {
+       dst[size - 1] = '\0';
+       return ret;
+     }
+
+   dst[off] = sep;
+   off++;
+
+   if (size <= off + b_len + 1)
+     {
+       memcpy(dst + off, b, size - off - 1);
+       dst[size - 1] = '\0';
+       return ret;
+     }
+
+   memcpy(dst + off, b, b_len);
+   dst[off + b_len] = '\0';
+   return ret;
+}
diff --git a/src/lib/eina_strbuf.c b/src/lib/eina_strbuf.c
new file mode 100644 (file)
index 0000000..edab7db
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "eina_str.h"
+#include "eina_strbuf.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#define EINA_STRBUF_INIT_SIZE 32
+#define EINA_STRBUF_INIT_STEP 32
+#define EINA_STRBUF_MAX_STEP 4096
+
+struct _Eina_Strbuf
+{
+   char *buf;
+   size_t len;
+   size_t size;
+   size_t step;
+};
+
+static int _eina_strbuf_resize(Eina_Strbuf *buf, size_t size);
+
+/**
+ * Create a new string buffer
+ */
+EAPI Eina_Strbuf *
+eina_strbuf_new(void)
+{
+   Eina_Strbuf *buf;
+
+   buf = malloc(sizeof(Eina_Strbuf));
+   if (!buf) return NULL;
+
+   buf->len = 0;
+   buf->size = EINA_STRBUF_INIT_SIZE;
+   buf->step = EINA_STRBUF_INIT_STEP;
+
+   buf->buf = malloc(buf->size);
+   buf->buf[0] = '\0';
+
+   return buf;
+}
+
+/**
+ * Free a string buffer
+ * @param buf the buffer to free
+ */
+EAPI void
+eina_strbuf_free(Eina_Strbuf *buf)
+{
+   free(buf->buf);
+   free(buf);
+}
+
+/**
+ * Append a string to a buffer, reallocating as necessary.
+ * @param buf the Eina_Strbuf to append to
+ * @param str the string to append
+ */
+EAPI void
+eina_strbuf_append(Eina_Strbuf *buf, const char *str)
+{
+   size_t l;
+   size_t off = 0;
+
+   l = eina_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 < EINA_STRBUF_MAX_STEP)
+         buf->step *= 2;
+       buf->buf = realloc(buf->buf, buf->size);
+       *(buf->buf + buf->len) = '\0';
+
+       l = eina_strlcpy(buf->buf + buf->len, str + off, buf->size - buf->len);
+     }
+   buf->len += l;
+}
+
+/**
+ * Insert a string to a buffer, reallocating as necessary.
+ * @param buf the Eina_Strbuf to insert
+ * @param str the string to insert
+ * @param pos the position to insert the string
+ */
+EAPI void
+eina_strbuf_insert(Eina_Strbuf *buf, const char *str, size_t pos)
+{
+   size_t len;
+
+   if (pos >= buf->len)
+     {
+       eina_strbuf_append(buf, str);
+       return;
+     }
+
+   /*
+    * resize the buffer if necessary
+    */
+   len = strlen(str);
+   if (!_eina_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 */
+   memcpy(buf->buf + pos, str, len);
+   buf->len += len;
+   buf->buf[buf->len] = 0;
+}
+
+/**
+ * Append a character to a string buffer, reallocating as necessary.
+ * @param buf the Eina_Strbuf to append to
+ * @param c the char to append
+ */
+EAPI void
+eina_strbuf_append_char(Eina_Strbuf *buf, char c)
+{
+   if (buf->len >= buf->size - 1)
+     {
+       buf->size += buf->step;
+       if (buf->step < EINA_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 Eina_Strbuf is modified.
+ */
+EAPI const char *
+eina_strbuf_string_get(Eina_Strbuf *buf)
+{
+   return buf->buf;
+}
+
+/**
+ * Retrieve the length of the string buffer content
+ * @param buf the buffer
+ */
+EAPI size_t
+eina_strbuf_length_get(Eina_Strbuf *buf)
+{
+   return buf->len;
+}
+
+/**
+ * Replace the n-th string with an other string.
+ * @param buf the Eina_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
+eina_strbuf_replace(Eina_Strbuf *buf, const char *str, const char *with,
+                     unsigned int n)
+{
+   size_t len1, len2;
+   char *spos;
+   size_t pos;
+
+   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 (!_eina_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 Eina_Strbuf to work with
+ * @param str the string to replace
+ * @param with the replaceing string
+ *
+ * @return how often the string was replaced
+ */
+EAPI int
+eina_strbuf_replace_all(Eina_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;
+
+   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 (!_eina_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
+_eina_strbuf_resize(Eina_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 < EINA_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;
+}