Enlightenment CVS committal

Author  : pfritz
Project : e17
Module  : libs/ecore

Dir     : e17/libs/ecore/src/lib/ecore


Modified Files:
        Ecore_Data.h ecore_strbuf.c 


Log Message:
- add ecore_strbuf_replace() and ecore_strbuf_replace_all()
- some formating and minor things

===================================================================
RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore/Ecore_Data.h,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -3 -r1.36 -r1.37
--- Ecore_Data.h        21 Feb 2007 06:08:22 -0000      1.36
+++ Ecore_Data.h        5 Mar 2007 21:41:39 -0000       1.37
@@ -483,14 +483,21 @@
    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
 }
===================================================================
RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore/ecore_strbuf.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -3 -r1.2 -r1.3
--- ecore_strbuf.c      21 Feb 2007 04:31:50 -0000      1.2
+++ ecore_strbuf.c      5 Mar 2007 21:41:39 -0000       1.3
@@ -15,10 +15,12 @@
   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 @@
  * 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 @@
  * @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 @@
   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 @@
    * 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 @@
  * @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 @@
  * 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 @@
  * 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;
 }
 



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to