imap-quote.c revision f58167d61d926f2ffd9366169ca5183e712e2992
2830N/A/* Copyright (C) 2002 Timo Sirainen */
2830N/A
2830N/A#include "lib.h"
2830N/A#include "str.h"
2830N/A#include "imap-quote.h"
2830N/A
2830N/Avoid imap_quote_append(string_t *str, const unsigned char *value,
2830N/A size_t value_len)
2830N/A{
2830N/A size_t i, linefeeds = 0;
2830N/A int last_lwsp = TRUE, literal = FALSE, modify = FALSE;
2830N/A
2830N/A if (value == NULL) {
2830N/A str_append(str, "NIL");
2830N/A return;
2830N/A }
2830N/A
2830N/A if (value_len == (size_t)-1)
2830N/A value_len = strlen((const char *) value);
2830N/A
2830N/A for (i = 0; i < value_len; i++) {
2830N/A switch (value[i]) {
6856N/A case 0:
2830N/A /* it's converted to 8bit char */
2830N/A literal = TRUE;
2830N/A case '\t':
2830N/A modify = TRUE;
2830N/A break;
2830N/A case ' ':
2830N/A if (last_lwsp)
2830N/A modify = TRUE;
2830N/A last_lwsp = TRUE;
2830N/A break;
2830N/A case 13:
2830N/A case 10:
2830N/A linefeeds++;
2830N/A modify = TRUE;
4910N/A break;
4910N/A default:
4910N/A if ((value[i] & 0x80) != 0 ||
4910N/A value[i] == '"' || value[i] == '\\')
4910N/A literal = TRUE;
4910N/A }
4910N/A }
if (!literal) {
/* no 8bit chars or imapspecials, return as "string" */
str_append_c(str, '"');
} else {
/* return as literal */
str_printfa(str, "{%"PRIuSIZE_T"}\r\n", value_len - linefeeds);
}
if (!modify)
str_append_n(str, value, value_len);
else {
last_lwsp = TRUE;
for (i = 0; i < value_len; i++) {
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;
}
}
}
if (!literal)
str_append_c(str, '"');
}
char *imap_quote(pool_t pool, const unsigned char *value, size_t value_len)
{
string_t *str;
char *ret;
i_assert(pool != data_stack_pool);
if (value == NULL)
return "NIL";
t_push();
str = t_str_new(value_len + MAX_INT_STRLEN + 5);
imap_quote_append(str, value, value_len);
ret = p_strndup(pool, str_data(str), str_len(str));
t_pop();
return ret;
}