[libgsf] GsfOutputIOChannel: fix seekability check.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgsf] GsfOutputIOChannel: fix seekability check.
- Date: Sat, 29 Nov 2014 19:43:55 +0000 (UTC)
commit 1e47bdb9ac38dfe7a4f4ce149f847d3037674e28
Author: Morten Welinder <terra gnome org>
Date: Sat Nov 29 14:43:31 2014 -0500
GsfOutputIOChannel: fix seekability check.
ChangeLog | 8 +++++++
NEWS | 1 +
gsf/gsf-output-gio.c | 51 +++++++++++++++----------------------------
gsf/gsf-output-iochannel.c | 5 +++-
4 files changed, 31 insertions(+), 34 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b048e94..881b67e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2014-11-29 Morten Welinder <terra gnome org>
+ * gsf/gsf-output-gio.c (gsf_output_gio_write): Simplify and handle
+ the zero bytes cases better.
+ (gsf_output_gio_new_full): Check seekability here and thus only
+ once.
+
+ * gsf/gsf-output-iochannel.c (gsf_output_iochannel_seek): Check
+ for is_seekable before trying to do so.
+
* gsf/gsf-outfile-zip.c (gsf_outfile_zip_class_init): Properly
install zip64 property.
(zip_header_write): Fix auto-zip64 mode's writing of sizes.
diff --git a/NEWS b/NEWS
index 5dff056..c145ef0 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ Morten:
* Fix minor zip file issues.
* Write zip archives with more than 64k+ members.
* Store unix modtime in zip. (Until that overflows.)
+ * Fix seekability checks in GsfOutputIOChannel.
--------------------------------------------------------------------------
libgsf 1.14.30
diff --git a/gsf/gsf-output-gio.c b/gsf/gsf-output-gio.c
index 72c7aa9..4985664 100644
--- a/gsf/gsf-output-gio.c
+++ b/gsf/gsf-output-gio.c
@@ -29,6 +29,7 @@ struct _GsfOutputGio {
GsfOutput output;
GFile *file;
GOutputStream *stream;
+ gboolean can_seek;
};
typedef struct {
@@ -38,21 +39,8 @@ typedef struct {
static gboolean
can_seek (GOutputStream *stream)
{
- if (!G_IS_SEEKABLE (stream))
- return FALSE;
-
- return g_seekable_can_seek (G_SEEKABLE (stream));
-}
-
-static GsfOutput *
-wrap_if_not_seekable (GsfOutputGio *output, GError **err)
-{
- if (!can_seek (output->stream)) {
- (void)err;
- /* todo: return a wrapper around the output that's seekable */
- }
-
- return GSF_OUTPUT (output);
+ return (G_IS_SEEKABLE (stream) &&
+ g_seekable_can_seek (G_SEEKABLE (stream)));
}
/**
@@ -75,11 +63,11 @@ gsf_output_gio_new_full (GFile *file, GError **err)
}
output = g_object_new (GSF_OUTPUT_GIO_TYPE, NULL);
- output->file = file;
+ output->file = g_object_ref (output->file);
output->stream = stream;
- g_object_ref (output->file);
+ output->can_seek = can_seek (stream);
- return wrap_if_not_seekable (output, err);
+ return GSF_OUTPUT (output);
}
/**
@@ -166,8 +154,7 @@ gsf_output_gio_finalize (GObject *obj)
gsf_output_gio_close (GSF_OUTPUT(output));
parent_class = g_type_class_peek (GSF_OUTPUT_TYPE);
- if (parent_class && parent_class->finalize)
- parent_class->finalize (obj);
+ parent_class->finalize (obj);
}
static gboolean
@@ -176,23 +163,20 @@ gsf_output_gio_write (GsfOutput *output,
guint8 const *buffer)
{
GsfOutputGio *gio = GSF_OUTPUT_GIO (output);
- size_t total_written = 0;
g_return_val_if_fail (gio != NULL, FALSE);
g_return_val_if_fail (gio->stream != NULL, FALSE);
- while (1) {
- gssize nwritten;
-
- nwritten = g_output_stream_write (gio->stream, (guint8 *)(buffer + total_written), (num_bytes
- total_written), NULL, NULL);
-
- if (nwritten >= 0) {
- total_written += nwritten;
- if (total_written == num_bytes)
- return TRUE;
- } else {
+ while (num_bytes > 0) {
+ gssize nwritten =
+ g_output_stream_write (gio->stream,
+ buffer, num_bytes,
+ NULL, NULL);
+ if (nwritten < 0)
return FALSE;
- }
+
+ buffer += nwritten;
+ num_bytes -= nwritten;
}
return TRUE;
@@ -206,7 +190,7 @@ gsf_output_gio_seek (GsfOutput *output, gsf_off_t offset, GSeekType whence)
g_return_val_if_fail (gio != NULL, FALSE);
g_return_val_if_fail (gio->stream != NULL, FALSE);
- if (!can_seek (gio->stream))
+ if (!gio->can_seek)
return FALSE;
return g_seekable_seek (G_SEEKABLE (gio->stream), offset, whence, NULL, NULL);
@@ -219,6 +203,7 @@ gsf_output_gio_init (GObject *obj)
gio->file = NULL;
gio->stream = NULL;
+ gio->can_seek = FALSE;
}
static void
diff --git a/gsf/gsf-output-iochannel.c b/gsf/gsf-output-iochannel.c
index 1521784..f15aeb5 100644
--- a/gsf/gsf-output-iochannel.c
+++ b/gsf/gsf-output-iochannel.c
@@ -77,11 +77,14 @@ gsf_output_iochannel_seek (GsfOutput *output, gsf_off_t offset,
GsfOutputIOChannel *io = GSF_OUTPUT_IOCHANNEL (output);
GIOStatus status = G_IO_STATUS_NORMAL;
+ if (!io->channel->is_seekable)
+ return FALSE;
+
status = g_io_channel_seek_position (io->channel, offset, whence, NULL);
if (status == G_IO_STATUS_NORMAL)
return TRUE;
- gsf_output_set_error (output, status, " ");
+ gsf_output_set_error (output, status, "?");
return FALSE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]