[easytag] Use GIO for writing WavPack tags



commit e49dac580f9d88380f1f44aabbc4a18f5f178446
Author: David King <amigadave amigadave com>
Date:   Tue Dec 23 20:01:35 2014 +0000

    Use GIO for writing WavPack tags
    
    Add a new EtWavpackWriteState struct, extended from EtWavpackState, and
    use it to store the IOStream during tag writing.

 src/tags/wavpack_private.c |   21 +++++++++++++++++++++
 src/tags/wavpack_private.h |   14 ++++++++++++++
 src/tags/wavpack_tag.c     |   40 +++++++++++++++++++++++++++++++++++++---
 3 files changed, 72 insertions(+), 3 deletions(-)
---
diff --git a/src/tags/wavpack_private.c b/src/tags/wavpack_private.c
index c969baa..2346c7f 100644
--- a/src/tags/wavpack_private.c
+++ b/src/tags/wavpack_private.c
@@ -159,3 +159,24 @@ wavpack_can_seek (void *id)
 
     return g_seekable_can_seek (state->seekable);
 }
+
+int32_t
+wavpack_write_bytes (void *id,
+                     void *data,
+                     int32_t bcount)
+{
+    EtWavpackWriteState *state;
+    gssize bytes_written;
+
+    state = (EtWavpackWriteState *)id;
+
+    bytes_written = g_output_stream_write (G_OUTPUT_STREAM (state->ostream),
+                                           data, bcount, NULL, &state->error);
+
+    if (bytes_written == -1)
+    {
+        return 0;
+    }
+
+    return bytes_written;
+}
diff --git a/src/tags/wavpack_private.h b/src/tags/wavpack_private.h
index 1f9815d..57654e4 100644
--- a/src/tags/wavpack_private.h
+++ b/src/tags/wavpack_private.h
@@ -35,6 +35,17 @@ typedef struct
     GError *error;
 } EtWavpackState;
 
+typedef struct
+{
+    /* Start fields copied from EtWavpackState. */
+    GFileInputStream *istream;
+    GSeekable *seekable;
+    GError *error;
+    /* End fields copied from EtWavpackState. */
+    GFileIOStream *iostream;
+    GFileOutputStream *ostream;
+} EtWavpackWriteState;
+
 int32_t wavpack_read_bytes (void *id, void *data, int32_t bcount);
 uint32_t wavpack_get_pos (void *id);
 int wavpack_set_pos_abs (void *id, uint32_t pos);
@@ -43,6 +54,9 @@ int wavpack_push_back_byte (void *id, int c);
 uint32_t wavpack_get_length (void *id);
 int wavpack_can_seek (void *id);
 
+/* Only use this with EtWavpackWriteState. */
+int32_t wavpack_write_bytes (void *id, void *data, int32_t bcount);
+
 G_END_DECLS
 
 #endif /* ENABLE_WAVPACK */
diff --git a/src/tags/wavpack_tag.c b/src/tags/wavpack_tag.c
index f77cf41..b804348 100644
--- a/src/tags/wavpack_tag.c
+++ b/src/tags/wavpack_tag.c
@@ -345,6 +345,12 @@ gboolean
 wavpack_tag_write_file_tag (const ET_File *ETFile,
                             GError **error)
 {
+    WavpackStreamReader writer = { wavpack_read_bytes, wavpack_get_pos,
+                                   wavpack_set_pos_abs, wavpack_set_pos_rel,
+                                   wavpack_push_back_byte, wavpack_get_length,
+                                   wavpack_can_seek, wavpack_write_bytes };
+    GFile *file;
+    EtWavpackWriteState state;
     const gchar *filename;
     const File_Tag *FileTag;
     WavpackContext *wpc;
@@ -357,12 +363,38 @@ wavpack_tag_write_file_tag (const ET_File *ETFile,
     filename = ((File_Name *)((GList *)ETFile->FileNameCur)->data)->value;
     FileTag = (File_Tag *)ETFile->FileTag->data;
 
-    /* TODO: Use WavpackOpenFileInputEx() instead. */
-    wpc = WavpackOpenFileInput (filename, message, OPEN_EDIT_TAGS, 0);
+    file = g_file_new_for_path (filename);
+    state.error = NULL;
+    state.iostream = g_file_open_readwrite (file, NULL, &state.error);
+    g_object_unref (file);
+
+    if (!state.iostream)
+    {
+        g_propagate_error (error, state.error);
+        return FALSE;
+    }
+
+    state.istream = G_FILE_INPUT_STREAM (g_io_stream_get_input_stream (G_IO_STREAM (state.iostream)));
+    state.ostream = G_FILE_OUTPUT_STREAM (g_io_stream_get_output_stream (G_IO_STREAM (state.iostream)));
+    state.seekable = G_SEEKABLE (state.iostream);
+
+    /* NULL for the WavPack correction file. */
+    wpc = WavpackOpenFileInputEx (&writer, &state, NULL, message,
+                                  OPEN_EDIT_TAGS, 0);
 
     if (wpc == NULL)
     {
-        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s", message);
+        if (state.error)
+        {
+            g_propagate_error (error, state.error);
+        }
+        else
+        {
+            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s",
+                         message);
+        }
+
+        g_object_unref (state.iostream);
         return FALSE;
     }
 
@@ -501,6 +533,8 @@ wavpack_tag_write_file_tag (const ET_File *ETFile,
 
     WavpackCloseFile (wpc);
 
+    g_object_unref (state.iostream);
+
     return TRUE;
 
 err:


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