Mercurial > dovecot > original-hg > dovecot-1.2
changeset 113:76a3a6c0c452 HEAD
forgot to add before
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 02 Sep 2002 20:11:26 +0300 |
parents | d6105a8a6ca9 |
children | 0c3ffb677ad1 |
files | src/lib-mail/message-part-serialize.c src/lib-mail/message-part-serialize.h src/lib-storage/index/index-msgcache.c |
diffstat | 3 files changed, 256 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-mail/message-part-serialize.c Mon Sep 02 20:11:26 2002 +0300 @@ -0,0 +1,155 @@ +/* Copyright (C) 2002 Timo Sirainen */ + +#include "lib.h" +#include "message-parser.h" +#include "message-part-serialize.h" + +/* + Serialized a series of SerializedMessageParts: + + root part + root's first children + children's first children + ... + root's next children + ... +*/ + +/* struct is 8 byte aligned */ +typedef struct { + uoff_t physical_pos; + + uoff_t header_physical_size; + uoff_t header_virtual_size; + + uoff_t body_physical_size; + uoff_t body_virtual_size; + + unsigned int header_lines; + unsigned int body_lines; + + unsigned int children_count; + unsigned int flags; +} SerializedMessagePart; + +static void message_part_serialize_part(MessagePart *part, + unsigned int *children_count, + SerializedMessagePart **spart_base, + unsigned int *pos, unsigned int *size) +{ + SerializedMessagePart *spart; + unsigned int buf_size; + + while (part != NULL) { + /* make sure we have space */ + if (*pos == *size) { + *size *= 2; + buf_size = sizeof(SerializedMessagePart) * (*size); + + *spart_base = t_buffer_reget(*spart_base, buf_size); + } + + /* create serialized part */ + spart = (*spart_base) + (*pos); + memset(spart, 0, sizeof(SerializedMessagePart)); + + spart->physical_pos = part->physical_pos; + + spart->header_physical_size = part->header_size.physical_size; + spart->header_virtual_size = part->header_size.virtual_size; + spart->header_lines = part->header_size.lines; + + spart->body_physical_size = part->body_size.physical_size; + spart->body_virtual_size = part->body_size.virtual_size; + spart->body_lines = part->body_size.lines; + + spart->children_count = 0; + spart->flags = part->flags; + + if (children_count != NULL) + (*children_count)++; + (*pos)++; + + if (part->children != NULL) { + message_part_serialize_part(part->children, + &spart->children_count, + spart_base, pos, size); + } + part = part->next; + } +} + +const void *message_part_serialize(MessagePart *part, unsigned int *size) +{ + SerializedMessagePart *spart_base; + unsigned int pos, buf_size; + + buf_size = 32; + spart_base = t_buffer_get(sizeof(SerializedMessagePart) * buf_size); + + pos = 0; + message_part_serialize_part(part, NULL, &spart_base, &pos, &buf_size); + + *size = sizeof(SerializedMessagePart) * pos; + t_buffer_alloc(*size); + return spart_base; +} + +static MessagePart * +message_part_deserialize_part(Pool pool, MessagePart *parent, + const SerializedMessagePart **spart_pos, + unsigned int *count, unsigned int child_count) +{ + const SerializedMessagePart *spart; + MessagePart *part, *first_part, **next_part; + unsigned int i; + + first_part = NULL; + next_part = NULL; + for (i = 0; i < child_count && *count > 0; i++) { + spart = *spart_pos; + (*spart_pos)++; + (*count)--; + + part = p_new(pool, MessagePart, 1); + part->physical_pos = spart->physical_pos; + + part->header_size.physical_size = spart->header_physical_size; + part->header_size.virtual_size = spart->header_virtual_size; + part->header_size.lines = spart->header_lines; + + part->body_size.physical_size = spart->body_physical_size; + part->body_size.virtual_size = spart->body_virtual_size; + part->body_size.lines = spart->body_lines; + + part->flags = spart->flags; + + part->parent = parent; + part->children = message_part_deserialize_part(pool, part, + spart_pos, count, + spart->children_count); + + if (first_part == NULL) + first_part = part; + if (next_part != NULL) + *next_part = part; + next_part = &part->next; + } + + return first_part; +} + +MessagePart *message_part_deserialize(Pool pool, const void *data, + unsigned int size) +{ + const SerializedMessagePart *spart; + unsigned int count; + + /* make sure it looks valid */ + if (size == 0 || (size % sizeof(SerializedMessagePart)) != 0) + return NULL; + + spart = data; + count = size / sizeof(SerializedMessagePart); + return message_part_deserialize_part(pool, NULL, &spart, &count, count); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-mail/message-part-serialize.h Mon Sep 02 20:11:26 2002 +0300 @@ -0,0 +1,12 @@ +#ifndef __MESSAGE_PART_SERIALIZE_H +#define __MESSAGE_PART_SERIALIZE_H + +/* Serialize message part, allocating memory from temporary pool. + size is updated to contain the size of returned data. */ +const void *message_part_serialize(MessagePart *part, unsigned int *size); + +/* Generate MessagePart from serialized data. */ +MessagePart *message_part_deserialize(Pool pool, const void *data, + unsigned int size); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib-storage/index/index-msgcache.c Mon Sep 02 20:11:26 2002 +0300 @@ -0,0 +1,89 @@ +/* Copyright (C) 2002 Timo Sirainen */ + +#include "lib.h" +#include "iobuffer.h" +#include "imap-message-cache.h" +#include "message-part-serialize.h" +#include "mail-index.h" + +#include <unistd.h> + +typedef struct { + MailIndex *index; + MailIndexRecord *rec; +} IndexMsgcacheContext; + +void *index_msgcache_get_context(MailIndex *index, MailIndexRecord *rec) +{ + IndexMsgcacheContext *ctx; + + ctx = t_new(IndexMsgcacheContext, 1); + ctx->index = index; + ctx->rec = rec; + return ctx; +} + +static IOBuffer *index_msgcache_open_mail(void *context) +{ + IndexMsgcacheContext *ctx = context; + + return ctx->index->open_mail(ctx->index, ctx->rec); +} + +static IOBuffer *index_msgcache_inbuf_rewind(IOBuffer *inbuf, + void *context __attr_unused__) +{ + if (!io_buffer_seek(inbuf, 0)) { + i_error("index_msgcache_inbuf_rewind: lseek() failed: %m"); + + (void)close(inbuf->fd); + io_buffer_destroy(inbuf); + return NULL; + } + + return inbuf; +} + +static const char *index_msgcache_get_cached_field(ImapCacheField field, + void *context) +{ + IndexMsgcacheContext *ctx = context; + MailField index_field; + + switch (field) { + case IMAP_CACHE_BODY: + index_field = FIELD_TYPE_BODY; + break; + case IMAP_CACHE_BODYSTRUCTURE: + index_field = FIELD_TYPE_BODYSTRUCTURE; + break; + case IMAP_CACHE_ENVELOPE: + index_field = FIELD_TYPE_ENVELOPE; + break; + default: + index_field = 0; + } + + return index_field == 0 ? NULL : + ctx->index->lookup_field(ctx->index, ctx->rec, index_field); +} + +static MessagePart *index_msgcache_get_cached_parts(Pool pool, void *context) +{ + IndexMsgcacheContext *ctx = context; + const void *part_data; + unsigned int part_size; + + part_data = ctx->index->lookup_field_raw(ctx->index, ctx->rec, + FIELD_TYPE_MESSAGEPART, + &part_size); + return part_data == NULL ? NULL : + message_part_deserialize(pool, part_data, part_size); +} + +ImapMessageCacheIface index_msgcache_iface = { + index_msgcache_open_mail, + index_msgcache_inbuf_rewind, + index_msgcache_get_cached_field, + index_msgcache_get_cached_parts +};