size_t value_len)
{
size_t i, linefeeds = 0;
- int literal = FALSE;
+ int last_lwsp, first_lwsp, literal = FALSE, modify = FALSE;
if (value == NULL) {
str_append(str, "NIL");
return;
}
- for (i = 0; i < value_len; i++) {
- if (value[i] == 0) {
- value_len = i;
- break;
- }
+ if (value_len == (size_t)-1)
+ value_len = strlen((const char *) value);
- if (value[i] == 13 || value[i] == 10)
- linefeeds++;
+ i = str_len(str);
+ first_lwsp = last_lwsp = i > 0 && str_data(str)[i-1] == ' ';
- if ((value[i] & 0x80) != 0 ||
- value[i] == '"' || value[i] == '\\')
+ for (i = 0; i < value_len; i++) {
+ switch (value[i]) {
+ case 0:
+ /* it's converted to 8bit char */
literal = TRUE;
+ case '\t':
+ modify = TRUE;
+ break;
+ case ' ':
+ if (last_lwsp)
+ modify = TRUE;
+ last_lwsp = TRUE;
+ break;
+ case 13:
+ case 10:
+ linefeeds++;
+ modify = TRUE;
+ break;
+ default:
+ if ((value[i] & 0x80) != 0 ||
+ value[i] == '"' || value[i] == '\\')
+ literal = TRUE;
+ }
}
if (!literal) {
str_printfa(str, "{%"PRIuSIZE_T"}\r\n", value_len - linefeeds);
}
- if (linefeeds == 0)
+ if (!modify)
str_append_n(str, value, value_len);
else {
+ last_lwsp = first_lwsp;
for (i = 0; i < value_len; i++) {
- if (value[i] != 13 && value[i] != 10)
+ switch (value[i]) {
+ case 0:
+ str_append_c(str, 128);
+ last_lwsp = FALSE;
+ break;
+ case ' ':
+ case '\t':
+ if (!last_lwsp)
+ str_append_c(str, ' ');
+ last_lwsp = TRUE;
+ break;
+ case 13:
+ case 10:
+ break;
+ default:
+ last_lwsp = FALSE;
str_append_c(str, value[i]);
+ break;
+ }
}
}
#define __IMAP_QUOTE_H
/* Return value suitable for sending to client, either as quoted-string or
- literal. */
+ literal. Note that this also converts TABs into spaces, multiple spaces
+ into single space and NULs to #128. */
char *imap_quote(pool_t pool, const unsigned char *value, size_t value_len);
/* Append to existing string. */