dovecot-1.2: mail_index_update_header_ext() can now be called mu...

dovecot at dovecot.org dovecot at dovecot.org
Wed Jun 18 12:09:57 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/efb782e078b9
changeset: 7896:efb782e078b9
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Jun 18 08:09:33 2008 +0300
description:
mail_index_update_header_ext() can now be called multiple times for the same
extension.

diffstat:

3 files changed, 65 insertions(+), 41 deletions(-)
src/lib-index/mail-index-transaction-private.h |   10 ++--
src/lib-index/mail-index-transaction.c         |   49 +++++++++++++-----------
src/lib-index/mail-transaction-log-append.c    |   47 +++++++++++++++--------

diffs (203 lines):

diff -r 5bedea448cf9 -r efb782e078b9 src/lib-index/mail-index-transaction-private.h
--- a/src/lib-index/mail-index-transaction-private.h	Wed Jun 18 08:08:45 2008 +0300
+++ b/src/lib-index/mail-index-transaction-private.h	Wed Jun 18 08:09:33 2008 +0300
@@ -10,10 +10,10 @@ struct mail_index_transaction_keyword_up
 };
 
 struct mail_index_transaction_ext_hdr_update {
-	uint32_t ext_id;
-	uint16_t offset;
-	uint16_t size;
-	/* unsigned char data[]; */
+	size_t alloc_size;
+	/* mask is in bytes, not bits */
+	unsigned char *mask;
+	unsigned char *data;
 };
 
 struct mail_index_transaction_vfuncs {
@@ -48,7 +48,7 @@ struct mail_index_transaction {
 	unsigned char post_hdr_mask[sizeof(struct mail_index_header)];
 
 	ARRAY_DEFINE(ext_hdr_updates,
-		     struct mail_index_transaction_ext_hdr_update *);
+		     struct mail_index_transaction_ext_hdr_update);
 	ARRAY_DEFINE(ext_rec_updates, ARRAY_TYPE(seq_array));
 	ARRAY_DEFINE(ext_resizes, struct mail_transaction_ext_intro);
 	ARRAY_DEFINE(ext_resets, struct mail_transaction_ext_reset);
diff -r 5bedea448cf9 -r efb782e078b9 src/lib-index/mail-index-transaction.c
--- a/src/lib-index/mail-index-transaction.c	Wed Jun 18 08:08:45 2008 +0300
+++ b/src/lib-index/mail-index-transaction.c	Wed Jun 18 08:09:33 2008 +0300
@@ -27,7 +27,7 @@ void mail_index_transaction_reset(struct
 void mail_index_transaction_reset(struct mail_index_transaction *t)
 {
 	ARRAY_TYPE(seq_array) *recs;
-	struct mail_index_transaction_ext_hdr_update **ext_hdrs;
+	struct mail_index_transaction_ext_hdr_update *ext_hdrs;
 	unsigned i, count;
 
 	if (array_is_created(&t->ext_rec_updates)) {
@@ -42,8 +42,10 @@ void mail_index_transaction_reset(struct
 	if (array_is_created(&t->ext_hdr_updates)) {
 		ext_hdrs = array_get_modifiable(&t->ext_hdr_updates, &count);
 
-		for (i = 0; i < count; i++)
-			i_free(ext_hdrs[i]);
+		for (i = 0; i < count; i++) {
+			i_free(ext_hdrs[i].data);
+			i_free(ext_hdrs[i].mask);
+		}
 		array_free(&t->ext_hdr_updates);
 	}
 
@@ -1134,11 +1136,11 @@ mail_index_transaction_has_ext_changes(s
 		}
 	}
 	if (array_is_created(&t->ext_hdr_updates)) {
-		struct mail_index_transaction_ext_hdr_update *const *hdr;
+		const struct mail_index_transaction_ext_hdr_update *hdr;
 
 		hdr = array_get(&t->ext_hdr_updates, &count);
 		for (i = 0; i < count; i++) {
-			if (hdr[i] != NULL)
+			if (hdr[i].alloc_size > 0)
 				return TRUE;
 		}
 	}
@@ -1178,11 +1180,14 @@ void mail_index_ext_set_reset_id(struct 
 	if (array_is_created(&t->ext_hdr_updates) &&
 	    ext_id < array_count(&t->ext_hdr_updates)) {
 		/* if extension headers have been updated, clear them */
-		struct mail_index_transaction_ext_hdr_update **hdr;
+		struct mail_index_transaction_ext_hdr_update *hdr;
 
 		hdr = array_idx_modifiable(&t->ext_hdr_updates, ext_id);
-		if (*hdr != NULL)
-			i_free_and_null(*hdr);
+		if (hdr->alloc_size > 0) {
+			i_free_and_null(hdr->mask);
+			i_free_and_null(hdr->data);
+		}
+		hdr->alloc_size = 0;
 	}
 	if (array_is_created(&t->ext_resets) &&
 	    ext_id < array_count(&t->ext_resets)) {
@@ -1206,23 +1211,25 @@ void mail_index_update_header_ext(struct
 				  uint32_t ext_id, size_t offset,
 				  const void *data, size_t size)
 {
-	struct mail_index_transaction_ext_hdr_update *hdr, **pos;
-
-	hdr = i_malloc(sizeof(*hdr) + size);
-	hdr->ext_id = ext_id;
-	hdr->offset = offset;
-	hdr->size = size;
-	memcpy(hdr + 1, data, size);
+	struct mail_index_transaction_ext_hdr_update *hdr;
+	size_t new_size;
+
+	i_assert(offset <= (uint16_t)-1 && size <= (uint16_t)-1 &&
+		 offset + size <= (uint16_t)-1);
 
 	if (!array_is_created(&t->ext_hdr_updates))
 		i_array_init(&t->ext_hdr_updates, ext_id + 2);
 
-	pos = array_idx_modifiable(&t->ext_hdr_updates, ext_id);
-	if (*pos != NULL) {
-		i_panic("mail_index_update_header_ext() doesn't currently "
-			"support multiple updates to the same ext header");
-	}
-	*pos = hdr;
+	hdr = array_idx_modifiable(&t->ext_hdr_updates, ext_id);
+	if (hdr->alloc_size < offset || hdr->alloc_size - offset < size) {
+		i_assert(size < (size_t)-1 - offset);
+		new_size = nearest_power(offset + size);
+		hdr->mask = i_realloc(hdr->mask, hdr->alloc_size, new_size);
+		hdr->data = i_realloc(hdr->data, hdr->alloc_size, new_size);
+		hdr->alloc_size = new_size;
+	}
+	memset(hdr->mask + offset, 1, size);
+	memcpy(hdr->data + offset, data, size);
 
 	t->log_ext_updates = TRUE;
 }
diff -r 5bedea448cf9 -r efb782e078b9 src/lib-index/mail-transaction-log-append.c
--- a/src/lib-index/mail-transaction-log-append.c	Wed Jun 18 08:08:45 2008 +0300
+++ b/src/lib-index/mail-transaction-log-append.c	Wed Jun 18 08:09:33 2008 +0300
@@ -289,18 +289,35 @@ static void log_append_ext_intro(struct 
 
 static void
 log_append_ext_hdr_update(struct log_append_context *ctx,
-			  struct mail_index_transaction_ext_hdr_update *hdr)
-{
-	struct mail_transaction_ext_hdr_update *trans_hdr;
+			const struct mail_index_transaction_ext_hdr_update *hdr)
+{
 	buffer_t *buf;
-	unsigned int hdr_size;
-
-	hdr_size = sizeof(*trans_hdr) + hdr->size + 4;
-	buf = buffer_create_static_hard(pool_datastack_create(), hdr_size);
-	trans_hdr = buffer_append_space_unsafe(buf, sizeof(*trans_hdr));
-	trans_hdr->offset = hdr->offset;
-	trans_hdr->size = hdr->size;
-	buffer_append(buf, hdr + 1, hdr->size);
+	const unsigned char *data, *mask;
+	struct mail_transaction_ext_hdr_update u;
+	uint16_t offset;
+	bool started = FALSE;
+
+	memset(&u, 0, sizeof(u));
+
+	data = hdr->data;
+	mask = hdr->mask;
+
+	buf = buffer_create_dynamic(pool_datastack_create(), 256);
+	for (offset = 0; offset <= hdr->alloc_size; offset++) {
+		if (offset < hdr->alloc_size && mask[offset] != 0) {
+			if (!started) {
+				u.offset = offset;
+				started = TRUE;
+			}
+		} else {
+			if (started) {
+				u.size = offset - u.offset;
+				buffer_append(buf, &u, sizeof(u));
+				buffer_append(buf, data + u.offset, u.size);
+				started = FALSE;
+			}
+		}
+	}
 	if (buf->used % 4 != 0)
 		buffer_append_zero(buf, 4 - buf->used % 4);
 	log_append_buffer(ctx, buf, NULL, MAIL_TRANSACTION_EXT_HDR_UPDATE);
@@ -311,7 +328,7 @@ mail_transaction_log_append_ext_intros(s
 {
 	struct mail_index_transaction *t = ctx->trans;
         const struct mail_transaction_ext_intro *resize;
-	struct mail_index_transaction_ext_hdr_update *const *hdrs;
+	const struct mail_index_transaction_ext_hdr_update *hdrs;
 	struct mail_transaction_ext_reset ext_reset;
 	unsigned int update_count, resize_count, ext_count = 0;
 	unsigned int hdrs_count, reset_id_count, reset_count;
@@ -377,7 +394,7 @@ mail_transaction_log_append_ext_intros(s
 		    (ext_id < update_count &&
 		     array_is_created(&update[ext_id])) ||
 		    ext_reset.new_reset_id != 0 ||
-		    (ext_id < hdrs_count && hdrs[ext_id] != NULL)) {
+		    (ext_id < hdrs_count && hdrs[ext_id].alloc_size > 0)) {
 			reset_id = ext_id < reset_id_count &&
 				ext_reset.new_reset_id == 0 ?
 				reset_ids[ext_id] : 0;
@@ -389,9 +406,9 @@ mail_transaction_log_append_ext_intros(s
 			log_append_buffer(ctx, buf, NULL,
 					  MAIL_TRANSACTION_EXT_RESET);
 		}
-		if (ext_id < hdrs_count && hdrs[ext_id] != NULL) {
+		if (ext_id < hdrs_count && hdrs[ext_id].alloc_size > 0) {
 			T_BEGIN {
-				log_append_ext_hdr_update(ctx, hdrs[ext_id]);
+				log_append_ext_hdr_update(ctx, &hdrs[ext_id]);
 			} T_END;
 		}
 	}


More information about the dovecot-cvs mailing list