sizeof(struct mail_sent_date),
sizeof(time_t),
sizeof(uoff_t),
- sizeof(uoff_t),
- sizeof(uoff_t),
- sizeof(uoff_t),
- 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
/* variable sized */
(unsigned int)-1, (unsigned int)-1, (unsigned int)-1, (unsigned int)-1,
MAIL_CACHE_MD5 = 0x00000004,
MAIL_CACHE_SENT_DATE = 0x00000008,
MAIL_CACHE_RECEIVED_DATE = 0x00000010,
- MAIL_CACHE_HEADER_SIZE = 0x00000020,
- MAIL_CACHE_BODY_SIZE = 0x00000040,
- MAIL_CACHE_VIRTUAL_HEADER_SIZE = 0x00000080,
- MAIL_CACHE_VIRTUAL_FULL_SIZE = 0x00000100,
+ MAIL_CACHE_VIRTUAL_FULL_SIZE = 0x00000020,
/* variable sized field */
MAIL_CACHE_HEADERS1 = 0x40000000,
MAIL_CACHE_LOCATION = 0x04000000,
MAIL_CACHE_BODY = 0x02000000,
MAIL_CACHE_BODYSTRUCTURE = 0x01000000,
- MAIL_CACHE_MESSAGEPART = 0x00800000,
+ MAIL_CACHE_ENVELOPE = 0x00800000,
+ MAIL_CACHE_MESSAGEPART = 0x00400000,
MAIL_CACHE_FIXED_MASK = MAIL_CACHE_INDEX_FLAGS |
MAIL_CACHE_LOCATION_OFFSET |
MAIL_CACHE_MD5 |
MAIL_CACHE_SENT_DATE |
MAIL_CACHE_RECEIVED_DATE |
- MAIL_CACHE_HEADER_SIZE |
- MAIL_CACHE_BODY_SIZE |
- MAIL_CACHE_VIRTUAL_HEADER_SIZE |
MAIL_CACHE_VIRTUAL_FULL_SIZE,
MAIL_CACHE_HEADERS_MASK = MAIL_CACHE_HEADERS1 |
MAIL_CACHE_HEADERS2 |
MAIL_CACHE_STRING_MASK = MAIL_CACHE_HEADERS_MASK |
MAIL_CACHE_LOCATION |
MAIL_CACHE_BODY |
- MAIL_CACHE_BODYSTRUCTURE,
+ MAIL_CACHE_BODYSTRUCTURE |
+ MAIL_CACHE_ENVELOPE,
MAIL_CACHE_BODYSTRUCTURE_MASK = MAIL_CACHE_BODY |
MAIL_CACHE_BODYSTRUCTURE |
MAIL_CACHE_MESSAGEPART
#include "lib.h"
#include "buffer.h"
#include "istream.h"
+#include "message-part-serialize.h"
#include "mbox-index.h"
#include "mbox-lock.h"
#include "mail-index-util.h"
struct mail_index_record *rec,
uoff_t *offset, uoff_t *hdr_size, uoff_t *body_size)
{
+ struct message_size _hdr_size, _body_size;
+ const void *data;
+ size_t size;
+
if (offset != NULL) {
if (!mail_cache_copy_fixed_field(index->cache, rec,
MAIL_CACHE_LOCATION_OFFSET,
}
}
- if (hdr_size != NULL) {
- if (!mail_cache_copy_fixed_field(index->cache, rec,
- MAIL_CACHE_HEADER_SIZE,
- hdr_size, sizeof(*hdr_size))) {
+ if (hdr_size != NULL || body_size != NULL) {
+ if (!mail_cache_lookup_field(index->cache, rec,
+ MAIL_CACHE_MESSAGEPART,
+ &data, &size)) {
mail_cache_set_corrupted(index->cache,
- "Missing header size for record %u", rec->uid);
+ "Missing message_part for record %u", rec->uid);
return FALSE;
}
- }
-
- if (body_size != NULL) {
- if (!mail_cache_copy_fixed_field(index->cache, rec,
- MAIL_CACHE_BODY_SIZE,
- body_size,
- sizeof(*body_size))) {
+ if (!message_part_deserialize_size(data, size,
+ &_hdr_size, &_body_size)) {
mail_cache_set_corrupted(index->cache,
- "Missing body size for record %u", rec->uid);
+ "Corrupted message_part for record %u",
+ rec->uid);
return FALSE;
}
+
+ if (hdr_size != NULL)
+ *hdr_size = _hdr_size.physical_size;
+ if (body_size != NULL)
+ *body_size = _body_size.physical_size;
}
return TRUE;
memcpy(&flags, buf, sizeof(flags));
buf += sizeof(flags);
- memcpy(&hdr_size->physical_size, buf, sizeof(uoff_t));
- buf += sizeof(uoff_t);
- memcpy(&hdr_size->virtual_size, buf, sizeof(uoff_t));
- buf += sizeof(uoff_t);
- hdr_size->lines = 0;
- memcpy(&body_size->physical_size, buf, sizeof(uoff_t));
- buf += sizeof(uoff_t);
- memcpy(&body_size->virtual_size, buf, sizeof(uoff_t));
- buf += sizeof(uoff_t);
-
- if ((flags & (MESSAGE_PART_FLAG_TEXT |
- MESSAGE_PART_FLAG_MESSAGE_RFC822)) == 0)
- body_size->lines = 0;
+ if (hdr_size == NULL)
+ buf += sizeof(uoff_t) * 2;
else {
- if (size < MINIMUM_SERIALIZED_SIZE + sizeof(unsigned int))
- return FALSE;
- memcpy(&body_size->lines, buf, sizeof(unsigned int));
+ memcpy(&hdr_size->physical_size, buf, sizeof(uoff_t));
+ buf += sizeof(uoff_t);
+ memcpy(&hdr_size->virtual_size, buf, sizeof(uoff_t));
+ buf += sizeof(uoff_t);
+ hdr_size->lines = 0;
+ }
+
+ if (body_size != NULL) {
+ memcpy(&body_size->physical_size, buf, sizeof(uoff_t));
+ buf += sizeof(uoff_t);
+ memcpy(&body_size->virtual_size, buf, sizeof(uoff_t));
+ buf += sizeof(uoff_t);
+
+ if ((flags & (MESSAGE_PART_FLAG_TEXT |
+ MESSAGE_PART_FLAG_MESSAGE_RFC822)) == 0)
+ body_size->lines = 0;
+ else {
+ if (size < MINIMUM_SERIALIZED_SIZE +
+ sizeof(unsigned int))
+ return FALSE;
+ memcpy(&body_size->lines, buf, sizeof(unsigned int));
+ }
}
return TRUE;
return &data->flags;
}
-static void cache_parts(struct index_mail *mail)
-{
- buffer_t *buffer;
- const void *buf_data;
- size_t buf_size;
-
- if (!index_mail_cache_can_add(mail, MAIL_CACHE_MESSAGEPART))
- return;
-
- t_push();
- buffer = buffer_create_dynamic(data_stack_pool, 1024, (size_t)-1);
- message_part_serialize(mail->data.parts, buffer);
-
- buf_data = buffer_get_data(buffer, &buf_size);
- index_mail_cache_add(mail, MAIL_CACHE_MESSAGEPART, buf_data, buf_size);
- t_pop();
-}
-
static const struct message_part *get_parts(struct mail *_mail)
{
struct index_mail *mail = (struct index_mail *) _mail;
if (!index_mail_parse_body(mail))
return NULL;
- cache_parts(mail);
return data->parts;
}
return data->parts != NULL;
}
-static void get_binary_sizes(struct index_mail *mail)
-{
- enum mail_index_record_flag index_flags;
- uoff_t size;
-
- index_flags = mail_cache_get_index_flags(mail->ibox->index->cache,
- mail->data. rec);
-
- if (!mail->data.hdr_size_set &&
- (index_flags & MAIL_INDEX_FLAG_BINARY_HEADER) != 0) {
- size = get_cached_uoff_t(mail, MAIL_CACHE_HEADER_SIZE);
- if (size != (uoff_t)-1) {
- mail->data.hdr_size.physical_size =
- mail->data.hdr_size.virtual_size = size;
- mail->data.hdr_size_set = TRUE;
- }
- }
-
- if (!mail->data.body_size_set &&
- (index_flags & MAIL_INDEX_FLAG_BINARY_BODY) != 0) {
- size = get_cached_uoff_t(mail, MAIL_CACHE_BODY_SIZE);
- if (size != (uoff_t)-1) {
- mail->data.body_size.physical_size =
- mail->data.body_size.virtual_size = size;
- mail->data.body_size_set = TRUE;
- }
- }
-}
-
-static void index_mail_cache_add_sizes(struct index_mail *mail)
-{
- if (mail->data.hdr_size_set) {
- index_mail_cache_add(mail, MAIL_CACHE_HEADER_SIZE,
- &mail->data.hdr_size.physical_size,
- sizeof(uoff_t));
- }
- if (mail->data.body_size_set) {
- index_mail_cache_add(mail, MAIL_CACHE_BODY_SIZE,
- &mail->data.body_size.physical_size,
- sizeof(uoff_t));
- }
-}
-
static uoff_t get_size(struct mail *_mail)
{
struct index_mail *mail = (struct index_mail *) _mail;
if (get_msgpart_sizes(mail))
return data->size;
- /* maybe it's binary */
- get_binary_sizes(mail);
- if (data->hdr_size_set && data->body_size_set) {
- data->size = data->hdr_size.virtual_size +
- data->body_size.virtual_size;
- return data->size;
- }
-
- /* do it the slow way */
if (_mail->get_stream(_mail, &hdr_size, &body_size) == NULL)
return (uoff_t)-1;
{
struct index_mail_data *data = &mail->data;
enum mail_index_record_flag index_flags;
+ buffer_t *buffer;
+ const void *buf_data;
+ size_t buf_size;
i_assert(data->parts == NULL);
i_assert(data->parser_ctx != NULL);
if (!index_mail_cache_transaction_begin(mail))
return TRUE;
+ /* update index_flags */
index_flags = mail_cache_get_index_flags(mail->ibox->index->cache,
mail->data.rec);
if (mail->mail.has_nuls)
mail->data.rec, index_flags))
return FALSE;
+ if (index_mail_cache_can_add(mail, MAIL_CACHE_MESSAGEPART)) {
+ t_push();
+ buffer = buffer_create_dynamic(data_stack_pool,
+ 1024, (size_t)-1);
+ message_part_serialize(mail->data.parts, buffer);
+
+ buf_data = buffer_get_data(buffer, &buf_size);
+ index_mail_cache_add(mail, MAIL_CACHE_MESSAGEPART,
+ buf_data, buf_size);
+ t_pop();
+ }
return TRUE;
}
if (!index_mail_open_stream(mail, 0))
return NULL;
- if (hdr_size != NULL || body_size != NULL) {
- if (!get_msgpart_sizes(mail))
- get_binary_sizes(mail);
- }
+ if (hdr_size != NULL || body_size != NULL)
+ (void)get_msgpart_sizes(mail);
if (hdr_size != NULL) {
if (!data->hdr_size_set) {
if (data->hdr_size_set && data->body_size_set) {
data->size = data->hdr_size.virtual_size +
data->body_size.virtual_size;
- if (data->parts->children != NULL) {
- /* cache the message parts only if this is a
- multipart message. it's pretty useless otherwise. */
- cache_parts(mail);
- } else {
- index_mail_cache_add_sizes(mail);
- index_mail_cache_add(mail, MAIL_CACHE_VIRTUAL_FULL_SIZE,
- &data->size, sizeof(data->size));
- }
- } else {
- index_mail_cache_add_sizes(mail);
}
i_stream_seek(data->stream, 0);
MAIL_CACHE_BODYSTRUCTURE : MAIL_CACHE_BODY;
index_mail_cache_add(mail, cache_field, str, strlen(str)+1);
- if (data->parts->children != NULL) {
- /* cache the message parts only if this is a
- multipart message. it's pretty useless otherwise. */
- cache_parts(mail);
- }
-
if (field == MAIL_FETCH_IMAP_BODYSTRUCTURE)
data->bodystructure = str;
else