diff options
author | Dan Winship <danw@src.gnome.org> | 2001-02-10 00:43:22 +0800 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2001-02-10 00:43:22 +0800 |
commit | 65eb577ecd2ce45f78f8df4da3386e2ac1f3c2c1 (patch) | |
tree | 1b71a69279b3130cab4dc333dd6a68d324ea4985 /camel | |
parent | 154d1b95c85bc8888bae6b64a4f2ba040fe869b4 (diff) | |
download | gsoc2013-evolution-65eb577ecd2ce45f78f8df4da3386e2ac1f3c2c1.tar.gz gsoc2013-evolution-65eb577ecd2ce45f78f8df4da3386e2ac1f3c2c1.tar.zst gsoc2013-evolution-65eb577ecd2ce45f78f8df4da3386e2ac1f3c2c1.zip |
Rewrite a bunch. Replace the existing folder cache stuff with much simpler
* camel-store.c: Rewrite a bunch. Replace the existing folder
cache stuff with much simpler code that still handles all the
existing cases. Now the folder hash table is always created by the
base class, using hash and compare functions provided by the class
implementation. (If they are set to NULL, CamelStore won't cache
folders.) lookup_folder, cache_folder, and uncache_folder are no
longer class methods, and get_name is gone completely.
(camel_store_get_inbox): Renamed from
camel_store_get_default_folder, since that wasn't being used, and
this is what we actually need.
(camel_store_get_root_folder): Removed, since it's not needed for
anything given get_folder_info.
* camel-remote-store.c:
* providers/local/camel-local-store.c:
* providers/local/camel-mbox-store.c:
* providers/local/camel-mh-store.c:
* providers/local/camel-maildir-store.c:
* providers/nntp/camel-nntp-store.c:
* providers/pop3/camel-pop3-store.c:
* providers/vee/camel-vee-store.c: Minor updates for CamelStore
changes
* providers/imap/camel-imap-store.c (camel_imap_store_class_init):
Update for CamelStore changes.
(hash_folder_name, compare_folder_name): treat INBOX
case-insensitively, otherwise use g_str_hash and g_str_equal.
* camel-service.c (camel_service_construct): Remove
camel_service_new and create camel_service_construct (as a class
method) in its place.
* camel-session.c (camel_session_get_service): Use
camel_object_new and camel_service_construct to replace
camel_service_new.
* providers/local/camel-local-store.c (construct): Append a '/' to
the URL path if it doesn't end with one
svn path=/trunk/; revision=8145
Diffstat (limited to 'camel')
-rw-r--r-- | camel/ChangeLog | 40 | ||||
-rw-r--r-- | camel/camel-remote-store.c | 13 | ||||
-rw-r--r-- | camel/camel-service.c | 83 | ||||
-rw-r--r-- | camel/camel-service.h | 10 | ||||
-rw-r--r-- | camel/camel-session.c | 9 | ||||
-rw-r--r-- | camel/camel-store.c | 320 | ||||
-rw-r--r-- | camel/camel-store.h | 25 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-store.c | 47 | ||||
-rw-r--r-- | camel/providers/local/camel-local-store.c | 72 | ||||
-rw-r--r-- | camel/providers/local/camel-maildir-store.c | 10 | ||||
-rw-r--r-- | camel/providers/local/camel-mbox-store.c | 11 | ||||
-rw-r--r-- | camel/providers/local/camel-mh-store.c | 10 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-store.c | 7 | ||||
-rw-r--r-- | camel/providers/pop3/camel-pop3-store.c | 26 | ||||
-rw-r--r-- | camel/providers/vee/camel-vee-store.c | 9 |
15 files changed, 243 insertions, 449 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 06e0ac796d..379219c7b9 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,43 @@ +2001-02-08 Dan Winship <danw@ximian.com> + + * camel-store.c: Rewrite a bunch. Replace the existing folder + cache stuff with much simpler code that still handles all the + existing cases. Now the folder hash table is always created by the + base class, using hash and compare functions provided by the class + implementation. (If they are set to NULL, CamelStore won't cache + folders.) lookup_folder, cache_folder, and uncache_folder are no + longer class methods, and get_name is gone completely. + + (camel_store_get_inbox): Renamed from + camel_store_get_default_folder, since that wasn't being used, and + this is what we actually need. + (camel_store_get_root_folder): Removed, since it's not needed for + anything given get_folder_info. + + * camel-remote-store.c: + * providers/nntp/camel-nntp-store.c: + * providers/pop3/camel-pop3-store.c: + * providers/vee/camel-vee-store.c: Minor updates for CamelStore + changes + + * providers/imap/camel-imap-store.c (camel_imap_store_class_init): + Update for CamelStore changes. + (hash_folder_name, compare_folder_name): treat INBOX + case-insensitively, otherwise use g_str_hash and g_str_equal. + + * camel-service.c (camel_service_construct): Remove + camel_service_new and create camel_service_construct (as a class + method) in its place. + + * camel-session.c (camel_session_get_service): Use + camel_object_new and camel_service_construct to replace + camel_service_new. + + * providers/local/camel-local-store.c: Update for CamelStore + changes + (construct): Append a '/' to the URL path if it doesn't end with + one + 2001-01-31 Jeffrey Stedfast <fejj@helixcode.com> * camel-tcp-stream-ssl.c: Oops, include the camel-tcp-stream-ssl diff --git a/camel/camel-remote-store.c b/camel/camel-remote-store.c index d1352300b7..52f1908f05 100644 --- a/camel/camel-remote-store.c +++ b/camel/camel-remote-store.c @@ -65,9 +65,6 @@ static gboolean remote_disconnect (CamelService *service, gboolean clean, C static GList *remote_query_auth_types(CamelService *service, gboolean connect, CamelException *ex); static void remote_free_auth_types (CamelService *service, GList *authtypes); static char *remote_get_name (CamelService *service, gboolean brief); -static char *remote_get_folder_name (CamelStore *store, - const char *folder_name, - CamelException *ex); static gint remote_send_string (CamelRemoteStore *store, CamelException *ex, char *fmt, va_list ap); static gint remote_send_stream (CamelRemoteStore *store, CamelStream *stream, @@ -81,8 +78,6 @@ camel_remote_store_class_init (CamelRemoteStoreClass *camel_remote_store_class) /* virtual method overload */ CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_remote_store_class); - CamelStoreClass *camel_store_class = - CAMEL_STORE_CLASS (camel_remote_store_class); store_class = CAMEL_STORE_CLASS (camel_type_get_global_classfuncs (camel_store_get_type ())); @@ -93,8 +88,6 @@ camel_remote_store_class_init (CamelRemoteStoreClass *camel_remote_store_class) camel_service_class->free_auth_types = remote_free_auth_types; camel_service_class->get_name = remote_get_name; - camel_store_class->get_folder_name = remote_get_folder_name; - camel_remote_store_class->send_string = remote_send_string; camel_remote_store_class->send_stream = remote_send_stream; camel_remote_store_class->recv_line = remote_recv_line; @@ -386,12 +379,6 @@ remote_disconnect (CamelService *service, gboolean clean, CamelException *ex) return TRUE; } -static gchar * -remote_get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) -{ - return g_strdup (folder_name); -} - static gint remote_send_string (CamelRemoteStore *store, CamelException *ex, char *fmt, va_list ap) { diff --git a/camel/camel-service.c b/camel/camel-service.c index 0eae1cd98a..bdaa807572 100644 --- a/camel/camel-service.c +++ b/camel/camel-service.c @@ -38,6 +38,9 @@ static CamelObjectClass *parent_class = NULL; /* Returns the class for a CamelService */ #define CSERV_CLASS(so) CAMEL_SERVICE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) +static void construct (CamelService *service, CamelSession *session, + CamelProvider *provider, CamelURL *url, + CamelException *ex); static gboolean service_connect(CamelService *service, CamelException *ex); static gboolean service_disconnect(CamelService *service, gboolean clean, CamelException *ex); @@ -46,7 +49,6 @@ static GList * query_auth_types (CamelService *service, gboolean connect, Camel static void free_auth_types (CamelService *service, GList *authtypes); static char * get_name (CamelService *service, gboolean brief); static char * get_path (CamelService *service); -static gboolean check_url (CamelService *service, CamelException *ex); static void @@ -55,9 +57,9 @@ camel_service_class_init (CamelServiceClass *camel_service_class) parent_class = camel_type_get_global_classfuncs (CAMEL_OBJECT_TYPE); /* virtual method definition */ + camel_service_class->construct = construct; camel_service_class->connect = service_connect; camel_service_class->disconnect = service_disconnect; - /*camel_service_class->is_connected = is_connected;*/ camel_service_class->query_auth_types = query_auth_types; camel_service_class->free_auth_types = free_auth_types; camel_service_class->get_name = get_name; @@ -125,82 +127,69 @@ camel_service_get_type (void) return camel_service_type; } -static gboolean -check_url (CamelService *service, CamelException *ex) + +static void +construct (CamelService *service, CamelSession *session, + CamelProvider *provider, CamelURL *url, CamelException *ex) { char *url_string; - if (((service->provider->url_flags & CAMEL_URL_NEED_USER) + if (((provider->url_flags & CAMEL_URL_NEED_USER) == CAMEL_URL_NEED_USER) && - (service->url->user == NULL || service->url->user[0] == '\0')) { - url_string = camel_url_to_string (service->url, FALSE); + (url->user == NULL || url->user[0] == '\0')) { + url_string = camel_url_to_string (url, FALSE); camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID, _("URL '%s' needs a username component"), url_string); g_free (url_string); - return FALSE; - } else if (((service->provider->url_flags & CAMEL_URL_NEED_HOST) + return; + } else if (((provider->url_flags & CAMEL_URL_NEED_HOST) == CAMEL_URL_NEED_HOST) && - (service->url->host == NULL || service->url->host[0] == '\0')) { - url_string = camel_url_to_string (service->url, FALSE); + (url->host == NULL || url->host[0] == '\0')) { + url_string = camel_url_to_string (url, FALSE); camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID, _("URL '%s' needs a host component"), url_string); g_free (url_string); - return FALSE; - } else if (((service->provider->url_flags & CAMEL_URL_NEED_PATH) + return; + } else if (((provider->url_flags & CAMEL_URL_NEED_PATH) == CAMEL_URL_NEED_PATH) && - (service->url->path == NULL || service->url->path[0] == '\0')) { - url_string = camel_url_to_string (service->url, FALSE); + (url->path == NULL || url->path[0] == '\0')) { + url_string = camel_url_to_string (url, FALSE); camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_URL_INVALID, _("URL '%s' needs a path component"), url_string); g_free (url_string); - return FALSE; + return; } - return TRUE; + service->provider = provider; + service->url = url; + service->session = session; + camel_object_ref (CAMEL_OBJECT (session)); + + service->connected = FALSE; } /** - * camel_service_new: create a new CamelService or subtype - * @type: the CamelType of the class to create + * camel_service_construct: + * @service: the CamelService * @session: the session for the service * @provider: the service's provider * @url: the default URL for the service (may be NULL) * @ex: a CamelException * - * Creates a new CamelService (or one of its subtypes), initialized - * with the given parameters. - * - * Return value: the CamelService, or NULL. + * Constructs a CamelService initialized with the given parameters. **/ -CamelService * -camel_service_new (CamelType type, CamelSession *session, - CamelProvider *provider, CamelURL *url, - CamelException *ex) +void +camel_service_construct (CamelService *service, CamelSession *session, + CamelProvider *provider, CamelURL *url, + CamelException *ex) { - CamelService *service; - - g_return_val_if_fail (CAMEL_IS_SESSION (session), NULL); - - service = CAMEL_SERVICE (camel_object_new (type)); - - /*service->connect_level = 0;*/ - - service->provider = provider; - service->url = url; - if (!check_url (service, ex)) { - camel_object_unref (CAMEL_OBJECT (service)); - return NULL; - } - - service->session = session; - camel_object_ref (CAMEL_OBJECT (session)); - - service->connected = FALSE; + g_return_if_fail (CAMEL_IS_SERVICE (service)); + g_return_if_fail (CAMEL_IS_SESSION (session)); - return service; + CSERV_CLASS (service)->construct (service, session, provider, url, ex); } diff --git a/camel/camel-service.h b/camel/camel-service.h index 728db6c4ce..aeb71c933d 100644 --- a/camel/camel-service.h +++ b/camel/camel-service.h @@ -59,14 +59,18 @@ struct _CamelService { typedef struct { CamelObjectClass parent_class; + void (*construct) (CamelService *service, + CamelSession *session, + CamelProvider *provider, + CamelURL *url, + CamelException *ex); + gboolean (*connect) (CamelService *service, CamelException *ex); gboolean (*disconnect) (CamelService *service, gboolean clean, CamelException *ex); - /*gboolean (*is_connected) (CamelService *service);*/ - GList * (*query_auth_types) (CamelService *service, gboolean connect, CamelException *ex); @@ -88,7 +92,7 @@ typedef struct { /* public methods */ -CamelService * camel_service_new (CamelType type, +void camel_service_construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, diff --git a/camel/camel-session.c b/camel/camel-session.c index a8ca5983ec..5ef31158b7 100644 --- a/camel/camel-session.c +++ b/camel/camel-session.c @@ -39,6 +39,7 @@ #include "string-utils.h" #include "camel-url.h" #include "hash-table-utils.h" +#include <gal/util/e-util.h> #include "camel-private.h" @@ -311,8 +312,12 @@ camel_session_get_service (CamelSession *session, const char *url_string, return service; } - service = camel_service_new (provider->object_types[type], session, provider, url, ex); - if (service) { + service = (CamelService *)camel_object_new (provider->object_types[type]); + camel_service_construct (service, session, provider, url, ex); + if (camel_exception_is_set (ex)) { + camel_object_unref (CAMEL_OBJECT (service)); + service = NULL; + } else { g_hash_table_insert (provider->service_cache, url, service); camel_object_hook_event (CAMEL_OBJECT (service), "finalize", (CamelObjectEventHookFunc) service_cache_remove, session); } diff --git a/camel/camel-store.c b/camel/camel-store.c index 5b48299231..e7bd25a4be 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -2,7 +2,6 @@ /* camel-store.c : Abstract class for an email store */ /* - * * Authors: * Bertrand Guiheneuf <bertrand@helixcode.com> * Dan Winship <danw@helixcode.com> @@ -24,6 +23,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ + #include <config.h> #include <string.h> @@ -40,16 +40,13 @@ static CamelServiceClass *parent_class = NULL; static CamelFolder *get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); +static CamelFolder *get_inbox (CamelStore *store, CamelException *ex); + static void delete_folder (CamelStore *store, const char *folder_name, CamelException *ex); static void rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex); -static char *get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex); -static char *get_root_folder_name (CamelStore *store, CamelException *ex); -static char *get_default_folder_name (CamelStore *store, CamelException *ex); - static void store_sync (CamelStore *store, CamelException *ex); static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, gboolean fast, gboolean recursive, @@ -57,11 +54,6 @@ static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, CamelException *ex); static void free_folder_info (CamelStore *store, CamelFolderInfo *tree); -static CamelFolder *lookup_folder (CamelStore *store, const char *folder_name); -static void cache_folder (CamelStore *store, const char *folder_name, - CamelFolder *folder); -static void uncache_folder (CamelStore *store, CamelFolder *folder); - static gboolean folder_subscribed (CamelStore *store, const char *folder_name); static void subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex); static void unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex); @@ -72,30 +64,31 @@ camel_store_class_init (CamelStoreClass *camel_store_class) parent_class = CAMEL_SERVICE_CLASS (camel_type_get_global_classfuncs (camel_service_get_type ())); /* virtual method definition */ + camel_store_class->hash_folder_name = g_str_hash; + camel_store_class->compare_folder_name = g_str_equal; camel_store_class->get_folder = get_folder; + camel_store_class->get_inbox = get_inbox; camel_store_class->delete_folder = delete_folder; camel_store_class->rename_folder = rename_folder; - camel_store_class->get_folder_name = get_folder_name; - camel_store_class->get_root_folder_name = get_root_folder_name; - camel_store_class->get_default_folder_name = get_default_folder_name; camel_store_class->sync = store_sync; camel_store_class->get_folder_info = get_folder_info; camel_store_class->free_folder_info = free_folder_info; - camel_store_class->lookup_folder = lookup_folder; - camel_store_class->cache_folder = cache_folder; - camel_store_class->uncache_folder = uncache_folder; camel_store_class->folder_subscribed = folder_subscribed; camel_store_class->subscribe_folder = subscribe_folder; camel_store_class->unsubscribe_folder = unsubscribe_folder; } static void -camel_store_init (void *o, void *k) +camel_store_init (void *o) { CamelStore *store = o; + CamelStoreClass *store_class = (CamelStoreClass *)CAMEL_OBJECT_GET_CLASS (o); - if (store->folders == NULL) - store->folders = g_hash_table_new (g_str_hash, g_str_equal); + if (store_class->hash_folder_name) { + store->folders = g_hash_table_new (store_class->hash_folder_name, + store_class->compare_folder_name); + } else + store->folders = NULL; store->flags = 0; store->priv = g_malloc0(sizeof(*store->priv)); @@ -146,106 +139,6 @@ camel_store_get_type (void) } -static CamelFolder * -get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) -{ - g_warning("CamelStore::get_folder not implemented for `%s'", - camel_type_to_name(CAMEL_OBJECT_GET_TYPE(store))); - return NULL; -} - -static void -delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) -{ - g_warning ("CamelStore::delete_folder not implemented for `%s'", - camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); -} - -static void -rename_folder (CamelStore *store, const char *old_name, - const char *new_name, CamelException *ex) -{ - g_warning ("CamelStore::rename_folder not implemented for `%s'", - camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); -} - - -/* CamelStore::get_folder_name should: - * a) make sure that the provided name is valid - * b) return it in canonical form, in allocated memory. - * - * This is used to make sure that duplicate names for the same folder - * don't result in duplicate cache entries. - */ -static char * -get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - g_warning ("CamelStore::get_folder_name not implemented for `%s'", - camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); - return NULL; -} - -static char * -get_root_folder_name (CamelStore *store, CamelException *ex) -{ - return g_strdup ("/"); -} - -static char * -get_default_folder_name (CamelStore *store, CamelException *ex) -{ - return CS_CLASS (store)->get_root_folder_name (store, ex); -} - -static CamelFolder * -lookup_folder (CamelStore *store, const char *folder_name) -{ - CamelFolder *folder = NULL; - - CAMEL_STORE_LOCK(store, cache_lock); - - if (store->folders) { - folder = g_hash_table_lookup (store->folders, folder_name); - if (folder) - camel_object_ref(CAMEL_OBJECT(folder)); - } - - CAMEL_STORE_UNLOCK(store, cache_lock); - - return folder; -} - -static void folder_finalize (CamelObject *folder, gpointer event_data, gpointer user_data) -{ - CS_CLASS (user_data)->uncache_folder (CAMEL_STORE(user_data), CAMEL_FOLDER(folder)); -} - -static void -cache_folder (CamelStore *store, const char *folder_name, CamelFolder *folder) -{ - CAMEL_STORE_LOCK(store, cache_lock); - - if (store->folders) { - if (g_hash_table_lookup (store->folders, folder_name)) { - g_warning ("Caching folder %s that already exists.", folder_name); - } - g_hash_table_insert (store->folders, g_strdup (folder_name), folder); - - camel_object_hook_event (CAMEL_OBJECT (folder), "finalize", folder_finalize, store); - } - - CAMEL_STORE_UNLOCK(store, cache_lock); - - /* - * gt_k so as not to get caught by my little gt_k cleanliness detector. - * - * gt_k_signal_connect_object (CAMEL_OBJECT (folder), "destroy", - * GT_K_SIGNAL_FUNC (CS_CLASS (store)->uncache_folder), - * CAMEL_OBJECT (store)); - */ -} - static gboolean folder_matches (gpointer key, gpointer value, gpointer user_data) { @@ -257,39 +150,25 @@ folder_matches (gpointer key, gpointer value, gpointer user_data) } static void -uncache_folder (CamelStore *store, CamelFolder *folder) +folder_finalize (CamelObject *folder, gpointer event_data, gpointer user_data) { - CAMEL_STORE_LOCK(store, cache_lock); - - g_hash_table_foreach_remove (store->folders, folder_matches, folder); + CamelStore *store = CAMEL_STORE (user_data); - CAMEL_STORE_UNLOCK(store, cache_lock); + if (store->folders) { + CAMEL_STORE_LOCK(store, cache_lock); + g_hash_table_foreach_remove (store->folders, folder_matches, folder); + CAMEL_STORE_UNLOCK(store, cache_lock); + } } - static CamelFolder * -get_folder_internal(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) +get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { - CamelFolder *folder = NULL; - - /* NB: we already have folder_lock */ - - /* Try cache first. */ - folder = CS_CLASS(store)->lookup_folder(store, folder_name); - - if (!folder) { - folder = CS_CLASS(store)->get_folder(store, folder_name, flags, ex); - if (!folder) - return NULL; - - CS_CLASS(store)->cache_folder(store, folder_name, folder); - } - - return folder; + g_warning ("CamelStore::get_folder not implemented for `%s'", + camel_type_to_name(CAMEL_OBJECT_GET_TYPE(store))); + return NULL; } - - /** * camel_store_get_folder: Return the folder corresponding to a path. * @store: a CamelStore @@ -297,32 +176,48 @@ get_folder_internal(CamelStore *store, const char *folder_name, guint32 flags, C * @flags: folder flags (create, save body index, etc) * @ex: a CamelException * - * Returns the folder corresponding to the path @folder_name. If the - * path begins with the separator character, it is relative to the - * root folder. Otherwise, it is relative to the default folder. - * - * Return value: the folder + * Return value: the folder corresponding to the path @folder_name. **/ CamelFolder * -camel_store_get_folder(CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) +camel_store_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { - char *name; CamelFolder *folder = NULL; CAMEL_STORE_LOCK(store, folder_lock); - name = CS_CLASS(store)->get_folder_name(store, folder_name, ex); - if (name) { - folder = get_folder_internal(store, name, flags, ex); - g_free (name); + if (store->folders) { + /* Try cache first. */ + CAMEL_STORE_LOCK(store, cache_lock); + folder = g_hash_table_lookup (store->folders, folder_name); + if (folder) + camel_object_ref (CAMEL_OBJECT (folder)); + CAMEL_STORE_UNLOCK(store, cache_lock); } - CAMEL_STORE_UNLOCK(store, folder_lock); + if (!folder) { + folder = CS_CLASS (store)->get_folder (store, folder_name, flags, ex); + if (folder && store->folders) { + CAMEL_STORE_LOCK(store, cache_lock); + g_hash_table_insert (store->folders, g_strdup (folder_name), folder); + + camel_object_hook_event (CAMEL_OBJECT (folder), "finalize", folder_finalize, store); + CAMEL_STORE_UNLOCK(store, cache_lock); + } + } + + CAMEL_STORE_UNLOCK(store, folder_lock); return folder; } +static void +delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) +{ + g_warning ("CamelStore::delete_folder not implemented for `%s'", + camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); +} + /** * camel_store_delete_folder: Delete the folder corresponding to a path. * @store: a CamelStore @@ -332,104 +227,65 @@ camel_store_get_folder(CamelStore *store, const char *folder_name, guint32 flags * Deletes the named folder. The folder must be empty. **/ void -camel_store_delete_folder (CamelStore *store, const char *folder_name, - CamelException *ex) +camel_store_delete_folder (CamelStore *store, const char *folder_name, CamelException *ex) { - char *name; - CAMEL_STORE_LOCK(store, folder_lock); + CS_CLASS (store)->delete_folder (store, folder_name, ex); + CAMEL_STORE_UNLOCK(store, folder_lock); - name = CS_CLASS (store)->get_folder_name (store, folder_name, ex); - if (name) { - CS_CLASS (store)->delete_folder (store, name, ex); - g_free (name); - } +} - CAMEL_STORE_UNLOCK(store, folder_lock); + +static void +rename_folder (CamelStore *store, const char *old_name, + const char *new_name, CamelException *ex) +{ + g_warning ("CamelStore::rename_folder not implemented for `%s'", + camel_type_to_name (CAMEL_OBJECT_GET_TYPE (store))); } /** * camel_store_rename_folder: - * @store: - * @old_name: - * @new_name: - * @ex: + * @store: a CamelStore + * @old_name: the current name of the folder + * @new_name: the new name of the folder + * @ex: a CamelException * * Rename a named folder to a new name. **/ -void camel_store_rename_folder (CamelStore *store, - const char *old_name, - const char *new_name, - CamelException *ex) +void +camel_store_rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex) { - char *old, *new; - CAMEL_STORE_LOCK(store, folder_lock); - - old = CS_CLASS (store)->get_folder_name(store, old_name, ex); - if (old) { - new = CS_CLASS (store)->get_folder_name(store, new_name, ex); - if (new) { - CS_CLASS (store)->rename_folder(store, old, new, ex); - g_free(new); - } - g_free(old); - } - + CS_CLASS (store)->rename_folder (store, old_name, new_name, ex); CAMEL_STORE_UNLOCK(store, folder_lock); } -/** - * camel_store_get_root_folder: return the top-level folder - * - * Returns the folder which is at the top of the folder hierarchy. - * This folder may or may not be the same as the default folder. - * - * Return value: the top-level folder. - **/ -CamelFolder * -camel_store_get_root_folder (CamelStore *store, CamelException *ex) +static CamelFolder * +get_inbox (CamelStore *store, CamelException *ex) { - char *name; - CamelFolder *folder = NULL; - - CAMEL_STORE_LOCK(store, folder_lock); - - name = CS_CLASS (store)->get_root_folder_name (store, ex); - if (name) { - folder = get_folder_internal (store, name, CAMEL_STORE_FOLDER_CREATE, ex); - g_free (name); - } - - CAMEL_STORE_UNLOCK(store, folder_lock); - - return folder; + /* Default: assume the inbox's name is "inbox" + * and open with default flags. + */ + return CS_CLASS (store)->get_folder (store, "inbox", 0, ex); } /** - * camel_store_get_default_folder: return the store default folder - * - * The default folder is the folder which is presented to the user in - * the default configuration. This defaults to the root folder if - * the store doesn't override it. + * camel_store_get_inbox: + * @store: a CamelStore + * @ex: a CamelException * - * Return value: the default folder. + * Return value: the folder in the store into which new mail is + * delivered, or %NULL if no such folder exists. **/ CamelFolder * -camel_store_get_default_folder (CamelStore *store, CamelException *ex) +camel_store_get_inbox (CamelStore *store, CamelException *ex) { - char *name; - CamelFolder *folder = NULL; + CamelFolder *folder; CAMEL_STORE_LOCK(store, folder_lock); - - name = CS_CLASS (store)->get_default_folder_name (store, ex); - if (name) { - folder = get_folder_internal (store, name, CAMEL_STORE_FOLDER_CREATE, ex); - g_free (name); - } - + folder = CS_CLASS (store)->get_inbox (store, ex); CAMEL_STORE_UNLOCK(store, folder_lock); return folder; @@ -446,9 +302,11 @@ sync_folder (gpointer key, gpointer folder, gpointer ex) static void store_sync (CamelStore *store, CamelException *ex) { - CAMEL_STORE_LOCK(store, cache_lock); - g_hash_table_foreach (store->folders, sync_folder, ex); - CAMEL_STORE_UNLOCK(store, cache_lock); + if (store->folders) { + CAMEL_STORE_LOCK(store, cache_lock); + g_hash_table_foreach (store->folders, sync_folder, ex); + CAMEL_STORE_UNLOCK(store, cache_lock); + } } /** diff --git a/camel/camel-store.h b/camel/camel-store.h index 1141f09dcf..da81a435f0 100644 --- a/camel/camel-store.h +++ b/camel/camel-store.h @@ -73,10 +73,15 @@ struct _CamelStore typedef struct { CamelServiceClass parent_class; + GHashFunc hash_folder_name; + GCompareFunc compare_folder_name; + CamelFolder * (*get_folder) (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); + CamelFolder * (*get_inbox) (CamelStore *store, + CamelException *ex); void (*delete_folder) (CamelStore *store, const char *folder_name, @@ -89,22 +94,6 @@ typedef struct { void (*sync) (CamelStore *store, CamelException *ex); - char * (*get_folder_name) (CamelStore *store, - const char *folder_name, - CamelException *ex); - char * (*get_root_folder_name) (CamelStore *store, - CamelException *ex); - char * (*get_default_folder_name) (CamelStore *store, - CamelException *ex); - - CamelFolder * (*lookup_folder) (CamelStore *store, - const char *folder_name); - void (*cache_folder) (CamelStore *store, - const char *folder_name, - CamelFolder *folder); - void (*uncache_folder) (CamelStore *store, - CamelFolder *folder); - /* this should take flags instead, so its more futureproof */ CamelFolderInfo *(*get_folder_info) (CamelStore *store, const char *top, @@ -134,9 +123,7 @@ CamelFolder * camel_store_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); -CamelFolder * camel_store_get_root_folder (CamelStore *store, - CamelException *ex); -CamelFolder * camel_store_get_default_folder (CamelStore *store, +CamelFolder * camel_store_get_inbox (CamelStore *store, CamelException *ex); void camel_store_delete_folder (CamelStore *store, diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index cd46d56226..f19d8feb31 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -60,10 +60,9 @@ static CamelRemoteStoreClass *remote_store_class = NULL; static gboolean imap_connect (CamelService *service, CamelException *ex); static gboolean imap_disconnect (CamelService *service, gboolean clean, CamelException *ex); static GList *query_auth_types (CamelService *service, gboolean connect, CamelException *ex); +static guint hash_folder_name (gconstpointer key); +static gint compare_folder_name (gconstpointer a, gconstpointer b); static CamelFolder *get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); -static char *get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex); -static char *get_root_folder_name (CamelStore *store, CamelException *ex); static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, gboolean fast, gboolean recursive, gboolean subscribed_only, @@ -94,9 +93,9 @@ camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class) camel_service_class->connect = imap_connect; camel_service_class->disconnect = imap_disconnect; + camel_store_class->hash_folder_name = hash_folder_name; + camel_store_class->compare_folder_name = compare_folder_name; camel_store_class->get_folder = get_folder; - camel_store_class->get_folder_name = get_folder_name; - camel_store_class->get_root_folder_name = get_root_folder_name; camel_store_class->get_folder_info = get_folder_info; camel_store_class->free_folder_info = camel_store_free_folder_info_full; @@ -603,6 +602,27 @@ imap_create (CamelImapStore *store, const char *folder_name, return !camel_exception_is_set (ex); } +static guint +hash_folder_name (gconstpointer key) +{ + if (g_strcasecmp (key, "INBOX") == 0) + return g_str_hash ("INBOX"); + else + return g_str_hash (key); +} + +static gint +compare_folder_name (gconstpointer a, gconstpointer b) +{ + gconstpointer aname = a, bname = b; + + if (g_strcasecmp (a, "INBOX") == 0) + aname = "INBOX"; + if (g_strcasecmp (b, "INBOX") == 0) + bname = "INBOX"; + return g_str_equal (aname, bname); +} + static CamelFolder * get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) @@ -661,23 +681,6 @@ get_folder (CamelStore *store, const char *folder_name, guint32 flags, return new_folder; } -static char * -get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - /* INBOX is case-insensitive */ - if (g_strcasecmp (folder_name, "INBOX") == 0) - return g_strdup ("INBOX"); - else - return g_strdup (folder_name); -} - -static char * -get_root_folder_name (CamelStore *store, CamelException *ex) -{ - return g_strdup (""); -} - static CamelFolderInfo * parse_list_response_as_folder_info (CamelImapStore *imap_store, const char *response) diff --git a/camel/providers/local/camel-local-store.c b/camel/providers/local/camel-local-store.c index 9af9df2744..b6ea31a98f 100644 --- a/camel/providers/local/camel-local-store.c +++ b/camel/providers/local/camel-local-store.c @@ -39,12 +39,11 @@ #define CLOCALS_CLASS(so) CAMEL_LOCAL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS(so)) #define CF_CLASS(so) CAMEL_FOLDER_CLASS (CAMEL_OBJECT_GET_CLASS(so)) +static void construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex); static CamelFolder *get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelException * ex); static char *get_name(CamelService *service, gboolean brief); -static char *get_root_folder_name (CamelStore *store, CamelException *ex); -static char *get_default_folder_name (CamelStore *store, CamelException *ex); +static CamelFolder *get_inbox (CamelStore *store, CamelException *ex); static void rename_folder(CamelStore *store, const char *old_name, const char *new_name, CamelException *ex); -static char *get_folder_name(CamelStore *store, const char *folder_name, CamelException *ex); static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, gboolean fast, gboolean recursive, gboolean subscribed_only, @@ -52,18 +51,21 @@ static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top, static void delete_folder(CamelStore *store, const char *folder_name, CamelException *ex); static void rename_folder(CamelStore *store, const char *old, const char *new, CamelException *ex); +static CamelStoreClass *parent_class = NULL; + static void camel_local_store_class_init (CamelLocalStoreClass *camel_local_store_class) { CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_local_store_class); CamelServiceClass *camel_service_class = CAMEL_SERVICE_CLASS (camel_local_store_class); + parent_class = CAMEL_STORE_CLASS (camel_type_get_global_classfuncs (camel_store_get_type ())); + /* virtual method overload */ + camel_service_class->construct = construct; camel_service_class->get_name = get_name; camel_store_class->get_folder = get_folder; - camel_store_class->get_root_folder_name = get_root_folder_name; - camel_store_class->get_default_folder_name = get_default_folder_name; - camel_store_class->get_folder_name = get_folder_name; + camel_store_class->get_inbox = get_inbox; camel_store_class->get_folder_info = get_folder_info; camel_store_class->free_folder_info = camel_store_free_folder_info_full; @@ -71,18 +73,6 @@ camel_local_store_class_init (CamelLocalStoreClass *camel_local_store_class) camel_store_class->rename_folder = rename_folder; } -static void -camel_local_store_init (gpointer object, gpointer klass) -{ - CamelStore *store = CAMEL_STORE (object); - - /* local names are filenames, so they are case-sensitive. */ - if (store->folders) - g_hash_table_destroy(store->folders); - - store->folders = g_hash_table_new (g_str_hash, g_str_equal); -} - CamelType camel_local_store_get_type (void) { @@ -94,13 +84,29 @@ camel_local_store_get_type (void) sizeof (CamelLocalStoreClass), (CamelObjectClassInitFunc) camel_local_store_class_init, NULL, - (CamelObjectInitFunc) camel_local_store_init, + NULL, NULL); } return camel_local_store_type; } +static void +construct (CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex) +{ + int len; + + CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex); + if (camel_exception_is_set (ex)) + return; + + len = strlen (service->url->path); + if (service->url->path[len - 1] != '/') { + service->url->path = g_realloc (service->url->path, len + 2); + strcpy (service->url->path + len, "/"); + } +} + const char * camel_local_store_get_toplevel_dir (CamelLocalStore *store) { @@ -161,37 +167,15 @@ get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelExce return NULL; } -static char * -get_root_folder_name(CamelStore *store, CamelException *ex) -{ - camel_exception_set(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Local stores do not have a root folder")); - return NULL; -} - -static char * -get_default_folder_name(CamelStore *store, CamelException *ex) +static CamelFolder * +get_inbox(CamelStore *store, CamelException *ex) { camel_exception_set(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Local stores do not have a default folder")); + _("Local stores do not have an inbox")); return NULL; } static char * -get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) -{ - /* For now, we don't allow hieararchy. FIXME. */ - if (strchr (folder_name + 1, '/')) { - camel_exception_set (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, - _("Local folders may not be nested.")); - return NULL; - } - - return *folder_name == '/' ? g_strdup (folder_name) : - g_strdup_printf ("/%s", folder_name); -} - -static char * get_name (CamelService *service, gboolean brief) { if (brief) diff --git a/camel/providers/local/camel-maildir-store.c b/camel/providers/local/camel-maildir-store.c index f5bd353b6f..d419095ea0 100644 --- a/camel/providers/local/camel-maildir-store.c +++ b/camel/providers/local/camel-maildir-store.c @@ -56,14 +56,6 @@ static void camel_maildir_store_class_init(CamelObjectClass * camel_maildir_stor camel_store_class->delete_folder = delete_folder; } -static void camel_maildir_store_init(CamelObject * object) -{ - CamelStore *store = CAMEL_STORE(object); - - /* maildir names are filenames, so they are case-sensitive. */ - store->folders = g_hash_table_new(g_str_hash, g_str_equal); -} - CamelType camel_maildir_store_get_type(void) { static CamelType camel_maildir_store_type = CAMEL_INVALID_TYPE; @@ -74,7 +66,7 @@ CamelType camel_maildir_store_get_type(void) sizeof(CamelMaildirStoreClass), (CamelObjectClassInitFunc) camel_maildir_store_class_init, NULL, - (CamelObjectInitFunc) camel_maildir_store_init, + NULL, NULL); } diff --git a/camel/providers/local/camel-mbox-store.c b/camel/providers/local/camel-mbox-store.c index 8ae0891b31..c6ddc7ce0a 100644 --- a/camel/providers/local/camel-mbox-store.c +++ b/camel/providers/local/camel-mbox-store.c @@ -54,15 +54,6 @@ camel_mbox_store_class_init (CamelMboxStoreClass *camel_mbox_store_class) camel_store_class->delete_folder = delete_folder; } -static void -camel_mbox_store_init (gpointer object, gpointer klass) -{ - CamelStore *store = CAMEL_STORE (object); - - /* mbox names are filenames, so they are case-sensitive. */ - store->folders = g_hash_table_new (g_str_hash, g_str_equal); -} - CamelType camel_mbox_store_get_type (void) { @@ -74,7 +65,7 @@ camel_mbox_store_get_type (void) sizeof (CamelMboxStoreClass), (CamelObjectClassInitFunc) camel_mbox_store_class_init, NULL, - (CamelObjectInitFunc) camel_mbox_store_init, + NULL, NULL); } diff --git a/camel/providers/local/camel-mh-store.c b/camel/providers/local/camel-mh-store.c index 3d637e4cad..a488a71c12 100644 --- a/camel/providers/local/camel-mh-store.c +++ b/camel/providers/local/camel-mh-store.c @@ -54,14 +54,6 @@ static void camel_mh_store_class_init(CamelObjectClass * camel_mh_store_class) camel_store_class->delete_folder = delete_folder; } -static void camel_mh_store_init(CamelObject * object) -{ - CamelStore *store = CAMEL_STORE(object); - - /* mh names are filenames, so they are case-sensitive. */ - store->folders = g_hash_table_new(g_str_hash, g_str_equal); -} - CamelType camel_mh_store_get_type(void) { static CamelType camel_mh_store_type = CAMEL_INVALID_TYPE; @@ -72,7 +64,7 @@ CamelType camel_mh_store_get_type(void) sizeof(CamelMhStoreClass), (CamelObjectClassInitFunc) camel_mh_store_class_init, NULL, - (CamelObjectInitFunc) camel_mh_store_init, + NULL, NULL); } diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c index 8edf05e099..c1e8fb81e8 100644 --- a/camel/providers/nntp/camel-nntp-store.c +++ b/camel/providers/nntp/camel-nntp-store.c @@ -543,12 +543,6 @@ nntp_store_get_folder_info (CamelStore *store, const char *top, } } -static char * -nntp_store_get_root_folder_name (CamelStore *store, CamelException *ex) -{ - return g_strdup (""); -} - static gboolean nntp_store_folder_subscribed (CamelStore *store, const char *folder_name) { @@ -601,7 +595,6 @@ camel_nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class) camel_service_class->get_name = nntp_store_get_name; camel_store_class->get_folder = nntp_store_get_folder; - camel_store_class->get_root_folder_name = nntp_store_get_root_folder_name; camel_store_class->get_folder_info = nntp_store_get_folder_info; camel_store_class->free_folder_info = camel_store_free_folder_info_full; diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c index f0338a8584..fac9cae931 100644 --- a/camel/providers/pop3/camel-pop3-store.c +++ b/camel/providers/pop3/camel-pop3-store.c @@ -76,9 +76,6 @@ static GList *query_auth_types (CamelService *service, gboolean connect, CamelEx static CamelFolder *get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); -static char *get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex); -static char *get_root_folder_name (CamelStore *store, CamelException *ex); static int pop3_get_response (CamelPop3Store *store, char **ret, CamelException *ex); @@ -90,9 +87,6 @@ camel_pop3_store_class_init (CamelPop3StoreClass *camel_pop3_store_class) CAMEL_SERVICE_CLASS (camel_pop3_store_class); CamelStoreClass *camel_store_class = CAMEL_STORE_CLASS (camel_pop3_store_class); - /*CamelRemoteStoreClass *camel_remote_store_class = - * CAMEL_STORE_CLASS (camel_pop3_store_class); - */ parent_class = CAMEL_REMOTE_STORE_CLASS(camel_type_get_global_classfuncs (camel_remote_store_get_type ())); @@ -103,8 +97,6 @@ camel_pop3_store_class_init (CamelPop3StoreClass *camel_pop3_store_class) camel_service_class->disconnect = pop3_disconnect; camel_store_class->get_folder = get_folder; - camel_store_class->get_folder_name = get_folder_name; - camel_store_class->get_root_folder_name = get_root_folder_name; } @@ -533,26 +525,12 @@ static CamelFolder * get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { - return camel_pop3_folder_new (store, ex); -} - -static char * -get_folder_name (CamelStore *store, const char *folder_name, - CamelException *ex) -{ - if (!g_strcasecmp (folder_name, "inbox")) - return g_strdup ("inbox"); - else { + if (g_strcasecmp (folder_name, "inbox") != 0) { camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID, _("No such folder `%s'."), folder_name); return NULL; } -} - -static char * -get_root_folder_name (CamelStore *store, CamelException *ex) -{ - return g_strdup ("inbox"); + return camel_pop3_folder_new (store, ex); } diff --git a/camel/providers/vee/camel-vee-store.c b/camel/providers/vee/camel-vee-store.c index 7acc127542..b39707e1a0 100644 --- a/camel/providers/vee/camel-vee-store.c +++ b/camel/providers/vee/camel-vee-store.c @@ -23,7 +23,6 @@ #include "camel-vee-folder.h" static CamelFolder *vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); -static char *vee_get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex); struct _CamelVeeStorePrivate { }; @@ -63,7 +62,6 @@ camel_vee_store_class_init (CamelVeeStoreClass *klass) /* virtual method overload */ store_class->get_folder = vee_get_folder; - store_class->get_folder_name = vee_get_folder_name; } static void @@ -93,10 +91,3 @@ vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Camel { return camel_vee_folder_new (store, folder_name, ex); } - -static char * -vee_get_folder_name (CamelStore *store, const char *folder_name, CamelException *ex) -{ - return g_strdup(folder_name); -} - |