changeset 856:e49f7397af98 HEAD

Some bugfixes and speedups for partial fetch handling.
author Timo Sirainen <tss@iki.fi>
date Fri, 27 Dec 2002 15:05:53 +0200
parents c77a8b9fb3ef
children 3d437b1e5257
files src/lib-imap/imap-message-cache.c src/lib-mail/message-parser.c src/lib-mail/message-send.c src/lib-mail/message-size.c src/lib-mail/message-size.h
diffstat 5 files changed, 54 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-imap/imap-message-cache.c	Fri Dec 27 12:34:14 2002 +0200
+++ b/src/lib-imap/imap-message-cache.c	Fri Dec 27 15:05:53 2002 +0200
@@ -507,11 +507,14 @@
 	return TRUE;
 }
 
-static void get_partial_size(IStream *stream,
-			     uoff_t virtual_skip, uoff_t max_virtual_size,
-			     MessageSize *partial, MessageSize *dest,
-			     int *cr_skipped)
+static uoff_t get_partial_size(IStream *stream,
+			       uoff_t virtual_skip, uoff_t max_virtual_size,
+			       MessageSize *partial, MessageSize *dest,
+			       int *cr_skipped)
 {
+	uoff_t physical_skip;
+	int last_cr;
+
 	/* see if we can use the existing partial */
 	if (partial->virtual_size > virtual_skip)
 		memset(partial, 0, sizeof(MessageSize));
@@ -521,23 +524,31 @@
 	}
 
 	message_skip_virtual(stream, virtual_skip, partial, cr_skipped);
+        physical_skip = partial->physical_size;
 
 	if (*cr_skipped && max_virtual_size != (uoff_t)-1) {
 		/* get_body_size() sees \n first, counting it as \r\n */
 		max_virtual_size++;
 	}
 
-	message_get_body_size(stream, dest, max_virtual_size);
+	message_get_body_size(stream, dest, max_virtual_size, &last_cr);
 
 	if (*cr_skipped) {
 		/* extra virtual \r counted, drop it */
 		dest->virtual_size--;
+	}
+
+	message_size_add(partial, dest);
+	if (last_cr != 0) {
 		/* we'll see \n as first character next time, so make sure
 		   we don't count the (virtual) \r twice. */
+		i_assert(partial->physical_size > 0);
+
+		if (last_cr == 1)
+			partial->physical_size--;
 		partial->virtual_size--;
 	}
-
-	// FIXME: add dest to partial
+	return physical_skip;
 }
 
 int imap_msgcache_get_rfc822_partial(ImapMessageCache *cache,
@@ -596,11 +607,10 @@
 		if (!get_header)
 			virtual_skip += msg->hdr_size->virtual_size;
 
-		get_partial_size(cache->open_stream, virtual_skip,
-				 max_virtual_size, msg->partial_size, size,
-				 cr_skipped);
-
-		physical_skip = msg->partial_size->physical_size;
+		physical_skip =
+			get_partial_size(cache->open_stream, virtual_skip,
+					 max_virtual_size, msg->partial_size,
+					 size, cr_skipped);
 	}
 
 	/* seek to wanted position */
--- a/src/lib-mail/message-parser.c	Fri Dec 27 12:34:14 2002 +0200
+++ b/src/lib-mail/message-parser.c	Fri Dec 27 15:05:53 2002 +0200
@@ -549,7 +549,7 @@
 	MessageBoundary *boundary;
 
 	if (boundaries == NULL) {
-		message_get_body_size(input, body_size, (uoff_t)-1);
+		message_get_body_size(input, body_size, (uoff_t)-1, NULL);
 		return NULL;
 	} else {
 		boundary = message_find_boundary(input, boundaries,
--- a/src/lib-mail/message-send.c	Fri Dec 27 12:34:14 2002 +0200
+++ b/src/lib-mail/message-send.c	Fri Dec 27 15:05:53 2002 +0200
@@ -37,26 +37,19 @@
 	message_skip_virtual(input, virtual_skip, NULL, &cr_skipped);
 
 	/* go through the message data and insert CRs where needed.  */
-	while (i_stream_read_data(input, &msg, &size, 0) > 0) {
+	while (max_virtual_size > 0 &&
+	       i_stream_read_data(input, &msg, &size, 0) > 0) {
 		add_cr = FALSE;
-		for (i = 0; i < size; i++) {
+		for (i = 0; i < size && max_virtual_size > 0; i++) {
+			max_virtual_size--;
+
 			if (msg[i] == '\n') {
 				if ((i == 0 && !cr_skipped) ||
 				    (i > 0 && msg[i-1] != '\r')) {
 					/* missing CR */
-					if (max_virtual_size > 0)
-						max_virtual_size--;
 					add_cr = TRUE;
 					break;
 				}
-
-			}
-
-			if (max_virtual_size > 0) {
-				if (--max_virtual_size == 0) {
-					i++;
-					break;
-				}
 			}
 		}
 
@@ -71,10 +64,6 @@
 			cr_skipped = i > 0 && msg[i-1] == '\r';
 		}
 
-		/* see if we've reached the limit */
-		if (max_virtual_size == 0)
-			break;
-
 		i_stream_skip(input, i);
 	}
 
--- a/src/lib-mail/message-size.c	Fri Dec 27 12:34:14 2002 +0200
+++ b/src/lib-mail/message-size.c	Fri Dec 27 15:05:53 2002 +0200
@@ -56,40 +56,44 @@
 }
 
 void message_get_body_size(IStream *input, MessageSize *body,
-			   uoff_t max_virtual_size)
+			   uoff_t max_virtual_size, int *last_cr)
 {
 	const unsigned char *msg;
 	size_t i, size, startpos, missing_cr_count;
+	int cr;
 
 	memset(body, 0, sizeof(MessageSize));
 
+	cr = 0;
 	missing_cr_count = 0; startpos = 0;
 	while (max_virtual_size != 0 &&
 	       i_stream_read_data(input, &msg, &size, startpos) > 0) {
-		for (i = startpos; i < size && max_virtual_size != 0; i++) {
-			if (max_virtual_size > 0)
-				max_virtual_size--;
-
-			if (msg[i] != '\n')
-				continue;
+		cr = 0;
+		for (i = startpos; i < size && max_virtual_size > 0; i++) {
+			max_virtual_size--;
 
-			if (i == 0 || msg[i-1] != '\r') {
-				/* missing CR */
-				missing_cr_count++;
+			if (msg[i] == '\n') {
+				if (i == 0 || msg[i-1] != '\r') {
+					/* missing CR */
+					missing_cr_count++;
 
-				if (max_virtual_size > 0) {
-					if (max_virtual_size == 0)
+					if (max_virtual_size == 0) {
+						cr = 2;
 						break;
+					}
 
 					max_virtual_size--;
 				}
-			}
 
-			/* increase after making sure we didn't break
-			   at virtual \r */
-			body->lines++;
+				/* increase after making sure we didn't break
+				   at virtual \r */
+				body->lines++;
+			}
 		}
 
+		if (cr == 0 && i > 0 && msg[i-1] == '\r')
+			cr = 1;
+
 		/* leave the last character, it may be \r */
 		i_stream_skip(input, i - 1);
 		startpos = 1;
@@ -101,6 +105,9 @@
 
 	body->virtual_size = body->physical_size + missing_cr_count;
 	i_assert(body->virtual_size >= body->physical_size);
+
+	if (last_cr != NULL)
+		*last_cr = cr;
 }
 
 void message_skip_virtual(IStream *input, uoff_t virtual_skip,
--- a/src/lib-mail/message-size.h	Fri Dec 27 12:34:14 2002 +0200
+++ b/src/lib-mail/message-size.h	Fri Dec 27 15:05:53 2002 +0200
@@ -7,9 +7,10 @@
    character in body. */
 void message_get_header_size(IStream *input, MessageSize *hdr);
 /* Calculate size of message body. Read only max_virtual_size virtual bytes,
-   if you want it unlimited, use (uoff_t)-1. */
+   if you want it unlimited, use (uoff_t)-1. If last_cr is not NULL, it's set
+   to 1 if last character is CR, 2 if it's virtual CR. */
 void message_get_body_size(IStream *input, MessageSize *body,
-			   uoff_t max_virtual_size);
+			   uoff_t max_virtual_size, int *last_cr);
 
 /* Skip number of virtual bytes from putfer. If first character is \n, and
    cr_skipped is FALSE, \r must be sent before it. msg_size is updated if