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