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