aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/imap4/camel-imap4-store-summary.c
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@novell.com>2004-10-27 05:22:17 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2004-10-27 05:22:17 +0800
commitaad2d708c31bc7b238fc4f7027e5c48fcee5f062 (patch)
tree5b68028a7a5dc5a7f6c5106ea51f7287b9980644 /camel/providers/imap4/camel-imap4-store-summary.c
parent99cbfb261554f038d9b709d2b3dab26a7f0e7bef (diff)
downloadgsoc2013-evolution-aad2d708c31bc7b238fc4f7027e5c48fcee5f062.tar.gz
gsoc2013-evolution-aad2d708c31bc7b238fc4f7027e5c48fcee5f062.tar.zst
gsoc2013-evolution-aad2d708c31bc7b238fc4f7027e5c48fcee5f062.zip
New files implementing a folder-info cache for offline mode (and faster
2004-10-26 Jeffrey Stedfast <fejj@novell.com> * providers/imap4/camel-imap4-store-summary.[c,h]: New files implementing a folder-info cache for offline mode (and faster startup I guess). * providers/imap4/camel-imap4-store.c (imap4_build_folder_info): Cache the folder-info for later use in offline mode. * providers/imap4/camel-imap4-utils.c (camel_imap4_get_path_delim): Instead of assigning top = "INBOX", do strcpy (top, "INBOX") so that we can later modify the string. Fixes bug #68814. 2004-10-25 Jeffrey Stedfast <fejj@novell.com> * providers/imap4/camel-imap4-engine.c (engine_parse_namespace): Updated to use the public function in camel-imap4-utils.c (camel_imap4_engine_finalize): Same. * providers/imap4/camel-imap4-store.c (imap4_construct): Setup and load the store summary. (camel_imap4_store_finalize): Unref the store summary. (imap4_get_folder): Implemented offline support. (imap4_folder_utf7_name): Pass the summary to get_delim rather than the engine. (imap4_create_folder): Same. (imap4_reconnect): Update the namespaces on the store summary. (connect_to_server): Update the store summary capabilities. * providers/imap4/camel-imap4-utils.c (camel_imap4_get_path_delim): Now takes a store-summary rather than an engine so that it will work in offline mode. (camel_imap4_namespace_clear): Moved here from camel-imap4-engine.c (camel_imap4_namespace_list_copy): New convenience function. (camel_imap4_namespace_list_free): New. * providers/imap4/camel-imap4-folder.c (camel_imap4_folder_new): Check the return value of summary loading in offline mode (if it fails, we can't get the folder). svn path=/trunk/; revision=27730
Diffstat (limited to 'camel/providers/imap4/camel-imap4-store-summary.c')
-rw-r--r--camel/providers/imap4/camel-imap4-store-summary.c390
1 files changed, 390 insertions, 0 deletions
diff --git a/camel/providers/imap4/camel-imap4-store-summary.c b/camel/providers/imap4/camel-imap4-store-summary.c
new file mode 100644
index 0000000000..7f9d211f4f
--- /dev/null
+++ b/camel/providers/imap4/camel-imap4-store-summary.c
@@ -0,0 +1,390 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@novell.com>
+ *
+ * Copyright 2004 Novell, Inc. (www.novell.com)
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <camel/camel-store.h>
+#include <camel/camel-file-utils.h>
+
+#include "camel-imap4-utils.h"
+#include "camel-imap4-store-summary.h"
+
+
+#define CAMEL_IMAP4_STORE_SUMMARY_VERSION_0 (0)
+#define CAMEL_IMAP4_STORE_SUMMARY_VERSION (0)
+
+static void camel_imap4_store_summary_class_init (CamelIMAP4StoreSummaryClass *klass);
+static void camel_imap4_store_summary_init (CamelIMAP4StoreSummary *obj);
+static void camel_imap4_store_summary_finalize (CamelObject *obj);
+
+static int summary_header_load (CamelStoreSummary *s, FILE *in);
+static int summary_header_save (CamelStoreSummary *s, FILE *out);
+
+#if 0
+static CamelStoreInfo *store_info_load (CamelStoreSummary *s, FILE *in);
+static int store_info_save (CamelStoreSummary *s, FILE *out, CamelStoreInfo *info);
+static void store_info_free (CamelStoreSummary *s, CamelStoreInfo *info);
+#endif
+
+
+static CamelStoreSummaryClass *parent_class = NULL;
+
+
+CamelType
+camel_imap4_store_summary_get_type (void)
+{
+ static CamelType type = CAMEL_INVALID_TYPE;
+
+ if (type == CAMEL_INVALID_TYPE) {
+ type = camel_type_register (camel_store_summary_get_type (),
+ "CamelIMAP4StoreSummary",
+ sizeof (CamelIMAP4StoreSummary),
+ sizeof (CamelIMAP4StoreSummaryClass),
+ (CamelObjectClassInitFunc) camel_imap4_store_summary_class_init,
+ NULL,
+ (CamelObjectInitFunc) camel_imap4_store_summary_init,
+ (CamelObjectFinalizeFunc) camel_imap4_store_summary_finalize);
+ }
+
+ return type;
+}
+
+
+static void
+camel_imap4_store_summary_class_init (CamelIMAP4StoreSummaryClass *klass)
+{
+ CamelStoreSummaryClass *ssklass = (CamelStoreSummaryClass *) klass;
+
+ parent_class = (CamelStoreSummaryClass *) camel_store_summary_get_type ();
+
+ ssklass->summary_header_load = summary_header_load;
+ ssklass->summary_header_save = summary_header_save;
+
+#if 0
+ ssklass->store_info_load = store_info_load;
+ ssklass->store_info_save = store_info_save;
+ ssklass->store_info_free = store_info_free;
+#endif
+}
+
+static void
+camel_imap4_store_summary_init (CamelIMAP4StoreSummary *s)
+{
+ ((CamelStoreSummary *) s)->store_info_size = sizeof (CamelIMAP4StoreInfo);
+ s->version = CAMEL_IMAP4_STORE_SUMMARY_VERSION;
+ s->namespaces = NULL;
+}
+
+static void
+camel_imap4_store_summary_finalize (CamelObject *obj)
+{
+ CamelIMAP4StoreSummary *s = (CamelIMAP4StoreSummary *) obj;
+
+ if (s->namespaces)
+ camel_imap4_namespace_list_free (s->namespaces);
+}
+
+
+static CamelIMAP4NamespaceList *
+load_namespaces (FILE *in)
+{
+ CamelIMAP4Namespace *ns, *tail;
+ CamelIMAP4NamespaceList *nsl;
+ guint32 i, j, n;
+
+ nsl = g_malloc (sizeof (CamelIMAP4NamespaceList));
+ nsl->personal = NULL;
+ nsl->shared = NULL;
+ nsl->other = NULL;
+
+ tail = (CamelIMAP4Namespace *) &nsl->personal;
+ if (camel_file_util_decode_fixed_int32 (in, &n) == -1)
+ goto exception;
+
+ for (j = 0; j < 3; j++) {
+ for (i = 0; i < n; i++) {
+ guint32 sep;
+ char *path;
+
+ if (camel_file_util_decode_string (in, &path) == -1)
+ goto exception;
+
+ if (camel_file_util_decode_uint32 (in, &sep) == -1) {
+ g_free (path);
+ goto exception;
+ }
+
+ tail->next = ns = g_malloc (sizeof (CamelIMAP4Namespace));
+ ns->sep = sep & 0xff;
+ ns->path = path;
+ ns->next = NULL;
+ tail = ns;
+ }
+
+ if (j == 0)
+ tail = (CamelIMAP4Namespace *) &nsl->shared;
+ else
+ tail = (CamelIMAP4Namespace *) &nsl->other;
+
+ if (camel_file_util_decode_fixed_int32 (in, &n) == -1)
+ goto exception;
+ }
+
+ return nsl;
+
+ exception:
+
+ camel_imap4_namespace_list_free (nsl);
+
+ return NULL;
+}
+
+static int
+summary_header_load (CamelStoreSummary *s, FILE *in)
+{
+ CamelIMAP4StoreSummary *is = (CamelIMAP4StoreSummary *) s;
+ guint32 version, capa;
+
+ if (parent_class->summary_header_load (s, in) == -1)
+ return -1;
+
+ if (camel_file_util_decode_fixed_int32 (in, &version) == -1)
+ return -1;
+
+ is->version = version;
+ if (version < CAMEL_IMAP4_STORE_SUMMARY_VERSION_0) {
+ g_warning ("Store summary header version too low");
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (camel_file_util_decode_fixed_int32 (in, &capa) == -1)
+ return -1;
+
+ is->capa = capa;
+
+ if (!(is->namespaces = load_namespaces (in)))
+ return -1;
+
+ return 0;
+}
+
+static int
+save_namespaces (FILE *out, CamelIMAP4NamespaceList *nsl)
+{
+ CamelIMAP4Namespace *cur, *ns;
+ guint32 i, n;
+
+ cur = nsl->personal;
+ for (i = 0; i < 3; i++) {
+ for (ns = cur, n = 0; ns; n++)
+ ns = ns->next;
+
+ if (camel_file_util_encode_fixed_int32 (out, n) == -1)
+ return -1;
+
+ ns = cur;
+ while (ns != NULL) {
+ if (camel_file_util_encode_string (out, ns->path) == -1)
+ return -1;
+
+ if (camel_file_util_encode_uint32 (out, ns->sep) == -1)
+ return -1;
+
+ ns = ns->next;
+ }
+
+ if (i == 0)
+ cur = nsl->shared;
+ else
+ cur = nsl->other;
+ }
+
+ return 0;
+}
+
+static int
+summary_header_save (CamelStoreSummary *s, FILE *out)
+{
+ CamelIMAP4StoreSummary *is = (CamelIMAP4StoreSummary *) s;
+
+ if (parent_class->summary_header_save (s, out) == -1)
+ return -1;
+
+ if (camel_file_util_encode_fixed_int32 (out, is->version) == -1)
+ return -1;
+
+ if (camel_file_util_encode_fixed_int32 (out, is->capa) == -1)
+ return -1;
+
+ if (save_namespaces (out, is->namespaces) == -1)
+ return -1;
+
+ return 0;
+}
+
+#if 0
+static CamelStoreInfo *
+store_info_load (CamelStoreSummary *s, FILE *in)
+{
+ return NULL;
+}
+
+static int
+store_info_save (CamelStoreSummary *s, FILE *out, CamelStoreInfo *info)
+{
+ return 0;
+}
+
+static void
+store_info_free (CamelStoreSummary *s, CamelStoreInfo *info)
+{
+ ;
+}
+#endif
+
+/**
+ * camel_imap4_store_summary_new:
+ *
+ * Create a new CamelIMAP4StoreSummary object.
+ *
+ * Returns a new CamelIMAP4StoreSummary object.
+ **/
+CamelIMAP4StoreSummary *
+camel_imap4_store_summary_new (void)
+{
+ return (CamelIMAP4StoreSummary *) camel_object_new (camel_imap4_store_summary_get_type ());
+}
+
+
+void
+camel_imap4_store_summary_set_capabilities (CamelIMAP4StoreSummary *s, guint32 capa)
+{
+ s->capa = capa;
+}
+
+
+void
+camel_imap4_store_summary_set_namespaces (CamelIMAP4StoreSummary *s, const CamelIMAP4NamespaceList *ns)
+{
+ if (s->namespaces)
+ camel_imap4_namespace_list_free (s->namespaces);
+ s->namespaces = camel_imap4_namespace_list_copy (ns);
+}
+
+
+void
+camel_imap4_store_summary_note_info (CamelIMAP4StoreSummary *s, CamelFolderInfo *fi)
+{
+ CamelStoreSummary *ss = (CamelStoreSummary *) s;
+ CamelStoreInfo *si;
+
+ if ((si = camel_store_summary_path (ss, fi->full_name))) {
+ if (fi->unread != -1) {
+ si->unread = fi->unread;
+ ss->flags |= CAMEL_STORE_SUMMARY_DIRTY;
+ }
+
+ if (fi->total != -1) {
+ si->total = fi->total;
+ ss->flags |= CAMEL_STORE_SUMMARY_DIRTY;
+ }
+
+ camel_store_summary_info_free (ss, si);
+ return;
+ }
+
+ si = camel_store_summary_info_new (ss);
+ si->path = g_strdup (fi->full_name);
+ si->uri = g_strdup (fi->uri);
+ si->flags = fi->flags;
+ si->unread = fi->unread;
+ si->total = fi->total;
+
+ camel_store_summary_add (ss, si);
+}
+
+
+static CamelFolderInfo *
+store_info_to_folder_info (CamelStoreSummary *s, CamelStoreInfo *si)
+{
+ CamelFolderInfo *fi;
+
+ fi = g_malloc0 (sizeof (CamelFolderInfo));
+ fi->full_name = g_strdup (camel_store_info_path (s, si));
+ fi->name = g_strdup (camel_store_info_name (s, si));
+ fi->uri = g_strdup (camel_store_info_uri (s, si));
+ fi->flags = si->flags;
+ fi->unread = si->unread;
+ fi->total = si->total;
+
+ return fi;
+}
+
+CamelFolderInfo *
+camel_imap4_store_summary_get_folder_info (CamelIMAP4StoreSummary *s, const char *top, guint32 flags)
+{
+ CamelStoreSummary *ss = (CamelStoreSummary *) s;
+ CamelFolderInfo *fi;
+ GPtrArray *folders;
+ CamelStoreInfo *si;
+ size_t toplen, len;
+ int i;
+
+ if (top == NULL)
+ top = "";
+
+ toplen = strlen (top);
+ folders = g_ptr_array_new ();
+
+ for (i = 0; i < ss->folders->len; i++) {
+ si = ss->folders->pdata[i];
+ if (strncmp (si->path, top, toplen) != 0)
+ continue;
+
+ if ((len = strlen (si->path)) > toplen && si->path[toplen] != '/')
+ continue;
+
+ if (len == toplen) {
+ /* found toplevel folder */
+ g_ptr_array_add (folders, store_info_to_folder_info (ss, si));
+ continue;
+ }
+
+ if ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) || !strchr (si->path + toplen + 1, '/'))
+ g_ptr_array_add (folders, store_info_to_folder_info (ss, si));
+ }
+
+ fi = camel_folder_info_build (folders, top, '/', TRUE);
+ g_ptr_array_free (folders, TRUE);
+
+ return fi;
+}