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
This commit is contained in:
Dan Winship
2001-02-09 16:43:22 +00:00
parent 154d1b95c8
commit 65eb577ecd
15 changed files with 244 additions and 450 deletions

View File

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

View File

@ -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)
{

View File

@ -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_if_fail (CAMEL_IS_SERVICE (service));
g_return_if_fail (CAMEL_IS_SESSION (session));
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;
return service;
CSERV_CLASS (service)->construct (service, session, provider, url, ex);
}

View File

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

View File

@ -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);
}

View File

@ -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);
CamelStore *store = CAMEL_STORE (user_data);
g_hash_table_foreach_remove (store->folders, folder_matches, folder);
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);
}
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);
name = CS_CLASS (store)->get_folder_name (store, folder_name, ex);
if (name) {
CS_CLASS (store)->delete_folder (store, name, ex);
g_free (name);
}
CS_CLASS (store)->delete_folder (store, folder_name, ex);
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
* camel_store_get_inbox:
* @store: a CamelStore
* @ex: a CamelException
*
* 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.
*
* 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);
}
}
/**

View File

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

View File

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

View File

@ -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,36 +167,14 @@ get_folder(CamelStore * store, const char *folder_name, guint32 flags, CamelExce
return NULL;
}
static char *
get_root_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 root folder"));
_("Local stores do not have an inbox"));
return NULL;
}
static char *
get_default_folder_name(CamelStore *store, CamelException *ex)
{
camel_exception_set(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
_("Local stores do not have a default folder"));
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)
{

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

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

View File

@ -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);
}

View File

@ -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);
}