Beispiel #1
0
EAPI Eina_Bool
eina_strbuf_replace(Eina_Strbuf *buf,
                    const char *str,
                    const char *with,
                    unsigned int n)
{
   size_t len1, len2;
   char *spos;
   size_t pos;

   EINA_SAFETY_ON_NULL_RETURN_VAL( str, EINA_FALSE);
   EINA_SAFETY_ON_NULL_RETURN_VAL(with, EINA_FALSE);
   EINA_MAGIC_CHECK_STRBUF(buf, 0);
   if (n == 0) return EINA_FALSE;

   spos = buf->buf;
   while (n--)
     {
        spos = strstr(spos, str);
        if (!spos || *spos == '\0') return EINA_FALSE;
        if (n) spos++;
     }

   /* This is a read only buffer which need change to be made */
   if (buf->ro)
     {
        char *dest;

        dest = malloc(buf->size);
        if (!dest) return 0;
        memcpy(dest, buf->buf, buf->len);
        buf->buf = dest;
     }

   pos = spos - (const char *)buf->buf;
   len1 = strlen(str);
   len2 = strlen(with);
   if (len1 != len2)
     {
        /* resize the buffer if necessary */
        if (EINA_UNLIKELY(!_eina_strbuf_common_grow(_STRBUF_CSIZE, buf,
                                                    buf->len - len1 + len2)))
           return EINA_FALSE; /* move the existing text */
        memmove(((unsigned char *)(buf->buf)) + pos + len2, 
                ((unsigned char *)(buf->buf)) + pos + len1,
                buf->len - pos - len1);
     }
   /* and now insert the given string */
   memcpy(((unsigned char *)(buf->buf)) + pos, with, len2);
   buf->len += len2 - len1;
   memset(((unsigned char *)(buf->buf)) + buf->len, 0, 1);
   return EINA_TRUE;
}
Beispiel #2
0
/**
 * @brief Replace all strings with an other string.

 * @param buf the string buffer to work with.
 * @param str The string to replace.
 * @param with The replaceing string.
 * @return How often the string was replaced.
 *
 * This function replaces all the occurrences of @p str in @ buf with
 * the string @p with. This function returns the number of times @p str
 * has been replaced. On failure, it returns 0.
 */
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;

	EINA_SAFETY_ON_NULL_RETURN_VAL(str, 0);
	EINA_SAFETY_ON_NULL_RETURN_VAL(with, 0);
	EINA_MAGIC_CHECK_STRBUF(buf, 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 - (const char *) buf->buf;
	tmp_buf = buf->buf;
	buf->buf = malloc(buf->size);
	if (EINA_UNLIKELY(!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_UNLIKELY
		    (!_eina_strbuf_common_grow(_STRBUF_CSIZE, 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;
	memset((char *) buf->buf + buf->len, 0, 1);

	free(tmp_buf);

	return n;
}