aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/camel-provider.c61
-rw-r--r--camel/camel-provider.h1
-rw-r--r--camel/camel-session.c78
-rw-r--r--camel/camel-session.h2
-rw-r--r--camel/string-utils.c44
-rw-r--r--camel/string-utils.h3
6 files changed, 186 insertions, 3 deletions
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 <config.h>
#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 <config.h>
#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 */