2005-07-01 [colin] 1.9.12cvs8
[claws.git] / src / msgcache.c
index 6167d2df4b3ab262d371b26260ddc2db773ed40c..4721a13fbfb1cc6c5eb28ce1d328681d9b502c1e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2001 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2005 Hiroyuki Yamamoto & The Sylpheed Claws Team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include "defs.h"
 
 #include <glib.h>
+#include <glib/gi18n.h>
 
 #include <time.h>
 
-#include "intl.h"
 #include "msgcache.h"
 #include "utils.h"
 #include "procmsg.h"
@@ -225,13 +225,14 @@ gint msgcache_get_memory_usage(MsgCache *cache)
  *  Cache saving functions
  */
 
-#define READ_CACHE_DATA(data, fp) \
+#define READ_CACHE_DATA(data, fp, total_len) \
 { \
-       if (msgcache_read_cache_data_str(fp, &data, conv) < 0) { \
+       if ((tmp_len = msgcache_read_cache_data_str(fp, &data, conv)) < 0) { \
                procmsg_msginfo_free(msginfo); \
                error = TRUE; \
                break; \
        } \
+       total_len += tmp_len; \
 }
 
 #define READ_CACHE_DATA_INT(n, fp) \
@@ -239,8 +240,9 @@ gint msgcache_get_memory_usage(MsgCache *cache)
        guint32 idata; \
        size_t ni; \
  \
-       if (sizeof(idata) != (ni = fread(&idata, 1, sizeof(idata), fp))) { \
-               g_warning("read_int: Cache data corrupted, read %d of %d at offset %d\n", ni, sizeof(idata), ftell(fp)); \
+       if ((ni = fread(&idata, 1, sizeof(idata), fp)) != sizeof(idata)) { \
+               g_warning("read_int: Cache data corrupted, read %d of %d at " \
+                         "offset %ld\n", ni, sizeof(idata), ftell(fp)); \
                procmsg_msginfo_free(msginfo); \
                error = TRUE; \
                break; \
@@ -269,12 +271,12 @@ gint msgcache_get_memory_usage(MsgCache *cache)
        } \
 }
 
-static FILE *msgcache_open_data_file(const gchar *file, gint version,
+static FILE *msgcache_open_data_file(const gchar *file, guint version,
                                     DataOpenMode mode,
                                     gchar *buf, size_t buf_size)
 {
        FILE *fp;
-       gint data_ver;
+       gint32 data_ver;
 
        g_return_val_if_fail(file != NULL, NULL);
 
@@ -292,19 +294,19 @@ static FILE *msgcache_open_data_file(const gchar *file, gint version,
 
        /* check version */
        if ((fp = fopen(file, "rb")) == NULL)
-               debug_print("Mark/Cache file not found\n");
+               debug_print("Mark/Cache file '%s' not found\n", file);
        else {
                if (buf && buf_size > 0)
                        setvbuf(fp, buf, _IOFBF, buf_size);
                if (fread(&data_ver, sizeof(data_ver), 1, fp) != 1 ||
                         version != data_ver) {
-                       debug_print("Mark/Cache version is different (%d != %d). "
-                                   "Discarding it.\n", data_ver, version);
+                       g_message("%s: Mark/Cache version is different (%u != %u). Discarding it.\n",
+                                 file, data_ver, version);
                        fclose(fp);
                        fp = NULL;
                }
        }
-
+       
        if (mode == DATA_READ)
                return fp;
 
@@ -323,39 +325,43 @@ static FILE *msgcache_open_data_file(const gchar *file, gint version,
        return fp;
 }
 
-static gint 
-msgcache_read_cache_data_str(FILE *fp, gchar **str, StringConverter *conv)
+static gint msgcache_read_cache_data_str(FILE *fp, gchar **str, 
+                                        StringConverter *conv)
 {
-    gchar *tmpstr = NULL;
-    size_t ni;
-    guint32 len;
-
-    *str = NULL;
-    if (sizeof(len) != (ni = fread(&len, 1, sizeof(len), fp))
-       || len > G_MAXINT) {
-       g_warning("read_data_str: Cache data (len) corrupted, read %d of %d bytes at offset %d\n", 
-               ni, sizeof(len), ftell(fp));
-       return -1;
-    }
-    if (0 == len)
-       return 0;
-    tmpstr = g_malloc(len + 1);
-
-    if (len != (ni = fread(tmpstr, 1, len, fp))) {
-       g_warning("read_data_str: Cache data corrupted, read %d of %d bytes at offset %d\n", 
-               ni, len, ftell(fp));
-       g_free(tmpstr);
-       return -1;
-    }
-    tmpstr[len] = 0;
-
-    if (conv != NULL) {
-           *str = conv->convert(conv, tmpstr);
-           g_free(tmpstr);
-    } else 
-           *str = tmpstr;
-
-    return 0;
+       gchar *tmpstr = NULL;
+       size_t ni;
+       guint32 len;
+
+       *str = NULL;
+       if ((ni = fread(&len, 1, sizeof(len), fp) != sizeof(len)) ||
+           len > G_MAXINT) {
+               g_warning("read_data_str: Cache data (len) corrupted, read %d "
+                         "of %d bytes at offset %ld\n", ni, sizeof(len), 
+                         ftell(fp));
+               return -1;
+       }
+
+       if (len == 0)
+               return 0;
+
+       tmpstr = g_malloc(len + 1);
+
+       if ((ni = fread(tmpstr, 1, len, fp)) != len) {
+               g_warning("read_data_str: Cache data corrupted, read %d of %d "
+                         "bytes at offset %ld\n", 
+                         ni, len, ftell(fp));
+               g_free(tmpstr);
+               return -1;
+       }
+       tmpstr[len] = 0;
+
+       if (conv != NULL) {
+               *str = conv->convert(conv, tmpstr);
+               g_free(tmpstr);
+       } else 
+               *str = tmpstr;
+
+       return len;
 }
 
 gchar *strconv_strdup_convert(StringConverter *conv, gchar *srcstr)
@@ -385,12 +391,21 @@ MsgCache *msgcache_read_cache(FolderItem *item, const gchar *cache_file)
        MsgInfo *msginfo;
        MsgTmpFlags tmp_flags = 0;
        gchar file_buf[BUFFSIZE];
-       guint num;
+       guint32 num;
+        guint refnum;
        gboolean error = FALSE;
        StringConverter *conv = NULL;
        gchar *srccharset = NULL;
        const gchar *dstcharset = NULL;
-
+       gchar *ref = NULL;
+       guint memusage = 0;
+       guint tmp_len = 0;
+#if 0
+       struct timeval start;
+       struct timeval end;
+       struct timeval diff;
+       gettimeofday(&start, NULL);
+#endif
        g_return_val_if_fail(cache_file != NULL, NULL);
        g_return_val_if_fail(item != NULL, NULL);
 
@@ -438,29 +453,46 @@ MsgCache *msgcache_read_cache(FolderItem *item, const gchar *cache_file)
 
        cache = msgcache_new();
        g_hash_table_freeze(cache->msgnum_table);
+       g_hash_table_freeze(cache->msgid_table);
 
        while (fread(&num, sizeof(num), 1, fp) == 1) {
                msginfo = procmsg_msginfo_new();
                msginfo->msgnum = num;
+               memusage += sizeof(MsgInfo);
+               
                READ_CACHE_DATA_INT(msginfo->size, fp);
                READ_CACHE_DATA_INT(msginfo->mtime, fp);
                READ_CACHE_DATA_INT(msginfo->date_t, fp);
                READ_CACHE_DATA_INT(msginfo->flags.tmp_flags, fp);
-
-               READ_CACHE_DATA(msginfo->fromname, fp);
-
-               READ_CACHE_DATA(msginfo->date, fp);
-               READ_CACHE_DATA(msginfo->from, fp);
-               READ_CACHE_DATA(msginfo->to, fp);
-               READ_CACHE_DATA(msginfo->cc, fp);
-               READ_CACHE_DATA(msginfo->newsgroups, fp);
-               READ_CACHE_DATA(msginfo->subject, fp);
-               READ_CACHE_DATA(msginfo->msgid, fp);
-               READ_CACHE_DATA(msginfo->inreplyto, fp);
-               READ_CACHE_DATA(msginfo->references, fp);
-               READ_CACHE_DATA(msginfo->xref, fp);
+                               
+               READ_CACHE_DATA(msginfo->fromname, fp, memusage);
+
+               READ_CACHE_DATA(msginfo->date, fp, memusage);
+               READ_CACHE_DATA(msginfo->from, fp, memusage);
+               READ_CACHE_DATA(msginfo->to, fp, memusage);
+               READ_CACHE_DATA(msginfo->cc, fp, memusage);
+               READ_CACHE_DATA(msginfo->newsgroups, fp, memusage);
+               READ_CACHE_DATA(msginfo->subject, fp, memusage);
+               READ_CACHE_DATA(msginfo->msgid, fp, memusage);
+               READ_CACHE_DATA(msginfo->inreplyto, fp, memusage);
+               READ_CACHE_DATA(msginfo->xref, fp, memusage);
+               
                READ_CACHE_DATA_INT(msginfo->planned_download, fp);
                READ_CACHE_DATA_INT(msginfo->total_size, fp);
+               READ_CACHE_DATA_INT(refnum, fp);
+               
+               for (; refnum != 0; refnum--) {
+                       ref = NULL;
+
+                       READ_CACHE_DATA(ref, fp, memusage);
+
+                       if (ref && strlen(ref))
+                               msginfo->references =
+                                       g_slist_prepend(msginfo->references, ref);
+               }
+               if (msginfo->references)
+                       msginfo->references =
+                               g_slist_reverse(msginfo->references);
 
                msginfo->folder = item;
                msginfo->flags.tmp_flags |= tmp_flags;
@@ -468,10 +500,10 @@ MsgCache *msgcache_read_cache(FolderItem *item, const gchar *cache_file)
                g_hash_table_insert(cache->msgnum_table, &msginfo->msgnum, msginfo);
                if(msginfo->msgid)
                        g_hash_table_insert(cache->msgid_table, msginfo->msgid, msginfo);
-               cache->memusage += procmsg_msginfo_memusage(msginfo);
        }
        fclose(fp);
        g_hash_table_thaw(cache->msgnum_table);
+       g_hash_table_thaw(cache->msgid_table);
 
        if (conv != NULL) {
                if (conv->free != NULL)
@@ -485,10 +517,15 @@ MsgCache *msgcache_read_cache(FolderItem *item, const gchar *cache_file)
        }
 
        cache->last_access = time(NULL);
+       cache->memusage = memusage;
 
        debug_print("done. (%d items read)\n", g_hash_table_size(cache->msgnum_table));
        debug_print("Cache size: %d messages, %d byte\n", g_hash_table_size(cache->msgnum_table), cache->memusage);
-
+#if 0
+       gettimeofday(&end, NULL);
+       timersub(&end, &start, &diff);
+       printf("spent %d seconds %d usages %d;%d\n", diff.tv_sec, diff.tv_usec, cache->memusage, memusage);
+#endif
        return cache;
 }
 
@@ -497,7 +534,7 @@ void msgcache_read_mark(MsgCache *cache, const gchar *mark_file)
        FILE *fp;
        MsgInfo *msginfo;
        MsgPermFlags perm_flags;
-       guint num;
+       guint32 num;
 
        if ((fp = msgcache_open_data_file(mark_file, MARK_VERSION, DATA_READ, NULL, 0)) == NULL)
                return;
@@ -518,6 +555,7 @@ void msgcache_read_mark(MsgCache *cache, const gchar *mark_file)
 void msgcache_write_cache(MsgInfo *msginfo, FILE *fp)
 {
        MsgTmpFlags flags = msginfo->flags.tmp_flags & MSG_CACHED_FLAG_MASK;
+       GSList *cur;
 
        WRITE_CACHE_DATA_INT(msginfo->msgnum, fp);
        WRITE_CACHE_DATA_INT(msginfo->size, fp);
@@ -535,10 +573,15 @@ void msgcache_write_cache(MsgInfo *msginfo, FILE *fp)
        WRITE_CACHE_DATA(msginfo->subject, fp);
        WRITE_CACHE_DATA(msginfo->msgid, fp);
        WRITE_CACHE_DATA(msginfo->inreplyto, fp);
-       WRITE_CACHE_DATA(msginfo->references, fp);
        WRITE_CACHE_DATA(msginfo->xref, fp);
        WRITE_CACHE_DATA_INT(msginfo->planned_download, fp);
        WRITE_CACHE_DATA_INT(msginfo->total_size, fp);
+        
+       WRITE_CACHE_DATA_INT(g_slist_length(msginfo->references), fp);
+
+       for (cur = msginfo->references; cur != NULL; cur = cur->next) {
+               WRITE_CACHE_DATA((gchar *)cur->data, fp);
+       }
 }
 
 static void msgcache_write_flags(MsgInfo *msginfo, FILE *fp)