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
+};