dovecot-2.2: lib-mail: Added support for struct message_part <->...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Apr 17 14:13:34 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/e5635fc0710f
changeset: 17238:e5635fc0710f
user: Timo Sirainen <tss at iki.fi>
date: Thu Apr 17 16:09:52 2014 +0200
description:
lib-mail: Added support for struct message_part <-> index number translations.
diffstat:
src/lib-mail/Makefile.am | 6 ++
src/lib-mail/message-parser.c | 4 +-
src/lib-mail/message-part-serialize.c | 4 +-
src/lib-mail/message-part.c | 40 +++++++++++++++
src/lib-mail/message-part.h | 11 ++++
src/lib-mail/test-message-part.c | 93 +++++++++++++++++++++++++++++++++++
6 files changed, 156 insertions(+), 2 deletions(-)
diffs (232 lines):
diff -r 63f12bb366b0 -r e5635fc0710f src/lib-mail/Makefile.am
--- a/src/lib-mail/Makefile.am Thu Apr 17 16:04:13 2014 +0200
+++ b/src/lib-mail/Makefile.am Thu Apr 17 16:09:52 2014 +0200
@@ -24,6 +24,7 @@
message-header-parser.c \
message-id.c \
message-parser.c \
+ message-part.c \
message-part-serialize.c \
message-search.c \
message-size.c \
@@ -77,6 +78,7 @@
test-message-header-parser \
test-message-id \
test-message-parser \
+ test-message-part \
test-quoted-printable \
test-rfc2231-parser
@@ -151,6 +153,10 @@
test_message_parser_LDADD = message-parser.lo message-header-parser.lo message-size.lo rfc822-parser.lo rfc2231-parser.lo $(test_libs)
test_message_parser_DEPENDENCIES = $(test_deps)
+test_message_part_SOURCES = test-message-part.c
+test_message_part_LDADD = message-part.lo message-parser.lo message-header-parser.lo message-size.lo rfc822-parser.lo rfc2231-parser.lo $(test_libs)
+test_message_part_DEPENDENCIES = $(test_deps)
+
test_quoted_printable_SOURCES = test-quoted-printable.c
test_quoted_printable_LDADD = quoted-printable.lo $(test_libs)
test_quoted_printable_DEPENDENCIES = $(test_deps)
diff -r 63f12bb366b0 -r e5635fc0710f src/lib-mail/message-parser.c
--- a/src/lib-mail/message-parser.c Thu Apr 17 16:04:13 2014 +0200
+++ b/src/lib-mail/message-parser.c Thu Apr 17 16:09:52 2014 +0200
@@ -163,10 +163,12 @@
static struct message_part *
message_part_append(pool_t pool, struct message_part *parent)
{
- struct message_part *part, **list;
+ struct message_part *p, *part, **list;
part = p_new(pool, struct message_part, 1);
part->parent = parent;
+ for (p = parent; p != NULL; p = p->parent)
+ p->children_count++;
/* set child position */
part->physical_pos =
diff -r 63f12bb366b0 -r e5635fc0710f src/lib-mail/message-part-serialize.c
--- a/src/lib-mail/message-part-serialize.c Thu Apr 17 16:04:13 2014 +0200
+++ b/src/lib-mail/message-part-serialize.c Thu Apr 17 16:09:52 2014 +0200
@@ -123,7 +123,7 @@
unsigned int siblings,
struct message_part **part_r)
{
- struct message_part *part, *first_part, **next_part;
+ struct message_part *p, *part, *first_part, **next_part;
unsigned int children_count;
uoff_t pos;
bool root = parent == NULL;
@@ -135,6 +135,8 @@
part = p_new(ctx->pool, struct message_part, 1);
part->parent = parent;
+ for (p = parent; p != NULL; p = p->parent)
+ p->children_count++;
if (!read_next(ctx, &part->flags, sizeof(part->flags)))
return FALSE;
diff -r 63f12bb366b0 -r e5635fc0710f src/lib-mail/message-part.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-mail/message-part.c Thu Apr 17 16:09:52 2014 +0200
@@ -0,0 +1,40 @@
+/* Copyright (c) 2014 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "message-part.h"
+
+unsigned int message_part_to_idx(const struct message_part *part)
+{
+ const struct message_part *p;
+ unsigned int n;
+
+ if (part->parent == NULL) {
+ /* root */
+ return 0;
+ }
+ for (n = 0, p = part->parent->children; p != part; p = p->next, n++)
+ ;
+ return n + 1 + message_part_to_idx(part->parent);
+}
+
+static struct message_part *
+message_sub_part_by_idx(struct message_part *parts,
+ unsigned int idx)
+{
+ struct message_part *part = parts;
+
+ for (; part != NULL && idx > 0; part = part->next) {
+ if (part->children_count >= idx)
+ return message_sub_part_by_idx(part->children, idx-1);
+ idx -= part->children_count + 1;
+ }
+ return part;
+}
+
+struct message_part *
+message_part_by_idx(struct message_part *parts, unsigned int idx);
+{
+ i_assert(parts->parent == NULL);
+
+ return message_sub_part_by_idx(parts, idx);
+}
diff -r 63f12bb366b0 -r e5635fc0710f src/lib-mail/message-part.h
--- a/src/lib-mail/message-part.h Thu Apr 17 16:04:13 2014 +0200
+++ b/src/lib-mail/message-part.h Thu Apr 17 16:09:52 2014 +0200
@@ -31,8 +31,19 @@
struct message_size header_size;
struct message_size body_size;
+ /* total number of message_parts under children */
+ unsigned int children_count;
enum message_part_flags flags;
void *context;
};
+/* Return index number for the message part. The indexes are in the same order
+ as they exist in the flat RFC822 message. The root part is 0, its first
+ child is 1 and so on. */
+unsigned int message_part_to_idx(const struct message_part *part);
+/* Find message part by its index number, or return NULL if the index
+ doesn't exist. */
+struct message_part *
+message_part_by_idx(struct message_part *parts, unsigned int idx);
+
#endif
diff -r 63f12bb366b0 -r e5635fc0710f src/lib-mail/test-message-part.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-mail/test-message-part.c Thu Apr 17 16:09:52 2014 +0200
@@ -0,0 +1,93 @@
+/* Copyright (c) 2014 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "istream.h"
+#include "message-parser.h"
+#include "test-common.h"
+
+static const char test_msg[] =
+"From user at domain Fri Feb 22 17:06:23 2008\n"
+"From: user at domain.org\n"
+"Date: Sat, 24 Mar 2007 23:00:00 +0200\n"
+"Mime-Version: 1.0\n"
+"Content-Type: multipart/mixed; boundary=\"foo bar\"\n"
+"\n"
+"Root MIME prologue\n"
+"\n"
+"--foo bar\n"
+"Content-Type: text/x-myown; charset=us-ascii\n"
+"\n"
+"hello\n"
+"\n"
+"--foo bar\n"
+"Content-Type: message/rfc822\n"
+"\n"
+"From: sub at domain.org\n"
+"Date: Sun, 12 Aug 2012 12:34:56 +0300\n"
+"Subject: submsg\n"
+"Content-Type: multipart/alternative; boundary=\"sub1\"\n"
+"\n"
+"Sub MIME prologue\n"
+"--sub1\n"
+"Content-Type: text/html\n"
+"\n"
+"<p>Hello world</p>\n"
+"\n"
+"--sub1\n"
+"Content-Type: text/plain\n"
+"\n"
+"Hello another world\n"
+"\n"
+"--sub1--\n"
+"Sub MIME epilogue\n"
+"\n"
+"--foo bar--\n"
+"Root MIME epilogue\n"
+"\n";
+#define TEST_MSG_LEN (sizeof(test_msg)-1)
+
+static void test_message_part_idx(void)
+{
+ struct message_parser_ctx *parser;
+ struct istream *input;
+ struct message_part *parts, *part, *prev_part;
+ struct message_block block;
+ unsigned int i;
+ pool_t pool;
+ int ret;
+
+ test_begin("message part indexes");
+ pool = pool_alloconly_create("message parser", 10240);
+ input = i_stream_create_from_data(test_msg, TEST_MSG_LEN);
+
+ parser = message_parser_init(pool, input, 0, 0);
+ while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
+ test_assert(ret < 0);
+ test_assert(message_parser_deinit(&parser, &parts) == 0);
+
+ part = message_part_by_idx(parts, 0);
+ test_assert(part == parts);
+ test_assert(message_part_by_idx(parts, 1) == parts->children);
+
+ for (i = 1; i < 6; i++) {
+ prev_part = part;
+ part = message_part_by_idx(parts, i);
+ test_assert(part != NULL);
+ test_assert(message_part_to_idx(part) == i);
+ test_assert(prev_part->physical_pos < part->physical_pos);
+ }
+ test_assert(message_part_by_idx(parts, i) == NULL);
+
+ i_stream_unref(&input);
+ pool_unref(&pool);
+ test_end();
+}
+
+int main(void)
+{
+ static void (*test_functions[])(void) = {
+ test_message_part_idx,
+ NULL
+ };
+ return test_run(test_functions);
+}
More information about the dovecot-cvs
mailing list