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.
This commit is contained in:
Willy Tarreau 2016-01-06 18:07:04 +01:00
parent 70af633ebe
commit 898529b4a8
2 changed files with 49 additions and 39 deletions

View File

@ -388,25 +388,34 @@ char *encode_chunk(char *start, char *stop,
* the input string is null-terminated. * the input string is null-terminated.
* *
* If <quote> is 0, the result is returned escaped but without double quote. * If <quote> 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. * format.
* *
* printf("..., \"%s\", ...\r\n", csv_enc(str, 0)); * printf("..., \"%s\", ...\r\n", csv_enc(str, 0, &trash));
* *
* If the <quote> is 1, the converter put the quotes only if any character is * If <quote> is 1, the converter puts the quotes only if any character is
* escaped. If the <quote> is 2, the converter put always the quotes. * escaped. If <quote> is 2, the converter always puts the quotes.
* *
* <output> is a struct chunk used for storing the output string if any * <output> is a struct chunk used for storing the output string.
* change will be done.
* *
* The function returns the converted string on this output. If an error * The function returns the converted string on its output. If an error
* occurs, the function return an empty string. This type of output is useful * occurs, the function returns an empty string. This type of output is useful
* for using the function directly as printf() argument. * 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. * 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 /* Decode an URL-encoded string in-place. The resulting string might
* be shorter. If some forbidden characters are found, the conversion is * be shorter. If some forbidden characters are found, the conversion is

View File

@ -1438,61 +1438,62 @@ char *encode_chunk(char *start, char *stop,
* the input string is null-terminated. * the input string is null-terminated.
* *
* If <quote> is 0, the result is returned escaped but without double quote. * If <quote> 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. * format.
* *
* printf("..., \"%s\", ...\r\n", csv_enc(str, 0)); * printf("..., \"%s\", ...\r\n", csv_enc(str, 0, &trash));
* *
* If the <quote> is 1, the converter put the quotes only if any character is * If <quote> is 1, the converter puts the quotes only if any character is
* escaped. If the <quote> is 2, the converter put always the quotes. * escaped. If <quote> is 2, the converter always puts the quotes.
* *
* <output> is a struct chunk used for storing the output string if any * <output> is a struct chunk used for storing the output string.
* change will be done.
* *
* The function returns the converted string on this output. If an error * The function returns the converted string on its output. If an error
* occurs, the function return an empty string. This type of output is useful * occurs, the function returns an empty string. This type of output is useful
* for using the function directly as printf() argument. * for using the function directly as printf() argument.
* *
* If the output buffer is too short to contain the input string, the result * If the output buffer is too short to contain the input string, the result
* is truncated. * 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 *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. */ while (*str && ptr < end - 2) { /* -2 for reserving space for <"> and \0. */
*out = *str; *ptr = *str;
if (*str == '"') { if (*str == '"') {
if (quote == 1) if (quote == 1)
quote = 2; quote = 2;
out++; ptr++;
if (out >= end - 2) { if (ptr >= end - 2) {
out--; ptr--;
break; break;
} }
*out = '"'; *ptr = '"';
} }
if (quote == 1 && ( *str == '\r' || *str == '\n' || *str == ',') ) if (quote == 1 && ( *str == '\r' || *str == '\n' || *str == ',') )
quote = 2; quote = 2;
out++; ptr++;
str++; str++;
} }
if (quote == 1) if (quote < 2) {
quote = 0; *ptr = '\0';
output->len = ptr - output->str;
if (!quote) { return out;
*out = '\0';
return output->str + 1;
} }
/* else quote == 2 */ /* quote == 2 : add quotes */
*output->str = '"'; *--out = '"';
*out = '"'; *++ptr = '"';
out++; *ptr = '\0';
*out = '\0'; output->len = ptr - output->str;
return output->str; return out;
} }
/* Decode an URL-encoded string in-place. The resulting string might /* Decode an URL-encoded string in-place. The resulting string might