[gimp] libgimpconfig: make GimpConfigWriter a boxed type



commit f90e19091d79a2c3fe409d9bdb2d61abde05631a
Author: Michael Natterer <mitch gimp org>
Date:   Wed Aug 7 21:50:51 2019 +0200

    libgimpconfig: make GimpConfigWriter a boxed type

 libgimpconfig/gimpconfig.def     |   3 +
 libgimpconfig/gimpconfigwriter.c | 127 +++++++++++++++++++++++++++++++++------
 libgimpconfig/gimpconfigwriter.h |  16 +++++
 3 files changed, 126 insertions(+), 20 deletions(-)
---
diff --git a/libgimpconfig/gimpconfig.def b/libgimpconfig/gimpconfig.def
index 21dd67de31..1861758b0f 100644
--- a/libgimpconfig/gimpconfig.def
+++ b/libgimpconfig/gimpconfig.def
@@ -60,6 +60,7 @@ EXPORTS
        gimp_config_writer_comment_mode
        gimp_config_writer_data
        gimp_config_writer_finish
+       gimp_config_writer_get_type
        gimp_config_writer_identifier
        gimp_config_writer_linefeed
        gimp_config_writer_new_fd
@@ -70,8 +71,10 @@ EXPORTS
        gimp_config_writer_open
        gimp_config_writer_print
        gimp_config_writer_printf
+       gimp_config_writer_ref
        gimp_config_writer_revert
        gimp_config_writer_string
+       gimp_config_writer_unref
        gimp_file_get_config_path
        gimp_file_new_for_config_path
        gimp_param_config_path_get_type
diff --git a/libgimpconfig/gimpconfigwriter.c b/libgimpconfig/gimpconfigwriter.c
index 47b10b8fad..8fe906c2f5 100644
--- a/libgimpconfig/gimpconfigwriter.c
+++ b/libgimpconfig/gimpconfigwriter.c
@@ -56,6 +56,9 @@
 
 struct _GimpConfigWriter
 {
+  gint           ref_count;
+  gboolean       finished;
+
   GOutputStream *output;
   GFile         *file;
   GError        *error;
@@ -66,6 +69,10 @@ struct _GimpConfigWriter
 };
 
 
+G_DEFINE_BOXED_TYPE (GimpConfigWriter, gimp_config_writer,
+                     gimp_config_writer_ref, gimp_config_writer_unref)
+
+
 static inline void  gimp_config_writer_flush        (GimpConfigWriter  *writer);
 static inline void  gimp_config_writer_newline      (GimpConfigWriter  *writer);
 static gboolean     gimp_config_writer_close_output (GimpConfigWriter  *writer,
@@ -212,9 +219,10 @@ gimp_config_writer_new_gfile (GFile        *file,
 
   writer = g_slice_new0 (GimpConfigWriter);
 
-  writer->output = output;
-  writer->file   = g_object_ref (file);
-  writer->buffer = g_string_new (NULL);
+  writer->ref_count = 1;
+  writer->output    = output;
+  writer->file      = g_object_ref (file);
+  writer->buffer    = g_string_new (NULL);
 
   if (header)
     {
@@ -250,8 +258,9 @@ gimp_config_writer_new_stream (GOutputStream  *output,
 
   writer = g_slice_new0 (GimpConfigWriter);
 
-  writer->output = g_object_ref (output);
-  writer->buffer = g_string_new (NULL);
+  writer->ref_count = 1;
+  writer->output    = g_object_ref (output);
+  writer->buffer    = g_string_new (NULL);
 
   if (header)
     {
@@ -279,6 +288,8 @@ gimp_config_writer_new_fd (gint fd)
 
   writer = g_slice_new0 (GimpConfigWriter);
 
+  writer->ref_count = 1;
+
 #ifdef G_OS_WIN32
   writer->output = g_win32_output_stream_new ((gpointer) fd, FALSE);
 #else
@@ -307,11 +318,73 @@ gimp_config_writer_new_string (GString *string)
 
   writer = g_slice_new0 (GimpConfigWriter);
 
-  writer->buffer = string;
+  writer->ref_count = 1;
+  writer->buffer    = string;
 
   return writer;
 }
 
+/**
+ * gimp_config_writer_ref:
+ * @writer: #GimpConfigWriter to ref
+ *
+ * Adds a reference to a #GimpConfigWriter.
+ *
+ * Returns: the same @writer.
+ *
+ * Since: 3.0
+ */
+GimpConfigWriter *
+gimp_config_writer_ref (GimpConfigWriter *writer)
+{
+  g_return_val_if_fail (writer != NULL, NULL);
+
+  writer->ref_count++;
+
+  return writer;
+}
+
+/**
+ * gimp_config_writer_unref:
+ * @writer: #GimpConfigWriter to unref
+ *
+ * Unref a #GimpConfigWriter. If the reference count drops to zero, the
+ * array including its contents are freed.
+ *
+ * Note that at least one of the references has to be dropped using
+ * gimp_config_writer_finish().
+ *
+ * Since: 3.0
+ */
+void
+gimp_config_writer_unref (GimpConfigWriter *writer)
+{
+  g_return_if_fail (writer != NULL);
+
+  writer->ref_count--;
+
+  if (writer->ref_count < 1)
+    {
+      if (! writer->finished)
+        {
+          GError *error = NULL;
+
+          g_printerr ("%s: dropping last reference via unref(), you should "
+                      "call gimp_config_writer_finish()\n", G_STRFUNC);
+
+          if (! gimp_config_writer_finish (writer, NULL, &error))
+            {
+              g_printerr ("%s: error on finishing writer: %s\n",
+                          G_STRFUNC, error->message);
+            }
+        }
+      else
+        {
+          g_slice_free (GimpConfigWriter, writer);
+        }
+    }
+}
+
 /**
  * gimp_config_writer_comment_mode:
  * @writer: a #GimpConfigWriter
@@ -331,6 +404,7 @@ gimp_config_writer_comment_mode (GimpConfigWriter *writer,
                                  gboolean          enable)
 {
   g_return_if_fail (writer != NULL);
+  g_return_if_fail (writer->finished == FALSE);
 
   if (writer->error)
     return;
@@ -368,6 +442,7 @@ gimp_config_writer_open (GimpConfigWriter *writer,
                          const gchar      *name)
 {
   g_return_if_fail (writer != NULL);
+  g_return_if_fail (writer->finished == FALSE);
   g_return_if_fail (name != NULL);
 
   if (writer->error)
@@ -401,6 +476,7 @@ gimp_config_writer_print (GimpConfigWriter  *writer,
                           gint               len)
 {
   g_return_if_fail (writer != NULL);
+  g_return_if_fail (writer->finished == FALSE);
   g_return_if_fail (len == 0 || string != NULL);
 
   if (writer->error)
@@ -435,6 +511,7 @@ gimp_config_writer_printf (GimpConfigWriter *writer,
   va_list  args;
 
   g_return_if_fail (writer != NULL);
+  g_return_if_fail (writer->finished == FALSE);
   g_return_if_fail (format != NULL);
 
   if (writer->error)
@@ -465,6 +542,7 @@ gimp_config_writer_string (GimpConfigWriter *writer,
                            const gchar      *string)
 {
   g_return_if_fail (writer != NULL);
+  g_return_if_fail (writer->finished == FALSE);
 
   if (writer->error)
     return;
@@ -488,6 +566,7 @@ gimp_config_writer_identifier (GimpConfigWriter *writer,
                                const gchar      *identifier)
 {
   g_return_if_fail (writer != NULL);
+  g_return_if_fail (writer->finished == FALSE);
   g_return_if_fail (identifier != NULL);
 
   if (writer->error)
@@ -513,6 +592,7 @@ gimp_config_writer_data (GimpConfigWriter *writer,
   gint i;
 
   g_return_if_fail (writer != NULL);
+  g_return_if_fail (writer->finished == FALSE);
   g_return_if_fail (length >= 0);
   g_return_if_fail (data != NULL || length == 0);
 
@@ -546,6 +626,7 @@ void
 gimp_config_writer_revert (GimpConfigWriter *writer)
 {
   g_return_if_fail (writer != NULL);
+  g_return_if_fail (writer->finished == FALSE);
 
   if (writer->error)
     return;
@@ -571,6 +652,7 @@ void
 gimp_config_writer_close (GimpConfigWriter *writer)
 {
   g_return_if_fail (writer != NULL);
+  g_return_if_fail (writer->finished == FALSE);
 
   if (writer->error)
     return;
@@ -593,13 +675,16 @@ gimp_config_writer_close (GimpConfigWriter *writer)
  * @footer: text to include as comment at the bottom of the file
  * @error: return location for possible errors
  *
- * This function finishes the work of @writer and frees it afterwards.
- * It closes all open elements, appends an optional comment and
- * releases all resources allocated by @writer. You must not access
- * the @writer afterwards.
+ * This function finishes the work of @writer and unrefs it
+ * afterwards.  It closes all open elements, appends an optional
+ * comment and releases all resources allocated by @writer.
+ *
+ * Using any function except gimp_config_writer_ref() or
+ * gimp_config_writer_unref() after this function is forbidden
+ * and will trigger warnings.
  *
  * Returns: %TRUE if everything could be successfully written,
- *               %FALSE otherwise
+ *          %FALSE otherwise
  *
  * Since: 2.4
  **/
@@ -611,6 +696,7 @@ gimp_config_writer_finish (GimpConfigWriter  *writer,
   gboolean success = TRUE;
 
   g_return_val_if_fail (writer != NULL, FALSE);
+  g_return_val_if_fail (writer->finished == FALSE, FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
   if (writer->depth < 0)
@@ -633,10 +719,10 @@ gimp_config_writer_finish (GimpConfigWriter  *writer,
     {
       success = gimp_config_writer_close_output (writer, error);
 
-      if (writer->file)
-        g_object_unref (writer->file);
+      g_clear_object (&writer->file);
 
       g_string_free (writer->buffer, TRUE);
+      writer->buffer = NULL;
     }
 
   if (writer->error)
@@ -649,7 +735,9 @@ gimp_config_writer_finish (GimpConfigWriter  *writer,
       success = FALSE;
     }
 
-  g_slice_free (GimpConfigWriter, writer);
+  writer->finished = TRUE;
+
+  gimp_config_writer_unref (writer);
 
   return success;
 }
@@ -658,6 +746,7 @@ void
 gimp_config_writer_linefeed (GimpConfigWriter *writer)
 {
   g_return_if_fail (writer != NULL);
+  g_return_if_fail (writer->finished == FALSE);
 
   if (writer->error)
     return;
@@ -705,6 +794,7 @@ gimp_config_writer_comment (GimpConfigWriter *writer,
 #define LINE_LENGTH 75
 
   g_return_if_fail (writer != NULL);
+  g_return_if_fail (writer->finished == FALSE);
 
   if (writer->error)
     return;
@@ -767,8 +857,7 @@ gimp_config_writer_close_output (GimpConfigWriter  *writer,
       g_output_stream_close (writer->output, cancellable, NULL);
       g_object_unref (cancellable);
 
-      g_object_unref (writer->output);
-      writer->output = NULL;
+      g_clear_object (&writer->output);
 
       return FALSE;
     }
@@ -785,15 +874,13 @@ gimp_config_writer_close_output (GimpConfigWriter  *writer,
                        my_error->message);
           g_clear_error (&my_error);
 
-          g_object_unref (writer->output);
-          writer->output = NULL;
+          g_clear_object (&writer->output);
 
           return FALSE;
         }
     }
 
-  g_object_unref (writer->output);
-  writer->output = NULL;
+  g_clear_object (&writer->output);
 
   return TRUE;
 }
diff --git a/libgimpconfig/gimpconfigwriter.h b/libgimpconfig/gimpconfigwriter.h
index 91a1a10bc8..ab5905c2e9 100644
--- a/libgimpconfig/gimpconfigwriter.h
+++ b/libgimpconfig/gimpconfigwriter.h
@@ -27,6 +27,19 @@
 #define __GIMP_CONFIG_WRITER_H__
 
 
+/**
+ * GIMP_TYPE_CONFIG_WRITER:
+ *
+ * The type ID of the "GimpConfigWriter" type which is a boxed type,
+ * used to write config files.
+ *
+ * Since: 3.0
+ */
+#define GIMP_TYPE_CONFIG_WRITER (gimp_config_writer_get_type ())
+
+
+GType              gimp_config_writer_get_type     (void) G_GNUC_CONST;
+
 GimpConfigWriter * gimp_config_writer_new_file     (const gchar       *filename,
                                                     gboolean           atomic,
                                                     const gchar       *header,
@@ -41,6 +54,9 @@ GimpConfigWriter * gimp_config_writer_new_stream   (GOutputStream     *output,
 GimpConfigWriter * gimp_config_writer_new_fd       (gint               fd);
 GimpConfigWriter * gimp_config_writer_new_string   (GString           *string);
 
+GimpConfigWriter * gimp_config_writer_ref          (GimpConfigWriter  *writer);
+void               gimp_config_writer_unref        (GimpConfigWriter  *writer);
+
 void               gimp_config_writer_open         (GimpConfigWriter  *writer,
                                                     const gchar       *name);
 void               gimp_config_writer_comment_mode (GimpConfigWriter  *writer,


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