mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-23 14:51:27 +02:00
MINOR: tools: make csv_enc_append() always start at the first byte of the chunk
csv_enc_append() returns a pointer to the beginning of the encoded string, which makes it convenient to use in printf(). However it's not convenient for use in chunks as it may leave an unused byte at the beginning depending on the automatic quoting. Let's modify it to work in two passes. First it looks for a character that requires escaping using strpbrk(), and second it encodes the string. This way it guarantees to always start at the first available byte of the chunk. Additionally it made the code quite simpler.
This commit is contained in:
parent
898529b4a8
commit
b631c291c9
@ -1443,8 +1443,8 @@ char *encode_chunk(char *start, char *stop,
|
|||||||
*
|
*
|
||||||
* printf("..., \"%s\", ...\r\n", csv_enc(str, 0, &trash));
|
* printf("..., \"%s\", ...\r\n", csv_enc(str, 0, &trash));
|
||||||
*
|
*
|
||||||
* If <quote> is 1, the converter puts the quotes only if any character is
|
* If <quote> is 1, the converter puts the quotes only if any reserved character
|
||||||
* escaped. If <quote> is 2, the converter always puts the quotes.
|
* is present. If <quote> is 2, the converter always puts the quotes.
|
||||||
*
|
*
|
||||||
* <output> is a struct chunk used for storing the output string.
|
* <output> is a struct chunk used for storing the output string.
|
||||||
*
|
*
|
||||||
@ -1455,20 +1455,29 @@ char *encode_chunk(char *start, char *stop,
|
|||||||
* 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
|
* This function appends the encoding to the existing output chunk, and it
|
||||||
* use csv_enc() instead if you want to replace the output chunk.
|
* guarantees that it starts immediately at the first available character of
|
||||||
|
* the chunk. Please use csv_enc() instead if you want to replace the output
|
||||||
|
* chunk.
|
||||||
*/
|
*/
|
||||||
const char *csv_enc_append(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 + output->len + 1; /* +1 for reserving space for a first <"> */
|
char *out = output->str + output->len;
|
||||||
char *ptr = out;
|
char *ptr = out;
|
||||||
|
|
||||||
|
if (quote == 1) {
|
||||||
|
/* automatic quoting: first verify if we'll have to quote the string */
|
||||||
|
if (!strpbrk(str, "\n\r,\""))
|
||||||
|
quote = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quote)
|
||||||
|
*ptr++ = '"';
|
||||||
|
|
||||||
while (*str && ptr < end - 2) { /* -2 for reserving space for <"> and \0. */
|
while (*str && ptr < end - 2) { /* -2 for reserving space for <"> and \0. */
|
||||||
*ptr = *str;
|
*ptr = *str;
|
||||||
if (*str == '"') {
|
if (*str == '"') {
|
||||||
if (quote == 1)
|
|
||||||
quote = 2;
|
|
||||||
ptr++;
|
ptr++;
|
||||||
if (ptr >= end - 2) {
|
if (ptr >= end - 2) {
|
||||||
ptr--;
|
ptr--;
|
||||||
@ -1476,21 +1485,13 @@ const char *csv_enc_append(const char *str, int quote, struct chunk *output)
|
|||||||
}
|
}
|
||||||
*ptr = '"';
|
*ptr = '"';
|
||||||
}
|
}
|
||||||
if (quote == 1 && ( *str == '\r' || *str == '\n' || *str == ',') )
|
|
||||||
quote = 2;
|
|
||||||
ptr++;
|
ptr++;
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quote < 2) {
|
if (quote)
|
||||||
*ptr = '\0';
|
*ptr++ = '"';
|
||||||
output->len = ptr - output->str;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* quote == 2 : add quotes */
|
|
||||||
*--out = '"';
|
|
||||||
*++ptr = '"';
|
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
output->len = ptr - output->str;
|
output->len = ptr - output->str;
|
||||||
return out;
|
return out;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user