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



On Tue, 2006-07-11 at 16:47 +0200, Philip Van Hoof wrote:
> 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.

This version (version ten) fixes a few strdup()'s, free()'s and other
stuff. Carefully look at the comments of the providers.

I had to disable some things that would otherwise corrupt the mmap()ed
memory block.

These things probably need some refactoring thoughts.

However. I'm sending this using an Evolution that is running from
LD_LIBRARY_PATH=/opt/camel/lib. So far Evolution hasn't crashed and it's
still writing summary new files for all my folders ;-).

http://pvanhoof.be/files/camel_folder_summary_with_mmap_fixes10.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
? 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 19:50:11 -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 19:50:12 -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 19:50:15 -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 *);
 
@@ -138,6 +139,7 @@ camel_folder_summary_init (CamelFolderSu
 	s->time = 0;
 	s->nextuid = 1;
 
+
 	s->messages = g_ptr_array_new();
 	s->messages_uid = g_hash_table_new(g_str_hash, g_str_equal);
 	
@@ -160,6 +162,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 +243,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 +511,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 +554,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 +591,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 +604,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 +661,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 +694,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 +711,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 +743,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 +769,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 +787,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 +1332,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 +1355,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 +1381,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 +1423,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 +1625,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 +1646,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 +1675,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 +1722,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 +1882,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 +1912,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 +1932,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 +2007,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 +2768,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 19:50:16 -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 19:50:20 -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 19:50:21 -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 ;
 }
 
 
@@ -309,6 +314,7 @@ camel_gw_summary_add_offline (CamelFolde
 
 	mi->info.size = camel_message_info_size(info);
 	mi->info.uid = g_strdup (uid);
+	mi->info.uid_needs_free = TRUE;
 
 	camel_folder_summary_add (summary, (CamelMessageInfo *)mi);
 
@@ -321,6 +327,8 @@ camel_gw_summary_add_offline_uncached (C
 
 	mi = camel_message_info_clone(info);
 	mi->info.uid = g_strdup(uid);
+	mi->info.uid_needs_free = TRUE;
+
 	camel_folder_summary_add (summary, (CamelMessageInfo *)mi);
 }
 
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 19:50:24 -0000
@@ -2296,6 +2296,7 @@ add_message_from_data (CamelFolder *fold
 	}
 	
 	mi = (CamelImapMessageInfo *)camel_folder_summary_info_new_from_message (folder->summary, msg);
+	
 	camel_object_unref (CAMEL_OBJECT (msg));
 	
 	if ((idate = g_datalist_get_data (&data, "INTERNALDATE")))
@@ -2511,8 +2512,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 19:50:25 -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 19:50:26 -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
@@ -298,6 +312,8 @@ camel_imap_summary_add_offline (CamelFol
 	}
 
 	mi->info.size = camel_message_info_size(info);
+
+	mi->info.uid_needs_free = TRUE;
 	mi->info.uid = g_strdup (uid);
 
 	label_to_flags(mi);
@@ -312,7 +328,9 @@ camel_imap_summary_add_offline_uncached 
 	CamelImapMessageInfo *mi;
 
 	mi = camel_message_info_clone(info);
+
 	mi->info.uid = g_strdup(uid);
+	mi->info.uid_needs_free = TRUE;
 
 	label_to_flags(mi);
 
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 19:50:28 -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;
 }
@@ -492,6 +492,9 @@ decode_envelope (CamelIMAP4Engine *engin
 	/* subject */
 	if (envelope_decode_nstring (engine, &nstring, TRUE, ex) == -1)
 		goto exception;
+
+	iinfo->info.needs_free = TRUE;
+
 	iinfo->info.subject = camel_pstring_strdup (nstring);
 	g_free(nstring);
 	
@@ -992,8 +995,11 @@ untagged_fetch_all (CamelIMAP4Engine *en
 					g_assert_not_reached ();
 				}
 			} else {
-				g_free (info->uid);
+				if (((CamelMessageInfoBase*)info)->uid_needs_free)
+					g_free (info->uid);
 				info->uid = g_strdup (uid);
+				((CamelMessageInfoBase*)info)->uid_needs_free = TRUE;
+
 				g_hash_table_insert (fetch->uid_hash, (void *) camel_message_info_uid (info), envelope);
 				changed |= IMAP4_FETCH_UID;
 			}
@@ -1063,9 +1069,12 @@ untagged_fetch_all (CamelIMAP4Engine *en
 				h = camel_mime_parser_headers_raw (parser);
 				
 				/* find our mailing-list header */
-				mlist = camel_header_raw_check_mailing_list (&h);
-				iinfo->info.mlist = camel_pstring_strdup (mlist);
-				g_free (mlist);
+
+				/* This introduces a problem for the mmap() implementation */
+
+				// mlist = camel_header_raw_check_mailing_list (&h);
+				// iinfo->info.mlist = camel_pstring_strdup (mlist);
+				// g_free (mlist);
 				
 				/* check if we possibly have attachments */
 				if ((str = camel_header_raw_find (&h, "Content-Type", NULL))) {
@@ -1249,22 +1258,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 19:50:28 -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 19:50:29 -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 19:50:31 -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 19:50:32 -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]