From f888058fc6e6db2309336426662023502a461d5a Mon Sep 17 00:00:00 2001 From: bertrand Date: Thu, 12 Aug 1999 10:24:01 +0000 Subject: new function: returns a store for an URL. 1999-08-12 bertrand * camel/camel-session.c (camel_session_get_store): new function: returns a store for an URL. (camel_session_get_store_for_protocol): new functionc: returns a store for a given store protocol (as IMAP/POP/MH ...) * camel/string-utils.c (g_strcase_equal): (g_strcase_hash): case insensitive hash table funcs. * camel/camel-session.c (camel_session_init): hash table keys are case insensitive. * camel/camel-provider.c (camel_provider_get_for_protocol): new function, returns the last registered provider for a protocol. svn path=/trunk/; revision=1106 --- ChangeLog | 16 +++++++++++ camel/camel-provider.c | 61 ++++++++++++++++++++++++++++++++++++++- camel/camel-provider.h | 1 + camel/camel-session.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++-- camel/camel-session.h | 2 ++ camel/string-utils.c | 44 ++++++++++++++++++++++++++++ camel/string-utils.h | 3 ++ 7 files changed, 202 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3fee0827ee..7aee44624e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,21 @@ 1999-08-12 bertrand + * camel/camel-session.c (camel_session_get_store): + new function: returns a store for an URL. + (camel_session_get_store_for_protocol): + new functionc: returns a store for a given + store protocol (as IMAP/POP/MH ...) + * camel/string-utils.c (g_strcase_equal): + (g_strcase_hash): case insensitive hash table + funcs. + + * camel/camel-session.c (camel_session_init): hash table + keys are case insensitive. + + * camel/camel-provider.c (camel_provider_get_for_protocol): + new function, returns the last registered + provider for a protocol. + * camel/providers/MH/camel-mh-provider.c: new file. MH provider registration stuff. diff --git a/camel/camel-provider.c b/camel/camel-provider.c index 0018e262e0..98c43bd7ce 100644 --- a/camel/camel-provider.c +++ b/camel/camel-provider.c @@ -72,7 +72,9 @@ camel_provider_register (CamelProvider *provider) // camel_provider_unref (CAMEL_PROVIDER (old_provider_node->data)); old_provider_node->data = provider; } else { - _provider_list = g_list_append (_provider_list, provider); + /* be careful, we use prepend here, so that last registered + providers come first */ + _provider_list = g_list_prepend (_provider_list, provider); } // camel_provider_ref (provider); @@ -122,3 +124,60 @@ camel_provider_register_as_module (const gchar *module_path) } + + + + +/* + be careful to this function, @a is expected to be + a provider, @b a protocol name (const gchar *) +*/ +static gint +_provider_protocol_find (gconstpointer a, gconstpointer b) +{ + CamelProvider *provider_a = CAMEL_PROVIDER (a); + const gchar *name_b = (const gchar *)b; + + return g_strcasecmp ( provider_a->name, name_b); +} + +/** + * camel_provider_get_for_protocol: get a registered provider for a protocol + * @protocol: protocol name (case insensitive) + * @type: provider type (transport, store, ...) + * + * Look into the list of registered provider if + * one correspond both to the protocol name + * and to the protocol type. When several providerss + * exist for a same protocol, the last registered + * is returned. + * + * Return value: Matching provider or NULL if none exists. + **/ +const CamelProvider * +camel_provider_get_for_protocol (const gchar *protocol, ProviderType type) +{ + GList *found_provider_node; + CamelProvider *found_provider = NULL; + + g_assert (protocol); + g_return_val_if_fail (_provider_list, NULL); + + /* we've got a compilation warning here because of bad prototype of + g_list_find_custom (), don't worry about that */ + do { + found_provider_node = g_list_find_custom (_provider_list, (gconstpointer)protocol, _provider_name_cmp); + /* we will get the last registered provider + here because providers are registered + using g_list_prepend(). This is a bit + dangerous however because we rely on + the way g_list_find_custom() is implemented. + This should be changed one day */ + if (found_provider_node) + found_provider = (CamelProvider*)found_provider_node->data; + else found_provider = NULL; + } + while (found_provider && (found_provider->provider_type != type)); + + return found_provider; +} diff --git a/camel/camel-provider.h b/camel/camel-provider.h index 3099efa265..d256d83c1a 100644 --- a/camel/camel-provider.h +++ b/camel/camel-provider.h @@ -54,6 +54,7 @@ typedef struct { void camel_provider_register (CamelProvider *provider); const CamelProvider *camel_provider_register_as_module (const gchar *module_path); +const CamelProvider *camel_provider_get_for_protocol (const gchar *protocol, ProviderType type); #ifdef __cplusplus diff --git a/camel/camel-session.c b/camel/camel-session.c index fef670ece6..2c2d64ade6 100644 --- a/camel/camel-session.c +++ b/camel/camel-session.c @@ -22,6 +22,7 @@ */ #include #include "camel-session.h" +#include "string-utils.h" static GtkObjectClass *parent_class=NULL; @@ -45,8 +46,8 @@ camel_session_class_init (CamelSessionClass *camel_session_class) static void camel_session_init (CamelSession *session) { - session->store_provider_list = g_hash_table_new (g_str_hash, g_str_equal); - session->transport_provider_list = g_hash_table_new (g_str_hash, g_str_equal); + session->store_provider_list = g_hash_table_new (g_strcase_hash, g_strcase_equal); + session->transport_provider_list = g_hash_table_new (g_strcase_hash, g_strcase_equal); } @@ -129,3 +130,76 @@ camel_session_get_store_from_provider (CamelSession *session, CamelProvider *pro camel_store_init(store, session, NULL); return store; } + + + + +/** + * camel_session_get_store_for_protocol: get the store associated to a protocol + * @session: CamelSession object + * @protocol: protocol name + * + * Return a CamelStore object associated to a given + * store protocol. If a provider has been set for this + * protocol in the session @session using + * camel_session_set_provider (), then a store + * obtained from this provider is return. + * Otherwise, if one or more provider corresponding + * to this protocol has been registered (See + * camel_provider_register_as_module), the last registered + * one is used. + * + * Return value: store associated to this protocol or NULL if no provider was found. + **/ +CamelStore * +camel_session_get_store_for_protocol (CamelSession *session, const gchar *protocol) +{ + CamelProvider *provider = NULL; + CamelStore *new_store; + + /* look if there is a provider assiciated to this + protocol in this session */ + provider = CAMEL_PROVIDER (g_hash_table_lookup (session->store_provider_list, protocol)); + if (!provider) + /* no provider was found in this session, look + if there is a registered provider for this + protocol */ + provider = camel_provider_get_for_protocol (protocol, PROVIDER_STORE); + + if (!provider) return NULL; + + new_store = (CamelStore *)gtk_type_new (provider->object_type); + return new_store; +} + + + + +/** + * camel_session_get_store: get a store object for an URL + * @session: session object + * @url_string: url + * + * return a store corresponding to an URL. + * + * Return value: the store, or NULL if no provider correponds to the protocol + **/ +CamelStore * +camel_session_get_store (CamelSession *session, const gchar *url_string) +{ + Gurl *url = NULL; + CamelStore *new_store = NULL; + + url = g_url_new (url_string); + g_return_val_if_fail (url, NULL); + + if (url->protocol) { + new_store = camel_session_get_store_for_protocol (session, url->protocol); + if (new_store) + camel_store_init (new_store, session, url_string); + } + g_url_free (url); + + return new_store; + +} diff --git a/camel/camel-session.h b/camel/camel-session.h index 0fb881ea72..9bec37851a 100644 --- a/camel/camel-session.h +++ b/camel/camel-session.h @@ -73,6 +73,8 @@ GtkType camel_session_get_type (void); void camel_session_set_provider (CamelSession *session, CamelProvider *provider); +CamelStore *camel_session_get_store_for_protocol (CamelSession *session, const gchar *protocol); +CamelStore *camel_session_get_store (CamelSession *session, const gchar *url_string); #ifdef __cplusplus diff --git a/camel/string-utils.c b/camel/string-utils.c index e53c41308e..bfda0f0f8d 100644 --- a/camel/string-utils.c +++ b/camel/string-utils.c @@ -26,6 +26,7 @@ #include #include "string-utils.h" #include "camel-log.h" +#include "string.h" @@ -251,3 +252,46 @@ string_trim (gchar *string, const gchar *trim_chars, StringTrimOption options) +/***/ +/* use these two funcs for case insensitive hash table */ + +gint +g_strcase_equal (gconstpointer a, gconstpointer b) +{ + return (g_strcasecmp ((gchar *)a, (gchar *)b) == 0); +} + + +/* modified g_str_hash from glib/gstring.c + because it would have been too slow to + us g_strdown() on the string */ +/* a char* hash function from ASU */ +guint +g_strcase_hash (gconstpointer v) +{ + const char *s = (char*)v; + const char *p; + char c; + guint h=0, g; + + for(p = s; *p != '\0'; p += 1) { + c = isupper ((guchar)*p) ? tolower ((guchar)*p) : *p; + h = ( h << 4 ) + c; + if ( ( g = h & 0xf0000000 ) ) { + h = h ^ (g >> 24); + h = h ^ g; + } + } + + return h /* % M */; +} + + + + + + + + + +/***/ diff --git a/camel/string-utils.h b/camel/string-utils.h index 9805861daf..e75e1af9b1 100644 --- a/camel/string-utils.h +++ b/camel/string-utils.h @@ -60,6 +60,9 @@ GList *string_split (const gchar *string, char sep, void string_trim (gchar *string, const gchar *chars, StringTrimOption options); +gint g_strcase_equal (gconstpointer a, gconstpointer b); +guint g_strcase_hash (gconstpointer v); + #ifdef __cplusplus } #endif /* __cplusplus */ -- cgit v1.2.3