Re: Just, try it ;-)

Philip Van Hoof <[email protected]>
Newsgroups gmane.comp.gnome.evolution.devel
Message-ID <1152436229.21814.0.camel__30565.7045370483$1152494286$gmane$org@localhost.localdomain>
On Fri, 2006-07-07 at 18:35 +0200, Philip Van Hoof wrote: 
> It's almost working

This patch is actually functional and working.

Some notes:

- It will only work with the IMAP provider (not IMAP4). This is because
you need to do two or three small fixes in the provider-specific stuff.
I only did this for the provider that I'm testing with (being the IMAP
one).

- It's still highly untested and it will most likely crash your
evolution. I recommend testing it with tinymail (as that is what I've
been using so far).



-- 
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

_______________________________________________
Evolution-hackers mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/evolution-hackers
camel_folder_summary_with_mmap_works_first_time.diff (text/x-patch, 23 KB)
? 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 -r1.17 camel-file-utils.c
--- camel-file-utils.c	2 Jun 2006 00:52:29 -0000	1.17
+++ camel-file-utils.c	9 Jul 2006 09:02:31 -0000
@@ -269,11 +269,21 @@
 	
 	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)
+		{
+			fputc ('\0', out);
+			return 0;
+		}
+	}
+
 	return -1;
 }
 
Index: camel-folder-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-folder-summary.c,v
retrieving revision 1.149
diff -u -r1.149 camel-folder-summary.c
--- camel-folder-summary.c	6 Jul 2006 19:43:46 -0000	1.149
+++ camel-folder-summary.c	9 Jul 2006 09:02:35 -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 @@
 /* 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)
 
@@ -83,16 +84,17 @@
 	struct _node *next;
 };
 
+
 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 +162,11 @@
 	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 @@
 	CamelFolderSummary *new = CAMEL_FOLDER_SUMMARY ( camel_object_new (camel_folder_summary_get_type ()));
 
 	new->folder = folder;
-
+	
 	return new;
 }
 
@@ -504,17 +511,29 @@
 	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) {
+io(printf("READING LAST STUFF\n"));
+
+	ptrchr = s->filepos;
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &count, FALSE);
+	s->filepos = ptrchr;
+
+io(printf("token count a = %d\n", count));
+
+	if (count > 500) {
 		camel_folder_summary_content_info_free(s, ci);
 		return NULL;
 	}
 
 	for (i=0;i<count;i++) {
+io(printf("doing token/part %d of count a = %d\n", i, count));
+
 		part = perform_content_info_load(s, in);
 		if (part) {
 			my_list_append((struct _node **)&ci->childs, (struct _node *)part);
@@ -547,22 +566,28 @@
 	if (s->summary_path == NULL)
 		return 0;
 
-	in = g_fopen(s->summary_path, "rb");
+	if (!s->file)
+	{
+		s->file = g_mapped_file_new (s->summary_path, FALSE, NULL);
+		s->filepos = g_mapped_file_get_contents (s->file);
+	}
+
 	if (in == NULL)
 		return -1;
 
 	CAMEL_SUMMARY_LOCK(s, io_lock);
-	if ( ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, in) == -1)
+	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);
 			if (((CamelMessageInfoBase *)mi)->content == NULL) {
@@ -571,13 +596,12 @@
 			}
 		}
 
+io(printf("adding\n"));
+
 		camel_folder_summary_add(s, mi);
 	}
 
 	CAMEL_SUMMARY_UNLOCK(s, io_lock);
-	
-	if (fclose (in) != 0)
-		return -1;
 
 	s->flags &= ~CAMEL_SUMMARY_DIRTY;
 
@@ -588,7 +612,6 @@
 		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;
@@ -724,21 +747,21 @@
 int
 camel_folder_summary_header_load(CamelFolderSummary *s)
 {
-	FILE *in;
 	int ret;
 
 	if (s->summary_path == NULL)
 		return 0;
 
-	in = g_fopen(s->summary_path, "rb");
-	if (in == NULL)
-		return -1;
+	if (!s->file)
+	{
+		s->file = g_mapped_file_new (s->summary_path, FALSE, NULL);
+		s->filepos = g_mapped_file_get_contents (s->file);
+	}
 
 	CAMEL_SUMMARY_LOCK(s, io_lock);
-	ret = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, in);
+	ret = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, NULL);
 	CAMEL_SUMMARY_UNLOCK(s, io_lock);
 	
-	fclose(in);
 	s->flags &= ~CAMEL_SUMMARY_DIRTY;
 	return ret;
 }
@@ -1302,12 +1325,14 @@
 		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 fputc ('\0', out);
 		}
 	}
+
 	return 0;
 }
 
@@ -1322,20 +1347,20 @@
  * 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 = decode_uint32 ((unsigned char*)ptrchr, &len, TRUE);
+
+io(printf("token len = %d\n", len));
 
 	if (len<32) {
+
 		if (len <= 0) {
 			ret = NULL;
 		} else if (len<= tokens_len) {
@@ -1350,18 +1375,17 @@
 		*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;
+		ret = ptrchr;
+		ptrchr += len;
+
 	}
 
 	io(printf("Token = '%s'\n", ret));
 
+	s->filepos = ptrchr;
+
 	*str = ret;
 	return 0;
 }
@@ -1392,40 +1416,74 @@
 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
+	if (s->version != CAMEL_FOLDER_SUMMARY_VERSION) {
+		io(printf ("Summary header version needs upgrade"));
+
+		g_mapped_file_free (s->file);
+		s->file = NULL;
+		s->flags |= CAMEL_SUMMARY_DIRTY;
+
+		 CAMEL_SUMMARY_UNLOCK(s, io_lock);
+
+		s->folder->summary = s;
+
+		/* TODO: Handle offline case */
+
+		/* ((CamelDiscoFolderClass *)(CAMEL_OBJECT_GET_CLASS(s->folder)))->refresh_info_offline (s->folder, NULL); */
+		((CamelDiscoFolderClass *)(CAMEL_OBJECT_GET_CLASS(s->folder)))->refresh_info_online (s->folder, NULL);
+
+		camel_folder_summary_set_build_content (s, TRUE);
+		camel_folder_summary_save (s);
+		camel_folder_summary_set_build_content (s, FALSE);
+
+		 CAMEL_SUMMARY_LOCK(s, io_lock);
+
+		s->file = g_mapped_file_new (s->summary_path, FALSE, NULL);
+		ptr32 = g_mapped_file_get_contents (s->file);
+		s->filepos = ptr32;
+		s->version = g_ntohl (*ptr32); ptr32++; 
+
+		io(printf("Header upgraded to %d", (s->version&0xff)));
+
+
+	} else
 		io(printf("loading new-format summary\n"));
 
-	/* 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) {
-		return -1;
-	}
+	s->flags = g_ntohl (*ptr32); ptr32++; 
+	s->nextuid = g_ntohl (*ptr32); ptr32++; 
+	ptrt = (time_t*)ptr32;
+	s->time = *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++; 
+	}
+
+	io(printf ("CAMEL: ur:%d, dc:%d, jc:%d, v:%d\n",
+	s->unread_count, s->deleted_count, s->junk_count, s->version));
+     
+	/* The first is the implementation version, the second I don't yet know */
+	ptr32++; ptr32++;
 
-	/* 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->filepos = ptr32;
 
 	return 0;
 }
@@ -1681,79 +1739,181 @@
 	return (CamelMessageInfo *)mi;
 }
 
+unsigned char*
+decode_uint32 (unsigned char *start, guint32 *dest, gboolean is_string)
+{
+	guint32 value = 0;
+	unsigned char uv = *start;
+	int v;
+
+     /* until we get the last byte, keep decoding 7 bits at a time */
+
+
+io(printf ("START at %02x\n", uv));
+
+        while ( ((v = uv) & 0x80) == 0 ) {
+io(printf ("HAVE NEXT at %02x\n", v));
+                value |= v;
+                value <<= 7;
+		start++; uv = *start;
+        }
+
+	//if (v == EOF) {
+	//	*dest = value >> 7;
+	//	return -1;
+	//}
+
+	*dest = value | (v & 0x7f);
+
+	if (is_string && *dest == 1)
+		*dest = 0;
+
+
+	return ++start;
+
+}
+
 static CamelMessageInfo *
 message_info_load(CamelFolderSummary *s, FILE *in)
 {
 	CamelMessageInfoBase *mi;
-	guint count;
+	guint count, len, nlen;
+	unsigned char *ptrchr = s->filepos;
+	gint32 *ptr32;
+	time_t *ptrt;   
 	int i;
-	char *subject, *from, *to, *cc, *mlist, *uid;
 
 	mi = (CamelMessageInfoBase *)camel_message_info_new(s);
 
 	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 = decode_uint32 ((unsigned char*)ptrchr, &len, TRUE);
+	io(printf ("uid len = %d, str=%s\n", len, ptrchr));
+	mi->uid = ptrchr;
+	ptrchr += len;
+       
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len, FALSE);
+	mi->flags = ptrchr;
+
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len, FALSE);
+	mi->size = ptrchr;
+       
+	ptrt = ptrchr;
+	mi->date_sent = ptrt; ptrt++;
+	mi->date_received = ptrt; ptrt++;
+
+	ptrchr = ptrt;
+       
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len, TRUE);
+	mi->subject = ptrchr;
+	ptrchr += len;
+
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len, TRUE);
+	mi->from = ptrchr;
+	ptrchr += len;
+
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len, TRUE);
+	mi->to = ptrchr;
+	ptrchr += len;
+
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len, TRUE);
+	mi->cc = ptrchr;
+	ptrchr += len;
+
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len, TRUE);
+	mi->mlist = 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 = ptrchr;
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
+
+	mi->message_id.id.part.hi = g_ntohl (*ptr32); ptr32++;
+	mi->message_id.id.part.lo = g_ntohl (*ptr32); ptr32++;
+
+io(printf ("hi:%d lo:%d \n", mi->message_id.id.part.hi, mi->message_id.id.part.lo));
+
+	ptrchr = ptr32;
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &count, FALSE);
+	ptr32 = ptrchr;
+
+	if (count > 500)
 		goto error;
 
-	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);
-		}
+io(printf ("%d refs\n", count));
+
+	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++;
+
+io(printf ("refhi=%d reflo=%d at %d of %d flags\n", 
+	mi->references->references[i].id.part.hi,
+	mi->references->references[i].id.part.lo,
+	i, count));
+
 	}
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
+	ptrchr = ptr32;
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &count, FALSE);
+	
+	if (count > 500)
 		goto error;
 
+io(printf ("%d flags\n", count));
+
 	for (i=0;i<count;i++) {
 		char *name;
-		if (camel_file_util_decode_string(in, &name) == -1 || name == NULL)
+
+		ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len, TRUE);
+		name = ptrchr;
+		ptrchr += len;
+
+		if (name == NULL)
 			goto error;
+
+io(printf ("tag %s at %d of %d\n", name, i, count));
+
 		camel_flag_set(&mi->user_flags, name, TRUE);
-		g_free(name);
 	}
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &count, FALSE);
+
+io(printf ("%d tag sets\n", count));
+
+	if (count > 500)
 		goto error;
 
 	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)
+
+		ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len, TRUE);
+		name = ptrchr;
+		ptrchr += len;
+
+		if (name == NULL)
 			goto error;
+
+		ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len, TRUE);
+		value = ptrchr;
+		ptrchr += len;
+
+io(printf ("tag set %s v %s at %d of %d\n", name, value, i, count));
+
 		camel_tag_set(&mi->user_tags, name, value);
-		g_free(name);
-		g_free(value);
 	}
 
-	if (!ferror(in))
-		return (CamelMessageInfo *)mi;
+
+	s->filepos = ptrchr;
+
+io(printf ("mi ends at %02x\n", (unsigned char*)*ptrchr));
+
+	return (CamelMessageInfo *)mi;
 
 error:
 	camel_message_info_free((CamelMessageInfo *)mi);
@@ -1820,7 +1980,7 @@
 message_info_free(CamelFolderSummary *s, CamelMessageInfo *info)
 {
 	CamelMessageInfoBase *mi = (CamelMessageInfoBase *)info;
-
+/*
 	g_free(mi->uid);
 	camel_pstring_free(mi->subject);
 	camel_pstring_free(mi->from);
@@ -1828,6 +1988,7 @@
 	camel_pstring_free(mi->cc);
 	camel_pstring_free(mi->mlist);
 	g_free(mi->references);
+*/
 	camel_flag_list_free(&mi->user_flags);
 	camel_tag_list_free(&mi->user_tags);
 	if (s)
@@ -1861,42 +2022,54 @@
 	guint32 count, i;
 	CamelContentType *ct;
 
+	unsigned char *ptrchr = s->filepos;
+	gint32 *ptr32 = 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);
+	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)
+
+	ptrchr = s->filepos;
+
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &count, FALSE);
+	
+	s->filepos = ptrchr;
+
+	if (count > 500)
 		goto error;
 	
 	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);
+
+		//if (!(name && value))
+		//	goto error;
 		
 		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);
+
 	}
 	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);
+	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);
 
-	camel_file_util_decode_uint32(in, &ci->size);
+	ptrchr = s->filepos;
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &ci->size, FALSE);
+	s->filepos = ptrchr;
 
 	ci->childs = NULL;
 
-	if (!ferror(in))
-		return ci;
+	return ci;
 
  error:
 	camel_folder_summary_content_info_free(s, ci);
Index: camel-folder-summary.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-folder-summary.h,v
retrieving revision 1.86
diff -u -r1.86 camel-folder-summary.h
--- camel-folder-summary.h	31 Aug 2005 04:21:56 -0000	1.86
+++ camel-folder-summary.h	9 Jul 2006 09:02:36 -0000
@@ -224,6 +224,9 @@
 	GHashTable *messages_uid; /* CamelMessageInfo's by uid */
 
 	struct _CamelFolder *folder; /* parent folder, for events */
+
+	GMappedFile *file;
+	void *filepos;
 };
 
 struct _CamelFolderSummaryClass {
@@ -277,6 +280,9 @@
 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 +335,7 @@
 
 /* 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-string-utils.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-string-utils.c,v
retrieving revision 1.6
diff -u -r1.6 camel-string-utils.c
--- camel-string-utils.c	6 Jul 2006 19:43:47 -0000	1.6
+++ camel-string-utils.c	9 Jul 2006 09:02:37 -0000
@@ -164,10 +164,10 @@
 	char *pstr;
 	int count;
 	
-	if (s == NULL)
+	if (str == NULL)
 		return NULL;
 	
-	if (s[0] == '\0') {
+	if (str[0] == '\0') {
 		if (own)
 			g_free (str);
 		return "";
@@ -180,6 +180,7 @@
 	if (g_hash_table_lookup_extended (pstring_table, str, (void **) &pstr, &pcount)) {
 		count = GPOINTER_TO_INT (pcount) + 1;
 		g_hash_table_insert (pstring_table, pstr, GINT_TO_POINTER (count));
+		g_free (str);
 	} else {
 		pstr = own ? str : g_strdup (str);
 		g_hash_table_insert (pstring_table, pstr, GINT_TO_POINTER (1));
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 -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	9 Jul 2006 09:02:37 -0000
@@ -152,16 +152,18 @@
 	if (camel_imap_summary_parent->summary_header_load (s, in) == -1)
 		return -1;
 
-	/* Legacy version */
+	ims->validity = CAMEL_IMAP_SUMMARY_VERSION;
+
+	/* Legacy version 
 	if (s->version == 0x30c)
 		return camel_file_util_decode_uint32(in, &ims->validity);
 
-	/* Version 1 */
+	* Version 1 *
 	if (camel_file_util_decode_fixed_int32(in, &ims->version) == -1)
 		return -1;
 	
 	if (ims->version == 2) {
-		/* Version 2: for compat with version 2 of the imap4 summary files */
+		* 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)
@@ -176,7 +178,7 @@
 		errno = EINVAL;
 		return -1;
 	}
-
+*/
 	return 0;
 }
 
@@ -212,19 +214,15 @@
 	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 = decode_uint32 (ptrchr, &iinfo->server_flags, TRUE);
+		s->filepos = ptrchr;
 		label_to_flags(iinfo);
 	}
 
 	return info;
-error:
-	camel_message_info_free(info);
-	return NULL;
 }
 
 static int
@@ -254,10 +252,22 @@
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.