[easytag] Avoid truncating Vorbis file when saving tags
- From: David King <davidk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [easytag] Avoid truncating Vorbis file when saving tags
- Date: Wed, 19 Mar 2014 07:40:10 +0000 (UTC)
commit a27a8fe8cbd12dac86f0e615fbda068f8bdd4a10
Author: Abhinav <abhijangda hotmail com>
Date: Tue Mar 18 15:28:33 2014 +0530
Avoid truncating Vorbis file when saving tags
Rather than writing to the same Vorbis file that tags are being read
from, and thus truncating the file while saving changed tags, write to a
GMemoryOutputStream and then replace the on-disk contents with the
memory stream once it has been completely written.
https://bugzilla.gnome.org/show_bug.cgi?id=721351
src/vcedit.c | 114 +++++++++++++++++++++++++++++++++++++---------------------
1 files changed, 73 insertions(+), 41 deletions(-)
---
diff --git a/src/vcedit.c b/src/vcedit.c
index bf083d9..a208204 100644
--- a/src/vcedit.c
+++ b/src/vcedit.c
@@ -487,19 +487,27 @@ vcedit_write(vcedit_state *state, GFile *file, GError **error)
char *buffer;
int bytes;
int needflush=0, needout=0;
- GFileOutputStream *ostream;
+ GOutputStream *ostream;
+ gchar *buf;
+ gsize size;
+ GFileInfo *fileinfo;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- ostream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE,
- NULL, error);
-
- if (!ostream)
+ fileinfo = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE,
+ G_FILE_QUERY_INFO_NONE, NULL, error);
+ if (!fileinfo)
{
g_assert (error == NULL || *error != NULL);
return FALSE;
}
+ buf = g_malloc (g_file_info_get_size (fileinfo));
+ ostream = g_memory_output_stream_new (buf,
+ g_file_info_get_size (fileinfo),
+ g_realloc, g_free);
+ g_object_unref (fileinfo);
+
state->eosin = 0;
state->extrapage = 0;
@@ -529,9 +537,9 @@ vcedit_write(vcedit_state *state, GFile *file, GError **error)
{
gsize bytes_written;
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream),
- ogout.header, ogout.header_len,
- &bytes_written, NULL, error))
+ if (!g_output_stream_write_all (ostream, ogout.header,
+ ogout.header_len, &bytes_written, NULL,
+ error))
{
g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %ld bytes of data "
"were written", bytes_written, ogout.header_len);
@@ -539,9 +547,8 @@ vcedit_write(vcedit_state *state, GFile *file, GError **error)
goto cleanup;
}
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream), ogout.body,
- ogout.body_len, &bytes_written, NULL,
- error))
+ if (!g_output_stream_write_all (ostream, ogout.body, ogout.body_len,
+ &bytes_written, NULL, error))
{
g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %ld bytes of data "
"were written", bytes_written, ogout.body_len);
@@ -556,9 +563,9 @@ vcedit_write(vcedit_state *state, GFile *file, GError **error)
{
gsize bytes_written;
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream),
- ogout.header, ogout.header_len,
- &bytes_written, NULL, error))
+ if (!g_output_stream_write_all (ostream, ogout.header,
+ ogout.header_len, &bytes_written,
+ NULL, error))
{
g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %ld bytes of "
"data were written", bytes_written, ogout.header_len);
@@ -566,9 +573,9 @@ vcedit_write(vcedit_state *state, GFile *file, GError **error)
goto cleanup;
}
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream),
- ogout.body, ogout.body_len,
- &bytes_written, NULL, error))
+ if (!g_output_stream_write_all (ostream, ogout.body,
+ ogout.body_len, &bytes_written,
+ NULL, error))
{
g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %ld bytes of "
"data were written", bytes_written, ogout.body_len);
@@ -582,8 +589,8 @@ vcedit_write(vcedit_state *state, GFile *file, GError **error)
{
gsize bytes_written;
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream),
- ogout.header, ogout.header_len,
+ if (!g_output_stream_write_all (ostream, ogout.header,
+ ogout.header_len,
&bytes_written, NULL, error))
{
g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %ld bytes "
@@ -593,9 +600,9 @@ vcedit_write(vcedit_state *state, GFile *file, GError **error)
goto cleanup;
}
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream),
- ogout.body, ogout.body_len,
- &bytes_written, NULL, error))
+ if (!g_output_stream_write_all (ostream, ogout.body,
+ ogout.body_len, &bytes_written,
+ NULL, error))
{
g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %ld bytes "
"of data were written", bytes_written,
@@ -664,9 +671,9 @@ vcedit_write(vcedit_state *state, GFile *file, GError **error)
{
gsize bytes_written;
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream),
- ogout.header, ogout.header_len,
- &bytes_written, NULL, error))
+ if (!g_output_stream_write_all (ostream, ogout.header,
+ ogout.header_len, &bytes_written, NULL,
+ error))
{
g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %ld bytes of data "
"were written", bytes_written, ogout.header_len);
@@ -674,9 +681,8 @@ vcedit_write(vcedit_state *state, GFile *file, GError **error)
goto cleanup;
}
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream), ogout.body,
- ogout.body_len, &bytes_written, NULL,
- error))
+ if (!g_output_stream_write_all (ostream, ogout.body, ogout.body_len,
+ &bytes_written, NULL, error))
{
g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %ld bytes of data "
"were written", bytes_written, ogout.body_len);
@@ -689,9 +695,9 @@ vcedit_write(vcedit_state *state, GFile *file, GError **error)
{
gsize bytes_written;
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream),
- ogout.header, ogout.header_len,
- &bytes_written, NULL, error))
+ if (!g_output_stream_write_all (ostream, ogout.header,
+ ogout.header_len, &bytes_written, NULL,
+ error))
{
g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %ld bytes of data "
"were written", bytes_written, ogout.header_len);
@@ -699,9 +705,8 @@ vcedit_write(vcedit_state *state, GFile *file, GError **error)
goto cleanup;
}
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream), ogout.body,
- ogout.body_len, &bytes_written, NULL,
- error))
+ if (!g_output_stream_write_all (ostream, ogout.body, ogout.body_len,
+ &bytes_written, NULL, error))
{
g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %ld bytes of data "
"were written", bytes_written, ogout.body_len);
@@ -732,17 +737,17 @@ vcedit_write(vcedit_state *state, GFile *file, GError **error)
/* Don't bother going through the rest, we can just
* write the page out now */
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream),
- ogout.header, ogout.header_len,
+ if (!g_output_stream_write_all (ostream, ogout.header,
+ ogout.header_len,
&bytes_written, NULL, error))
{
g_assert (error == NULL || *error != NULL);
goto cleanup;
}
- if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream),
- ogout.body, ogout.body_len,
- &bytes_written, NULL, error))
+ if (!g_output_stream_write_all (ostream, ogout.body,
+ ogout.body_len, &bytes_written,
+ NULL, error))
{
g_assert (error == NULL || *error != NULL);
goto cleanup;
@@ -786,12 +791,39 @@ cleanup:
}
}
- g_object_unref (ostream);
-
if (error == NULL || *error != NULL)
+ {
+ g_object_unref (ostream);
return FALSE;
+ }
g_assert (error == NULL || *error == NULL);
+
+ if (!g_output_stream_close (ostream, NULL, error))
+ {
+ g_object_unref (ostream);
+ g_assert (error == NULL || *error != NULL);
+ return FALSE;
+ }
+
+ g_assert (error == NULL || *error == NULL);
+
+ buf = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream));
+ size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (ostream));
+
+ /* Write the in-memory data back out to the original file. */
+ if (!g_file_replace_contents (file, buf, size, NULL, FALSE,
+ G_FILE_CREATE_NONE, NULL, NULL, error))
+ {
+ g_object_unref (ostream);
+ g_free (buf);
+ g_assert (error == NULL || *error != NULL);
+ return FALSE;
+ }
+
+ g_free (buf);
+ g_object_unref (ostream);
+
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]