[tepl] Dumb FileSaver: remove all the implementation, UTF-8 only!



commit 58b9a5da064d41f877fdee443bf0af36ee843b42
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Mon May 11 20:06:41 2020 +0200

    Dumb FileSaver: remove all the implementation, UTF-8 only!
    
    The FileSaver will be made smarter again later, it is planned to use the
    libicu. First make it dumb, then it will be easier to re-add what is
    missing differently.
    
    Keep most of the TeplFileSaver API and docs, but remove all the
    implementation.

 docs/reference/tepl-sections.txt     |   2 -
 po/POTFILES.in                       |   1 -
 tepl/meson.build                     |   2 -
 tepl/tepl-buffer-input-stream.c      | 498 --------------------
 tepl/tepl-buffer-input-stream.h      |  54 ---
 tepl/tepl-file-saver.c               | 877 ++++-------------------------------
 tepl/tepl-file-saver.h               |  14 +-
 testsuite/meson.build                |   4 +-
 testsuite/test-buffer-input-stream.c | 135 ------
 testsuite/test-file-saver.c          | 801 --------------------------------
 10 files changed, 92 insertions(+), 2296 deletions(-)
---
diff --git a/docs/reference/tepl-sections.txt b/docs/reference/tepl-sections.txt
index 104bcbb..8a6860b 100644
--- a/docs/reference/tepl-sections.txt
+++ b/docs/reference/tepl-sections.txt
@@ -190,8 +190,6 @@ tepl_file_saver_new_with_target
 tepl_file_saver_get_buffer
 tepl_file_saver_get_file
 tepl_file_saver_get_location
-tepl_file_saver_set_encoding
-tepl_file_saver_get_encoding
 tepl_file_saver_set_newline_type
 tepl_file_saver_get_newline_type
 tepl_file_saver_set_compression_type
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5f13874..f339668 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -3,7 +3,6 @@ tepl/tepl-abstract-factory.c
 tepl/tepl-application.c
 tepl/tepl-application-window.c
 tepl/tepl-buffer.c
-tepl/tepl-buffer-input-stream.c
 tepl/tepl-close-confirm-dialog-single.c
 tepl/tepl-encoding.c
 tepl/tepl-encoding-converter.c
diff --git a/tepl/meson.build b/tepl/meson.build
index 998a588..f3ef0a4 100644
--- a/tepl/meson.build
+++ b/tepl/meson.build
@@ -61,7 +61,6 @@ tepl_public_c_files = [
 ]
 
 TEPL_PRIVATE_HEADERS = [
-  'tepl-buffer-input-stream.h',
   'tepl-close-confirm-dialog-single.h',
   'tepl-encoding-converter.h',
   'tepl-encoding-private.h',
@@ -79,7 +78,6 @@ TEPL_PRIVATE_HEADERS = [
 ]
 
 tepl_private_c_files = [
-  'tepl-buffer-input-stream.c',
   'tepl-close-confirm-dialog-single.c',
   'tepl-encoding-converter.c',
   'tepl-file-content.c',
diff --git a/tepl/tepl-file-saver.c b/tepl/tepl-file-saver.c
index e3a9fab..68c676a 100644
--- a/tepl/tepl-file-saver.c
+++ b/tepl/tepl-file-saver.c
@@ -1,20 +1,17 @@
 /* SPDX-FileCopyrightText: 2005-2007 - Paolo Borelli and Paolo Maggi
  * SPDX-FileCopyrightText: 2007 - Steve Frécinaux
  * SPDX-FileCopyrightText: 2008 - Jesse van den Kieboom
- * SPDX-FileCopyrightText: 2014, 2016, 2017 - Sébastien Wilmet
+ * SPDX-FileCopyrightText: 2014-2020 - Sébastien Wilmet
  * SPDX-License-Identifier: LGPL-3.0-or-later
  */
 
-#include "config.h"
 #include "tepl-file-saver.h"
-#include <glib/gi18n-lib.h>
-#include "tepl-buffer-input-stream.h"
 #include "tepl-enum-types.h"
 
 /**
  * SECTION:file-saver
- * @Short_description: Save a TeplBuffer into a file
  * @Title: TeplFileSaver
+ * @Short_description: Save a #TeplBuffer into a file
  * @See_also: #TeplFile, #TeplFileLoader
  *
  * A #TeplFileSaver object permits to save a #TeplBuffer into a #GFile.
@@ -22,24 +19,8 @@
  * A file saver should be used only for one save operation, including errors
  * handling. If an error occurs, you can reconfigure the saver and relaunch the
  * operation with tepl_file_saver_save_async().
- *
- * #TeplFileSaver is a fork of #GtkSourceFileSaver, the code has been a little
- * improved (but no major changes). See the description of #TeplFile for more
- * background on why a fork was needed.
- */
-
-/* The code has been written initially in gedit (GeditDocumentSaver).
- * It uses a TeplBufferInputStream as input, create converter(s) if needed
- * for the encoding and the compression, and write the contents to a
- * GOutputStream (the file).
  */
 
-#if 0
-#define DEBUG(x) (x)
-#else
-#define DEBUG(x)
-#endif
-
 #define WRITE_CHUNK_SIZE 8192
 
 enum
@@ -48,10 +29,10 @@ enum
        PROP_BUFFER,
        PROP_FILE,
        PROP_LOCATION,
-       PROP_ENCODING,
        PROP_NEWLINE_TYPE,
        PROP_COMPRESSION_TYPE,
-       PROP_FLAGS
+       PROP_FLAGS,
+       N_PROPERTIES
 };
 
 struct _TeplFileSaverPrivate
@@ -70,7 +51,6 @@ struct _TeplFileSaverPrivate
 
        GFile *location;
 
-       TeplEncoding *encoding;
        TeplNewlineType newline_type;
        TeplCompressionType compression_type;
        TeplFileSaverFlags flags;
@@ -81,41 +61,12 @@ struct _TeplFileSaverPrivate
 typedef struct _TaskData TaskData;
 struct _TaskData
 {
-       GFileOutputStream *file_output_stream;
-
-       /* The output_stream contains the file_output_stream, plus the required
-        * converter(s) for the encoding and the compression type.
-        * input_stream and output_stream cannot be spliced directly, because:
-        * (1) We need to call the progress callback.
-        * (2) Sync methods must be used for the input stream, and async
-        *     methods for the output stream.
-        */
-       TeplBufferInputStream *input_stream;
-       GOutputStream *output_stream;
-
-       goffset total_size;
-       GFileProgressCallback progress_cb;
-       gpointer progress_cb_data;
-       GDestroyNotify progress_cb_notify;
-
-       /* This field is used when cancelling the output stream: an error occurs
-        * and is stored in this field, the output stream is cancelled
-        * asynchronously, and then the error is reported to the task.
-        */
-       GError *error;
-
-       gssize chunk_bytes_read;
-       gssize chunk_bytes_written;
-       gchar chunk_buffer[WRITE_CHUNK_SIZE];
-
-       guint tried_mount : 1;
+       gint something;
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (TeplFileSaver, tepl_file_saver, G_TYPE_OBJECT)
+static GParamSpec *properties[N_PROPERTIES];
 
-static void read_file_chunk (GTask *task);
-static void write_file_chunk (GTask *task);
-static void recover_not_mounted (GTask *task);
+G_DEFINE_TYPE_WITH_PRIVATE (TeplFileSaver, tepl_file_saver, G_TYPE_OBJECT)
 
 static TaskData *
 task_data_new (void)
@@ -124,26 +75,9 @@ task_data_new (void)
 }
 
 static void
-task_data_free (gpointer data)
+task_data_free (TaskData *data)
 {
-       TaskData *task_data = data;
-
-       if (task_data == NULL)
-       {
-               return;
-       }
-
-       g_clear_object (&task_data->file_output_stream);
-       g_clear_object (&task_data->input_stream);
-       g_clear_object (&task_data->output_stream);
-       g_clear_error (&task_data->error);
-
-       if (task_data->progress_cb_notify != NULL)
-       {
-               task_data->progress_cb_notify (task_data->progress_cb_data);
-       }
-
-       g_free (task_data);
+       g_free (data);
 }
 
 static void
@@ -158,16 +92,12 @@ tepl_file_saver_set_property (GObject      *object,
        {
                case PROP_BUFFER:
                        g_assert (saver->priv->source_buffer == NULL);
-                       saver->priv->source_buffer = g_value_get_object (value);
-                       g_object_add_weak_pointer (G_OBJECT (saver->priv->source_buffer),
-                                                  (gpointer *)&saver->priv->source_buffer);
+                       g_set_weak_pointer (&saver->priv->source_buffer, g_value_get_object (value));
                        break;
 
                case PROP_FILE:
                        g_assert (saver->priv->file == NULL);
-                       saver->priv->file = g_value_get_object (value);
-                       g_object_add_weak_pointer (G_OBJECT (saver->priv->file),
-                                                  (gpointer *)&saver->priv->file);
+                       g_set_weak_pointer (&saver->priv->file, g_value_get_object (value));
                        break;
 
                case PROP_LOCATION:
@@ -175,10 +105,6 @@ tepl_file_saver_set_property (GObject      *object,
                        saver->priv->location = g_value_dup_object (value);
                        break;
 
-               case PROP_ENCODING:
-                       tepl_file_saver_set_encoding (saver, g_value_get_boxed (value));
-                       break;
-
                case PROP_NEWLINE_TYPE:
                        tepl_file_saver_set_newline_type (saver, g_value_get_enum (value));
                        break;
@@ -219,10 +145,6 @@ tepl_file_saver_get_property (GObject    *object,
                        g_value_set_object (value, saver->priv->location);
                        break;
 
-               case PROP_ENCODING:
-                       g_value_set_boxed (value, saver->priv->encoding);
-                       break;
-
                case PROP_NEWLINE_TYPE:
                        g_value_set_enum (value, saver->priv->newline_type);
                        break;
@@ -241,43 +163,6 @@ tepl_file_saver_get_property (GObject    *object,
        }
 }
 
-static void
-tepl_file_saver_dispose (GObject *object)
-{
-       TeplFileSaver *saver = TEPL_FILE_SAVER (object);
-
-       if (saver->priv->source_buffer != NULL)
-       {
-               g_object_remove_weak_pointer (G_OBJECT (saver->priv->source_buffer),
-                                             (gpointer *)&saver->priv->source_buffer);
-
-               saver->priv->source_buffer = NULL;
-       }
-
-       if (saver->priv->file != NULL)
-       {
-               g_object_remove_weak_pointer (G_OBJECT (saver->priv->file),
-                                             (gpointer *)&saver->priv->file);
-
-               saver->priv->file = NULL;
-       }
-
-       g_clear_object (&saver->priv->location);
-       g_clear_object (&saver->priv->task);
-
-       G_OBJECT_CLASS (tepl_file_saver_parent_class)->dispose (object);
-}
-
-static void
-tepl_file_saver_finalize (GObject *object)
-{
-       TeplFileSaver *saver = TEPL_FILE_SAVER (object);
-
-       tepl_encoding_free (saver->priv->encoding);
-
-       G_OBJECT_CLASS (tepl_file_saver_parent_class)->finalize (object);
-}
-
 static void
 tepl_file_saver_constructed (GObject *object)
 {
@@ -285,13 +170,9 @@ tepl_file_saver_constructed (GObject *object)
 
        if (saver->priv->file != NULL)
        {
-               const TeplEncoding *encoding;
                TeplNewlineType newline_type;
                TeplCompressionType compression_type;
 
-               encoding = tepl_file_get_encoding (saver->priv->file);
-               tepl_file_saver_set_encoding (saver, encoding);
-
                newline_type = tepl_file_get_newline_type (saver->priv->file);
                tepl_file_saver_set_newline_type (saver, newline_type);
 
@@ -317,16 +198,28 @@ tepl_file_saver_constructed (GObject *object)
        G_OBJECT_CLASS (tepl_file_saver_parent_class)->constructed (object);
 }
 
+static void
+tepl_file_saver_dispose (GObject *object)
+{
+       TeplFileSaver *saver = TEPL_FILE_SAVER (object);
+
+       g_clear_weak_pointer (&saver->priv->source_buffer);
+       g_clear_weak_pointer (&saver->priv->file);
+       g_clear_object (&saver->priv->location);
+       g_clear_object (&saver->priv->task);
+
+       G_OBJECT_CLASS (tepl_file_saver_parent_class)->dispose (object);
+}
+
 static void
 tepl_file_saver_class_init (TeplFileSaverClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-       object_class->dispose = tepl_file_saver_dispose;
-       object_class->finalize = tepl_file_saver_finalize;
        object_class->set_property = tepl_file_saver_set_property;
        object_class->get_property = tepl_file_saver_get_property;
        object_class->constructed = tepl_file_saver_constructed;
+       object_class->dispose = tepl_file_saver_dispose;
 
        /**
         * TeplFileSaver:buffer:
@@ -336,33 +229,31 @@ tepl_file_saver_class_init (TeplFileSaverClass *klass)
         *
         * Since: 1.0
         */
-       g_object_class_install_property (object_class,
-                                        PROP_BUFFER,
-                                        g_param_spec_object ("buffer",
-                                                             "TeplBuffer",
-                                                             "",
-                                                             GTK_SOURCE_TYPE_BUFFER,
-                                                             G_PARAM_READWRITE |
-                                                             G_PARAM_CONSTRUCT_ONLY |
-                                                             G_PARAM_STATIC_STRINGS));
+       properties[PROP_BUFFER] =
+               g_param_spec_object ("buffer",
+                                    "buffer",
+                                    "",
+                                    GTK_SOURCE_TYPE_BUFFER,
+                                    G_PARAM_READWRITE |
+                                    G_PARAM_CONSTRUCT_ONLY |
+                                    G_PARAM_STATIC_STRINGS);
 
        /**
         * TeplFileSaver:file:
         *
-        * The #TeplFile. The #TeplFileSaver object has a weak
-        * reference to the file.
+        * The #TeplFile. The #TeplFileSaver object has a weak reference to the
+        * file.
         *
         * Since: 1.0
         */
-       g_object_class_install_property (object_class,
-                                        PROP_FILE,
-                                        g_param_spec_object ("file",
-                                                             "TeplFile",
-                                                             "",
-                                                             TEPL_TYPE_FILE,
-                                                             G_PARAM_READWRITE |
-                                                             G_PARAM_CONSTRUCT_ONLY |
-                                                             G_PARAM_STATIC_STRINGS));
+       properties[PROP_FILE] =
+               g_param_spec_object ("file",
+                                    "file",
+                                    "",
+                                    TEPL_TYPE_FILE,
+                                    G_PARAM_READWRITE |
+                                    G_PARAM_CONSTRUCT_ONLY |
+                                    G_PARAM_STATIC_STRINGS);
 
        /**
         * TeplFileSaver:location:
@@ -372,32 +263,14 @@ tepl_file_saver_class_init (TeplFileSaverClass *klass)
         *
         * Since: 1.0
         */
-       g_object_class_install_property (object_class,
-                                        PROP_LOCATION,
-                                        g_param_spec_object ("location",
-                                                             "Location",
-                                                             "",
-                                                             G_TYPE_FILE,
-                                                             G_PARAM_READWRITE |
-                                                             G_PARAM_CONSTRUCT_ONLY |
-                                                             G_PARAM_STATIC_STRINGS));
-
-       /**
-        * TeplFileSaver:encoding:
-        *
-        * The file's encoding.
-        *
-        * Since: 1.0
-        */
-       g_object_class_install_property (object_class,
-                                        PROP_ENCODING,
-                                        g_param_spec_boxed ("encoding",
-                                                            "Encoding",
-                                                            "",
-                                                            TEPL_TYPE_ENCODING,
-                                                            G_PARAM_READWRITE |
-                                                            G_PARAM_CONSTRUCT |
-                                                            G_PARAM_STATIC_STRINGS));
+       properties[PROP_LOCATION] =
+               g_param_spec_object ("location",
+                                    "location",
+                                    "",
+                                    G_TYPE_FILE,
+                                    G_PARAM_READWRITE |
+                                    G_PARAM_CONSTRUCT_ONLY |
+                                    G_PARAM_STATIC_STRINGS);
 
        /**
         * TeplFileSaver:newline-type:
@@ -406,16 +279,15 @@ tepl_file_saver_class_init (TeplFileSaverClass *klass)
         *
         * Since: 1.0
         */
-       g_object_class_install_property (object_class,
-                                        PROP_NEWLINE_TYPE,
-                                        g_param_spec_enum ("newline-type",
-                                                           "Newline type",
-                                                           "",
-                                                           GTK_SOURCE_TYPE_NEWLINE_TYPE,
-                                                           TEPL_NEWLINE_TYPE_LF,
-                                                           G_PARAM_READWRITE |
-                                                           G_PARAM_CONSTRUCT |
-                                                           G_PARAM_STATIC_STRINGS));
+       properties[PROP_NEWLINE_TYPE] =
+               g_param_spec_enum ("newline-type",
+                                  "newline-type",
+                                  "",
+                                  GTK_SOURCE_TYPE_NEWLINE_TYPE,
+                                  TEPL_NEWLINE_TYPE_LF,
+                                  G_PARAM_READWRITE |
+                                  G_PARAM_CONSTRUCT |
+                                  G_PARAM_STATIC_STRINGS);
 
        /**
         * TeplFileSaver:compression-type:
@@ -424,16 +296,15 @@ tepl_file_saver_class_init (TeplFileSaverClass *klass)
         *
         * Since: 1.0
         */
-       g_object_class_install_property (object_class,
-                                        PROP_COMPRESSION_TYPE,
-                                        g_param_spec_enum ("compression-type",
-                                                           "Compression type",
-                                                           "",
-                                                           GTK_SOURCE_TYPE_COMPRESSION_TYPE,
-                                                           TEPL_COMPRESSION_TYPE_NONE,
-                                                           G_PARAM_READWRITE |
-                                                           G_PARAM_CONSTRUCT |
-                                                           G_PARAM_STATIC_STRINGS));
+       properties[PROP_COMPRESSION_TYPE] =
+               g_param_spec_enum ("compression-type",
+                                  "compression-type",
+                                  "",
+                                  GTK_SOURCE_TYPE_COMPRESSION_TYPE,
+                                  TEPL_COMPRESSION_TYPE_NONE,
+                                  G_PARAM_READWRITE |
+                                  G_PARAM_CONSTRUCT |
+                                  G_PARAM_STATIC_STRINGS);
 
        /**
         * TeplFileSaver:flags:
@@ -442,24 +313,17 @@ tepl_file_saver_class_init (TeplFileSaverClass *klass)
         *
         * Since: 1.0
         */
-       g_object_class_install_property (object_class,
-                                        PROP_FLAGS,
-                                        g_param_spec_flags ("flags",
-                                                            "Flags",
-                                                            "",
-                                                            TEPL_TYPE_FILE_SAVER_FLAGS,
-                                                            TEPL_FILE_SAVER_FLAGS_NONE,
-                                                            G_PARAM_READWRITE |
-                                                            G_PARAM_CONSTRUCT |
-                                                            G_PARAM_STATIC_STRINGS));
-
-       /* Due to potential deadlocks when registering types, we need to ensure
-        * the dependent private class TeplBufferInputStream has been registered
-        * up front.
-        *
-        * See https://bugzilla.gnome.org/show_bug.cgi?id=780216
-        */
-       g_type_ensure (TEPL_TYPE_BUFFER_INPUT_STREAM);
+       properties[PROP_FLAGS] =
+               g_param_spec_flags ("flags",
+                                   "flags",
+                                   "",
+                                   TEPL_TYPE_FILE_SAVER_FLAGS,
+                                   TEPL_FILE_SAVER_FLAGS_NONE,
+                                   G_PARAM_READWRITE |
+                                   G_PARAM_CONSTRUCT |
+                                   G_PARAM_STATIC_STRINGS);
+
+       g_object_class_install_properties (object_class, N_PROPERTIES, properties);
 }
 
 static void
@@ -468,475 +332,6 @@ tepl_file_saver_init (TeplFileSaver *saver)
        saver->priv = tepl_file_saver_get_instance_private (saver);
 }
 
-/* BEGIN NOTE:
- *
- * This fixes an issue in GOutputStream that applies the atomic replace save
- * strategy. The stream moves the written file to the original file when the
- * stream is closed. However, there is no way currently to tell the stream that
- * the save should be aborted (there could be a conversion error). The patch
- * explicitly closes the output stream in all these cases with a GCancellable in
- * the cancelled state, causing the output stream to close, but not move the
- * file. This makes use of an implementation detail in the local file stream
- * and should be properly fixed by adding the appropriate API in GIO. Until
- * then, at least we prevent data corruption for now.
- *
- * Relevant bug reports:
- *
- * Bug 615110 - write file ignore encoding errors (gedit)
- * https://bugzilla.gnome.org/show_bug.cgi?id=615110
- *
- * Bug 602412 - g_file_replace does not restore original file when there is
- *              errors while writing (glib/gio)
- * https://bugzilla.gnome.org/show_bug.cgi?id=602412
- */
-static void
-cancel_output_stream_ready_cb (GObject      *source_object,
-                              GAsyncResult *result,
-                              gpointer      user_data)
-{
-       GOutputStream *output_stream = G_OUTPUT_STREAM (source_object);
-       GTask *task = G_TASK (user_data);
-       TaskData *task_data;
-
-       task_data = g_task_get_task_data (task);
-
-       g_output_stream_close_finish (output_stream, result, NULL);
-
-       if (task_data->error != NULL)
-       {
-               GError *error = task_data->error;
-               task_data->error = NULL;
-               g_task_return_error (task, error);
-       }
-       else
-       {
-               g_task_return_boolean (task, FALSE);
-       }
-}
-
-static void
-cancel_output_stream (GTask *task)
-{
-       TaskData *task_data;
-       GCancellable *cancellable;
-
-       DEBUG ({
-              g_print ("Cancel output stream\n");
-       });
-
-       task_data = g_task_get_task_data (task);
-
-       cancellable = g_cancellable_new ();
-       g_cancellable_cancel (cancellable);
-
-       g_output_stream_close_async (task_data->output_stream,
-                                    g_task_get_priority (task),
-                                    cancellable,
-                                    cancel_output_stream_ready_cb,
-                                    task);
-
-       g_object_unref (cancellable);
-}
-
-/*
- * END NOTE
- */
-
-static void
-close_output_stream_cb (GObject      *source_object,
-                       GAsyncResult *result,
-                       gpointer      user_data)
-{
-       GOutputStream *output_stream = G_OUTPUT_STREAM (source_object);
-       GTask *task = G_TASK (user_data);
-       GError *error = NULL;
-
-       DEBUG ({
-              g_print ("%s\n", G_STRFUNC);
-       });
-
-       g_output_stream_close_finish (output_stream, result, &error);
-
-       if (error != NULL)
-       {
-               DEBUG ({
-                      g_print ("Closing stream error: %s\n", error->message);
-               });
-
-               g_task_return_error (task, error);
-               return;
-       }
-
-       /* Finished! */
-       g_task_return_boolean (task, TRUE);
-}
-
-static void
-write_complete (GTask *task)
-{
-       TaskData *task_data;
-       GError *error = NULL;
-
-       DEBUG ({
-              g_print ("Close input stream\n");
-       });
-
-       task_data = g_task_get_task_data (task);
-
-       g_input_stream_close (G_INPUT_STREAM (task_data->input_stream),
-                             g_task_get_cancellable (task),
-                             &error);
-
-       if (error != NULL)
-       {
-               DEBUG ({
-                      g_print ("Closing input stream error: %s\n", error->message);
-               });
-
-               g_clear_error (&task_data->error);
-               task_data->error = error;
-               cancel_output_stream (task);
-               return;
-       }
-
-       DEBUG ({
-              g_print ("Close output stream\n");
-       });
-
-       g_output_stream_close_async (task_data->output_stream,
-                                    g_task_get_priority (task),
-                                    g_task_get_cancellable (task),
-                                    close_output_stream_cb,
-                                    task);
-}
-
-static void
-write_file_chunk_cb (GObject      *source_object,
-                    GAsyncResult *result,
-                    gpointer      user_data)
-{
-       GOutputStream *output_stream = G_OUTPUT_STREAM (source_object);
-       GTask *task = G_TASK (user_data);
-       TaskData *task_data;
-       gssize bytes_written;
-       GError *error = NULL;
-
-       DEBUG ({
-              g_print ("%s\n", G_STRFUNC);
-       });
-
-       task_data = g_task_get_task_data (task);
-
-       bytes_written = g_output_stream_write_finish (output_stream, result, &error);
-
-       DEBUG ({
-              g_print ("Written: %" G_GSSIZE_FORMAT "\n", bytes_written);
-       });
-
-       if (error != NULL)
-       {
-               DEBUG ({
-                      g_print ("Write error: %s\n", error->message);
-               });
-
-               g_clear_error (&task_data->error);
-               task_data->error = error;
-               cancel_output_stream (task);
-               return;
-       }
-
-       task_data->chunk_bytes_written += bytes_written;
-
-       /* Write again */
-       if (task_data->chunk_bytes_written < task_data->chunk_bytes_read)
-       {
-               write_file_chunk (task);
-               return;
-       }
-
-       if (task_data->progress_cb != NULL)
-       {
-               gsize total_chars_written;
-
-               total_chars_written = _tepl_buffer_input_stream_tell (task_data->input_stream);
-
-               task_data->progress_cb (total_chars_written,
-                                       task_data->total_size,
-                                       task_data->progress_cb_data);
-       }
-
-       read_file_chunk (task);
-}
-
-static void
-write_file_chunk (GTask *task)
-{
-       TaskData *task_data;
-
-       DEBUG ({
-              g_print ("%s\n", G_STRFUNC);
-       });
-
-       task_data = g_task_get_task_data (task);
-
-       g_output_stream_write_async (task_data->output_stream,
-                                    task_data->chunk_buffer + task_data->chunk_bytes_written,
-                                    task_data->chunk_bytes_read - task_data->chunk_bytes_written,
-                                    g_task_get_priority (task),
-                                    g_task_get_cancellable (task),
-                                    write_file_chunk_cb,
-                                    task);
-}
-
-static void
-read_file_chunk (GTask *task)
-{
-       TaskData *task_data;
-       GError *error = NULL;
-
-       DEBUG ({
-              g_print ("%s\n", G_STRFUNC);
-       });
-
-       task_data = g_task_get_task_data (task);
-
-       task_data->chunk_bytes_written = 0;
-
-       /* We use sync methods on doc stream since it is in memory. Using async
-        * would be racy and we could end up with invalid iters.
-        */
-       task_data->chunk_bytes_read = g_input_stream_read (G_INPUT_STREAM (task_data->input_stream),
-                                                          task_data->chunk_buffer,
-                                                          WRITE_CHUNK_SIZE,
-                                                          g_task_get_cancellable (task),
-                                                          &error);
-
-       if (error != NULL)
-       {
-               g_clear_error (&task_data->error);
-               task_data->error = error;
-               cancel_output_stream (task);
-               return;
-       }
-
-       /* Check if we finished reading and writing. */
-       if (task_data->chunk_bytes_read == 0)
-       {
-               write_complete (task);
-               return;
-       }
-
-       write_file_chunk (task);
-}
-
-static void
-replace_file_cb (GObject      *source_object,
-                GAsyncResult *result,
-                gpointer      user_data)
-{
-       GFile *location = G_FILE (source_object);
-       GTask *task = G_TASK (user_data);
-       TeplFileSaver *saver;
-       TaskData *task_data;
-       GOutputStream *output_stream;
-       GError *error = NULL;
-
-       DEBUG ({
-              g_print ("%s\n", G_STRFUNC);
-       });
-
-       saver = g_task_get_source_object (task);
-       task_data = g_task_get_task_data (task);
-
-       g_clear_object (&task_data->file_output_stream);
-       task_data->file_output_stream = g_file_replace_finish (location, result, &error);
-
-       if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED) &&
-           !task_data->tried_mount)
-       {
-               recover_not_mounted (task);
-               g_error_free (error);
-               return;
-       }
-       else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WRONG_ETAG))
-       {
-               g_task_return_new_error (task,
-                                        TEPL_FILE_SAVER_ERROR,
-                                        TEPL_FILE_SAVER_ERROR_EXTERNALLY_MODIFIED,
-                                        _("The file is externally modified."));
-               g_error_free (error);
-               return;
-       }
-       else if (error != NULL)
-       {
-               DEBUG ({
-                      g_print ("Opening file failed: %s\n", error->message);
-               });
-
-               g_task_return_error (task, error);
-               return;
-       }
-
-       if (saver->priv->compression_type == TEPL_COMPRESSION_TYPE_GZIP)
-       {
-               GZlibCompressor *compressor;
-
-               DEBUG ({
-                      g_print ("Use gzip compressor\n");
-               });
-
-               compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1);
-
-               output_stream = g_converter_output_stream_new (G_OUTPUT_STREAM 
(task_data->file_output_stream),
-                                                              G_CONVERTER (compressor));
-
-               g_object_unref (compressor);
-       }
-       else
-       {
-               output_stream = G_OUTPUT_STREAM (task_data->file_output_stream);
-               g_object_ref (output_stream);
-       }
-
-       g_return_if_fail (saver->priv->encoding != NULL);
-
-       DEBUG ({
-              g_print ("Encoding charset: %s\n",
-                       tepl_encoding_get_charset (saver->priv->encoding));
-       });
-
-       if (!tepl_encoding_is_utf8 (saver->priv->encoding))
-       {
-               GCharsetConverter *converter;
-
-               converter = g_charset_converter_new (tepl_encoding_get_charset (saver->priv->encoding),
-                                                    "UTF-8",
-                                                    &error);
-
-               if (error != NULL)
-               {
-                       g_task_return_error (task, error);
-                       g_object_unref (output_stream);
-                       return;
-               }
-
-               g_clear_object (&task_data->output_stream);
-               task_data->output_stream = g_converter_output_stream_new (output_stream,
-                                                                         G_CONVERTER (converter));
-
-               g_object_unref (converter);
-               g_object_unref (output_stream);
-       }
-       else
-       {
-               g_clear_object (&task_data->output_stream);
-               task_data->output_stream = G_OUTPUT_STREAM (output_stream);
-       }
-
-       task_data->total_size = _tepl_buffer_input_stream_get_total_size (task_data->input_stream);
-
-       DEBUG ({
-              g_print ("Total number of characters: %" G_GINT64_FORMAT "\n", task_data->total_size);
-       });
-
-       read_file_chunk (task);
-}
-
-static void
-begin_write (GTask *task)
-{
-       TeplFileSaver *saver;
-       gboolean create_backup;
-       const gchar *etag;
-
-       saver = g_task_get_source_object (task);
-
-       create_backup = (saver->priv->flags & TEPL_FILE_SAVER_FLAGS_CREATE_BACKUP) != 0;
-
-       DEBUG ({
-              g_print ("Start replacing file contents\n");
-              g_print ("Make backup: %s\n", create_backup ? "yes" : "no");
-       });
-
-       if (saver->priv->flags & TEPL_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME)
-       {
-               etag = NULL;
-       }
-       else
-       {
-               etag = _tepl_file_get_etag (saver->priv->file);
-       }
-
-       g_file_replace_async (saver->priv->location,
-                             etag,
-                             create_backup,
-                             G_FILE_CREATE_NONE,
-                             g_task_get_priority (task),
-                             g_task_get_cancellable (task),
-                             replace_file_cb,
-                             task);
-}
-
-static void
-mount_cb (GObject      *source_object,
-         GAsyncResult *result,
-         gpointer      user_data)
-{
-       GFile *location = G_FILE (source_object);
-       GTask *task = G_TASK (user_data);
-       TeplFileSaver *saver;
-       GError *error = NULL;
-
-       DEBUG ({
-              g_print ("%s\n", G_STRFUNC);
-       });
-
-       saver = g_task_get_source_object (task);
-
-       g_file_mount_enclosing_volume_finish (location, result, &error);
-
-       if (error != NULL)
-       {
-               g_task_return_error (task, error);
-               return;
-       }
-
-       if (saver->priv->file != NULL)
-       {
-               _tepl_file_set_mounted (saver->priv->file);
-       }
-
-       begin_write (task);
-}
-
-static void
-recover_not_mounted (GTask *task)
-{
-       TeplFileSaver *saver;
-       TaskData *task_data;
-       GMountOperation *mount_operation;
-
-       saver = g_task_get_source_object (task);
-       task_data = g_task_get_task_data (task);
-
-       mount_operation = _tepl_file_create_mount_operation (saver->priv->file);
-
-       DEBUG ({
-              g_print ("%s\n", G_STRFUNC);
-       });
-
-       task_data->tried_mount = TRUE;
-
-       g_file_mount_enclosing_volume (saver->priv->location,
-                                      G_MOUNT_MOUNT_NONE,
-                                      mount_operation,
-                                      g_task_get_cancellable (task),
-                                      mount_cb,
-                                      task);
-
-       g_object_unref (mount_operation);
-}
-
 GQuark
 tepl_file_saver_error_quark (void)
 {
@@ -944,7 +339,7 @@ tepl_file_saver_error_quark (void)
 
        if (G_UNLIKELY (quark == 0))
        {
-               quark = g_quark_from_static_string ("gtk-source-file-saver-error");
+               quark = g_quark_from_static_string ("TeplFileSaverError");
        }
 
        return quark;
@@ -1059,62 +454,6 @@ tepl_file_saver_get_location (TeplFileSaver *saver)
        return saver->priv->location;
 }
 
-/**
- * tepl_file_saver_set_encoding:
- * @saver: a #TeplFileSaver.
- * @encoding: (allow-none): the new encoding, or %NULL for UTF-8.
- *
- * Sets the encoding. If @encoding is %NULL, the UTF-8 encoding will be set.
- * By default the encoding is taken from the #TeplFile.
- *
- * Since: 1.0
- */
-void
-tepl_file_saver_set_encoding (TeplFileSaver      *saver,
-                             const TeplEncoding *encoding)
-{
-       TeplEncoding *my_encoding;
-
-       g_return_if_fail (TEPL_IS_FILE_SAVER (saver));
-       g_return_if_fail (saver->priv->task == NULL);
-
-       if (encoding == NULL)
-       {
-               my_encoding = tepl_encoding_new_utf8 ();
-       }
-       else
-       {
-               my_encoding = tepl_encoding_copy (encoding);
-       }
-
-       if (!tepl_encoding_equals (saver->priv->encoding, my_encoding))
-       {
-               tepl_encoding_free (saver->priv->encoding);
-               saver->priv->encoding = my_encoding;
-
-               g_object_notify (G_OBJECT (saver), "encoding");
-       }
-       else
-       {
-               tepl_encoding_free (my_encoding);
-       }
-}
-
-/**
- * tepl_file_saver_get_encoding:
- * @saver: a #TeplFileSaver.
- *
- * Returns: the encoding.
- * Since: 1.0
- */
-const TeplEncoding *
-tepl_file_saver_get_encoding (TeplFileSaver *saver)
-{
-       g_return_val_if_fail (TEPL_IS_FILE_SAVER (saver), NULL);
-
-       return saver->priv->encoding;
-}
-
 /**
  * tepl_file_saver_set_newline_type:
  * @saver: a #TeplFileSaver.
@@ -1135,7 +474,7 @@ tepl_file_saver_set_newline_type (TeplFileSaver   *saver,
        if (saver->priv->newline_type != newline_type)
        {
                saver->priv->newline_type = newline_type;
-               g_object_notify (G_OBJECT (saver), "newline-type");
+               g_object_notify_by_pspec (G_OBJECT (saver), properties[PROP_NEWLINE_TYPE]);
        }
 }
 
@@ -1174,7 +513,7 @@ tepl_file_saver_set_compression_type (TeplFileSaver       *saver,
        if (saver->priv->compression_type != compression_type)
        {
                saver->priv->compression_type = compression_type;
-               g_object_notify (G_OBJECT (saver), "compression-type");
+               g_object_notify_by_pspec (G_OBJECT (saver), properties[PROP_COMPRESSION_TYPE]);
        }
 }
 
@@ -1210,7 +549,7 @@ tepl_file_saver_set_flags (TeplFileSaver      *saver,
        if (saver->priv->flags != flags)
        {
                saver->priv->flags = flags;
-               g_object_notify (G_OBJECT (saver), "flags");
+               g_object_notify_by_pspec (G_OBJECT (saver), properties[PROP_FLAGS]);
        }
 }
 
@@ -1252,7 +591,7 @@ tepl_file_saver_get_flags (TeplFileSaver *saver)
  */
 
 /* The GDestroyNotify is needed, currently the following bug is not fixed:
- * https://bugzilla.gnome.org/show_bug.cgi?id=616044
+ * https://gitlab.gnome.org/GNOME/gobject-introspection/issues/25
  */
 void
 tepl_file_saver_save_async (TeplFileSaver         *saver,
@@ -1265,8 +604,6 @@ tepl_file_saver_save_async (TeplFileSaver         *saver,
                            gpointer               user_data)
 {
        TaskData *task_data;
-       gboolean check_invalid_chars;
-       gboolean implicit_trailing_newline;
 
        g_return_if_fail (TEPL_IS_FILE_SAVER (saver));
        g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
@@ -1276,11 +613,7 @@ tepl_file_saver_save_async (TeplFileSaver         *saver,
        g_task_set_priority (saver->priv->task, io_priority);
 
        task_data = task_data_new ();
-       g_task_set_task_data (saver->priv->task, task_data, task_data_free);
-
-       task_data->progress_cb = progress_callback;
-       task_data->progress_cb_data = progress_callback_data;
-       task_data->progress_cb_notify = progress_callback_notify;
+       g_task_set_task_data (saver->priv->task, task_data, (GDestroyNotify)task_data_free);
 
        if (saver->priv->source_buffer == NULL ||
            saver->priv->file == NULL ||
@@ -1290,32 +623,7 @@ tepl_file_saver_save_async (TeplFileSaver         *saver,
                return;
        }
 
-       check_invalid_chars = (saver->priv->flags & TEPL_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS) == 0;
-
-       if (check_invalid_chars && _tepl_buffer_has_invalid_chars (TEPL_BUFFER (saver->priv->source_buffer)))
-       {
-               g_task_return_new_error (saver->priv->task,
-                                        TEPL_FILE_SAVER_ERROR,
-                                        TEPL_FILE_SAVER_ERROR_INVALID_CHARS,
-                                        _("The buffer contains invalid characters."));
-               return;
-       }
-
-       DEBUG ({
-              g_print ("Start saving\n");
-       });
-
-       implicit_trailing_newline = gtk_source_buffer_get_implicit_trailing_newline 
(saver->priv->source_buffer);
-
-       /* The BufferInputStream has a strong reference to the buffer.
-        * We create the BufferInputStream here so we are sure that the
-        * buffer will not be destroyed during the file saving.
-        */
-       task_data->input_stream = _tepl_buffer_input_stream_new (GTK_TEXT_BUFFER (saver->priv->source_buffer),
-                                                                saver->priv->newline_type,
-                                                                implicit_trailing_newline);
-
-       begin_write (saver->priv->task);
+       g_task_return_boolean (saver->priv->task, TRUE);
 }
 
 /**
@@ -1351,15 +659,9 @@ tepl_file_saver_save_finish (TeplFileSaver  *saver,
 
        if (ok && saver->priv->file != NULL)
        {
-               TaskData *task_data;
-               gchar *new_etag;
-
                tepl_file_set_location (saver->priv->file,
                                        saver->priv->location);
 
-               _tepl_file_set_encoding (saver->priv->file,
-                                        saver->priv->encoding);
-
                _tepl_file_set_newline_type (saver->priv->file,
                                             saver->priv->newline_type);
 
@@ -1369,11 +671,6 @@ tepl_file_saver_save_finish (TeplFileSaver  *saver,
                _tepl_file_set_externally_modified (saver->priv->file, FALSE);
                _tepl_file_set_deleted (saver->priv->file, FALSE);
                _tepl_file_set_readonly (saver->priv->file, FALSE);
-
-               task_data = g_task_get_task_data (G_TASK (result));
-               new_etag = g_file_output_stream_get_etag (task_data->file_output_stream);
-               _tepl_file_set_etag (saver->priv->file, new_etag);
-               g_free (new_etag);
        }
 
        if (ok && saver->priv->source_buffer != NULL)
diff --git a/tepl/tepl-file-saver.h b/tepl/tepl-file-saver.h
index b4210c0..19a9e69 100644
--- a/tepl/tepl-file-saver.h
+++ b/tepl/tepl-file-saver.h
@@ -1,7 +1,7 @@
 /* SPDX-FileCopyrightText: 2005, 2007 - Paolo Maggi
- * Copyrhing 2007 - Steve Frécinaux
+ * SPDX-FileCopyrightText: 2007 - Steve Frécinaux
  * SPDX-FileCopyrightText: 2008 - Jesse van den Kieboom
- * SPDX-FileCopyrightText: 2014, 2016, 2017 - Sébastien Wilmet
+ * SPDX-FileCopyrightText: 2014-2020 - Sébastien Wilmet
  * SPDX-License-Identifier: LGPL-3.0-or-later
  */
 
@@ -14,7 +14,6 @@
 
 #include <gtksourceview/gtksource.h>
 #include <tepl/tepl-buffer.h>
-#include <tepl/tepl-encoding.h>
 #include <tepl/tepl-file.h>
 
 G_BEGIN_DECLS
@@ -40,6 +39,7 @@ typedef struct _TeplFileSaverPrivate TeplFileSaverPrivate;
  *   modified.
  *
  * An error code used with the %TEPL_FILE_SAVER_ERROR domain.
+ *
  * Since: 1.0
  */
 typedef enum
@@ -56,6 +56,7 @@ typedef enum
  * @TEPL_FILE_SAVER_FLAGS_CREATE_BACKUP: Create a backup before saving the file.
  *
  * Flags to define the behavior of a #TeplFileSaver.
+ *
  * Since: 1.0
  */
 typedef enum
@@ -104,13 +105,6 @@ TeplFile *          tepl_file_saver_get_file               (TeplFileSaver *saver);
 _TEPL_EXTERN
 GFile *                         tepl_file_saver_get_location           (TeplFileSaver *saver);
 
-_TEPL_EXTERN
-void                    tepl_file_saver_set_encoding           (TeplFileSaver      *saver,
-                                                                const TeplEncoding *encoding);
-
-_TEPL_EXTERN
-const TeplEncoding *    tepl_file_saver_get_encoding           (TeplFileSaver *saver);
-
 _TEPL_EXTERN
 void                    tepl_file_saver_set_newline_type       (TeplFileSaver   *saver,
                                                                 TeplNewlineType  newline_type);
diff --git a/testsuite/meson.build b/testsuite/meson.build
index f61f744..ae0a5c6 100644
--- a/testsuite/meson.build
+++ b/testsuite/meson.build
@@ -1,11 +1,9 @@
 unit_tests = [
-  'test-buffer-input-stream',
   'test-encoding',
   'test-encoding-converter',
-  'test-file',
+  #'test-file',
   'test-file-content',
   'test-file-loader',
-  'test-file-saver',
   'test-fold-region',
   'test-info-bar',
   'test-metadata',


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