[evolution-data-server/imapx-extensible: 7/10] IMAPX: (utils) made capabilities flags extensible
- From: Christian Hilberg <chilberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/imapx-extensible: 7/10] IMAPX: (utils) made capabilities flags extensible
- Date: Tue, 26 Jun 2012 14:42:59 +0000 (UTC)
commit f816109d2e02d315cb51b4f6e84f4c10908e6fc3
Author: Christian Hilberg <chilberg src gnome org>
Date: Fri Jun 22 17:16:50 2012 +0200
IMAPX: (utils) made capabilities flags extensible
* added a hash table as an IMAP capabilities flags
lookup mechanism for the capabilities parser util
function
* added a capabilities strings registration function
(to add new capabilities flags, which will then be
known to the parser and assigned a new flag bit.
This is returned by the registration function so
the caller can test whether the bit is set in the
CamelIMAPXServer capabilities bitstring)
camel/camel-imapx-utils.c | 91 ++++++++++++++++++++++++++++++++++++++++++--
camel/camel-imapx-utils.h | 1 +
2 files changed, 87 insertions(+), 5 deletions(-)
---
diff --git a/camel/camel-imapx-utils.c b/camel/camel-imapx-utils.c
index 856600a..4a7f2cc 100644
--- a/camel/camel-imapx-utils.c
+++ b/camel/camel-imapx-utils.c
@@ -354,7 +354,7 @@ imapx_update_store_summary (CamelFolder *folder)
struct {
const gchar *name;
guint32 flag;
-} capa_table[] = {
+} capa_table[] = { /* used to create capa_htable only */
{ "IMAP4", IMAPX_CAPABILITY_IMAP4 },
{ "IMAP4REV1", IMAPX_CAPABILITY_IMAP4REV1 },
{ "STATUS", IMAPX_CAPABILITY_STATUS } ,
@@ -369,14 +369,42 @@ struct {
{ "LIST-STATUS", IMAPX_CAPABILITY_LIST_STATUS },
};
+static GMutex capa_htable_lock; /* capabilities lookup table lock */
+static GHashTable *capa_htable = NULL; /* capabilities lookup table (extensible) */
+
+static void
+create_initial_capabilities_table (void)
+{
+ gint i = 0;
+
+ /* call within g_init_once() only,
+ * or require table lock
+ */
+
+ /* TODO add imapx_utils_uninit()
+ * to free hash table
+ */
+ capa_htable = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ NULL);
+
+ for (i = 0; i < G_N_ELEMENTS (capa_table); i++) {
+ g_hash_table_insert (capa_htable,
+ g_strdup (capa_table[i].name),
+ GUINT_TO_POINTER (capa_table[i].flag));
+ }
+}
+
struct _capability_info *
imapx_parse_capability (CamelIMAPXStream *stream,
GCancellable *cancellable,
GError **error)
{
- gint tok, i;
+ gint tok;
guint len;
guchar *token, *p, c;
+ gpointer pp = NULL;
gboolean free_token = FALSE;
struct _capability_info * cinfo;
GError *local_error = NULL;
@@ -408,9 +436,14 @@ imapx_parse_capability (CamelIMAPXStream *stream,
}
case IMAPX_TOK_INT:
d(stream->tagprefix, " cap: '%s'\n", token);
- for (i = 0; i < G_N_ELEMENTS (capa_table); i++)
- if (!strcmp ((gchar *) token, capa_table[i].name))
- cinfo->capa |= capa_table[i].flag;
+ g_mutex_lock (&capa_htable_lock);
+ pp = g_hash_table_lookup (capa_htable,
+ (gchar*) token);
+ g_mutex_unlock (&capa_htable_lock);
+ if (pp != NULL) {
+ guint32 capa_id = GPOINTER_TO_UINT (pp);
+ cinfo->capa |= capa_id;
+ }
if (free_token) {
g_free (token);
token = NULL;
@@ -438,6 +471,53 @@ void imapx_free_capability (struct _capability_info *cinfo)
g_free (cinfo);
}
+guint32
+imapx_register_capability (const gchar *capability)
+{
+ guint32 capa_id = 0;
+ guint64 check_id = 0;
+ GList *keys = NULL;
+ GList *tmp_keys = NULL;
+
+ g_assert (capability != NULL);
+
+ g_mutex_lock (&capa_htable_lock);
+
+ /* we rely on IMAP being the first flag, non-zero value
+ * (1 << 0), so we can use GPOINTER_TO_UINT (NULL) as
+ * invalid value
+ */
+ capa_id = GPOINTER_TO_UINT (g_hash_table_lookup (capa_htable,
+ capability));
+ if (capa_id > 0)
+ goto exit;
+
+ /* not yet there, find biggest flag so far */
+ keys = g_hash_table_get_keys (capa_htable);
+ tmp_keys = keys;
+ while (tmp_keys != NULL) {
+ guint32 tmp_id = GPOINTER_TO_UINT (tmp_keys->data);
+ if (capa_id < tmp_id)
+ capa_id = tmp_id;
+ tmp_keys = g_list_next (tmp_keys);
+ }
+
+ /* shift-left biggest-so-far, sanity-check */
+ check_id = (capa_id << 1);
+ g_assert (check_id <= (guint64) G_MAXUINT32);
+ capa_id = (guint32) check_id;
+
+ /* insert */
+ g_hash_table_insert (capa_htable,
+ g_strdup (capability),
+ GUINT_TO_POINTER (capa_id));
+
+ exit:
+ g_mutex_unlock (&capa_htable_lock);
+
+ return capa_id;
+}
+
struct _CamelIMAPXNamespaceList *
imapx_parse_namespace_list (CamelIMAPXStream *stream,
GCancellable *cancellable,
@@ -1993,6 +2073,7 @@ imapx_utils_init (void)
imapx_specials[i] = v;
}
+ create_initial_capabilities_table ();
camel_imapx_set_debug_flags ();
g_once_init_leave (&imapx_utils_initialized, 1);
diff --git a/camel/camel-imapx-utils.h b/camel/camel-imapx-utils.h
index d8bd6aa..b777065 100644
--- a/camel/camel-imapx-utils.h
+++ b/camel/camel-imapx-utils.h
@@ -135,6 +135,7 @@ struct _capability_info {
struct _capability_info *imapx_parse_capability (struct _CamelIMAPXStream *stream, GCancellable *cancellable, GError **error);
void imapx_free_capability (struct _capability_info *);
+guint32 imapx_register_capability (const gchar *capability);
gboolean imapx_parse_param_list (struct _CamelIMAPXStream *is, struct _camel_header_param **plist, GCancellable *cancellable, GError **error) /* IO,PARSE */;
struct _CamelContentDisposition *imapx_parse_ext_optional (struct _CamelIMAPXStream *is, GCancellable *cancellable, GError **error) /* IO,PARSE */;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]