[evolution-data-server/wip/camel-more-gobject: 47/62] Add CamelIMAPXMessageInfo



commit 83e9ccb55a033a237fcfa1fcaff0283096f429f4
Author: Milan Crha <mcrha redhat com>
Date:   Mon Sep 5 18:38:26 2016 +0200

    Add CamelIMAPXMessageInfo

 camel/camel-message-info-base.c                  |   71 +++--
 camel/camel-message-info.c                       |   12 +
 camel/camel-mime-utils.c                         |   87 +++++-
 camel/camel-mime-utils.h                         |    7 +-
 camel/providers/imapx/Makefile.am                |    2 +
 camel/providers/imapx/camel-imapx-message-info.c |  386 ++++++++++++++++++++++
 camel/providers/imapx/camel-imapx-message-info.h |   87 +++++
 7 files changed, 618 insertions(+), 34 deletions(-)
---
diff --git a/camel/camel-message-info-base.c b/camel/camel-message-info-base.c
index ca361de..9a4950f 100644
--- a/camel/camel-message-info-base.c
+++ b/camel/camel-message-info-base.c
@@ -162,16 +162,13 @@ message_info_base_take_user_flags (xCamelMessageInfo *mi,
 
        xcamel_message_info_property_lock (mi);
 
-       /* Consider them the same if they are the same pointer or they both are empty;
-          otherwise report change. */
-       changed = !(bmi->priv->user_flags == user_flags ||
-                  (bmi->priv->user_flags && user_flags &&
-                  !camel_named_flags_length (bmi->priv->user_flags) &&
-                  !camel_named_flags_length (user_flags)));
+       changed = !camel_named_flags_equal (bmi->priv->user_flags, user_flags);
 
        if (changed) {
                camel_named_flags_free (bmi->priv->user_flags);
                bmi->priv->user_flags = user_flags;
+       } else {
+               camel_named_flags_free (user_flags);
        }
 
        xcamel_message_info_property_unlock (mi);
@@ -251,16 +248,13 @@ message_info_base_take_user_tags (xCamelMessageInfo *mi,
 
        xcamel_message_info_property_lock (mi);
 
-       /* Consider them the same if they are the same pointer or they both are empty;
-          otherwise report change. */
-       changed = !(bmi->priv->user_tags == user_tags ||
-                  (bmi->priv->user_tags && user_tags &&
-                  !camel_name_value_array_length (bmi->priv->user_tags) &&
-                  !camel_name_value_array_length (user_tags)));
+       changed = !camel_name_value_array_equal (bmi->priv->user_tags, user_tags, TRUE);
 
        if (changed) {
                camel_name_value_array_free (bmi->priv->user_tags);
                bmi->priv->user_tags = user_tags;
+       } else {
+               camel_name_value_array_free (user_tags);
        }
 
        xcamel_message_info_property_unlock (mi);
@@ -698,6 +692,32 @@ message_info_base_get_references (const xCamelMessageInfo *mi)
 }
 
 static gboolean
+message_info_base_references_equal (const GArray *references_a,
+                                   const GArray *references_b)
+{
+       guint ii, len;
+
+       if (references_a == references_b)
+               return TRUE;
+
+       if (!references_a || !references_b)
+               return FALSE;
+
+       len = references_a->len;
+       if (len != references_b->len)
+               return FALSE;
+
+       /* They can be still the same, only having the items on different indexes,
+          but that's too expensive to compare precisely. */
+       for (ii = 0; ii < len; ii++) {
+               if (g_array_index (references_a, guint64, ii) != g_array_index (references_b, guint64, ii))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
+static gboolean
 message_info_base_take_references (xCamelMessageInfo *mi,
                                   GArray *references)
 {
@@ -710,17 +730,14 @@ message_info_base_take_references (xCamelMessageInfo *mi,
 
        xcamel_message_info_property_lock (mi);
 
-       /* Consider them the same if they are the same pointer or they both are empty;
-          otherwise report change. */
-       changed = !(bmi->priv->references == references ||
-                  (bmi->priv->references && references &&
-                  !bmi->priv->references->len &&
-                  !references->len));
+       changed = !message_info_base_references_equal (bmi->priv->references, references);
 
        if (changed) {
                if (bmi->priv->references)
                        g_array_unref (bmi->priv->references);
                bmi->priv->references = references;
+       } else if (references) {
+               g_array_unref (references);
        }
 
        xcamel_message_info_property_unlock (mi);
@@ -758,17 +775,13 @@ message_info_base_take_headers (xCamelMessageInfo *mi,
 
        xcamel_message_info_property_lock (mi);
 
-       /* Consider them the same if they are the same pointer or they both are empty;
-          otherwise report change. */
-       changed = !(bmi->priv->headers == headers ||
-                  (bmi->priv->headers && headers &&
-                  !camel_name_value_array_length (bmi->priv->headers) &&
-                  !camel_name_value_array_length (headers)));
+       changed = !camel_name_value_array_equal (bmi->priv->headers, headers, TRUE);
 
        if (changed) {
-               if (bmi->priv->headers)
-                       camel_name_value_array_free (bmi->priv->headers);
+               camel_name_value_array_free (bmi->priv->headers);
                bmi->priv->headers = headers;
+       } else {
+               camel_name_value_array_free (headers);
        }
 
        xcamel_message_info_property_unlock (mi);
@@ -781,12 +794,12 @@ message_info_base_dispose (GObject *object)
 {
        xCamelMessageInfoBase *bmi = XCAMEL_MESSAGE_INFO_BASE (object);
 
-       camel_name_value_array_free (bmi->priv->user_tags);
-       bmi->priv->user_tags = NULL;
-
        camel_named_flags_free (bmi->priv->user_flags);
        bmi->priv->user_flags = NULL;
 
+       camel_name_value_array_free (bmi->priv->user_tags);
+       bmi->priv->user_tags = NULL;
+
        #define free_ptr(x) G_STMT_START { g_free (x); x = NULL; } G_STMT_END
 
        free_ptr (bmi->priv->subject);
diff --git a/camel/camel-message-info.c b/camel/camel-message-info.c
index 14b465a..4988515 100644
--- a/camel/camel-message-info.c
+++ b/camel/camel-message-info.c
@@ -1245,6 +1245,9 @@ xcamel_message_info_dup_user_flags (const xCamelMessageInfo *mi)
  * set automatically. There is also emitted folder's "changed" signal
  * for this @mi, if necessary.
  *
+ * Note that it's not safe to use the @user_flags after the call to this function,
+ * because it can be freed due to no change.
+ *
  * Returns: Whether the message info changed.
  *
  * Since: 3.24
@@ -1420,6 +1423,9 @@ xcamel_message_info_dup_user_tags (const xCamelMessageInfo *mi)
  * set automatically. There is also emitted folder's "changed" signal
  * for this @mi, if necessary.
  *
+ * Note that it's not safe to use the @user_tags after the call to this function,
+ * because it can be freed due to no change.
+ *
  * Returns: Whether the @mi changed.
  *
  * Since: 3.24
@@ -2264,6 +2270,9 @@ xcamel_message_info_dup_references (const xCamelMessageInfo *mi)
  * set automatically. There is not emitted folder's "changed" signal
  * for this @mi.
  *
+ * Note that it's not safe to use the @references after the call to this function,
+ * because it can be freed due to no change.
+ *
  * Returns: Whether the value changed.
  *
  * Since: 3.24
@@ -2369,6 +2378,9 @@ xcamel_message_info_dup_headers (const xCamelMessageInfo *mi)
  * set automatically. There is not emitted folder's "changed" signal
  * for this @mi.
  *
+ * Note that it's not safe to use the @headers after the call to this function,
+ * because it can be freed due to no change.
+ *
  * Returns: Whether the value changed.
  *
  * Since: 3.24
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index a44b6e0..ab551fd 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -226,9 +226,8 @@ camel_name_value_array_copy (const CamelNameValueArray *array)
 void
 camel_name_value_array_free (CamelNameValueArray *array)
 {
-       if (array) {
+       if (array)
                g_array_free ((GArray *) array, TRUE);
-       }
 }
 
 /**
@@ -667,6 +666,50 @@ camel_name_value_array_clear (CamelNameValueArray *array)
        g_array_remove_range (arr, 0, arr->len);
 }
 
+/**
+ * camel_name_value_array_equal:
+ * @array_a: (nullable): the first #CamelNameValueArray
+ * @array_b: (nullable): the second #CamelNameValueArray
+ * @case_sensitive: whether to search for names case sensitively
+ *
+ * Compares content of the two #CamelNameValueArray and returns whether
+ * they equal. Note this is an expensive operation for large arrays.
+ *
+ * Returns: Whether the two #CamelNameValueArray have the same content.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_name_value_array_equal (const CamelNameValueArray *array_a,
+                             const CamelNameValueArray *array_b,
+                             gboolean case_sensitive)
+{
+       guint ii, len;
+
+       if (array_a == array_b)
+               return TRUE;
+
+       if (!array_a || !array_b)
+               return FALSE;
+
+       len = camel_name_value_array_length (array_a);
+       if (len != camel_name_value_array_length (array_b))
+               return FALSE;
+
+       for (ii = 0; ii < len; ii++) {
+               const gchar *value1, *value2;
+
+               value1 = camel_name_value_array_get_value (array_a, ii);
+               value2 = camel_name_value_array_get_named (array_b, case_sensitive,
+                       camel_name_value_array_get_name (array_a, ii));
+
+               if (g_strcmp0 (value1, value2) != 0)
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
 /* ------------------------------------------------------------------------ */
 
 G_DEFINE_BOXED_TYPE (CamelNamedFlags,
@@ -760,7 +803,7 @@ camel_named_flags_free (CamelNamedFlags *named_flags)
 }
 
 static guint
-camel_named_flags_find (CamelNamedFlags *named_flags,
+camel_named_flags_find (const CamelNamedFlags *named_flags,
                        const gchar *name)
 {
        GPtrArray *arr = (GPtrArray *) named_flags;
@@ -856,7 +899,7 @@ camel_named_flags_remove (CamelNamedFlags *named_flags,
  * Since: 3.24
  **/
 gboolean
-camel_named_flags_contains (CamelNamedFlags *named_flags,
+camel_named_flags_contains (const CamelNamedFlags *named_flags,
                            const gchar *name)
 {
        g_return_val_if_fail (named_flags != NULL, FALSE);
@@ -924,6 +967,42 @@ camel_named_flags_get (const CamelNamedFlags *named_flags,
        return g_ptr_array_index (arr, index);
 }
 
+/**
+ * camel_named_flags_equal:
+ * @named_flags_a: (nullable): the first #CamelNamedFlags
+ * @named_flags_b: (nullable): the second #CamelNamedFlags
+ *
+ * Compares content of the two #CamelNamedFlags and returns whether
+ * they equal. Note this is an expensive operation for large sets.
+ *
+ * Returns: Whether the two #CamelNamedFlags have the same content.
+ *
+ * Since: 3.24
+ **/
+gboolean
+camel_named_flags_equal (const CamelNamedFlags *named_flags_a,
+                        const CamelNamedFlags *named_flags_b)
+{
+       guint ii, len;
+
+       if (named_flags_a == named_flags_b)
+               return TRUE;
+
+       if (!named_flags_a || !named_flags_b)
+               return FALSE;
+
+       len = camel_named_flags_length (named_flags_a);
+       if (len != camel_named_flags_length (named_flags_b))
+               return FALSE;
+
+       for (ii = 0; ii < len; ii++) {
+               if (!camel_named_flags_contains (named_flags_a, camel_named_flags_get (named_flags_b, ii)))
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
 /* ------------------------------------------------------------------------ */
 
 /**
diff --git a/camel/camel-mime-utils.h b/camel/camel-mime-utils.h
index 0cd2101..1714a55 100644
--- a/camel/camel-mime-utils.h
+++ b/camel/camel-mime-utils.h
@@ -105,6 +105,9 @@ guint               camel_name_value_array_remove_named
                                                 const gchar *name,
                                                 gboolean all_occurrences);
 void           camel_name_value_array_clear    (CamelNameValueArray *array);
+gboolean       camel_name_value_array_equal    (const CamelNameValueArray *array_a,
+                                                const CamelNameValueArray *array_b,
+                                                gboolean case_sensitive);
 
 /**
  * CamelNamedFlags:
@@ -128,12 +131,14 @@ gboolean  camel_named_flags_insert        (CamelNamedFlags *named_flags,
                                                 const gchar *name);
 gboolean       camel_named_flags_remove        (CamelNamedFlags *named_flags,
                                                 const gchar *name);
-gboolean       camel_named_flags_contains      (CamelNamedFlags *named_flags,
+gboolean       camel_named_flags_contains      (const CamelNamedFlags *named_flags,
                                                 const gchar *name);
 void           camel_named_flags_clear         (CamelNamedFlags *named_flags);
 guint          camel_named_flags_length        (const CamelNamedFlags *named_flags);
 const gchar *  camel_named_flags_get           (const CamelNamedFlags *named_flags,
                                                 guint index);
+gboolean       camel_named_flags_equal         (const CamelNamedFlags *named_flags_a,
+                                                const CamelNamedFlags *named_flags_b);
 
 typedef struct _camel_header_param {
        struct _camel_header_param *next;
diff --git a/camel/providers/imapx/Makefile.am b/camel/providers/imapx/Makefile.am
index 85c59ff..2ddd14a 100644
--- a/camel/providers/imapx/Makefile.am
+++ b/camel/providers/imapx/Makefile.am
@@ -37,6 +37,8 @@ libcamelimapx_la_SOURCES = \
        camel-imapx-logger.h \
        camel-imapx-mailbox.c \
        camel-imapx-mailbox.h \
+       camel-imapx-message-info.c \
+       camel-imapx-message-info.h \
        camel-imapx-namespace.c \
        camel-imapx-namespace.h \
        camel-imapx-namespace-response.c \
diff --git a/camel/providers/imapx/camel-imapx-message-info.c 
b/camel/providers/imapx/camel-imapx-message-info.c
new file mode 100644
index 0000000..316d69a
--- /dev/null
+++ b/camel/providers/imapx/camel-imapx-message-info.c
@@ -0,0 +1,386 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "camel/camel.h"
+#include "camel-imapx-summary.h"
+
+#include "camel-imapx-message-info.h"
+
+struct _xCamelIMAPXMessageInfoPrivate {
+       guint32 server_flags;
+       CamelNamedFlags *server_user_flags;
+       CamelNameValueArray *server_user_tags;
+};
+
+enum {
+       PROP_0,
+       PROP_SERVER_FLAGS,
+       PROP_SERVER_USER_FLAGS,
+       PROP_SERVER_USER_TAGS
+};
+
+G_DEFINE_TYPE (xCamelIMAPXMessageInfo, xcamel_imapx_message_info, XCAMEL_TYPE_MESSAGE_INFO_BASE)
+
+static xCamelMessageInfo *
+imapx_message_info_clone (const xCamelMessageInfo *mi,
+                         CamelFolderSummary *assign_summary)
+{
+       xCamelMessageInfo *result;
+
+       g_return_val_if_fail (XCAMEL_IS_IMAPX_MESSAGE_INFO (mi), NULL);
+
+       result = XCAMEL_MESSAGE_INFO_CLASS (xcamel_imapx_message_info_parent_class)->clone (mi, 
assign_summary);
+       if (!result)
+               return NULL;
+
+       if (XCAMEL_IS_IMAPX_MESSAGE_INFO (result)) {
+               xCamelIMAPXMessageInfo *imi, *imi_result;
+
+               imi = XCAMEL_IMAPX_MESSAGE_INFO (mi);
+               imi_result = XCAMEL_IMAPX_MESSAGE_INFO (result);
+
+               xcamel_imapx_message_info_set_server_flags (imi_result, 
xcamel_imapx_message_info_get_server_flags (imi));
+               xcamel_imapx_message_info_take_server_user_flags (imi_result, 
xcamel_imapx_message_info_dup_server_user_flags (imi));
+               xcamel_imapx_message_info_take_server_user_tags (imi_result, 
xcamel_imapx_message_info_dup_server_user_tags (imi));
+       }
+
+       return result;
+}
+
+static void
+imapx_message_info_set_property (GObject *object,
+                                guint property_id,
+                                const GValue *value,
+                                GParamSpec *pspec)
+{
+       xCamelIMAPXMessageInfo *imi = XCAMEL_IMAPX_MESSAGE_INFO (object);
+
+       switch (property_id) {
+       case PROP_SERVER_FLAGS:
+               xcamel_imapx_message_info_set_server_flags (imi, g_value_get_uint (value));
+               return;
+
+       case PROP_SERVER_USER_FLAGS:
+               xcamel_imapx_message_info_take_server_user_flags (imi, g_value_dup_boxed (value));
+               return;
+
+       case PROP_SERVER_USER_TAGS:
+               xcamel_imapx_message_info_take_server_user_tags (imi, g_value_dup_boxed (value));
+               return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+imapx_message_info_get_property (GObject *object,
+                                guint property_id,
+                                GValue *value,
+                                GParamSpec *pspec)
+{
+       xCamelIMAPXMessageInfo *imi = XCAMEL_IMAPX_MESSAGE_INFO (object);
+
+       switch (property_id) {
+       case PROP_SERVER_FLAGS:
+               g_value_set_uint (value, xcamel_imapx_message_info_get_server_flags (imi));
+               return;
+
+       case PROP_SERVER_USER_FLAGS:
+               g_value_take_boxed (value, xcamel_imapx_message_info_dup_server_user_flags (imi));
+               return;
+
+       case PROP_SERVER_USER_TAGS:
+               g_value_take_boxed (value, xcamel_imapx_message_info_dup_server_user_tags (imi));
+               return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+imapx_message_info_dispose (GObject *object)
+{
+       xCamelIMAPXMessageInfo *imi = XCAMEL_IMAPX_MESSAGE_INFO (object);
+
+       camel_named_flags_free (imi->priv->server_user_flags);
+       imi->priv->server_user_flags = NULL;
+
+       camel_name_value_array_free (imi->priv->server_user_tags);
+       imi->priv->server_user_tags = NULL;
+
+       /* Chain up to parent's method. */
+       G_OBJECT_CLASS (xcamel_imapx_message_info_parent_class)->dispose (object);
+}
+
+static void
+xcamel_imapx_message_info_class_init (xCamelIMAPXMessageInfoClass *class)
+{
+       xCamelMessageInfoClass *mi_class;
+       GObjectClass *object_class;
+
+       g_type_class_add_private (class, sizeof (xCamelIMAPXMessageInfoPrivate));
+
+       mi_class = XCAMEL_MESSAGE_INFO_CLASS (class);
+       mi_class->clone = imapx_message_info_clone;
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->set_property = imapx_message_info_set_property;
+       object_class->get_property = imapx_message_info_get_property;
+       object_class->dispose = imapx_message_info_dispose;
+
+       /**
+        * xCamelIMAPXMessageInfo:server-flags
+        *
+        * Bit-or of #CamelMessageFlags of the flags stored on the server.
+        *
+        * Since: 3.24
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_SERVER_FLAGS,
+               g_param_spec_uint (
+                       "server-flags",
+                       "Server Flags",
+                       NULL,
+                       0, G_MAXUINT32, 0,
+                       G_PARAM_READWRITE));
+
+       /**
+        * xCamelIMAPXMessageInfo:server-user-flags
+        *
+        * User flags for the associated message, as stored on the server.
+        * Can be %NULL.
+        *
+        * Since: 3.24
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_SERVER_USER_FLAGS,
+               g_param_spec_boxed (
+                       "server-user-flags",
+                       "Server User Flags",
+                       NULL,
+                       CAMEL_TYPE_NAMED_FLAGS,
+                       G_PARAM_READWRITE));
+
+       /**
+        * xCamelIMAPXMessageInfo:server-user-tags
+        *
+        * User tags for the associated message, as stored on the server.
+        * Can be %NULL.
+        *
+        * Since: 3.24
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_SERVER_USER_TAGS,
+               g_param_spec_boxed (
+                       "server-user-tags",
+                       "Server User tags",
+                       NULL,
+                       CAMEL_TYPE_NAME_VALUE_ARRAY,
+                       G_PARAM_READWRITE));
+
+}
+
+static void
+xcamel_imapx_message_info_init (xCamelIMAPXMessageInfo *vmi)
+{
+       vmi->priv = G_TYPE_INSTANCE_GET_PRIVATE (vmi, XCAMEL_TYPE_IMAPX_MESSAGE_INFO, 
xCamelIMAPXMessageInfoPrivate);
+}
+
+guint32
+xcamel_imapx_message_info_get_server_flags (const xCamelIMAPXMessageInfo *imi)
+{
+       xCamelMessageInfo *mi;
+       guint32 result;
+
+       g_return_val_if_fail (XCAMEL_IS_IMAPX_MESSAGE_INFO (imi), 0);
+
+       mi = XCAMEL_MESSAGE_INFO (imi);
+
+       xcamel_message_info_property_lock (mi);
+       result = imi->priv->server_flags;
+       xcamel_message_info_property_unlock (mi);
+
+       return result;
+}
+
+gboolean
+xcamel_imapx_message_info_set_server_flags (xCamelIMAPXMessageInfo *imi,
+                                           guint32 server_flags)
+{
+       xCamelMessageInfo *mi;
+       gboolean changed;
+
+       g_return_val_if_fail (XCAMEL_IS_IMAPX_MESSAGE_INFO (imi), FALSE);
+
+       mi = XCAMEL_MESSAGE_INFO (imi);
+
+       xcamel_message_info_property_lock (mi);
+
+       changed = imi->priv->server_flags != server_flags;
+       if (changed)
+               imi->priv->server_flags = server_flags;
+
+       xcamel_message_info_property_unlock (mi);
+
+       if (changed) {
+               g_object_notify (G_OBJECT (imi), "server-flags");
+               xcamel_message_info_set_dirty (mi, TRUE);
+       }
+
+       return changed;
+}
+
+const CamelNamedFlags *
+xcamel_imapx_message_info_get_server_user_flags (const xCamelIMAPXMessageInfo *imi)
+{
+       xCamelMessageInfo *mi;
+       const CamelNamedFlags *result;
+
+       g_return_val_if_fail (XCAMEL_IS_IMAPX_MESSAGE_INFO (imi), NULL);
+
+       mi = XCAMEL_MESSAGE_INFO (imi);
+
+       xcamel_message_info_property_lock (mi);
+       result = imi->priv->server_user_flags;
+       xcamel_message_info_property_unlock (mi);
+
+       return result;
+}
+
+CamelNamedFlags *
+xcamel_imapx_message_info_dup_server_user_flags (const xCamelIMAPXMessageInfo *imi)
+{
+       xCamelMessageInfo *mi;
+       CamelNamedFlags *result;
+
+       g_return_val_if_fail (XCAMEL_IS_IMAPX_MESSAGE_INFO (imi), NULL);
+
+       mi = XCAMEL_MESSAGE_INFO (imi);
+
+       xcamel_message_info_property_lock (mi);
+       result = camel_named_flags_copy (imi->priv->server_user_flags);
+       xcamel_message_info_property_unlock (mi);
+
+       return result;
+}
+
+gboolean
+xcamel_imapx_message_info_take_server_user_flags (xCamelIMAPXMessageInfo *imi,
+                                                 CamelNamedFlags *server_user_flags)
+{
+       xCamelMessageInfo *mi;
+       gboolean changed;
+
+       g_return_val_if_fail (XCAMEL_IS_IMAPX_MESSAGE_INFO (imi), FALSE);
+
+       mi = XCAMEL_MESSAGE_INFO (imi);
+
+       xcamel_message_info_property_lock (mi);
+
+       changed = !camel_named_flags_equal (imi->priv->server_user_flags, server_user_flags);
+
+       if (changed) {
+               camel_named_flags_free (imi->priv->server_user_flags);
+               imi->priv->server_user_flags = server_user_flags;
+       } else {
+               camel_named_flags_free (server_user_flags);
+       }
+
+       xcamel_message_info_property_unlock (mi);
+
+       if (changed) {
+               g_object_notify (G_OBJECT (imi), "server-user-flags");
+               xcamel_message_info_set_dirty (mi, TRUE);
+       }
+
+       return changed;
+}
+
+const CamelNameValueArray *
+xcamel_imapx_message_info_get_server_user_tags (const xCamelIMAPXMessageInfo *imi)
+{
+       xCamelMessageInfo *mi;
+       const CamelNameValueArray *result;
+
+       g_return_val_if_fail (XCAMEL_IS_IMAPX_MESSAGE_INFO (imi), NULL);
+
+       mi = XCAMEL_MESSAGE_INFO (imi);
+
+       xcamel_message_info_property_lock (mi);
+       result = imi->priv->server_user_tags;
+       xcamel_message_info_property_unlock (mi);
+
+       return result;
+}
+
+CamelNameValueArray *
+xcamel_imapx_message_info_dup_server_user_tags (const xCamelIMAPXMessageInfo *imi)
+{
+       xCamelMessageInfo *mi;
+       CamelNameValueArray *result;
+
+       g_return_val_if_fail (XCAMEL_IS_IMAPX_MESSAGE_INFO (imi), NULL);
+
+       mi = XCAMEL_MESSAGE_INFO (imi);
+
+       xcamel_message_info_property_lock (mi);
+       result = camel_name_value_array_copy (imi->priv->server_user_tags);
+       xcamel_message_info_property_unlock (mi);
+
+       return result;
+}
+
+gboolean
+xcamel_imapx_message_info_take_server_user_tags (xCamelIMAPXMessageInfo *imi,
+                                                CamelNameValueArray *server_user_tags)
+{
+       xCamelMessageInfo *mi;
+       gboolean changed;
+
+       g_return_val_if_fail (XCAMEL_IS_IMAPX_MESSAGE_INFO (imi), FALSE);
+
+       mi = XCAMEL_MESSAGE_INFO (imi);
+
+       xcamel_message_info_property_lock (mi);
+
+       changed = !camel_name_value_array_equal (imi->priv->server_user_tags, server_user_tags, TRUE);
+
+       if (changed) {
+               camel_name_value_array_free (imi->priv->server_user_tags);
+               imi->priv->server_user_tags = server_user_tags;
+       } else {
+               camel_name_value_array_free (server_user_tags);
+       }
+
+       xcamel_message_info_property_unlock (mi);
+
+       if (changed) {
+               g_object_notify (G_OBJECT (imi), "server-user-tags");
+               xcamel_message_info_set_dirty (mi, TRUE);
+       }
+
+       return changed;
+}
diff --git a/camel/providers/imapx/camel-imapx-message-info.h 
b/camel/providers/imapx/camel-imapx-message-info.h
new file mode 100644
index 0000000..ee6a147
--- /dev/null
+++ b/camel/providers/imapx/camel-imapx-message-info.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2016 Red Hat, Inc. (www.redhat.com)
+ *
+ * This library is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef XCAMEL_IMAPX_MESSAGE_INFO_H
+#define XCAMEL_IMAPX_MESSAGE_INFO_H
+
+#include <glib-object.h>
+
+#include <camel/camel.h>
+
+/* Standard GObject macros */
+#define XCAMEL_TYPE_IMAPX_MESSAGE_INFO \
+       (xcamel_imapx_message_info_get_type ())
+#define XCAMEL_IMAPX_MESSAGE_INFO(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST \
+       ((obj), XCAMEL_TYPE_IMAPX_MESSAGE_INFO, xCamelIMAPXMessageInfo))
+#define XCAMEL_IMAPX_MESSAGE_INFO_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_CAST \
+       ((cls), XCAMEL_TYPE_IMAPX_MESSAGE_INFO, xCamelIMAPXMessageInfoClass))
+#define XCAMEL_IS_IMAPX_MESSAGE_INFO(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE \
+       ((obj), XCAMEL_TYPE_IMAPX_MESSAGE_INFO))
+#define XCAMEL_IS_IMAPX_MESSAGE_INFO_CLASS(cls) \
+       (G_TYPE_CHECK_CLASS_TYPE \
+       ((cls), XCAMEL_TYPE_IMAPX_MESSAGE_INFO))
+#define XCAMEL_IMAPX_MESSAGE_INFO_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS \
+       ((obj), XCAMEL_TYPE_IMAPX_MESSAGE_INFO, xCamelIMAPXMessageInfoClass))
+
+G_BEGIN_DECLS
+
+typedef struct _xCamelIMAPXMessageInfo xCamelIMAPXMessageInfo;
+typedef struct _xCamelIMAPXMessageInfoClass xCamelIMAPXMessageInfoClass;
+typedef struct _xCamelIMAPXMessageInfoPrivate xCamelIMAPXMessageInfoPrivate;
+
+struct _xCamelIMAPXMessageInfo {
+       xCamelMessageInfoBase parent;
+       xCamelIMAPXMessageInfoPrivate *priv;
+};
+
+struct _xCamelIMAPXMessageInfoClass {
+       xCamelMessageInfoBaseClass parent_class;
+};
+
+GType          xcamel_imapx_message_info_get_type      (void);
+
+guint32                xcamel_imapx_message_info_get_server_flags
+                                                       (const xCamelIMAPXMessageInfo *imi);
+gboolean       xcamel_imapx_message_info_set_server_flags
+                                                       (xCamelIMAPXMessageInfo *imi,
+                                                        guint32 server_flags);
+const CamelNamedFlags *
+               xcamel_imapx_message_info_get_server_user_flags
+                                                       (const xCamelIMAPXMessageInfo *imi);
+CamelNamedFlags *
+               xcamel_imapx_message_info_dup_server_user_flags
+                                                       (const xCamelIMAPXMessageInfo *imi);
+gboolean       xcamel_imapx_message_info_take_server_user_flags
+                                                       (xCamelIMAPXMessageInfo *imi,
+                                                        CamelNamedFlags *server_user_flags);
+const CamelNameValueArray *
+               xcamel_imapx_message_info_get_server_user_tags
+                                                       (const xCamelIMAPXMessageInfo *imi);
+CamelNameValueArray *
+               xcamel_imapx_message_info_dup_server_user_tags
+                                                       (const xCamelIMAPXMessageInfo *imi);
+gboolean       xcamel_imapx_message_info_take_server_user_tags
+                                                       (xCamelIMAPXMessageInfo *imi,
+                                                        CamelNameValueArray *server_user_tags);
+
+G_END_DECLS
+
+#endif /* XCAMEL_IMAPX_MESSAGE_INFO_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]