Mercurial > dovecot > original-hg > dovecot-1.2
view src/lib-mail/message-header-decode.c @ 956:26cafa3dc09c HEAD
minor optimization
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 12 Jan 2003 01:49:45 +0200 |
parents | 411006be3c66 |
children | 60646878858e |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" #include "base64.h" #include "buffer.h" #include "quoted-printable.h" #include "message-header-decode.h" static int split_encoded(const unsigned char *data, size_t *size_p, const char **charset, const char **encoding, const unsigned char **text, size_t *text_size_r) { size_t size, pos, textpos; size = *size_p; /* get charset */ for (pos = 0; pos < size && data[pos] != '?'; pos++) ; if (data[pos] != '?') return FALSE; *charset = t_strndup(data, pos); /* get encoding */ pos++; if (pos+2 >= size || data[pos+1] != '?') return FALSE; if (data[pos] == 'Q' || data[pos] == 'q') *encoding = "Q"; else if (data[pos] == 'B' || data[pos] == 'b') *encoding = "B"; else return FALSE; /* get text */ pos += 2; textpos = pos; while (pos < size && data[pos] != '?') pos++; if (data[pos] != '?' || pos+1 >= size || data[pos+1] != '=') return FALSE; *text = data + textpos; *text_size_r = pos - textpos; *size_p = pos+2; return TRUE; } static int message_header_decode_encoded(const unsigned char *data, size_t *size, message_header_decode_callback_t callback, void *context) { const unsigned char *text; const char *charset, *encoding; buffer_t *decodebuf; size_t text_size; int ret; t_push(); /* first split the string charset?encoding?text?= */ if (!split_encoded(data, size, &charset, &encoding, &text, &text_size)) { t_pop(); return TRUE; } decodebuf = buffer_create_static_hard(data_stack_pool, text_size); if (*encoding == 'Q') quoted_printable_decode(text, text_size, NULL, decodebuf); else { if (base64_decode(text, text_size, NULL, decodebuf) < 0) { /* corrupted encoding */ t_pop(); return TRUE; } } ret = callback(buffer_get_data(decodebuf, NULL), buffer_get_used_size(decodebuf), charset, context); t_pop(); return ret; } void message_header_decode(const unsigned char *data, size_t size, message_header_decode_callback_t callback, void *context) { size_t pos, start_pos, subsize; start_pos = pos = 0; while (pos < size) { if (data[pos] == '=' && pos+1 < size && data[pos+1] == '?') { /* encoded string beginning */ if (pos != start_pos) { /* send the unencoded data so far */ if (!callback(data + start_pos, pos - start_pos, NULL, context)) return; } pos += 2; subsize = size - pos; if (!message_header_decode_encoded(data + pos, &subsize, callback, context)) return; pos += subsize; start_pos = pos; } else { pos++; } } (void)callback(data + start_pos, size - start_pos, NULL, context); }