From: Willy Tarreau Date: Wed, 6 Jan 2016 17:07:04 +0000 (+0100) Subject: MEDIUM: tools: add csv_enc_append() to preserve the original chunk X-Git-Tag: v1.7-dev2~157 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=898529b4a8ed14b61af14785d27f293b79653627;p=thirdparty%2Fhaproxy.git MEDIUM: tools: add csv_enc_append() to preserve the original chunk We have csv_enc() but there's no way to append some CSV-encoded data to an existing chunk, so here we modify the existing function for this and create an inlined version of csv_enc() which first resets the output chunk. It will be handy to append data to an existing chunk without having to use an extra temporary chunk, or to encode multiple strings into a single chunk with chunk_newstr(). The patch is quite small, in fact most changes are typo fixes in the comments. --- diff --git a/include/common/standard.h b/include/common/standard.h index 0fe0fb08b3..357d22cfde 100644 --- a/include/common/standard.h +++ b/include/common/standard.h @@ -388,25 +388,34 @@ char *encode_chunk(char *start, char *stop, * the input string is null-terminated. * * If is 0, the result is returned escaped but without double quote. - * Is it useful if the escaped string is used between double quotes in the + * It is useful if the escaped string is used between double quotes in the * format. * - * printf("..., \"%s\", ...\r\n", csv_enc(str, 0)); + * printf("..., \"%s\", ...\r\n", csv_enc(str, 0, &trash)); * - * If the is 1, the converter put the quotes only if any character is - * escaped. If the is 2, the converter put always the quotes. + * If is 1, the converter puts the quotes only if any character is + * escaped. If is 2, the converter always puts the quotes. * - * is a struct chunk used for storing the output string if any - * change will be done. + * is a struct chunk used for storing the output string. * - * The function returns the converted string on this output. If an error - * occurs, the function return an empty string. This type of output is useful + * The function returns the converted string on its output. If an error + * occurs, the function returns an empty string. This type of output is useful * for using the function directly as printf() argument. * - * If the output buffer is too short to conatin the input string, the result + * If the output buffer is too short to contain the input string, the result * is truncated. + * + * This function appends the encoding to the existing output chunk. Please + * use csv_enc() instead if you want to replace the output chunk. */ -const char *csv_enc(const char *str, int quote, struct chunk *output); +const char *csv_enc_append(const char *str, int quote, struct chunk *output); + +/* same as above but the output chunk is reset first */ +static inline const char *csv_enc(const char *str, int quote, struct chunk *output) +{ + chunk_reset(output); + return csv_enc_append(str, quote, output); +} /* Decode an URL-encoded string in-place. The resulting string might * be shorter. If some forbidden characters are found, the conversion is diff --git a/src/standard.c b/src/standard.c index 969daf6b3f..adbffd4c49 100644 --- a/src/standard.c +++ b/src/standard.c @@ -1438,61 +1438,62 @@ char *encode_chunk(char *start, char *stop, * the input string is null-terminated. * * If is 0, the result is returned escaped but without double quote. - * Is it useful if the escaped string is used between double quotes in the + * It is useful if the escaped string is used between double quotes in the * format. * - * printf("..., \"%s\", ...\r\n", csv_enc(str, 0)); + * printf("..., \"%s\", ...\r\n", csv_enc(str, 0, &trash)); * - * If the is 1, the converter put the quotes only if any character is - * escaped. If the is 2, the converter put always the quotes. + * If is 1, the converter puts the quotes only if any character is + * escaped. If is 2, the converter always puts the quotes. * - * is a struct chunk used for storing the output string if any - * change will be done. + * is a struct chunk used for storing the output string. * - * The function returns the converted string on this output. If an error - * occurs, the function return an empty string. This type of output is useful + * The function returns the converted string on its output. If an error + * occurs, the function returns an empty string. This type of output is useful * for using the function directly as printf() argument. * * If the output buffer is too short to contain the input string, the result * is truncated. + * + * This function appends the encoding to the existing output chunk. Please + * use csv_enc() instead if you want to replace the output chunk. */ -const char *csv_enc(const char *str, int quote, struct chunk *output) +const char *csv_enc_append(const char *str, int quote, struct chunk *output) { char *end = output->str + output->size; - char *out = output->str + 1; /* +1 for reserving space for a first <"> */ + char *out = output->str + output->len + 1; /* +1 for reserving space for a first <"> */ + char *ptr = out; - while (*str && out < end - 2) { /* -2 for reserving space for <"> and \0. */ - *out = *str; + while (*str && ptr < end - 2) { /* -2 for reserving space for <"> and \0. */ + *ptr = *str; if (*str == '"') { if (quote == 1) quote = 2; - out++; - if (out >= end - 2) { - out--; + ptr++; + if (ptr >= end - 2) { + ptr--; break; } - *out = '"'; + *ptr = '"'; } if (quote == 1 && ( *str == '\r' || *str == '\n' || *str == ',') ) quote = 2; - out++; + ptr++; str++; } - if (quote == 1) - quote = 0; - - if (!quote) { - *out = '\0'; - return output->str + 1; + if (quote < 2) { + *ptr = '\0'; + output->len = ptr - output->str; + return out; } - /* else quote == 2 */ - *output->str = '"'; - *out = '"'; - out++; - *out = '\0'; - return output->str; + /* quote == 2 : add quotes */ + *--out = '"'; + *++ptr = '"'; + *ptr = '\0'; + output->len = ptr - output->str; + return out; } /* Decode an URL-encoded string in-place. The resulting string might