[evolution-data-server/tintou/camel-store-info: 26/26] M!91 - CamelStoreSummary: Make CamelStoreInfo a boxed class




commit 2f252421bcb9ec21b23828db5788d7e6c16fe9b2
Author: Corentin Noël <corentin noel collabora com>
Date:   Fri Feb 11 13:11:09 2022 +0100

    M!91 - CamelStoreSummary: Make CamelStoreInfo a boxed class
    
    Store the CamelStoreSummary info the CamelStoreInfo and create simple accessors
    and ref/unref methods.
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/merge_requests/91

 src/camel/camel-store-summary.c | 216 ++++++++++++++++++++++++++++------------
 src/camel/camel-store-summary.h |  11 +-
 2 files changed, 162 insertions(+), 65 deletions(-)
---
diff --git a/src/camel/camel-store-summary.c b/src/camel/camel-store-summary.c
index 98115f0e6..211639422 100644
--- a/src/camel/camel-store-summary.c
+++ b/src/camel/camel-store-summary.c
@@ -68,25 +68,18 @@ struct _CamelStoreSummaryPrivate {
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (CamelStoreSummary, camel_store_summary, G_TYPE_OBJECT)
+G_DEFINE_BOXED_TYPE(CamelStoreInfo, camel_store_info, camel_store_info_ref, camel_store_info_unref)
 
 static void
 store_summary_finalize (GObject *object)
 {
        CamelStoreSummary *summary = CAMEL_STORE_SUMMARY (object);
-       guint ii;
 
-       for (ii = 0; ii < summary->priv->folders->len; ii++) {
-               CamelStoreInfo *info;
+       g_clear_pointer (&summary->priv->folders, g_ptr_array_unref);
+       g_clear_pointer (&summary->priv->folders_path, g_hash_table_unref);
+       g_clear_pointer (&summary->priv->folder_summaries, g_hash_table_unref);
 
-               info = g_ptr_array_index (summary->priv->folders, ii);
-               camel_store_summary_info_unref (summary, info);
-       }
-
-       g_ptr_array_free (summary->priv->folders, TRUE);
-       g_hash_table_destroy (summary->priv->folders_path);
-       g_hash_table_destroy (summary->priv->folder_summaries);
-
-       g_free (summary->priv->summary_path);
+       g_clear_pointer (&summary->priv->summary_path, g_free);
 
        g_rec_mutex_clear (&summary->priv->summary_lock);
        g_rec_mutex_clear (&summary->priv->io_lock);
@@ -168,7 +161,6 @@ store_summary_store_info_new (CamelStoreSummary *summary,
        CamelStoreInfo *info;
 
        info = camel_store_summary_info_new (summary);
-
        info->path = g_strdup (path);
        info->unread = CAMEL_STORE_INFO_FOLDER_UNKNOWN;
        info->total = CAMEL_STORE_INFO_FOLDER_UNKNOWN;
@@ -190,7 +182,7 @@ store_summary_store_info_load (CamelStoreSummary *summary,
            camel_file_util_decode_uint32 (in, &info->flags) == -1 ||
            camel_file_util_decode_uint32 (in, &info->unread) == -1 ||
            camel_file_util_decode_uint32 (in, &info->total) == -1) {
-               camel_store_summary_info_unref (summary, info);
+               camel_store_info_unref (info);
 
                return NULL;
        }
@@ -198,7 +190,7 @@ store_summary_store_info_load (CamelStoreSummary *summary,
        if (!ferror (in))
                return info;
 
-       camel_store_summary_info_unref (summary, info);
+       camel_store_info_unref (info);
 
        return NULL;
 }
@@ -210,7 +202,7 @@ store_summary_store_info_save (CamelStoreSummary *summary,
 {
        io (printf ("Saving folder info\n"));
 
-       if (camel_file_util_encode_string (out, camel_store_info_path (summary, info)) == -1 ||
+       if (camel_file_util_encode_string (out, camel_store_info_get_path (info)) == -1 ||
            camel_file_util_encode_uint32 (out, info->flags) == -1 ||
            camel_file_util_encode_uint32 (out, info->unread) == -1 ||
            camel_file_util_encode_uint32 (out, info->total) == -1)
@@ -228,7 +220,7 @@ store_summary_store_info_free (CamelStoreSummary *summary,
        class = CAMEL_STORE_SUMMARY_GET_CLASS (summary);
        g_return_if_fail (class != NULL);
 
-       g_free (info->path);
+       g_clear_pointer (&info->path, g_free);
        g_slice_free1 (class->store_info_size, info);
 }
 
@@ -240,10 +232,10 @@ store_summary_store_info_set_string (CamelStoreSummary *summary,
 {
        switch (type) {
        case CAMEL_STORE_INFO_PATH:
-               g_hash_table_remove (summary->priv->folders_path, (gchar *) camel_store_info_path (summary, 
info));
+               g_hash_table_remove (summary->priv->folders_path, (gchar *) camel_store_info_get_path (info));
                g_free (info->path);
                info->path = g_strdup (str);
-               g_hash_table_insert (summary->priv->folders_path, (gchar *) camel_store_info_path (summary, 
info), info);
+               g_hash_table_insert (summary->priv->folders_path, (gchar *) camel_store_info_get_path (info), 
info);
                summary->priv->dirty = TRUE;
                break;
        }
@@ -275,7 +267,7 @@ camel_store_summary_init (CamelStoreSummary *summary)
 
        summary->priv->version = CAMEL_STORE_SUMMARY_VERSION;
 
-       summary->priv->folders = g_ptr_array_new ();
+       summary->priv->folders = g_ptr_array_new_with_free_func ((GDestroyNotify) camel_store_info_unref);
        summary->priv->folders_path = g_hash_table_new (g_str_hash, g_str_equal);
        summary->priv->folder_summaries = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
        summary->priv->scheduled_save_id = 0;
@@ -356,12 +348,7 @@ camel_store_summary_array (CamelStoreSummary *summary)
 
        g_rec_mutex_lock (&summary->priv->summary_lock);
 
-       res = g_ptr_array_sized_new (summary->priv->folders->len);
-       for (i = 0; i < summary->priv->folders->len; i++) {
-               info = g_ptr_array_index (summary->priv->folders, i);
-               camel_store_summary_info_ref (summary, info);
-               g_ptr_array_add (res, info);
-       }
+       res = g_ptr_array_copy (summary->priv->folders, (GCopyFunc) camel_store_info_ref, NULL);
 
        g_rec_mutex_unlock (&summary->priv->summary_lock);
 
@@ -385,10 +372,8 @@ camel_store_summary_array_free (CamelStoreSummary *summary,
        g_return_if_fail (CAMEL_IS_STORE_SUMMARY (summary));
        g_return_if_fail (array != NULL);
 
-       for (i = 0; i < array->len; i++)
-               camel_store_summary_info_unref (summary, array->pdata[i]);
-
-       g_ptr_array_free (array, TRUE);
+       g_ptr_array_foreach (array, (GFunc) camel_store_info_unref, NULL);
+       g_ptr_array_unref (array);
 }
 
 /**
@@ -399,9 +384,9 @@ camel_store_summary_array_free (CamelStoreSummary *summary,
  * Retrieve a summary item by path name.
  *
  * The returned #CamelStoreInfo is referenced for thread-safety and should be
- * unreferenced with camel_store_summary_info_unref() when finished with it.
+ * unreferenced with camel_store_info_unref() when finished with it.
  *
- * Returns: (nullable): the summary item, or %NULL if the @path name is not
+ * Returns: (nullable) (transfer full): the summary item, or %NULL if the @path name is not
  * available
  **/
 CamelStoreInfo *
@@ -418,7 +403,7 @@ camel_store_summary_path (CamelStoreSummary *summary,
        info = g_hash_table_lookup (summary->priv->folders_path, path);
 
        if (info != NULL)
-               camel_store_summary_info_ref (summary, info);
+               camel_store_info_ref (info);
 
        g_rec_mutex_unlock (&summary->priv->summary_lock);
 
@@ -555,7 +540,7 @@ camel_store_summary_save (CamelStoreSummary *summary)
 
        count = summary->priv->folders->len;
        for (i = 0; i < count; i++) {
-               info = summary->priv->folders->pdata[i];
+               info = g_ptr_array_index (summary->priv->folders, i);
                class->store_info_save (summary, out, info);
        }
 
@@ -579,7 +564,7 @@ camel_store_summary_save (CamelStoreSummary *summary)
 /**
  * camel_store_summary_add:
  * @summary: a #CamelStoreSummary object
- * @info: a #CamelStoreInfo
+ * @info: (transfer full): a #CamelStoreInfo
  *
  * The @info record should have been generated by calling one of the
  * info_new_*() functions, as it will be free'd based on the summary
@@ -594,7 +579,7 @@ camel_store_summary_add (CamelStoreSummary *summary,
        if (info == NULL)
                return;
 
-       if (camel_store_info_path (summary, info) == NULL) {
+       if (camel_store_info_get_path (info) == NULL) {
                g_warning ("Trying to add a folder info with missing required path name\n");
                return;
        }
@@ -602,20 +587,20 @@ camel_store_summary_add (CamelStoreSummary *summary,
        g_rec_mutex_lock (&summary->priv->summary_lock);
 
        g_ptr_array_add (summary->priv->folders, info);
-       g_hash_table_insert (summary->priv->folders_path, (gchar *) camel_store_info_path (summary, info), 
info);
+       g_hash_table_insert (summary->priv->folders_path, (gchar *) camel_store_info_get_path (info), info);
        summary->priv->dirty = TRUE;
 
        g_rec_mutex_unlock (&summary->priv->summary_lock);
 }
 
 /**
- * camel_store_summary_add_from_path: (skip)
+ * camel_store_summary_add_from_path:
  * @summary: a #CamelStoreSummary object
  * @path: item path
  *
  * Build a new info record based on the name, and add it to the summary.
  *
- * Returns: (transfer none): the newly added record
+ * Returns: (transfer none) (nullable): the newly added record or %NULL if the @path already exists
  **/
 CamelStoreInfo *
 camel_store_summary_add_from_path (CamelStoreSummary *summary,
@@ -642,7 +627,7 @@ camel_store_summary_add_from_path (CamelStoreSummary *summary,
                info = class->store_info_new (summary, path);
 
                g_ptr_array_add (summary->priv->folders, info);
-               g_hash_table_insert (summary->priv->folders_path, (gchar *) camel_store_info_path (summary, 
info), info);
+               g_hash_table_insert (summary->priv->folders_path, (gchar *) camel_store_info_get_path (info), 
info);
                summary->priv->dirty = TRUE;
        }
 
@@ -659,6 +644,8 @@ camel_store_summary_add_from_path (CamelStoreSummary *summary,
  * Add an extra reference to @info.
  *
  * Returns: (transfer full): the @info argument
+ *
+ * Deprecated: 3.44: Use camel_store_info_ref() instead.
  **/
 CamelStoreInfo *
 camel_store_summary_info_ref (CamelStoreSummary *summary,
@@ -667,9 +654,7 @@ camel_store_summary_info_ref (CamelStoreSummary *summary,
        g_return_val_if_fail (info != NULL, NULL);
        g_return_val_if_fail (info->refcount > 0, NULL);
 
-       g_atomic_int_inc (&info->refcount);
-
-       return info;
+       return camel_store_info_ref (info);
 }
 
 /**
@@ -678,6 +663,8 @@ camel_store_summary_info_ref (CamelStoreSummary *summary,
  * @info: (transfer full): a #CamelStoreInfo
  *
  * Unref and potentially free @info, and all associated memory.
+ *
+ * Deprecated: 3.44: Use camel_store_info_unref() instead.
  **/
 void
 camel_store_summary_info_unref (CamelStoreSummary *summary,
@@ -687,15 +674,7 @@ camel_store_summary_info_unref (CamelStoreSummary *summary,
        g_return_if_fail (info != NULL);
        g_return_if_fail (info->refcount > 0);
 
-       if (g_atomic_int_dec_and_test (&info->refcount)) {
-               CamelStoreSummaryClass *class;
-
-               class = CAMEL_STORE_SUMMARY_GET_CLASS (summary);
-               g_return_if_fail (class != NULL);
-               g_return_if_fail (class->store_info_free != NULL);
-
-               class->store_info_free (summary, info);
-       }
+       camel_store_info_unref (info);
 }
 
 /**
@@ -730,12 +709,10 @@ camel_store_summary_remove (CamelStoreSummary *summary,
        g_return_if_fail (info != NULL);
 
        g_rec_mutex_lock (&summary->priv->summary_lock);
-       g_hash_table_remove (summary->priv->folders_path, camel_store_info_path (summary, info));
+       g_hash_table_remove (summary->priv->folders_path, camel_store_info_get_path (info));
        g_ptr_array_remove (summary->priv->folders, info);
        summary->priv->dirty = TRUE;
        g_rec_mutex_unlock (&summary->priv->summary_lock);
-
-       camel_store_summary_info_unref (summary, info);
 }
 
 /**
@@ -758,17 +735,17 @@ camel_store_summary_remove_path (CamelStoreSummary *summary,
        g_rec_mutex_lock (&summary->priv->summary_lock);
        if (g_hash_table_lookup_extended (summary->priv->folders_path, path, (gpointer) &oldpath, (gpointer) 
&oldinfo)) {
                /* make sure it doesn't vanish while we're removing it */
-               camel_store_summary_info_ref (summary, oldinfo);
+               camel_store_info_ref (oldinfo);
                g_rec_mutex_unlock (&summary->priv->summary_lock);
                camel_store_summary_remove (summary, oldinfo);
-               camel_store_summary_info_unref (summary, oldinfo);
+               camel_store_info_unref (oldinfo);
        } else {
                g_rec_mutex_unlock (&summary->priv->summary_lock);
        }
 }
 
 /**
- * camel_store_summary_info_new: (skip)
+ * camel_store_summary_info_new:
  * @summary: a #CamelStoreSummary object
  *
  * Allocate a new #CamelStoreInfo, suitable for adding to this
@@ -789,11 +766,41 @@ camel_store_summary_info_new (CamelStoreSummary *summary)
        g_return_val_if_fail (class->store_info_size > 0, NULL);
 
        info = g_slice_alloc0 (class->store_info_size);
+       info->summary = summary;
        info->refcount = 1;
 
        return info;
 }
 
+/**
+ * camel_store_info_set_value:
+ * @info: a #CamelStoreInfo
+ * @type: specific string being set
+ * @value: string value to set
+ *
+ * Set a specific string on the @info.
+ **/
+void
+camel_store_info_set_value (CamelStoreInfo *info,
+                            gint type,
+                            const gchar *value)
+{
+       CamelStoreSummaryClass *class;
+
+       g_return_if_fail (info != NULL);
+       g_return_if_fail (CAMEL_IS_STORE_SUMMARY (info->summary));
+
+       class = CAMEL_STORE_SUMMARY_GET_CLASS (info->summary);
+       g_return_if_fail (class != NULL);
+       g_return_if_fail (class->store_info_set_string != NULL);
+
+       g_rec_mutex_lock (&info->summary->priv->summary_lock);
+
+       class->store_info_set_string (info->summary, info, type, value);
+
+       g_rec_mutex_unlock (&info->summary->priv->summary_lock);
+}
+
 /**
  * camel_store_info_set_string:
  * @summary: a #CamelStoreSummary object
@@ -802,6 +809,8 @@ camel_store_summary_info_new (CamelStoreSummary *summary)
  * @value: string value to set
  *
  * Set a specific string on the @info.
+ *
+ * Deprecated: 3.44: Use camel_store_info_set_value() instead.
  **/
 void
 camel_store_info_set_string (CamelStoreSummary *summary,
@@ -825,6 +834,85 @@ camel_store_info_set_string (CamelStoreSummary *summary,
        g_rec_mutex_unlock (&summary->priv->summary_lock);
 }
 
+
+/**
+ * camel_store_info_ref:
+ * @info: a #CamelStoreInfo
+ *
+ * Increase the reference count of @info.
+ *
+ * Returns: (transfer full): the @info argument
+ **/
+CamelStoreInfo *
+camel_store_info_ref (CamelStoreInfo *info)
+{
+       g_return_val_if_fail (info != NULL, NULL);
+       g_return_val_if_fail (info->refcount > 0, NULL);
+
+       g_atomic_int_inc (&info->refcount);
+
+       return info;
+}
+
+/**
+ * camel_store_info_unref:
+ * @info: a #CamelStoreInfo
+ *
+ * Unref and potentially free @info, and all associated memory.
+ **/
+void
+camel_store_info_unref (CamelStoreInfo *info)
+{
+       g_return_if_fail (info != NULL);
+       g_return_if_fail (info->refcount > 0);
+
+       if (g_atomic_int_dec_and_test (&info->refcount)) {
+               CamelStoreSummaryClass *class;
+
+               class = CAMEL_STORE_SUMMARY_GET_CLASS (info->summary);
+               g_return_if_fail (class != NULL);
+               g_return_if_fail (class->store_info_free != NULL);
+
+               class->store_info_free (info->summary, info);
+       }
+}
+
+/**
+ * camel_store_info_get_path:
+ * @info: a #CamelStoreInfo
+ *
+ * Returns the path string from @info.
+ *
+ * Returns: the path string from @info
+ **/
+const gchar *
+camel_store_info_get_path (CamelStoreInfo *info)
+{
+       g_return_val_if_fail (info != NULL, NULL);
+
+       return info->path;
+}
+
+/**
+ * camel_store_info_get_name:
+ * @info: a #CamelStoreInfo
+ *
+ * Returns the last segment of the path string from @info.
+ *
+ * Returns: the last segment of the path string from @info
+ **/
+const gchar *
+camel_store_info_get_name (CamelStoreInfo *info)
+{
+       const gchar *cp;
+
+       g_return_val_if_fail (info != NULL, NULL);
+
+       cp = strrchr (info->path, '/');
+
+       return (cp != NULL) ? cp + 1 : info->path;
+}
+
 /**
  * camel_store_info_path:
  * @summary: a #CamelStoreSummary
@@ -833,6 +921,8 @@ camel_store_info_set_string (CamelStoreSummary *summary,
  * Returns the path string from @info.
  *
  * Returns: the path string from @info
+ *
+ * Deprecated: 3.44: Use camel_store_info_get_path() instead.
  **/
 const gchar *
 camel_store_info_path (CamelStoreSummary *summary,
@@ -842,7 +932,7 @@ camel_store_info_path (CamelStoreSummary *summary,
        g_return_val_if_fail (info != NULL, NULL);
 
        /* XXX Not thread-safe; should return a duplicate. */
-       return info->path;
+       return camel_store_info_get_path (info);
 }
 
 /**
@@ -853,20 +943,18 @@ camel_store_info_path (CamelStoreSummary *summary,
  * Returns the last segment of the path string from @info.
  *
  * Returns: the last segment of the path string from @info
+ *
+ * Deprecated: 3.44: Use camel_store_info_get_name() instead.
  **/
 const gchar *
 camel_store_info_name (CamelStoreSummary *summary,
                        CamelStoreInfo *info)
 {
-       const gchar *cp;
-
        g_return_val_if_fail (CAMEL_IS_STORE_SUMMARY (summary), NULL);
        g_return_val_if_fail (info != NULL, NULL);
 
-       cp = strrchr (info->path, '/');
-
        /* XXX Not thread-safe; should return a duplicate. */
-       return (cp != NULL) ? cp + 1 : info->path;
+       return camel_store_info_get_name (info);
 }
 
 /**
diff --git a/src/camel/camel-store-summary.h b/src/camel/camel-store-summary.h
index 247439e9e..91ac58ab8 100644
--- a/src/camel/camel-store-summary.h
+++ b/src/camel/camel-store-summary.h
@@ -67,6 +67,7 @@ enum {
 
 struct _CamelStoreInfo {
        volatile gint refcount;
+       CamelStoreSummary *summary;
        gchar *path;
        guint32 flags;
        guint32 unread;
@@ -162,11 +163,19 @@ GPtrArray *       camel_store_summary_array       (CamelStoreSummary *summary);
 void           camel_store_summary_array_free  (CamelStoreSummary *summary,
                                                 GPtrArray *array);
 
+GType          camel_store_info_get_type       (void) G_GNUC_CONST;
+CamelStoreInfo *
+               camel_store_info_ref            (CamelStoreInfo *info);
+void           camel_store_info_unref          (CamelStoreInfo *info);
+void           camel_store_info_set_value      (CamelStoreInfo *info,
+                                                gint type,
+                                                const gchar *value);
+const gchar *  camel_store_info_get_path       (CamelStoreInfo *info);
+const gchar *  camel_store_info_get_name       (CamelStoreInfo *info);
 void           camel_store_info_set_string     (CamelStoreSummary *summary,
                                                 CamelStoreInfo *info,
                                                 gint type,
                                                 const gchar *value);
-
 const gchar *  camel_store_info_path           (CamelStoreSummary *summary,
                                                 CamelStoreInfo *info);
 const gchar *  camel_store_info_name           (CamelStoreSummary *summary,


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