[gimp] libgimpconfig: port GimpConfigWriter to GIO



commit 53b5822926bf93cbc30c181ee9c5916c3ac21034
Author: Michael Natterer <mitch gimp org>
Date:   Wed Jul 2 23:53:57 2014 +0200

    libgimpconfig: port GimpConfigWriter to GIO

 libgimpconfig/Makefile.am        |   14 ++-
 libgimpconfig/gimpconfigwriter.c |  263 ++++++++++++++++----------------------
 2 files changed, 120 insertions(+), 157 deletions(-)
---
diff --git a/libgimpconfig/Makefile.am b/libgimpconfig/Makefile.am
index a6f2f43..0b0d61d 100644
--- a/libgimpconfig/Makefile.am
+++ b/libgimpconfig/Makefile.am
@@ -47,6 +47,8 @@ AM_CPPFLAGS = \
        -DG_LOG_DOMAIN=\"LibGimpConfig\"        \
        -DGIMP_CONFIG_COMPILATION               \
        -I$(top_srcdir)                         \
+       $(GIO_UNIX_CFLAGS)                      \
+       $(GIO_WINDOWS_CFLAGS)                   \
        $(GEGL_CFLAGS)                          \
        $(CAIRO_CFLAGS)                         \
        $(GDK_PIXBUF_CFLAGS)                    \
@@ -113,11 +115,13 @@ libgimpconfig_ GIMP_API_VERSION@_la_LDFLAGS = \
 EXTRA_libgimpconfig_ GIMP_API_VERSION@_la_DEPENDENCIES = $(gimpconfig_def)
 
 libgimpconfig_ GIMP_API_VERSION@_la_LIBADD = \
-       $(libgimpbase)  \
-       $(libgimpcolor) \
-       $(libgimpmath)  \
-       $(GEGL_LIBS)    \
-       $(CAIRO_LIBS)   \
+       $(libgimpbase)          \
+       $(libgimpcolor)         \
+       $(libgimpmath)          \
+       $(GIO_UNIX_LIBS)        \
+       $(GIO_WINDOWS_LIBS)     \
+       $(GEGL_LIBS)            \
+       $(CAIRO_LIBS)           \
        $(GDK_PIXBUF_LIBS)
 
 
diff --git a/libgimpconfig/gimpconfigwriter.c b/libgimpconfig/gimpconfigwriter.c
index 6aaafeb..d5f3cf5 100644
--- a/libgimpconfig/gimpconfigwriter.c
+++ b/libgimpconfig/gimpconfigwriter.c
@@ -21,21 +21,14 @@
 
 #include "config.h"
 
-#include <errno.h>
-#include <fcntl.h>
 #include <string.h>
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <sys/types.h>
-
 #include <gio/gio.h>
-#include <glib/gstdio.h>
 
 #ifdef G_OS_WIN32
-#include <io.h>
+#include <gio/gwin32outputstream.h>
+#else
+#include <gio/gunixoutputstream.h>
 #endif
 
 #include "libgimpbase/gimpbase.h"
@@ -63,14 +56,13 @@
 
 struct _GimpConfigWriter
 {
-  gint      fd;
-  gchar    *filename;
-  gchar    *tmpname;
-  GError   *error;
-  GString  *buffer;
-  gboolean  comment;
-  gint      depth;
-  gint      marker;
+  GOutputStream *output;
+  GFile         *file;
+  GError        *error;
+  GString       *buffer;
+  gboolean       comment;
+  gint           depth;
+  gint           marker;
 };
 
 
@@ -82,10 +74,27 @@ static gboolean     gimp_config_writer_close_file (GimpConfigWriter  *writer,
 static inline void
 gimp_config_writer_flush (GimpConfigWriter *writer)
 {
-  if (write (writer->fd, writer->buffer->str, writer->buffer->len) < 0)
-    g_set_error (&writer->error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
-                 _("Error writing to '%s': %s"),
-                 gimp_filename_to_utf8 (writer->filename), g_strerror (errno));
+  gsize   bytes_written;
+  GError *error = NULL;
+
+  if (! g_output_stream_write_all (writer->output,
+                                   writer->buffer->str,
+                                   writer->buffer->len,
+                                   &bytes_written,
+                                   NULL, &error))
+    {
+      const gchar *path;
+
+      if (writer->file)
+        path = gimp_file_get_utf8_name (writer->file);
+      else
+        path = "file descriptor";
+
+      g_set_error (&writer->error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
+                   _("Error writing to '%s': %s"),
+                   path, error->message);
+      g_clear_error (&error);
+    }
 
   g_string_truncate (writer->buffer, 0);
 }
@@ -127,52 +136,16 @@ gimp_config_writer_new_file (const gchar  *filename,
                              GError      **error)
 {
   GimpConfigWriter *writer;
-  gchar            *tmpname = NULL;
-  gint              fd;
+  GFile            *file;
 
   g_return_val_if_fail (filename != NULL, NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  if (atomic)
-    {
-      tmpname = g_strconcat (filename, "XXXXXX", NULL);
-
-      fd = g_mkstemp (tmpname);
+  file = g_file_new_for_path (filename);
 
-      if (fd == -1)
-        {
-          g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
-                       _("Could not create temporary file for '%s': %s"),
-                       gimp_filename_to_utf8 (filename), g_strerror (errno));
-          g_free (tmpname);
-          return NULL;
-        }
-    }
-  else
-    {
-      fd = g_creat (filename, 0644);
+  writer = gimp_config_writer_new_gfile (file, atomic, header, error);
 
-      if (fd == -1)
-        {
-          g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
-                       _("Could not open '%s' for writing: %s"),
-                       gimp_filename_to_utf8 (filename), g_strerror (errno));
-          return NULL;
-        }
-    }
-
-  writer = g_slice_new0 (GimpConfigWriter);
-
-  writer->fd       = fd;
-  writer->filename = g_strdup (filename);
-  writer->tmpname  = tmpname;
-  writer->buffer   = g_string_new (NULL);
-
-  if (header)
-    {
-      gimp_config_writer_comment (writer, header);
-      gimp_config_writer_linefeed (writer);
-    }
+  g_object_unref (file);
 
   return writer;
 }
@@ -200,15 +173,50 @@ gimp_config_writer_new_gfile (GFile        *file,
                               GError      **error)
 {
   GimpConfigWriter *writer;
-  gchar            *path;
+  GOutputStream    *output;
+  GError           *my_error = NULL;
 
   g_return_val_if_fail (G_IS_FILE (file), NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
-  path = g_file_get_path (file);
+  if (atomic)
+    {
+      output = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE,
+                                                G_FILE_CREATE_NONE,
+                                                NULL, &my_error));
+      if (! output)
+        g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
+                     _("Could not create temporary file for '%s': %s"),
+                     gimp_file_get_utf8_name (file), my_error->message);
+    }
+  else
+    {
+      output = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE,
+                                                G_FILE_CREATE_REPLACE_DESTINATION,
+                                                NULL, &my_error));
+      if (! output)
+        g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
+                     _("Could not open '%s' for writing: %s"),
+                     gimp_file_get_utf8_name (file), my_error->message);
+    }
 
-  writer = gimp_config_writer_new_file (path, atomic, header, error);
+  if (! output)
+    {
+      g_clear_error (&my_error);
+      return NULL;
+    }
 
-  g_free (path);
+  writer = g_slice_new0 (GimpConfigWriter);
+
+  writer->output = output;
+  writer->file   = g_object_ref (file);
+  writer->buffer = g_string_new (NULL);
+
+  if (header)
+    {
+      gimp_config_writer_comment (writer, header);
+      gimp_config_writer_linefeed (writer);
+    }
 
   return writer;
 }
@@ -230,7 +238,12 @@ gimp_config_writer_new_fd (gint fd)
 
   writer = g_slice_new0 (GimpConfigWriter);
 
-  writer->fd     = fd;
+#ifdef G_OS_WIN32
+  writer->output = g_win32_input_stream_new ((HANDLE *) fd, FALSE);
+#else
+  writer->output = g_unix_output_stream_new (fd, FALSE);
+#endif
+
   writer->buffer = g_string_new (NULL);
 
   return writer;
@@ -529,7 +542,7 @@ gimp_config_writer_close (GimpConfigWriter *writer)
     {
       g_string_append_c (writer->buffer, '\n');
 
-      if (writer->fd)
+      if (writer->output)
         gimp_config_writer_flush (writer);
     }
 }
@@ -576,19 +589,15 @@ gimp_config_writer_finish (GimpConfigWriter  *writer,
       gimp_config_writer_comment (writer, footer);
     }
 
-  if (writer->fd)
+  if (writer->output)
     {
       success = gimp_config_writer_close_file (writer, error);
 
-      g_free (writer->filename);
-      g_free (writer->tmpname);
+      if (writer->file)
+        g_object_unref (writer->file);
 
       g_string_free (writer->buffer, TRUE);
     }
-  else
-    {
-      success = TRUE;
-    }
 
   if (writer->error)
     {
@@ -611,10 +620,18 @@ gimp_config_writer_linefeed (GimpConfigWriter *writer)
 
   if (writer->buffer->len == 0 && !writer->comment)
     {
-      if (write (writer->fd, "\n", 1) < 0)
-        g_set_error_literal (&writer->error,
-                            GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
-                            g_strerror (errno));
+      gsize   bytes_written;
+      GError *error = NULL;
+
+      if (! g_output_stream_write_all (writer->output, "\n", 1,
+                                       &bytes_written,
+                                       NULL, &error))
+        {
+          g_set_error (&writer->error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
+                       _("Error writing to '%s': %s"),
+                       gimp_file_get_utf8_name (writer->file), error->message);
+          g_clear_error (&error);
+        }
     }
   else
     {
@@ -695,93 +712,35 @@ static gboolean
 gimp_config_writer_close_file (GimpConfigWriter  *writer,
                                GError           **error)
 {
-  g_return_val_if_fail (writer->fd != 0, FALSE);
+  GError *my_error = NULL;
 
-  if (! writer->filename)
+  g_return_val_if_fail (writer->output != NULL, FALSE);
+
+  if (! writer->file)
     return TRUE;
 
   if (writer->error)
     {
-      close (writer->fd);
-
-      if (writer->tmpname)
-        g_unlink (writer->tmpname);
-
+      g_object_unref (writer->output);
+      writer->output = NULL;
       return FALSE;
     }
 
-#ifdef HAVE_FSYNC
-  /* If the final destination exists, we want to sync the newly written
-   * file to ensure the data is on disk when we rename over the destination.
-   * otherwise if we get a system crash we can lose both the new and the
-   * old file on some filesystems. (I.E. those that don't guarantee the
-   * data is written to the disk before the metadata.)
-   */
-  if (writer->tmpname && g_file_test (writer->filename, G_FILE_TEST_EXISTS))
+  if (! g_output_stream_close (writer->output, NULL, &my_error))
     {
-      if (fsync (writer->fd) != 0)
-        {
-          g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
-                       _("Error writing to temporary file for '%s': %s\n"
-                         "The original file has not been touched."),
-                       gimp_filename_to_utf8 (writer->filename),
-                       g_strerror (errno));
-
-          close (writer->fd);
-          g_unlink (writer->tmpname);
+      g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
+                   _("Error writing '%s': %s"),
+                   gimp_file_get_utf8_name (writer->file), my_error->message);
+      g_clear_error (&my_error);
 
-          return FALSE;
-        }
-    }
-#endif
-
-  if (close (writer->fd) != 0)
-    {
-      if (writer->tmpname)
-        {
-          if (g_file_test (writer->filename, G_FILE_TEST_EXISTS))
-            {
-              g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
-                           _("Error writing to temporary file for '%s': %s\n"
-                             "The original file has not been touched."),
-                           gimp_filename_to_utf8 (writer->filename),
-                           g_strerror (errno));
-            }
-          else
-            {
-              g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
-                           _("Error writing to temporary file for '%s': %s\n"
-                             "No file has been created."),
-                           gimp_filename_to_utf8 (writer->filename),
-                           g_strerror (errno));
-            }
-
-          g_unlink (writer->tmpname);
-        }
-      else
-        {
-          g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
-                       _("Error writing to '%s': %s"),
-                       gimp_filename_to_utf8 (writer->filename),
-                       g_strerror (errno));
-        }
+      g_object_unref (writer->output);
+      writer->output = NULL;
 
       return FALSE;
     }
 
-  if (writer->tmpname)
-    {
-      if (g_rename (writer->tmpname, writer->filename) == -1)
-        {
-          g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_WRITE,
-                       _("Could not create '%s': %s"),
-                       gimp_filename_to_utf8 (writer->filename),
-                       g_strerror (errno));
-
-          g_unlink (writer->tmpname);
-          return FALSE;
-        }
-    }
+  g_object_unref (writer->output);
+  writer->output = NULL;
 
   return TRUE;
 }


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