#include "msgcache.h"
#include "utils.h"
#include "procmsg.h"
+#include "codeconv.h"
typedef enum
{
time_t last_access;
};
+typedef struct _StringConverter StringConverter;
+struct _StringConverter {
+ gchar *(*convert) (StringConverter *converter, gchar *srcstr);
+ void (*free) (StringConverter *converter);
+};
+
+typedef struct _StrdupConverter StrdupConverter;
+struct _StrdupConverter {
+ StringConverter converter;
+};
+
+typedef struct _CharsetConverter CharsetConverter;
+struct _CharsetConverter {
+ StringConverter converter;
+
+ gchar *srccharset;
+ gchar *dstcharset;
+};
+
MsgCache *msgcache_new(void)
{
MsgCache *cache;
g_return_if_fail(msginfo != NULL);
oldmsginfo = g_hash_table_lookup(cache->msgnum_table, &msginfo->msgnum);
- if(oldmsginfo && oldmsginfo->msgid) {
+ if(oldmsginfo && oldmsginfo->msgid)
g_hash_table_remove(cache->msgid_table, oldmsginfo->msgid);
- }
-
if (oldmsginfo) {
g_hash_table_remove(cache->msgnum_table, &oldmsginfo->msgnum);
- procmsg_msginfo_free(oldmsginfo);
cache->memusage -= procmsg_msginfo_memusage(oldmsginfo);
+ procmsg_msginfo_free(oldmsginfo);
}
newmsginfo = procmsg_msginfo_new_ref(msginfo);
#define READ_CACHE_DATA(data, fp) \
{ \
- if (msgcache_read_cache_data_str(fp, &data) < 0) { \
+ if (msgcache_read_cache_data_str(fp, &data, conv) < 0) { \
procmsg_msginfo_free(msginfo); \
error = TRUE; \
break; \
return fp;
}
-static gint msgcache_read_cache_data_str(FILE *fp, gchar **str)
+static gint msgcache_read_cache_data_str(FILE *fp, gchar **str, StringConverter *conv)
{
- gchar buf[BUFFSIZE];
+ gchar buf[BUFFSIZE], *tmpstr = NULL;
gint ret = 0;
guint32 len;
if (fread(buf, size, 1, fp) != 1) {
ret = -1;
if (tmp) g_free(tmp);
- *str = NULL;
+ tmpstr = NULL;
break;
}
if (tmp) {
*str = g_strconcat(tmp, buf, NULL);
g_free(tmp);
- tmp = *str;
+ tmp = tmpstr;
} else
- tmp = *str = g_strdup(buf);
+ tmp = tmpstr = g_strdup(buf);
len -= size;
}
if (ret < 0)
g_warning("Cache data is corrupted\n");
+ if (tmpstr != NULL && conv != NULL) {
+ *str = conv->convert(conv, tmpstr);
+ g_free(tmpstr);
+ } else if (tmpstr != NULL) {
+ *str = g_strdup(tmpstr);
+ g_free(tmpstr);
+ } else
+ *str = NULL;
+
return ret;
}
+gchar *strconv_strdup_convert(StringConverter *conv, gchar *srcstr)
+{
+ return g_strdup(srcstr);
+}
+
+gchar *strconv_charset_convert(StringConverter *conv, gchar *srcstr)
+{
+ CharsetConverter *charsetconv = (CharsetConverter *) conv;
+
+ return conv_codeset_strdup(srcstr, charsetconv->srccharset, charsetconv->dstcharset);
+}
+
+void strconv_charset_free(StringConverter *conv)
+{
+ CharsetConverter *charsetconv = (CharsetConverter *) conv;
+
+ g_free(charsetconv->srccharset);
+ g_free(charsetconv->dstcharset);
+}
+
MsgCache *msgcache_read_cache(FolderItem *item, const gchar *cache_file)
{
MsgCache *cache;
gchar file_buf[BUFFSIZE];
guint num;
gboolean error = FALSE;
+ StringConverter *conv = NULL;
+ gchar *srccharset = NULL;
+ const gchar *dstcharset = NULL;
g_return_val_if_fail(cache_file != NULL, NULL);
g_return_val_if_fail(item != NULL, NULL);
tmp_flags |= MSG_DRAFT;
}
- cache = msgcache_new();
+ if (msgcache_read_cache_data_str(fp, &srccharset, NULL) < 0)
+ return NULL;
+ dstcharset = CS_UTF_8;
+ if (srccharset == NULL || dstcharset == NULL) {
+ conv = NULL;
+ } else if (strcmp(srccharset, dstcharset) == 0) {
+ StrdupConverter *strdupconv;
+
+ debug_print("using StrdupConverter\n");
+ strdupconv = g_new0(StrdupConverter, 1);
+ strdupconv->converter.convert = strconv_strdup_convert;
+ strdupconv->converter.free = NULL;
+
+ conv = (StringConverter *) strdupconv;
+ } else {
+ CharsetConverter *charsetconv;
+
+ debug_print("using CharsetConverter\n");
+
+ charsetconv = g_new0(CharsetConverter, 1);
+ charsetconv->converter.convert = strconv_charset_convert;
+ charsetconv->converter.free = strconv_charset_free;
+ charsetconv->srccharset = g_strdup(srccharset);
+ charsetconv->dstcharset = g_strdup(dstcharset);
+
+ conv = (StringConverter *) charsetconv;
+ }
+ g_free(srccharset);
+
+ cache = msgcache_new();
g_hash_table_freeze(cache->msgnum_table);
while (fread(&num, sizeof(num), 1, fp) == 1) {
return NULL;
}
+ if (conv != NULL) {
+ if (conv->free != NULL)
+ conv->free(conv);
+ g_free(conv);
+ }
+
cache->last_access = time(NULL);
debug_print("done. (%d items read)\n", g_hash_table_size(cache->msgnum_table));
if (write_fps.cache_fp == NULL)
return -1;
+ WRITE_CACHE_DATA(CS_UTF_8, write_fps.cache_fp);
+
write_fps.mark_fp = msgcache_open_data_file(mark_file, MARK_VERSION,
DATA_WRITE, NULL, 0);
if (write_fps.mark_fp == NULL) {