--- gpl/axl/src/axl_stream.c 2011/06/08 07:09:12 1.1.1.1 +++ gpl/axl/src/axl_stream.c 2012/02/17 12:50:03 1.1.1.2 @@ -1504,8 +1504,10 @@ char * __axl_stream_get_untilv_wide (axlStream * strea } /* in the case a memory chunk is being read */ - if (stream->accept_terminator) + if (stream->accept_terminator) { stream->stream_index += length; + stream->global_index += length; + } stream->stream_index += index; stream->global_index += index; stream->previous_inspect = 0; @@ -2424,6 +2426,9 @@ char * axl_stream_strdup_n (const char * chunk, i */ int axl_stream_vprintf_len (const char * format, va_list args) { + /** IMPLEMENTATION NOTE: in the case this code is update, + * update exarg_vprintf_len **/ + #if defined (AXL_OS_WIN32) && ! defined (__GNUC__) # if HAVE_VSCPRINTF if (format == NULL) @@ -2597,11 +2602,11 @@ char * axl_stream_strdup_printf (const char * c * * @return A newly allocated string. * - * IMPLEMENTATION NOTE: This function have a fundamental bug due to - * the design of va_list arguments under amd64 platforms. In short, a - * function receiving a va_list argument can't use it twice. In you + * IMPLEMENTATION NOTE: This function may have a fundamental bug due + * to the design of va_list arguments under amd64 platforms. In short, + * a function receiving a va_list argument can't use it twice. In you * are running amd64, check your axl_config.h did find - * AXL_HAVE_VASPRINTF. + * AXL_HAVE_VASPRINTF. */ char * axl_stream_strdup_printfv (const char * chunk, va_list args) { @@ -2612,13 +2617,13 @@ char * axl_stream_strdup_printfv (const char * chu int size; #endif char * result = NULL; - int new_size = -1; axl_return_val_if_fail (chunk, NULL); #ifdef AXL_HAVE_VASPRINTF /* do the operation using the GNU extension */ - new_size = vasprintf (&result, chunk, args); + if (vasprintf (&result, chunk, args) == -1) + return NULL; #else /* get the amount of memory to be allocated */ size = axl_stream_vprintf_len (chunk, args); @@ -2634,9 +2639,9 @@ char * axl_stream_strdup_printfv (const char * chu /* copy current size */ # if defined(AXL_OS_WIN32) && ! defined (__GNUC__) - new_size = _vsnprintf_s (result, size + 1, size, chunk, args); + _vsnprintf_s (result, size + 1, size, chunk, args); # else - new_size = vsnprintf (result, size + 1, chunk, args); + vsnprintf (result, size + 1, chunk, args); # endif #endif /* return the result */ @@ -3001,6 +3006,119 @@ char * axl_stream_join (char ** s /* return string created */ return result; +} + +/** + * @brief Allows to replace the provided string by the provided + * replacement on the provided source string, doing the replacement in + * an effective manner. + * + * @param source The source string where to look and replace. The + * result will be reported as a new pointer on this parameter. The + * function will dealloc previous string (passed in source). + * + * @param source_len The replace function can handle binary + * strings. This parameter signals the function how many bytes are + * found on the source pointer. + * + * @param string The string that will be looked for replacement. The + * string can be binary data but its length must be configured. + * + * @param string_len String length or -1. The string parameter can be + * binary data (may include \0) but length must be especified. If -1 + * is provided, the function will use strlen () to get current string + * size. + * + * @param replacement The replace string. The replacement can be + * binary data but its length must be configured. + * + * @param replacement_len Replacement string length or -1. The + * replacement parameter can be binary data (may include \0) but + * length must be especified. If -1 is provided, the function will use + * strlen () to get current string size. + * + * @return The function returns the new size of the string. The + * function returns the same source length when no replacement was + * done. The function return source_len in the case some argument is NULL. + */ +int axl_stream_replace (char ** source, int source_len, + const char * string, int string_len, + const char * replacement, int replacement_len) +{ + int iterator; + int iterator2; + int count; + char * result; + int old_source_len; + + /* check arguments */ + axl_return_val_if_fail (source && string && replacement, source_len); + + /* get sizes if not configured */ + if (source_len == -1) + source_len = strlen (*source); + if (string_len == -1) + string_len = strlen (string); + if (replacement_len == -1) + replacement_len = strlen (replacement); + + /* find how many strings must be replaced */ + iterator = 0; + count = 0; + while ((iterator + string_len - 1) < source_len) { + /* check if the string is found */ + if (axl_memcmp ((*source) + iterator, string, string_len)) { + /* string found ! */ + count++; + + /* skip these bytes */ + iterator += string_len; + continue; + } + + /* next position */ + iterator++; + } /* end while */ + + /* check if we have found some to replace */ + if (count == 0) + return source_len; + + /* update source length */ + old_source_len = source_len; + source_len = source_len - (string_len * count) + (replacement_len * count); + + /* alloc memory for the replacement */ + result = axl_new (char, source_len + 1); + + /* do replacement */ + iterator = 0; + iterator2 = 0; + while (iterator < old_source_len) { + /* check if the string is found */ + if (((iterator + string_len - 1) < old_source_len) && axl_memcmp ((*source) + iterator, string, string_len)) { + /* string found!, replace */ + memcpy (result + iterator2, replacement, replacement_len); + + /* skip these bytes */ + iterator += string_len; + iterator2 += replacement_len; + continue; + } + + /* copy byte by byte */ + result[iterator2] = (*source)[iterator]; + + /* next position */ + iterator++; + iterator2++; + } /* end while */ + + /* release and report new string */ + axl_free (*source); + *source = result; + + return source_len; } /**