Re: [Evolution-hackers] Folder summaries with mmap() (version nine -- fixes a leak)



On Tue, 2006-07-11 at 13:17 +0200, Philip Van Hoof wrote:
> This is a version (version eight) that actually works (afaics).

This version (version nine) fixes a leak when new messages arrive.

However. The implementation/architecture of Camel requires that new
messages get transformed into CamelMessageInfo instances and added to
the CamelSummaryInfo structure. I think it would be better to simply
a.s.a.p. write it to the summary file and at the end of getting the new
messages, create a new CamelSummaryInfo structure with the new message
info instances ... using the mmap technique.

Currently it's obviously consuming more memory when new messages arrive
(compared to the mmap technique). In Evolution, such a folder never gets
closed. So it will for ever keep using this memory structure (in stead
of the information using the mmap).

Doing this would require appending to the summary file, closing the
summary object instance (which closes the mmap), reopening it when
receiving new messages completed and letting the mmap code parse that
into message-info instances.

Note .. starting from "add_message_from_data" (in camel-imap-folder.c),
there's a leak.

I think the leak is at camel_folder_summary_info_new_from_message and
more specific the message_info_new_from_header. The leak is ~200 kb for
a folder of ~10,000 headers

http://pvanhoof.be/files/camel_folder_summary_with_mmap_fixes09.diff

There's lots of decoding and copying happening there. So it's not going
to be easy to spot it.


> Therefore I'm re-adding the evolution-patches mailing list. Because the
> mailing lists are slow, I'm also adding some people that might have a
> direct interest in this.
> 
> Please review this patch carefully and multiple times. Please do ask me
> questions about it (if needed). Please do test it extensively. Please do
> launch your evolution with valgrind massif and also under gdb.
> 
> In case a crash happens in the ..decode_uint32 method , 'up' twice and
> 'print *s' so that you know the filename and other interesting infor-
> mation. Also check s->filepos to know the current file position and for
> example check variables like 'count' and 'len' after doing one 'up'.
> 
> You can also find a copy here. I will upload new versions to the same
> location (and will increase the version number in the filename).
> 
> http://pvanhoof.be/files/camel_folder_summary_with_mmap_fixes08.diff
> 

-- 
Philip Van Hoof, software developer at x-tend 
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
work: vanhoof at x-tend dot be 
http://www.pvanhoof.be - http://www.x-tend.be
? .broken-date-parser.c.swp
? camel-mime-tables.c
Index: camel-file-utils.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-file-utils.c,v
retrieving revision 1.17
diff -u -p -r1.17 camel-file-utils.c
--- camel-file-utils.c	2 Jun 2006 00:52:29 -0000	1.17
+++ camel-file-utils.c	11 Jul 2006 14:34:18 -0000
@@ -105,6 +105,46 @@ camel_file_util_decode_uint32 (FILE *in,
 }
 
 
+unsigned char*
+camel_file_util_mmap_decode_uint32 (unsigned char *start, guint32 *dest, gboolean is_string)
+{
+	guint32 value = 0, rlen;
+	int v;
+	unsigned char *retval;
+
+	/* until we get the last byte, keep decoding 7 bits at a time */
+
+        while ( ((v = *start++) & 0x80) == 0 ) {
+                value |= v;
+                value <<= 7;
+        }
+
+	rlen = value | (v & 0x7f);
+	retval = start;
+
+	if (is_string) {
+#ifdef DEVEL
+		if (rlen == 1) {
+			rlen = 0;
+		} else {
+			unsigned int slen = strlen ((char*)retval)+1;
+			if (slen != rlen) {
+				printf ("Problem in fileformat. String was %d, should be %d for %s %02x at %d\n", rlen, slen, retval, *retval, retval);
+				rlen = slen;
+			}
+		}
+#else
+		if (rlen == 1)
+			rlen = 0;
+#endif
+
+	}
+
+
+	*dest = rlen;
+	return retval;
+}
+
 /**
  * camel_file_util_encode_fixed_int32:
  * @out: file to output to
@@ -167,7 +207,7 @@ int							\
 camel_file_util_decode_##type(FILE *in, type *dest)	\
 {							\
 	type save = 0;					\
-	int i = sizeof(type) - 1;			\
+	int i = sizeof(type) -1;			\
 	int v = EOF;					\
 							\
         while (i >= 0 && (v = fgetc (in)) != EOF) {	\
@@ -181,6 +221,24 @@ camel_file_util_decode_##type(FILE *in, 
 }
 
 
+#define MMAP_DECODE_T(type)				\
+unsigned char*						\
+camel_file_util_mmap_decode_##type(unsigned char *start, type *dest)	\
+{							\
+	type save = 0;					\
+	int i = sizeof(type) - 1;			\
+	int v;						\
+							\
+        while (i >= 0) {				\
+		v = *start++;				\
+		save |= ((type)v) << (i * 8);		\
+		i--;					\
+	}						\
+	*dest = save;					\
+	return start;					\
+}
+
+
 /**
  * camel_file_util_encode_time_t:
  * @out: file to output to
@@ -202,6 +260,7 @@ CFU_ENCODE_T(time_t)
  * Return value: 0 on success, -1 on error.
  **/
 CFU_DECODE_T(time_t)
+MMAP_DECODE_T(time_t)
 
 /**
  * camel_file_util_encode_off_t:
@@ -225,6 +284,7 @@ CFU_ENCODE_T(off_t)
  * Return value: 0 on success, -1 on failure.
  **/
 CFU_DECODE_T(off_t)
+MMAP_DECODE_T(off_t)
 
 /**
  * camel_file_util_encode_size_t:
@@ -248,6 +308,7 @@ CFU_ENCODE_T(size_t)
  * Return value: 0 on success, -1 on failure.
  **/
 CFU_DECODE_T(size_t)
+MMAP_DECODE_T(size_t)
 
 
 /**
@@ -269,11 +330,22 @@ camel_file_util_encode_string (FILE *out
 	
 	if ((len = strlen (str)) > 65536)
 		len = 65536;
+
+	if (len==0) len=-1;
 	
 	if (camel_file_util_encode_uint32 (out, len+1) == -1)
 		return -1;
-	if (len == 0 || fwrite (str, len, 1, out) == 1)
-		return 0;
+
+	if (len != 0)
+	{
+		if (fwrite (str, len, 1, out) == 1)
+		{
+			if (fputc ('\0', out) == -1)
+				return -1;
+			return 0;
+		}
+	}
+
 	return -1;
 }
 
@@ -291,7 +363,8 @@ int
 camel_file_util_decode_string (FILE *in, char **str)
 {
 	guint32 len;
-	register char *ret;
+	register char *ret, c;
+	long a;
 
 	if (camel_file_util_decode_uint32 (in, &len) == -1) {
 		*str = NULL;
@@ -311,7 +384,14 @@ camel_file_util_decode_string (FILE *in,
 		return -1;
 	}
 
+	a = ftell (in);
+
+	if ((c = fgetc (in)) != '\0')
+		/* If this is the old format, oeps .. we are so sorry */
+		fseek (in, a, SEEK_SET);
+
 	ret[len] = 0;
+
 	*str = ret;
 	return 0;
 }
Index: camel-file-utils.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-file-utils.h,v
retrieving revision 1.11
diff -u -p -r1.11 camel-file-utils.h
--- camel-file-utils.h	10 Jan 2006 07:56:46 -0000	1.11
+++ camel-file-utils.h	11 Jul 2006 14:34:18 -0000
@@ -46,6 +46,7 @@ int camel_file_util_encode_fixed_int32 (
 int camel_file_util_decode_fixed_int32 (FILE *in, gint32 *);
 int camel_file_util_encode_uint32 (FILE *out, guint32);
 int camel_file_util_decode_uint32 (FILE *in, guint32 *);
+
 int camel_file_util_encode_time_t (FILE *out, time_t);
 int camel_file_util_decode_time_t (FILE *in, time_t *);
 int camel_file_util_encode_off_t (FILE *out, off_t);
@@ -54,6 +55,11 @@ int camel_file_util_encode_size_t (FILE 
 int camel_file_util_decode_size_t (FILE *in, size_t *);
 int camel_file_util_encode_string (FILE *out, const char *);
 int camel_file_util_decode_string (FILE *in, char **);
+
+unsigned char* camel_file_util_mmap_decode_time_t(unsigned char *start, time_t *dest);
+unsigned char* camel_file_util_mmap_decode_off_t(unsigned char *start, off_t *dest);
+unsigned char* camel_file_util_mmap_decode_size_t(unsigned char *start, size_t *dest);
+unsigned char* camel_file_util_mmap_decode_uint32 (unsigned char *start, guint32 *dest, gboolean is_string);
 
 char *camel_file_util_safe_filename (const char *name);
 
Index: camel-folder-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-folder-summary.c,v
retrieving revision 1.149
diff -u -p -r1.149 camel-folder-summary.c
--- camel-folder-summary.c	6 Jul 2006 19:43:46 -0000	1.149
+++ camel-folder-summary.c	11 Jul 2006 14:34:19 -0000
@@ -50,6 +50,7 @@
 #include "camel-stream-null.h"
 #include "camel-stream-filter.h"
 #include "camel-string-utils.h"
+#include "camel-disco-folder.h"
 
 #include "libedataserver/md5-utils.h"
 #include "libedataserver/e-memory.h"
@@ -66,15 +67,15 @@ static pthread_mutex_t info_lock = PTHRE
 /* this should probably be conditional on it existing */
 #define USE_BSEARCH
 
-#define d(x)
+#define d(x)	
 #define io(x)			/* io debug */
-#define w(x)
+#define w(x)	
 
 #if 0
 extern int strdup_count, malloc_count, free_count;
 #endif
 
-#define CAMEL_FOLDER_SUMMARY_VERSION (13)
+#define CAMEL_FOLDER_SUMMARY_VERSION (14)
 
 #define _PRIVATE(o) (((CamelFolderSummary *)(o))->priv)
 
@@ -86,13 +87,13 @@ struct _node {
 static struct _node *my_list_append(struct _node **list, struct _node *n);
 static int my_list_size(struct _node **list);
 
-static int summary_header_load(CamelFolderSummary *, FILE *);
-static int summary_header_save(CamelFolderSummary *, FILE *);
+static int summary_header_load(CamelFolderSummary *, FILE *in);
+static int summary_header_save(CamelFolderSummary *, FILE *out);
 
 static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
 static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
 static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg);
-static CamelMessageInfo * message_info_load(CamelFolderSummary *, FILE *);
+static CamelMessageInfo * message_info_load(CamelFolderSummary *, FILE *in);
 static int		  message_info_save(CamelFolderSummary *, FILE *, CamelMessageInfo *);
 static void		  message_info_free(CamelFolderSummary *, CamelMessageInfo *);
 
@@ -160,6 +161,11 @@ camel_folder_summary_finalize (CamelObje
 	struct _CamelFolderSummaryPrivate *p;
 	CamelFolderSummary *s = (CamelFolderSummary *)obj;
 
+
+	if (s->file)
+		g_mapped_file_free (s->file);
+	s->file = NULL;
+
 	p = _PRIVATE(obj);
 
 	camel_folder_summary_clear(s);
@@ -236,7 +242,7 @@ camel_folder_summary_new (struct _CamelF
 	CamelFolderSummary *new = CAMEL_FOLDER_SUMMARY ( camel_object_new (camel_folder_summary_get_type ()));
 
 	new->folder = folder;
-
+	
 	return new;
 }
 
@@ -504,17 +510,24 @@ perform_content_info_load(CamelFolderSum
 	int i;
 	guint32 count;
 	CamelMessageContentInfo *ci, *part;
+	unsigned char *ptrchr = s->filepos;
 
 	ci = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_load(s, in);
+
 	if (ci == NULL)
 		return NULL;
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500) {
+	ptrchr = s->filepos;
+	ptrchr = camel_file_util_mmap_decode_uint32 ((unsigned char*)ptrchr, &count, FALSE);
+	s->filepos = ptrchr;
+
+	if (count > 500) {
 		camel_folder_summary_content_info_free(s, ci);
 		return NULL;
 	}
 
 	for (i=0;i<count;i++) {
+
 		part = perform_content_info_load(s, in);
 		if (part) {
 			my_list_append((struct _node **)&ci->childs, (struct _node *)part);
@@ -540,31 +553,34 @@ perform_content_info_load(CamelFolderSum
 int
 camel_folder_summary_load(CamelFolderSummary *s)
 {
-	FILE *in;
 	int i;
 	CamelMessageInfo *mi;
 
-	if (s->summary_path == NULL)
-		return 0;
 
-	in = g_fopen(s->summary_path, "rb");
-	if (in == NULL)
-		return -1;
+	if (s->summary_path == NULL || !g_file_test (s->summary_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
+		return 0;
 
 	CAMEL_SUMMARY_LOCK(s, io_lock);
-	if ( ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, in) == -1)
+
+	if (!s->file)
+		s->file = g_mapped_file_new (s->summary_path, FALSE, NULL);
+
+	s->filepos = g_mapped_file_get_contents (s->file);
+
+	if ( ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, NULL) == -1)
 		goto error;
 
 	/* now read in each message ... */
 	for (i=0;i<s->saved_count;i++) {
-		mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_load(s, in);
+		mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_load(s, NULL);
 
 		if (mi == NULL)
 			goto error;
 
 		/* FIXME: this should be done differently, how i don't know */
+
 		if (s->build_content) {
-			((CamelMessageInfoBase *)mi)->content = perform_content_info_load(s, in);
+			((CamelMessageInfoBase *)mi)->content = perform_content_info_load(s, NULL);
 			if (((CamelMessageInfoBase *)mi)->content == NULL) {
 				camel_message_info_free(mi);
 				goto error;
@@ -574,13 +590,12 @@ camel_folder_summary_load(CamelFolderSum
 		camel_folder_summary_add(s, mi);
 	}
 
+
 	CAMEL_SUMMARY_UNLOCK(s, io_lock);
-	
-	if (fclose (in) != 0)
-		return -1;
 
 	s->flags &= ~CAMEL_SUMMARY_DIRTY;
 
+
 	return 0;
 
 error:
@@ -588,7 +603,6 @@ error:
 		g_warning ("Cannot load summary file: `%s': %s", s->summary_path, g_strerror (errno));
 	
 	CAMEL_SUMMARY_UNLOCK(s, io_lock);
-	fclose (in);
 	s->flags |= ~CAMEL_SUMMARY_DIRTY;
 
 	return -1;
@@ -646,6 +660,7 @@ camel_folder_summary_save(CamelFolderSum
 	fd = g_open(path, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0600);
 	if (fd == -1)
 		return -1;
+
 	out = fdopen(fd, "wb");
 	if (out == NULL) {
 		i = errno;
@@ -678,10 +693,11 @@ camel_folder_summary_save(CamelFolderSum
 	
 	if (fflush (out) != 0 || fsync (fileno (out)) == -1)
 		goto exception;
+
+	CAMEL_SUMMARY_UNLOCK(s, io_lock);
 	
 	fclose (out);
-	
-	CAMEL_SUMMARY_UNLOCK(s, io_lock);
+
 	
 #ifdef G_OS_WIN32
 	g_unlink(s->summary_path);
@@ -694,19 +710,21 @@ camel_folder_summary_save(CamelFolderSum
 	}
 	
 	s->flags &= ~CAMEL_SUMMARY_DIRTY;
+
 	return 0;
 	
  exception:
+
+	CAMEL_SUMMARY_UNLOCK(s, io_lock);
 	
 	i = errno;
 	
 	fclose (out);
-	
-	CAMEL_SUMMARY_UNLOCK(s, io_lock);
-	
+		
 	g_unlink (path);
 	errno = i;
 	
+
 	return -1;
 }
 
@@ -724,22 +742,24 @@ camel_folder_summary_save(CamelFolderSum
 int
 camel_folder_summary_header_load(CamelFolderSummary *s)
 {
-	FILE *in;
 	int ret;
 
-	if (s->summary_path == NULL)
+	if (s->summary_path == NULL || !g_file_test (s->summary_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
 		return 0;
 
-	in = g_fopen(s->summary_path, "rb");
-	if (in == NULL)
-		return -1;
-
 	CAMEL_SUMMARY_LOCK(s, io_lock);
-	ret = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, in);
-	CAMEL_SUMMARY_UNLOCK(s, io_lock);
+
+	if (!s->file)
+		s->file = g_mapped_file_new (s->summary_path, FALSE, NULL);
+
+	s->filepos = g_mapped_file_get_contents (s->file);
+
+	
+	ret = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, NULL);
 	
-	fclose(in);
 	s->flags &= ~CAMEL_SUMMARY_DIRTY;
+	CAMEL_SUMMARY_UNLOCK(s, io_lock);
+
 	return ret;
 }
 
@@ -748,11 +768,15 @@ summary_assign_uid(CamelFolderSummary *s
 {
 	const char *uid;
 	CamelMessageInfo *mi;
+	CamelMessageInfoBase *bi = (CamelMessageInfoBase*)info;
 
 	uid = camel_message_info_uid(info);
 	if (uid == NULL || uid[0] == 0) {
-		g_free(info->uid);
+
+		if (bi->uid_needs_free || bi->needs_free)
+			g_free(info->uid);
 		uid = info->uid = camel_folder_summary_next_uid_string(s);
+		bi->uid_needs_free = TRUE;
 	}
 
 	CAMEL_SUMMARY_LOCK(s, summary_lock);
@@ -762,8 +786,13 @@ summary_assign_uid(CamelFolderSummary *s
 		if (mi == info)
 			return 0;
 		d(printf ("Trying to insert message with clashing uid (%s).  new uid re-assigned", camel_message_info_uid(info)));
-		g_free(info->uid);
+
+
+		if (bi->uid_needs_free || bi->needs_free)
+			g_free(info->uid);
 		uid = info->uid = camel_folder_summary_next_uid_string(s);
+		bi->uid_needs_free = TRUE;
+
 		camel_message_info_set_flags(info, CAMEL_MESSAGE_FOLDER_FLAGGED, CAMEL_MESSAGE_FOLDER_FLAGGED);
 		CAMEL_SUMMARY_LOCK(s, summary_lock);
 	}
@@ -1302,12 +1331,15 @@ camel_folder_summary_encode_token(FILE *
 		if (token != -1) {
 			return camel_file_util_encode_uint32(out, token+1);
 		} else {
-			if (camel_file_util_encode_uint32(out, len+32) == -1)
+			if (camel_file_util_encode_uint32(out, len+32 + 1) == -1)
 				return -1;
 			if (fwrite(str, len, 1, out) != 1)
 				return -1;
+			else if (fputc ('\0', out) == -1)
+				return -1;
 		}
 	}
+
 	return 0;
 }
 
@@ -1322,24 +1354,22 @@ camel_folder_summary_encode_token(FILE *
  * Returns %0 on success or %-1 on fail
  **/
 int
-camel_folder_summary_decode_token(FILE *in, char **str)
+camel_folder_summary_decode_token(CamelFolderSummary *s, FILE *in, char **str)
 {
 	char *ret;
 	guint32 len;
+	unsigned char *ptrchr = s->filepos;
 
 	io(printf("Decode token ...\n"));
-	
-	if (camel_file_util_decode_uint32(in, &len) == -1) {
-		io(printf ("Could not decode token from file"));
-		*str = NULL;
-		return -1;
-	}
+
+	ptrchr = camel_file_util_mmap_decode_uint32 ((unsigned char*)ptrchr, &len, FALSE);
 
 	if (len<32) {
+
 		if (len <= 0) {
 			ret = NULL;
 		} else if (len<= tokens_len) {
-			ret = g_strdup(tokens[len-1]);
+			ret = tokens[len-1];
 		} else {
 			io(printf ("Invalid token encountered: %d", len));
 			*str = NULL;
@@ -1350,17 +1380,17 @@ camel_folder_summary_decode_token(FILE *
 		*str = NULL;
 		return -1;
 	} else {
+
 		len -= 32;
-		ret = g_malloc(len+1);
-		if (len > 0 && fread(ret, len, 1, in) != 1) {
-			g_free(ret);
-			*str = NULL;
-			return -1;
-		}
-		ret[len]=0;
+
+		if (len != 1)
+			ret = (char*)ptrchr;
+		else ret = NULL;
+
+		ptrchr += len;
 	}
 
-	io(printf("Token = '%s'\n", ret));
+	s->filepos = ptrchr;
 
 	*str = ret;
 	return 0;
@@ -1392,40 +1422,46 @@ my_list_size(struct _node **list)
 static int
 summary_header_load(CamelFolderSummary *s, FILE *in)
 {
-	fseek(in, 0, SEEK_SET);
+	time_t *ptrt;
+	gint32 *ptr32 = s->filepos;
 
-	io(printf("Loading header\n"));
+	s->version = g_ntohl (*ptr32); ptr32++; 
 
-	if (camel_file_util_decode_fixed_int32(in, &s->version) == -1)
-		return -1;
+	io(printf("Loading header %d", (s->version&0xff)));
 
-	/* Legacy version check, before version 12 we have no upgrade knowledge */
+	/* Legacy version check, before version 13 we have no upgrade knowledge */
 	if ((s->version > 0xff) && (s->version & 0xff) < 12) {
 		io(printf ("Summary header version mismatch"));
 		errno = EINVAL;
 		return -1;
 	}
 
-	if (!(s->version < 0x100 && s->version >= 13))
-		io(printf("Loading legacy summary\n"));
-	else
-		io(printf("loading new-format summary\n"));
+	/* Check for MMAPable file */
+	if (s->version != CAMEL_FOLDER_SUMMARY_VERSION)
+	{
+		/* Put a summary-file-upgrader here */
 
-	/* legacy version */
-	if (camel_file_util_decode_fixed_int32(in, &s->flags) == -1
-	    || camel_file_util_decode_fixed_int32(in, &s->nextuid) == -1
-	    || camel_file_util_decode_time_t(in, &s->time) == -1
-	    || camel_file_util_decode_fixed_int32(in, &s->saved_count) == -1) {
+		errno = EINVAL;
 		return -1;
 	}
 
-	/* version 13 */
-	if (s->version < 0x100 && s->version >= 13
-	    && (camel_file_util_decode_fixed_int32(in, &s->unread_count) == -1
-		|| camel_file_util_decode_fixed_int32(in, &s->deleted_count) == -1
-		|| camel_file_util_decode_fixed_int32(in, &s->junk_count) == -1)) {
-		return -1;
+	s->flags = g_ntohl (*ptr32); ptr32++; 
+	s->nextuid = g_ntohl (*ptr32); ptr32++; 
+
+	ptrt = (time_t*)ptr32;
+	s->time = (time_t)g_ntohl (*ptrt); ptrt++; 
+	ptr32 = (gint32*)ptrt;
+
+	s->saved_count = g_ntohl (*ptr32); ptr32++; 
+
+
+	if (s->version < 0x100 && s->version >= 13) {
+		s->unread_count = g_ntohl (*ptr32); ptr32++; 
+		s->deleted_count = g_ntohl (*ptr32); ptr32++; 
+		s->junk_count = g_ntohl (*ptr32); ptr32++; 
 	}
+     
+	s->filepos = ptr32;
 
 	return 0;
 }
@@ -1588,8 +1624,9 @@ camel_folder_summary_content_info_new(Ca
 		s->content_info_chunks = e_memchunk_new(32, s->content_info_size);
 	ci = e_memchunk_alloc(s->content_info_chunks);
 	CAMEL_SUMMARY_UNLOCK(s, alloc_lock);
-
+	ci->needs_free = FALSE;
 	memset(ci, 0, s->content_info_size);
+
 	return ci;
 }
 
@@ -1608,6 +1645,8 @@ message_info_new_from_header(CamelFolder
 
 	mi = (CamelMessageInfoBase *)camel_message_info_new(s);
 
+	mi->needs_free = TRUE;
+
 	if ((content = camel_header_raw_find(&h, "Content-Type", NULL))
 	     && (ct = camel_content_type_decode(content))
 	     && (charset = camel_content_type_param(ct, "charset"))
@@ -1635,6 +1674,7 @@ message_info_new_from_header(CamelFolder
 	mi->user_tags = NULL;
 	mi->date_sent = camel_header_decode_date(camel_header_raw_find(&h, "date", NULL), NULL);
 	received = camel_header_raw_find(&h, "received", NULL);
+
 	if (received)
 		received = strrchr(received, ';');
 	if (received)
@@ -1681,84 +1721,104 @@ message_info_new_from_header(CamelFolder
 	return (CamelMessageInfo *)mi;
 }
 
+
 static CamelMessageInfo *
 message_info_load(CamelFolderSummary *s, FILE *in)
 {
 	CamelMessageInfoBase *mi;
-	guint count;
-	int i;
-	char *subject, *from, *to, *cc, *mlist, *uid;
+	guint count, len, slen;
+	unsigned char *ptrchr = s->filepos;
+	gint32 *ptr32; unsigned int i;
 
 	mi = (CamelMessageInfoBase *)camel_message_info_new(s);
 
+	mi->needs_free = FALSE;
+
 	io(printf("Loading message info\n"));
 
-	camel_file_util_decode_string(in, &uid);
-	camel_file_util_decode_uint32(in, &mi->flags);
-	camel_file_util_decode_uint32(in, &mi->size);
-	camel_file_util_decode_time_t(in, &mi->date_sent);
-	camel_file_util_decode_time_t(in, &mi->date_received);
-	camel_file_util_decode_string(in, &subject);
-	camel_file_util_decode_string(in, &from);
-	camel_file_util_decode_string(in, &to);
-	camel_file_util_decode_string(in, &cc);
-	camel_file_util_decode_string(in, &mlist);
-	
-	mi->uid = uid;
-	mi->subject = camel_pstring_add (subject, TRUE);
-	mi->from = camel_pstring_add (from, TRUE);
-	mi->to = camel_pstring_add (to, TRUE);
-	mi->cc = camel_pstring_add (cc, TRUE);
-	mi->mlist = camel_pstring_add (mlist, TRUE);
-	
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+	if (len) mi->uid = (char*)ptrchr;
+	ptrchr += len;
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &mi->flags, FALSE);
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &mi->size, FALSE);
+	ptrchr = camel_file_util_mmap_decode_time_t (ptrchr, &mi->date_sent);
+	ptrchr = camel_file_util_mmap_decode_time_t (ptrchr, &mi->date_received);
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+	if (len) mi->subject = (const char*)ptrchr;
+	slen = strlen(mi->subject);
+	ptrchr += len;
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+	if (len) mi->from = (const char*)ptrchr;
+	ptrchr += len;
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+	if (len) mi->to = (const char*)ptrchr;
+	ptrchr += len;
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+	if (len) mi->cc = (const char*)ptrchr;
+	ptrchr += len;
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+	if (len) mi->mlist = (const char*)ptrchr;
+	ptrchr += len;	
+
 	mi->content = NULL;
 
-	camel_file_util_decode_fixed_int32(in, &mi->message_id.id.part.hi);
-	camel_file_util_decode_fixed_int32(in, &mi->message_id.id.part.lo);
+	ptr32 = (gint32*) ptrchr;
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
-		goto error;
+	mi->message_id.id.part.hi = g_ntohl (*ptr32); ptr32++;
+	mi->message_id.id.part.lo = g_ntohl (*ptr32); ptr32++;
 
-	if (count > 0) {
-		mi->references = g_malloc(sizeof(*mi->references) + ((count-1) * sizeof(mi->references->references[0])));
-		mi->references->size = count;
-		for (i=0;i<count;i++) {
-			camel_file_util_decode_fixed_int32(in, &mi->references->references[i].id.part.hi);
-			camel_file_util_decode_fixed_int32(in, &mi->references->references[i].id.part.lo);
-		}
-	}
+	ptrchr = (unsigned char*) ptr32;
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &count, FALSE);
+	ptr32 = (gint32*) ptrchr;
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
-		goto error;
+	mi->references = g_malloc(sizeof(*mi->references) + ((count-1) * sizeof(mi->references->references[0])));
+	mi->references->size = count;
+	
+	for (i=0;i<count;i++) {
+		mi->references->references[i].id.part.hi = g_ntohl (*ptr32); ptr32++;
+		mi->references->references[i].id.part.lo = g_ntohl (*ptr32); ptr32++;
+	}
 
+	ptrchr = (unsigned char*) ptr32;
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &count, FALSE);
+	
 	for (i=0;i<count;i++) {
-		char *name;
-		if (camel_file_util_decode_string(in, &name) == -1 || name == NULL)
-			goto error;
+		char *name = NULL;
+
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+		if (len) name = (char*) ptrchr;
+		ptrchr += len;
+
 		camel_flag_set(&mi->user_flags, name, TRUE);
-		g_free(name);
 	}
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
-		goto error;
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &count, FALSE);
 
 	for (i=0;i<count;i++) {
-		char *name, *value;
-		if (camel_file_util_decode_string(in, &name) == -1 || name == NULL
-		    || camel_file_util_decode_string(in, &value) == -1)
-			goto error;
+		char *name = NULL, *value = NULL;
+
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+		if (len) name = (char*)ptrchr;
+		ptrchr += len;
+
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+		if (len) value =(char*) ptrchr;
+		ptrchr += len;
+
 		camel_tag_set(&mi->user_tags, name, value);
-		g_free(name);
-		g_free(value);
 	}
 
-	if (!ferror(in))
-		return (CamelMessageInfo *)mi;
 
-error:
-	camel_message_info_free((CamelMessageInfo *)mi);
+	s->filepos = (void*) ptrchr;
+
+	return (CamelMessageInfo *)mi;
 
-	return NULL;
 }
 
 static int
@@ -1821,15 +1881,23 @@ message_info_free(CamelFolderSummary *s,
 {
 	CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
 
-	g_free(mi->uid);
-	camel_pstring_free(mi->subject);
-	camel_pstring_free(mi->from);
-	camel_pstring_free(mi->to);
-	camel_pstring_free(mi->cc);
-	camel_pstring_free(mi->mlist);
+	if (mi->needs_free)
+	{
+		g_free(mi->uid);
+		camel_pstring_free(mi->subject);
+		camel_pstring_free(mi->from);
+		camel_pstring_free(mi->to);
+		camel_pstring_free(mi->cc);
+		camel_pstring_free(mi->mlist);
+
+		camel_flag_list_free(&mi->user_flags);
+		camel_tag_list_free(&mi->user_tags);
+
+	} else if (mi->uid_needs_free)
+		g_free (mi->uid);
+
 	g_free(mi->references);
-	camel_flag_list_free(&mi->user_flags);
-	camel_tag_list_free(&mi->user_tags);
+
 	if (s)
 		e_memchunk_free(s->message_info_chunks, mi);
 	else
@@ -1843,8 +1911,10 @@ content_info_new_from_header(CamelFolder
 	const char *charset;
 	
 	ci = camel_folder_summary_content_info_new (s);
+	ci->needs_free = TRUE;
 	
 	charset = e_iconv_locale_charset ();
+
 	ci->id = camel_header_msgid_decode (camel_header_raw_find (&h, "content-id", NULL));
 	ci->description = camel_header_decode_string (camel_header_raw_find (&h, "content-description", NULL), charset);
 	ci->encoding = camel_content_transfer_encoding_decode (camel_header_raw_find (&h, "content-transfer-encoding", NULL));
@@ -1861,57 +1931,56 @@ content_info_load(CamelFolderSummary *s,
 	guint32 count, i;
 	CamelContentType *ct;
 
+	unsigned char *ptrchr = s->filepos;
+
 	io(printf("Loading content info\n"));
 
 	ci = camel_folder_summary_content_info_new(s);
-	
-	camel_folder_summary_decode_token(in, &type);
-	camel_folder_summary_decode_token(in, &subtype);
+	ci->needs_free = FALSE;
+
+	camel_folder_summary_decode_token(s, in, &type);
+	camel_folder_summary_decode_token(s, in, &subtype);
+
 	ct = camel_content_type_new(type, subtype);
-	g_free(type);		/* can this be removed? */
-	g_free(subtype);
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
-		goto error;
+
+	ptrchr = s->filepos;
+	ptrchr = camel_file_util_mmap_decode_uint32 ((unsigned char*)ptrchr, &count, FALSE);	
+	s->filepos = ptrchr;
 	
 	for (i=0;i<count;i++) {
 		char *name, *value;
-		camel_folder_summary_decode_token(in, &name);
-		camel_folder_summary_decode_token(in, &value);
-		if (!(name && value))
-			goto error;
+
+		camel_folder_summary_decode_token(s, in, &name);
+		camel_folder_summary_decode_token(s, in, &value);
 		
-		camel_content_type_set_param(ct, name, value);
-		/* TODO: do this so we dont have to double alloc/free */
-		g_free(name);
-		g_free(value);
+		camel_content_type_set_param (ct, name, value);
 	}
-	ci->type = ct;
 
-	camel_folder_summary_decode_token(in, &ci->id);
-	camel_folder_summary_decode_token(in, &ci->description);
-	camel_folder_summary_decode_token(in, &ci->encoding);
+	ci->type = ct;
 
-	camel_file_util_decode_uint32(in, &ci->size);
+	camel_folder_summary_decode_token(s, in, &ci->id);
+	camel_folder_summary_decode_token(s, in, &ci->description);
+	camel_folder_summary_decode_token(s, in, &ci->encoding);
+
+	ptrchr = s->filepos;
+	ptrchr = camel_file_util_mmap_decode_uint32 ((unsigned char*)ptrchr, &ci->size, FALSE);
+	s->filepos = ptrchr;
 
 	ci->childs = NULL;
 
-	if (!ferror(in))
-		return ci;
-
- error:
-	camel_folder_summary_content_info_free(s, ci);
-	return NULL;
+	return ci;
 }
 
 static int
 content_info_save(CamelFolderSummary *s, FILE *out, CamelMessageContentInfo *ci)
 {
-	CamelContentType *ct;
+	CamelContentType *ct=NULL;
 	struct _camel_header_param *hp;
 
 	io(printf("Saving content info\n"));
 
 	ct = ci->type;
+
 	if (ct) {
 		camel_folder_summary_encode_token(out, ct->type);
 		camel_folder_summary_encode_token(out, ct->subtype);
@@ -1937,9 +2006,14 @@ static void
 content_info_free(CamelFolderSummary *s, CamelMessageContentInfo *ci)
 {
 	camel_content_type_unref(ci->type);
-	g_free(ci->id);
-	g_free(ci->description);
-	g_free(ci->encoding);
+
+	if (ci->needs_free)
+	{
+		g_free (ci->id);
+		g_free (ci->description);
+		g_free (ci->encoding);
+	}
+
 	e_memchunk_free(s->content_info_chunks, ci);
 }
 
@@ -2693,6 +2767,8 @@ message_info_clone(CamelFolderSummary *s
 	to->refcount = 1;
 
 	/* NB: We don't clone the uid */
+
+	from->needs_free = TRUE;
 
 	to->subject = camel_pstring_strdup(from->subject);
 	to->from = camel_pstring_strdup(from->from);
Index: camel-folder-summary.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-folder-summary.h,v
retrieving revision 1.86
diff -u -p -r1.86 camel-folder-summary.h
--- camel-folder-summary.h	31 Aug 2005 04:21:56 -0000	1.86
+++ camel-folder-summary.h	11 Jul 2006 14:34:19 -0000
@@ -59,6 +59,7 @@ struct _CamelMessageContentInfo {
 	char *description;
 	char *encoding;		/* this should be an enum?? */
 	guint32 size;
+	gboolean needs_free;
 };
 
 /* system flag bits */
@@ -178,6 +179,7 @@ struct _CamelMessageInfoBase {
 
 	/* tree of content description - NULL if it is not available */
 	CamelMessageContentInfo *content;
+	gboolean needs_free, uid_needs_free;
 };
 
 /* probably do this as well, removing CamelFolderChangeInfo and interfaces 
@@ -224,6 +226,9 @@ struct _CamelFolderSummary {
 	GHashTable *messages_uid; /* CamelMessageInfo's by uid */
 
 	struct _CamelFolder *folder; /* parent folder, for events */
+
+	GMappedFile *file;
+	void *filepos;
 };
 
 struct _CamelFolderSummaryClass {
@@ -277,6 +282,9 @@ struct _CamelFolderSummaryClass {
 CamelType			 camel_folder_summary_get_type	(void);
 CamelFolderSummary      *camel_folder_summary_new	(struct _CamelFolder *folder);
 
+unsigned char*
+decode_uint32 (unsigned char *start, guint32 *dest, gboolean is_string);
+
 void camel_folder_summary_set_filename(CamelFolderSummary *summary, const char *filename);
 void camel_folder_summary_set_index(CamelFolderSummary *summary, CamelIndex *index);
 void camel_folder_summary_set_build_content(CamelFolderSummary *summary, gboolean state);
@@ -329,7 +337,7 @@ void camel_folder_summary_array_free(Cam
 
 /* basically like strings, but certain keywords can be compressed and de-cased */
 int camel_folder_summary_encode_token(FILE *out, const char *str);
-int camel_folder_summary_decode_token(FILE *in, char **str);
+int camel_folder_summary_decode_token(CamelFolderSummary *s,FILE *in, char **str);
 
 /* message flag operations */
 gboolean	camel_flag_get(CamelFlag **list, const char *name);
Index: camel-object.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-object.c,v
retrieving revision 1.60
diff -u -p -r1.60 camel-object.c
--- camel-object.c	12 Apr 2006 19:14:13 -0000	1.60
+++ camel-object.c	11 Jul 2006 14:34:19 -0000
@@ -580,7 +580,7 @@ cobject_state_write(CamelObject *obj, FI
 
 	res = 0;
 abort:
-	for (i=0;i<argv->argc;i++) {
+/*	for (i=0;i<argv->argc;i++) {
 		CamelArg *arg = &argv->argv[i];
 
 		if ((argv->argv[i].tag & CAMEL_ARG_TYPE) == CAMEL_ARG_STR)
@@ -595,7 +595,7 @@ abort:
 
 	if (meta)
 		camel_object_free(obj, CAMEL_OBJECT_METADATA, meta);
-
+*/
 	return res;
 }
 
Index: providers/groupwise/camel-groupwise-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/providers/groupwise/camel-groupwise-summary.c,v
retrieving revision 1.11
diff -u -p -r1.11 camel-groupwise-summary.c
--- providers/groupwise/camel-groupwise-summary.c	20 Apr 2006 07:47:21 -0000	1.11
+++ providers/groupwise/camel-groupwise-summary.c	11 Jul 2006 14:34:20 -0000
@@ -156,16 +156,23 @@ static int
 gw_summary_header_load (CamelFolderSummary *s, FILE *in)
 {
 	CamelGroupwiseSummary *ims = CAMEL_GROUPWISE_SUMMARY (s);
+	gint32 *ptr32 = s->filepos;
+	unsigned char *ptrchr;
+	gint len;
 
 	if (camel_groupwise_summary_parent->summary_header_load (s, in) == -1)
 		return -1 ;
 
-	if (camel_file_util_decode_fixed_int32(in, &ims->version) == -1
-			|| camel_file_util_decode_fixed_int32(in, &ims->validity) == -1)
-		return -1;
-	
-	if (camel_file_util_decode_string (in, &ims->time_string) == -1)
-		return -1;
+	ims->version = g_ntohl (*ptr32); ptr32++;
+	ims->validity = g_ntohl (*ptr32); ptr32++;
+	ptrchr = (unsigned char*)ptr32;
+
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+	if (len) ims->time_string = (const char*)ptrchr;
+	ptrchr += len;
+		
+	s->filepos = ptrchr;
+
 	return 0 ;
 }
 
@@ -191,18 +198,16 @@ gw_message_info_load (CamelFolderSummary
 	CamelMessageInfo *info ;
 	CamelGroupwiseMessageInfo *gw_info ;
 
-
 	info = camel_groupwise_summary_parent->message_info_load(s,in) ;
 	if (info) {
+		unsigned char *ptrchr = s->filepos;
 		gw_info = (CamelGroupwiseMessageInfo*) info ;
-		if (camel_file_util_decode_uint32 (in, &gw_info->server_flags) == -1)
-			goto error ;
+
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &gw_info->server_flags, FALSE);
+		s->filepos = ptrchr;
 	}
 
 	return info ;
-error:
-	camel_message_info_free (info) ;
-	return NULL ;
 }
 
 
Index: providers/imap/camel-imap-folder.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/providers/imap/camel-imap-folder.c,v
retrieving revision 1.361
diff -u -p -r1.361 camel-imap-folder.c
--- providers/imap/camel-imap-folder.c	19 May 2006 15:25:08 -0000	1.361
+++ providers/imap/camel-imap-folder.c	11 Jul 2006 14:34:20 -0000
@@ -2511,8 +2511,11 @@ imap_update_summary (CamelFolder *folder
 		}
 		
 		uid = g_datalist_get_data (&data, "UID");
+
+		/* This strdup() might not get freed since the mmap() patch! */
 		if (uid)
 			mi->info.uid = g_strdup (uid);
+
 		flags = GPOINTER_TO_INT (g_datalist_get_data (&data, "FLAGS"));
 		if (flags) {
 			((CamelImapMessageInfo *)mi)->server_flags = flags;
Index: providers/imap/camel-imap-store-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/providers/imap/camel-imap-store-summary.c,v
retrieving revision 1.18
diff -u -p -r1.18 camel-imap-store-summary.c
--- providers/imap/camel-imap-store-summary.c	12 Apr 2006 19:14:14 -0000	1.18
+++ providers/imap/camel-imap-store-summary.c	11 Jul 2006 14:34:20 -0000
@@ -469,27 +469,44 @@ namespace_load(CamelStoreSummary *s, FIL
 	guint32 sep = '/';
 
 	ns = g_malloc0(sizeof(*ns));
-	if (camel_file_util_decode_string(in, &ns->path) == -1
-	    || camel_file_util_decode_string(in, &ns->full_name) == -1
-	    || camel_file_util_decode_uint32(in, &sep) == -1) {
-		namespace_free(s, ns);
-		ns = NULL;
-	} else {
-		ns->sep = sep;
-	}
+
+	if (camel_file_util_decode_string(in, &ns->path) == -1)
+		goto nserror;
+
+	if (camel_file_util_decode_string(in, &ns->full_name) == -1)
+		goto nserror;
+	
+	if (camel_file_util_decode_uint32(in, &sep) == -1)
+		goto nserror;
+
+	ns->sep = sep;
 
 	return ns;
+
+ nserror:
+
+	namespace_free(s, ns);
+	return NULL;
 }
 
 static int
 namespace_save(CamelStoreSummary *s, FILE *in, CamelImapStoreNamespace *ns)
 {
-	if (camel_file_util_encode_string(in, ns->path) == -1
-	    || camel_file_util_encode_string(in, ns->full_name) == -1
-	    || camel_file_util_encode_uint32(in, (guint32)ns->sep) == -1)
-		return -1;
+	if (camel_file_util_encode_string(in, ns->path) == -1)
+		goto serr;
+
+	if (camel_file_util_encode_string(in, ns->full_name) == -1)
+		goto serr;
+
+	if (camel_file_util_encode_uint32(in, (guint32)ns->sep) == -1)
+		goto serr;
 
 	return 0;
+
+ serr:
+	printf ("Error happend while writing\n");
+	return -1;
+
 }
 
 static int
Index: providers/imap/camel-imap-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/providers/imap/camel-imap-summary.c,v
retrieving revision 1.25
diff -u -p -r1.25 camel-imap-summary.c
--- providers/imap/camel-imap-summary.c	31 Aug 2005 04:26:02 -0000	1.25
+++ providers/imap/camel-imap-summary.c	11 Jul 2006 14:34:20 -0000
@@ -148,28 +148,34 @@ static int
 summary_header_load (CamelFolderSummary *s, FILE *in)
 {
 	CamelImapSummary *ims = CAMEL_IMAP_SUMMARY (s);
+	gint32 *ptr32;
 	
 	if (camel_imap_summary_parent->summary_header_load (s, in) == -1)
 		return -1;
 
 	/* Legacy version */
 	if (s->version == 0x30c)
-		return camel_file_util_decode_uint32(in, &ims->validity);
+	{
+		unsigned char* ptrchr = s->filepos;
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &ims->validity, FALSE);
+		s->filepos = ptrchr;
+		return 0;
+	}
 
 	/* Version 1 */
-	if (camel_file_util_decode_fixed_int32(in, &ims->version) == -1)
-		return -1;
+	ptr32 = s->filepos;
+	ims->version = g_ntohl (*ptr32); ptr32++;
+	s->filepos = ptr32;
 	
 	if (ims->version == 2) {
 		/* Version 2: for compat with version 2 of the imap4 summary files */
 		int have_mlist;
-		
-		if (camel_file_util_decode_fixed_int32 (in, &have_mlist) == -1)
-			return -1;
+		have_mlist = g_ntohl (*ptr32); ptr32++;
+		s->filepos = ptr32;
 	}
-	
-	if (camel_file_util_decode_fixed_int32(in, &ims->validity) == -1)
-		return -1;
+
+	ims->validity = g_ntohl (*ptr32); ptr32++;
+	s->filepos = ptr32;
 	
 	if (ims->version > CAMEL_IMAP_SUMMARY_VERSION) {
 		g_warning("Unkown summary version\n");
@@ -212,19 +218,15 @@ message_info_load (CamelFolderSummary *s
 	CamelImapMessageInfo *iinfo;
 
 	info = camel_imap_summary_parent->message_info_load (s, in);
-	if (info) {
-		iinfo = (CamelImapMessageInfo *)info;
-
-		if (camel_file_util_decode_uint32 (in, &iinfo->server_flags) == -1)
-			goto error;
 
+	if (info) {
+		unsigned char* ptrchr = s->filepos;
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &iinfo->server_flags, FALSE);
+		s->filepos = ptrchr;
 		label_to_flags(iinfo);
 	}
 
 	return info;
-error:
-	camel_message_info_free(info);
-	return NULL;
 }
 
 static int
@@ -254,10 +256,22 @@ info_set_user_tag(CamelMessageInfo *info
 static CamelMessageContentInfo *
 content_info_load (CamelFolderSummary *s, FILE *in)
 {
-	if (fgetc (in))
-		return camel_imap_summary_parent->content_info_load (s, in);
-	else
-		return camel_folder_summary_content_info_new (s);
+	unsigned char* ptrchr = s->filepos;
+	CamelMessageContentInfo *retval;
+
+	if (*ptrchr == 1) {
+		ptrchr++;
+		s->filepos = ptrchr;
+
+		retval = camel_imap_summary_parent->content_info_load (s, in);
+	} else {
+		ptrchr++; 
+		s->filepos = ptrchr;
+
+		retval = camel_folder_summary_content_info_new (s);
+	}
+
+	return retval;
 }
 
 static int
Index: providers/imap4/camel-imap4-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/providers/imap4/camel-imap4-summary.c,v
retrieving revision 1.46
diff -u -p -r1.46 camel-imap4-summary.c
--- providers/imap4/camel-imap4-summary.c	18 May 2006 15:28:10 -0000	1.46
+++ providers/imap4/camel-imap4-summary.c	11 Jul 2006 14:34:21 -0000
@@ -146,13 +146,14 @@ static int
 imap4_header_load (CamelFolderSummary *summary, FILE *fin)
 {
 	CamelIMAP4Summary *imap4_summary = (CamelIMAP4Summary *) summary;
+	gint32 *ptr32 = summary->filepos;
 	
 	if (CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->summary_header_load (summary, fin) == -1)
 		return -1;
 	
-	if (camel_file_util_decode_fixed_int32 (fin, &imap4_summary->version) == -1)
-		return -1;
-	
+	imap4_summary->version = g_ntohl (*ptr32); ptr32++;
+	summary->filepos = ptr32;
+
 	if (imap4_summary->version > CAMEL_IMAP4_SUMMARY_VERSION) {
 		g_warning ("Unknown IMAP4 summary version\n");
 		errno = EINVAL;
@@ -162,9 +163,8 @@ imap4_header_load (CamelFolderSummary *s
 	if (imap4_summary->version == 2) {
 		/* check that we have Mailing-List info */
 		int have_mlist;
-		
-		if (camel_file_util_decode_fixed_int32 (fin, &have_mlist) == -1)
-			return -1;
+
+		have_mlist = g_ntohl (*ptr32); ptr32++;
 		
 		if (have_mlist)
 			summary->flags |= CAMEL_IMAP4_SUMMARY_HAVE_MLIST;
@@ -172,8 +172,8 @@ imap4_header_load (CamelFolderSummary *s
 			summary->flags ^= CAMEL_IMAP4_SUMMARY_HAVE_MLIST;
 	}
 	
-	if (camel_file_util_decode_fixed_int32 (fin, &imap4_summary->uidvalidity) == -1)
-		return -1;
+	imap4_summary->uidvalidity = g_ntohl (*ptr32); ptr32++;
+	summary->filepos = ptr32;
 	
 	return 0;
 }
@@ -1249,22 +1249,17 @@ imap4_message_info_load (CamelFolderSumm
 {
 	CamelIMAP4MessageInfo *minfo;
 	CamelMessageInfo *info;
-	
+	unsigned char *ptrchr = summary->filepos;
+
 	if (!(info = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->message_info_load (summary, fin)))
 		return NULL;
 	
 	minfo = (CamelIMAP4MessageInfo *) info;
 	
-	if (camel_file_util_decode_uint32 (fin, &minfo->server_flags) == -1)
-		goto exception;
-	
+	ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &minfo->server_flags, FALSE);
+	summary->filepos = ptrchr;
+
 	return info;
-	
- exception:
-	
-	camel_message_info_free(info);
-	
-	return NULL;
 }
 
 static int
Index: providers/imapp/camel-imapp-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/providers/imapp/camel-imapp-summary.c,v
retrieving revision 1.4
diff -u -p -r1.4 camel-imapp-summary.c
--- providers/imapp/camel-imapp-summary.c	31 Aug 2005 04:26:05 -0000	1.4
+++ providers/imapp/camel-imapp-summary.c	11 Jul 2006 14:34:21 -0000
@@ -115,17 +115,27 @@ static int
 summary_header_load(CamelFolderSummary *s, FILE *in)
 {
 	CamelIMAPPSummary *ims = CAMEL_IMAPP_SUMMARY(s);
+	unsigned char *ptrchr = s->filepos;
+	gint32 *ptr32;
 
 	if (camel_imapp_summary_parent->summary_header_load(s, in) == -1)
 		return -1;
 
 	/* Legacy version */
 	if (s->version == 0x100c)
-		return camel_file_util_decode_uint32(in, &ims->uidvalidity);
+	{		
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &ims->uidvalidity, FALSE);
+		s->filepos = ptrchr;
 
-	if (camel_file_util_decode_fixed_int32(in, &ims->version) == -1
-	    || camel_file_util_decode_fixed_int32(in, &ims->uidvalidity) == -1)
-		return -1;
+		return 0;
+	}
+
+	ptr32 = s->filepos;
+
+	ims->version = g_ntohl (*ptr32); ptr32++;
+	ims->uidvalidity = g_ntohl (*ptr32); ptr32++;
+
+	s->filepos = ptr32;
 
 	if (ims->version > CAMEL_IMAPP_SUMMARY_VERSION) {
 		g_warning("Unkown summary version\n");
@@ -160,16 +170,14 @@ message_info_load(CamelFolderSummary *s,
 
 	info = camel_imapp_summary_parent->message_info_load(s, in);
 	if (info) {
+		unsigned char *ptrchr = s->filepos;
 		iinfo =(CamelIMAPPMessageInfo *)info;
 
-		if (camel_file_util_decode_uint32(in, &iinfo->server_flags) == -1)
-			goto error;
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &iinfo->server_flags, FALSE);
+		s->filepos = ptrchr;		
 	}
 
 	return info;
-error:
-	camel_message_info_free(info);
-	return NULL;
 }
 
 static int
Index: providers/local/camel-local-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/providers/local/camel-local-summary.c,v
retrieving revision 1.34
diff -u -p -r1.34 camel-local-summary.c
--- providers/local/camel-local-summary.c	9 Jun 2006 01:21:53 -0000	1.34
+++ providers/local/camel-local-summary.c	11 Jul 2006 14:34:21 -0000
@@ -593,6 +593,7 @@ static int
 summary_header_load(CamelFolderSummary *s, FILE *in)
 {
 	CamelLocalSummary *cls = (CamelLocalSummary *)s;
+	gint32 *ptr32 = s->filepos;
 
 	/* We dont actually add our own headers, but version that we don't anyway */
 
@@ -604,7 +605,12 @@ summary_header_load(CamelFolderSummary *
 		return 0;
 
 	/* otherwise load the version number */
-	return camel_file_util_decode_fixed_int32(in, &cls->version);
+	
+	ptr32 = s->filepos;
+	cls->version = g_ntohl (*ptr32); ptr32++;
+	s->filepos = ptr32;
+
+	return 0;
 }
 
 static int
Index: providers/local/camel-mbox-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/providers/local/camel-mbox-summary.c,v
retrieving revision 1.60
diff -u -p -r1.60 camel-mbox-summary.c
--- providers/local/camel-mbox-summary.c	15 Jun 2006 11:16:25 -0000	1.60
+++ providers/local/camel-mbox-summary.c	11 Jul 2006 14:34:21 -0000
@@ -233,22 +233,32 @@ mbox_summary_encode_x_evolution (CamelLo
 	}
 }
 
+
+	
 static int
 summary_header_load(CamelFolderSummary *s, FILE *in)
 {
 	CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY(s);
+	gint32 *ptr32;
+	unsigned char *ptrchr;
 
 	if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->summary_header_load(s, in) == -1)
 		return -1;
 
 	/* legacy version */
 	if (s->version == 0x120c)
-		return camel_file_util_decode_uint32(in, (guint32 *) &mbs->folder_size);
+	{
+		unsigned char* ptrchr = s->filepos;
+		ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &mbs->folder_size, FALSE);
+		s->filepos = ptrchr;
+	}
 
 	/* version 1 */
-	if (camel_file_util_decode_fixed_int32(in, &mbs->version) == -1
-	    || camel_file_util_decode_size_t(in, &mbs->folder_size) == -1)
-		return -1;
+	ptr32 = s->filepos;
+	mbs->version = g_ntohl (*ptr32); ptr32++;
+	ptrchr = (unsigned char*)ptr32;
+	ptrchr = camel_file_util_mmap_decode_size_t (ptrchr, &mbs->folder_size);
+	s->filepos = ptrchr;
 
 	return 0;
 }
@@ -361,6 +371,7 @@ message_info_new_from_parser(CamelFolder
 	return mi;
 }
 
+
 static CamelMessageInfo *
 message_info_load(CamelFolderSummary *s, FILE *in)
 {
@@ -371,17 +382,16 @@ message_info_load(CamelFolderSummary *s,
 	mi = ((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_load(s, in);
 	if (mi) {
 		CamelMboxMessageInfo *mbi = (CamelMboxMessageInfo *)mi;
-		
-		if (camel_file_util_decode_off_t(in, &mbi->frompos) == -1)
-			goto error;
+
+		unsigned char *ptrchr = s->filepos;
+		ptrchr = camel_file_util_mmap_decode_off_t (ptrchr, &mbi->frompos);
+		s->filepos = ptrchr;
 	}
 	
 	return mi;
-error:
-	camel_message_info_free(mi);
-	return NULL;
 }
 
+
 static int
 message_info_save(CamelFolderSummary *s, FILE *out, CamelMessageInfo *mi)
 {
@@ -390,7 +400,7 @@ message_info_save(CamelFolderSummary *s,
 	io(printf("saving mbox message info\n"));
 
 	if (((CamelFolderSummaryClass *)camel_mbox_summary_parent)->message_info_save(s, out, mi) == -1
-	    || camel_file_util_encode_off_t(out, mbi->frompos) == -1)
+	    || camel_file_util_encode_off_t (out, mbi->frompos) == -1)
 		return -1;
 
 	return 0;
Index: providers/nntp/camel-nntp-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/providers/nntp/camel-nntp-summary.c,v
retrieving revision 1.23
diff -u -p -r1.23 camel-nntp-summary.c
--- providers/nntp/camel-nntp-summary.c	9 Jun 2006 01:21:53 -0000	1.23
+++ providers/nntp/camel-nntp-summary.c	11 Jul 2006 14:34:21 -0000
@@ -162,18 +162,23 @@ static int
 summary_header_load(CamelFolderSummary *s, FILE *in)
 {
 	CamelNNTPSummary *cns = CAMEL_NNTP_SUMMARY(s);
+	gint32 *ptr32 = s->filepos;
+	unsigned char *ptrchr = s->filepos;
 
 	if (((CamelFolderSummaryClass *)camel_nntp_summary_parent)->summary_header_load(s, in) == -1)
 		return -1;
 
 	/* Legacy version */
 	if (s->version == 0x20c) {
-		camel_file_util_decode_fixed_int32(in, &cns->high);
-		return camel_file_util_decode_fixed_int32(in, &cns->low);
+		cns->high = g_ntohl (*ptr32); ptr32++;
+		cns->low = g_ntohl (*ptr32); ptr32++;
+		s->filepos = ptr32;
+
+		return 0;
 	}
 
-	if (camel_file_util_decode_fixed_int32(in, &cns->version) == -1)
-		return -1;
+	cns->version = g_ntohl (*ptr32); ptr32++;
+	s->filepos = ptr32;
 
 	if (cns->version > CAMEL_NNTP_SUMMARY_VERSION) {
 		g_warning("Unknown NNTP summary version");
@@ -181,9 +186,10 @@ summary_header_load(CamelFolderSummary *
 		return -1;
 	}
 
-	if (camel_file_util_decode_fixed_int32(in, &cns->high) == -1
-	    || camel_file_util_decode_fixed_int32(in, &cns->low) == -1)
-		return -1;
+	cns->high = g_ntohl (*ptr32); ptr32++;
+	cns->low = g_ntohl (*ptr32); ptr32++;
+
+	s->filepos = ptr32;
 
 	return 0;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]