/**
* SECTION:goutputstream
* @short_description: Base class for implementing streaming output
- *
- *
+ *
+ *
*
**/
return -1;
}
- if (stream->priv->closed)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
- _("Stream is already closed"));
- return -1;
- }
-
- if (stream->priv->pending)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
- _("Stream has outstanding operation"));
- return -1;
- }
-
class = G_OUTPUT_STREAM_GET_CLASS (stream);
- if (class->write == NULL)
+ if (class->write_fn == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Output stream doesn't implement write"));
return -1;
}
+ if (!g_output_stream_set_pending (stream, error))
+ return -1;
+
if (cancellable)
g_push_current_cancellable (cancellable);
- stream->priv->pending = TRUE;
- res = class->write (stream, buffer, count, cancellable, error);
- stream->priv->pending = FALSE;
+ res = class->write_fn (stream, buffer, count, cancellable, error);
if (cancellable)
g_pop_current_cancellable (cancellable);
+ g_output_stream_clear_pending (stream);
+
return res;
}
g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
- if (stream->priv->closed)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
- _("Stream is already closed"));
- return FALSE;
- }
-
- if (stream->priv->pending)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
- _("Stream has outstanding operation"));
- return FALSE;
- }
+ if (!g_output_stream_set_pending (stream, error))
+ return FALSE;
class = G_OUTPUT_STREAM_GET_CLASS (stream);
if (cancellable)
g_push_current_cancellable (cancellable);
- stream->priv->pending = TRUE;
res = class->flush (stream, cancellable, error);
- stream->priv->pending = FALSE;
if (cancellable)
g_pop_current_cancellable (cancellable);
}
+ g_output_stream_clear_pending (stream);
+
return res;
}
g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
g_return_val_if_fail (G_IS_INPUT_STREAM (source), -1);
- if (stream->priv->closed)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
- _("Target stream is already closed"));
- return -1;
- }
-
if (g_input_stream_is_closed (source))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
return -1;
}
- if (stream->priv->pending)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
- _("Stream has outstanding operation"));
- return -1;
- }
+ if (!g_output_stream_set_pending (stream, error))
+ return -1;
class = G_OUTPUT_STREAM_GET_CLASS (stream);
if (cancellable)
g_push_current_cancellable (cancellable);
- stream->priv->pending = TRUE;
res = class->splice (stream, source, flags, cancellable, error);
- stream->priv->pending = FALSE;
if (cancellable)
g_pop_current_cancellable (cancellable);
+ g_output_stream_clear_pending (stream);
+
return res;
}
char buffer[8192], *p;
gboolean res;
- if (class->write == NULL)
+ bytes_copied = 0;
+ if (class->write_fn == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("Output stream doesn't implement write"));
goto notsupported;
}
- bytes_copied = 0;
res = TRUE;
do
{
p = buffer;
while (n_read > 0)
{
- n_written = class->write (stream, p, n_read, cancellable, error);
+ n_written = class->write_fn (stream, p, n_read, cancellable, error);
if (n_written == -1)
{
res = FALSE;
if (flags & G_OUTPUT_STREAM_SPLICE_FLAGS_CLOSE_TARGET)
{
/* But write errors on close are bad! */
- if (!class->close (stream, cancellable, error))
+ if (!class->close_fn (stream, cancellable, error))
res = FALSE;
}
if (stream->priv->closed)
return TRUE;
- if (stream->priv->pending)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
- _("Stream has outstanding operation"));
- return FALSE;
- }
+ if (!g_output_stream_set_pending (stream, error))
+ return FALSE;
- stream->priv->pending = TRUE;
-
if (cancellable)
g_push_current_cancellable (cancellable);
- res = class->flush (stream, cancellable, error);
-
+ if (class->flush)
+ res = class->flush (stream, cancellable, error);
+ else
+ res = TRUE;
+
if (!res)
{
/* flushing caused the error that we want to return,
* but we still want to close the underlying stream if possible
*/
- if (class->close)
- class->close (stream, cancellable, NULL);
+ if (class->close_fn)
+ class->close_fn (stream, cancellable, NULL);
}
else
{
res = TRUE;
- if (class->close)
- res = class->close (stream, cancellable, error);
+ if (class->close_fn)
+ res = class->close_fn (stream, cancellable, error);
}
if (cancellable)
g_pop_current_cancellable (cancellable);
stream->priv->closed = TRUE;
- stream->priv->pending = FALSE;
+ g_output_stream_clear_pending (stream);
return res;
}
{
GOutputStream *stream = G_OUTPUT_STREAM (source_object);
- stream->priv->pending = FALSE;
+ g_output_stream_clear_pending (stream);
if (stream->priv->outstanding_callback)
(*stream->priv->outstanding_callback) (source_object, res, user_data);
g_object_unref (stream);
{
GOutputStream *stream = G_OUTPUT_STREAM (source_object);
- stream->priv->pending = FALSE;
stream->priv->closed = TRUE;
+ g_output_stream_clear_pending (stream);
if (stream->priv->outstanding_callback)
(*stream->priv->outstanding_callback) (source_object, res, user_data);
g_object_unref (stream);
{
GOutputStreamClass *class;
GSimpleAsyncResult *simple;
+ GError *error = NULL;
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
g_return_if_fail (buffer != NULL);
return;
}
- if (stream->priv->closed)
+ if (!g_output_stream_set_pending (stream, &error))
{
- g_simple_async_report_error_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_CLOSED,
- _("Stream is already closed"));
+ g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
+ callback,
+ user_data,
+ error);
+ g_error_free (error);
return;
}
- if (stream->priv->pending)
- {
- g_simple_async_report_error_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_PENDING,
- _("Stream has outstanding operation"));
- return;
- }
-
class = G_OUTPUT_STREAM_GET_CLASS (stream);
- stream->priv->pending = TRUE;
stream->priv->outstanding_callback = callback;
g_object_ref (stream);
class->write_async (stream, buffer, count, io_priority, cancellable,
GOutputStream *stream = G_OUTPUT_STREAM (source_object);
SpliceUserData *data = _data;
- stream->priv->pending = FALSE;
+ g_output_stream_clear_pending (stream);
if (data->callback)
(*data->callback) (source_object, res, data->user_data);
{
GOutputStreamClass *class;
SpliceUserData *data;
+ GError *error = NULL;
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
g_return_if_fail (G_IS_INPUT_STREAM (source));
- if (stream->priv->closed)
- {
- g_simple_async_report_error_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_CLOSED,
- _("Target stream is already closed"));
- return;
- }
-
if (g_input_stream_is_closed (source))
{
g_simple_async_report_error_in_idle (G_OBJECT (stream),
return;
}
- if (stream->priv->pending)
+ if (!g_output_stream_set_pending (stream, &error))
{
- g_simple_async_report_error_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_PENDING,
- _("Stream has outstanding operation"));
+ g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
+ callback,
+ user_data,
+ error);
+ g_error_free (error);
return;
}
class = G_OUTPUT_STREAM_GET_CLASS (stream);
- stream->priv->pending = TRUE;
-
data = g_new0 (SpliceUserData, 1);
data->callback = callback;
data->user_data = user_data;
{
GOutputStreamClass *class;
GSimpleAsyncResult *simple;
+ GError *error = NULL;
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
- if (stream->priv->closed)
- {
- g_simple_async_report_error_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_CLOSED,
- _("Stream is already closed"));
- return;
- }
-
- if (stream->priv->pending)
+ if (!g_output_stream_set_pending (stream, &error))
{
- g_simple_async_report_error_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_PENDING,
- _("Stream has outstanding operation"));
+ g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
+ callback,
+ user_data,
+ error);
+ g_error_free (error);
return;
}
+ stream->priv->outstanding_callback = callback;
+ g_object_ref (stream);
+
class = G_OUTPUT_STREAM_GET_CLASS (stream);
if (class->flush_async == NULL)
{
simple = g_simple_async_result_new (G_OBJECT (stream),
- callback,
+ async_ready_callback_wrapper,
user_data,
g_output_stream_flush_async);
g_simple_async_result_complete_in_idle (simple);
return;
}
- stream->priv->pending = TRUE;
- stream->priv->outstanding_callback = callback;
- g_object_ref (stream);
class->flush_async (stream, io_priority, cancellable,
async_ready_callback_wrapper, user_data);
}
{
GOutputStreamClass *class;
GSimpleAsyncResult *simple;
+ GError *error = NULL;
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
return;
}
- if (stream->priv->pending)
+ if (!g_output_stream_set_pending (stream, &error))
{
- g_simple_async_report_error_in_idle (G_OBJECT (stream),
- callback,
- user_data,
- G_IO_ERROR, G_IO_ERROR_PENDING,
- _("Stream has outstanding operation"));
+ g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
+ callback,
+ user_data,
+ error);
+ g_error_free (error);
return;
}
class = G_OUTPUT_STREAM_GET_CLASS (stream);
- stream->priv->pending = TRUE;
stream->priv->outstanding_callback = callback;
g_object_ref (stream);
class->close_async (stream, io_priority, cancellable,
/**
* g_output_stream_set_pending:
* @stream: a #GOutputStream.
- * @pending: a #gboolean.
+ * @error: a #GError location to store the error occuring, or %NULL to
+ * ignore.
*
- * Sets the @stream as having pending actions if @pending is %TRUE.
+ * Sets @stream to have actions pending. If the pending flag is
+ * already set or @stream is closed, it will return %FALSE and set
+ * @error.
+ *
+ * Return value: %TRUE if pending was previously unset and is now set.
**/
-void
+gboolean
g_output_stream_set_pending (GOutputStream *stream,
- gboolean pending)
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
+
+ if (stream->priv->closed)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
+ _("Stream is already closed"));
+ return FALSE;
+ }
+
+ if (stream->priv->pending)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
+ _("Stream has outstanding operation"));
+ return FALSE;
+ }
+
+ stream->priv->pending = TRUE;
+ return TRUE;
+}
+
+/**
+ * g_output_stream_clear_pending:
+ * @stream: output stream
+ *
+ * Clears the pending flag on @stream.
+ **/
+void
+g_output_stream_clear_pending (GOutputStream *stream)
{
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
- stream->priv->pending = pending;
+ stream->priv->pending = FALSE;
}
class = G_OUTPUT_STREAM_GET_CLASS (object);
op = g_simple_async_result_get_op_res_gpointer (res);
- op->count_written = class->write (G_OUTPUT_STREAM (object), op->buffer, op->count_requested,
- cancellable, &error);
+ op->count_written = class->write_fn (G_OUTPUT_STREAM (object), op->buffer, op->count_requested,
+ cancellable, &error);
if (op->count_written == -1)
{
g_simple_async_result_set_from_error (res, error);
op->flags,
cancellable,
&error);
-
if (op->bytes_copied == -1)
{
g_simple_async_result_set_from_error (result, error);
open handles */
class = G_OUTPUT_STREAM_GET_CLASS (object);
- result = class->close (G_OUTPUT_STREAM (object), cancellable, &error);
+ result = class->close_fn (G_OUTPUT_STREAM (object), cancellable, &error);
if (!result)
{
g_simple_async_result_set_from_error (res, error);