1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2006-2007 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: Alexander Larsson <alexl@redhat.com>
24 #include "goutputstream.h"
25 #include "gcancellable.h"
26 #include "gasyncresult.h"
27 #include "gsimpleasyncresult.h"
28 #include "ginputstream.h"
34 * SECTION:goutputstream
35 * @short_description: Base class for implementing streaming output
38 * GOutputStream has functions to write to a stream (g_output_stream_write()),
39 * to close a stream (g_output_stream_close()) and to flush pending writes
40 * (g_output_stream_flush()).
42 * To copy the content of an input stream to an output stream without
43 * manually handling the reads and writes, use g_output_stream_splice().
45 * All of these functions have async variants too.
48 G_DEFINE_ABSTRACT_TYPE (GOutputStream, g_output_stream, G_TYPE_OBJECT);
50 struct _GOutputStreamPrivate {
54 GAsyncReadyCallback outstanding_callback;
57 static gssize g_output_stream_real_splice (GOutputStream *stream,
59 GOutputStreamSpliceFlags flags,
60 GCancellable *cancellable,
62 static void g_output_stream_real_write_async (GOutputStream *stream,
66 GCancellable *cancellable,
67 GAsyncReadyCallback callback,
69 static gssize g_output_stream_real_write_finish (GOutputStream *stream,
72 static void g_output_stream_real_splice_async (GOutputStream *stream,
74 GOutputStreamSpliceFlags flags,
76 GCancellable *cancellable,
77 GAsyncReadyCallback callback,
79 static gssize g_output_stream_real_splice_finish (GOutputStream *stream,
82 static void g_output_stream_real_flush_async (GOutputStream *stream,
84 GCancellable *cancellable,
85 GAsyncReadyCallback callback,
87 static gboolean g_output_stream_real_flush_finish (GOutputStream *stream,
90 static void g_output_stream_real_close_async (GOutputStream *stream,
92 GCancellable *cancellable,
93 GAsyncReadyCallback callback,
95 static gboolean g_output_stream_real_close_finish (GOutputStream *stream,
98 static gboolean _g_output_stream_close_internal (GOutputStream *stream,
99 GCancellable *cancellable,
103 g_output_stream_finalize (GObject *object)
105 G_OBJECT_CLASS (g_output_stream_parent_class)->finalize (object);
109 g_output_stream_dispose (GObject *object)
111 GOutputStream *stream;
113 stream = G_OUTPUT_STREAM (object);
115 if (!stream->priv->closed)
116 g_output_stream_close (stream, NULL, NULL);
118 G_OBJECT_CLASS (g_output_stream_parent_class)->dispose (object);
122 g_output_stream_class_init (GOutputStreamClass *klass)
124 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
126 g_type_class_add_private (klass, sizeof (GOutputStreamPrivate));
128 gobject_class->finalize = g_output_stream_finalize;
129 gobject_class->dispose = g_output_stream_dispose;
131 klass->splice = g_output_stream_real_splice;
133 klass->write_async = g_output_stream_real_write_async;
134 klass->write_finish = g_output_stream_real_write_finish;
135 klass->splice_async = g_output_stream_real_splice_async;
136 klass->splice_finish = g_output_stream_real_splice_finish;
137 klass->flush_async = g_output_stream_real_flush_async;
138 klass->flush_finish = g_output_stream_real_flush_finish;
139 klass->close_async = g_output_stream_real_close_async;
140 klass->close_finish = g_output_stream_real_close_finish;
144 g_output_stream_init (GOutputStream *stream)
146 stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
147 G_TYPE_OUTPUT_STREAM,
148 GOutputStreamPrivate);
152 * g_output_stream_write:
153 * @stream: a #GOutputStream.
154 * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write.
155 * @count: the number of bytes to write
156 * @cancellable: (allow-none): optional cancellable object
157 * @error: location to store the error occurring, or %NULL to ignore
159 * Tries to write @count bytes from @buffer into the stream. Will block
160 * during the operation.
162 * If count is 0, returns 0 and does nothing. A value of @count
163 * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
165 * On success, the number of bytes written to the stream is returned.
166 * It is not an error if this is not the same as the requested size, as it
167 * can happen e.g. on a partial I/O error, or if there is not enough
168 * storage in the stream. All writes block until at least one byte
169 * is written or an error occurs; 0 is never returned (unless
172 * If @cancellable is not NULL, then the operation can be cancelled by
173 * triggering the cancellable object from another thread. If the operation
174 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
175 * operation was partially finished when the operation was cancelled the
176 * partial result will be returned, without an error.
178 * On error -1 is returned and @error is set accordingly.
180 * Return value: Number of bytes written, or -1 on error
183 g_output_stream_write (GOutputStream *stream,
186 GCancellable *cancellable,
189 GOutputStreamClass *class;
192 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
193 g_return_val_if_fail (buffer != NULL, 0);
198 if (((gssize) count) < 0)
200 g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
201 _("Too large count value passed to %s"), G_STRFUNC);
205 class = G_OUTPUT_STREAM_GET_CLASS (stream);
207 if (class->write_fn == NULL)
209 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
210 _("Output stream doesn't implement write"));
214 if (!g_output_stream_set_pending (stream, error))
218 g_cancellable_push_current (cancellable);
220 res = class->write_fn (stream, buffer, count, cancellable, error);
223 g_cancellable_pop_current (cancellable);
225 g_output_stream_clear_pending (stream);
231 * g_output_stream_write_all:
232 * @stream: a #GOutputStream.
233 * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write.
234 * @count: the number of bytes to write
235 * @bytes_written: (out): location to store the number of bytes that was
236 * written to the stream
237 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
238 * @error: location to store the error occurring, or %NULL to ignore
240 * Tries to write @count bytes from @buffer into the stream. Will block
241 * during the operation.
243 * This function is similar to g_output_stream_write(), except it tries to
244 * write as many bytes as requested, only stopping on an error.
246 * On a successful write of @count bytes, %TRUE is returned, and @bytes_written
249 * If there is an error during the operation FALSE is returned and @error
250 * is set to indicate the error status, @bytes_written is updated to contain
251 * the number of bytes written into the stream before the error occurred.
253 * Return value: %TRUE on success, %FALSE if there was an error
256 g_output_stream_write_all (GOutputStream *stream,
259 gsize *bytes_written,
260 GCancellable *cancellable,
263 gsize _bytes_written;
266 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
267 g_return_val_if_fail (buffer != NULL, FALSE);
270 while (_bytes_written < count)
272 res = g_output_stream_write (stream, (char *)buffer + _bytes_written, count - _bytes_written,
277 *bytes_written = _bytes_written;
282 g_warning ("Write returned zero without error");
284 _bytes_written += res;
288 *bytes_written = _bytes_written;
294 * g_output_stream_flush:
295 * @stream: a #GOutputStream.
296 * @cancellable: (allow-none): optional cancellable object
297 * @error: location to store the error occurring, or %NULL to ignore
299 * Flushed any outstanding buffers in the stream. Will block during
300 * the operation. Closing the stream will implicitly cause a flush.
302 * This function is optional for inherited classes.
304 * If @cancellable is not %NULL, then the operation can be cancelled by
305 * triggering the cancellable object from another thread. If the operation
306 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
308 * Return value: %TRUE on success, %FALSE on error
311 g_output_stream_flush (GOutputStream *stream,
312 GCancellable *cancellable,
315 GOutputStreamClass *class;
318 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
320 if (!g_output_stream_set_pending (stream, error))
323 class = G_OUTPUT_STREAM_GET_CLASS (stream);
329 g_cancellable_push_current (cancellable);
331 res = class->flush (stream, cancellable, error);
334 g_cancellable_pop_current (cancellable);
337 g_output_stream_clear_pending (stream);
343 * g_output_stream_splice:
344 * @stream: a #GOutputStream.
345 * @source: a #GInputStream.
346 * @flags: a set of #GOutputStreamSpliceFlags.
347 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
348 * @error: a #GError location to store the error occurring, or %NULL to
351 * Splices an input stream into an output stream.
353 * Returns: a #gssize containing the size of the data spliced, or
354 * -1 if an error occurred. Note that if the number of bytes
355 * spliced is greater than %G_MAXSSIZE, then that will be
356 * returned, and there is no way to determine the actual number
360 g_output_stream_splice (GOutputStream *stream,
361 GInputStream *source,
362 GOutputStreamSpliceFlags flags,
363 GCancellable *cancellable,
366 GOutputStreamClass *class;
369 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
370 g_return_val_if_fail (G_IS_INPUT_STREAM (source), -1);
372 if (g_input_stream_is_closed (source))
374 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
375 _("Source stream is already closed"));
379 if (!g_output_stream_set_pending (stream, error))
382 class = G_OUTPUT_STREAM_GET_CLASS (stream);
385 g_cancellable_push_current (cancellable);
387 bytes_copied = class->splice (stream, source, flags, cancellable, error);
390 g_cancellable_pop_current (cancellable);
392 g_output_stream_clear_pending (stream);
398 g_output_stream_real_splice (GOutputStream *stream,
399 GInputStream *source,
400 GOutputStreamSpliceFlags flags,
401 GCancellable *cancellable,
404 GOutputStreamClass *class = G_OUTPUT_STREAM_GET_CLASS (stream);
405 gssize n_read, n_written;
407 char buffer[8192], *p;
411 if (class->write_fn == NULL)
413 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
414 _("Output stream doesn't implement write"));
422 n_read = g_input_stream_read (source, buffer, sizeof (buffer), cancellable, error);
435 n_written = class->write_fn (stream, p, n_read, cancellable, error);
444 bytes_copied += n_written;
447 if (bytes_copied > G_MAXSSIZE)
448 bytes_copied = G_MAXSSIZE;
454 error = NULL; /* Ignore further errors */
456 if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE)
458 /* Don't care about errors in source here */
459 g_input_stream_close (source, cancellable, NULL);
462 if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET)
464 /* But write errors on close are bad! */
465 res = _g_output_stream_close_internal (stream, cancellable, error);
474 /* Must always be called inside
475 * g_output_stream_set_pending()/g_output_stream_clear_pending(). */
477 _g_output_stream_close_internal (GOutputStream *stream,
478 GCancellable *cancellable,
481 GOutputStreamClass *class;
484 if (stream->priv->closed)
487 class = G_OUTPUT_STREAM_GET_CLASS (stream);
489 stream->priv->closing = TRUE;
492 g_cancellable_push_current (cancellable);
495 res = class->flush (stream, cancellable, error);
501 /* flushing caused the error that we want to return,
502 * but we still want to close the underlying stream if possible
505 class->close_fn (stream, cancellable, NULL);
511 res = class->close_fn (stream, cancellable, error);
515 g_cancellable_pop_current (cancellable);
517 stream->priv->closing = FALSE;
518 stream->priv->closed = TRUE;
524 * g_output_stream_close:
525 * @stream: A #GOutputStream.
526 * @cancellable: (allow-none): optional cancellable object
527 * @error: location to store the error occurring, or %NULL to ignore
529 * Closes the stream, releasing resources related to it.
531 * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED.
532 * Closing a stream multiple times will not return an error.
534 * Closing a stream will automatically flush any outstanding buffers in the
537 * Streams will be automatically closed when the last reference
538 * is dropped, but you might want to call this function to make sure
539 * resources are released as early as possible.
541 * Some streams might keep the backing store of the stream (e.g. a file descriptor)
542 * open after the stream is closed. See the documentation for the individual
543 * stream for details.
545 * On failure the first error that happened will be reported, but the close
546 * operation will finish as much as possible. A stream that failed to
547 * close will still return %G_IO_ERROR_CLOSED for all operations. Still, it
548 * is important to check and report the error to the user, otherwise
549 * there might be a loss of data as all data might not be written.
551 * If @cancellable is not NULL, then the operation can be cancelled by
552 * triggering the cancellable object from another thread. If the operation
553 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
554 * Cancelling a close will still leave the stream closed, but there some streams
555 * can use a faster close that doesn't block to e.g. check errors. On
556 * cancellation (as with any error) there is no guarantee that all written
557 * data will reach the target.
559 * Return value: %TRUE on success, %FALSE on failure
562 g_output_stream_close (GOutputStream *stream,
563 GCancellable *cancellable,
568 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
570 if (stream->priv->closed)
573 if (!g_output_stream_set_pending (stream, error))
576 res = _g_output_stream_close_internal (stream, cancellable, error);
578 g_output_stream_clear_pending (stream);
584 async_ready_callback_wrapper (GObject *source_object,
588 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
590 g_output_stream_clear_pending (stream);
591 if (stream->priv->outstanding_callback)
592 (*stream->priv->outstanding_callback) (source_object, res, user_data);
593 g_object_unref (stream);
598 GCancellable *cancellable;
604 async_ready_close_callback_wrapper (GObject *source_object,
608 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
609 CloseUserData *data = user_data;
611 stream->priv->closing = FALSE;
612 stream->priv->closed = TRUE;
614 g_output_stream_clear_pending (stream);
616 if (stream->priv->outstanding_callback)
618 if (data->flush_error != NULL)
620 GSimpleAsyncResult *err;
622 err = g_simple_async_result_new_take_error (source_object,
623 stream->priv->outstanding_callback,
626 data->flush_error = NULL;
628 (*stream->priv->outstanding_callback) (source_object,
629 G_ASYNC_RESULT (err),
631 g_object_unref (err);
635 (*stream->priv->outstanding_callback) (source_object,
641 g_object_unref (stream);
643 if (data->cancellable)
644 g_object_unref (data->cancellable);
646 if (data->flush_error)
647 g_error_free (data->flush_error);
649 g_slice_free (CloseUserData, data);
653 async_ready_close_flushed_callback_wrapper (GObject *source_object,
657 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
658 GOutputStreamClass *class;
659 CloseUserData *data = user_data;
660 GSimpleAsyncResult *simple;
662 /* propagate the possible error */
663 if (G_IS_SIMPLE_ASYNC_RESULT (res))
665 simple = G_SIMPLE_ASYNC_RESULT (res);
666 g_simple_async_result_propagate_error (simple, &data->flush_error);
669 class = G_OUTPUT_STREAM_GET_CLASS (stream);
671 /* we still close, even if there was a flush error */
672 class->close_async (stream, data->io_priority, data->cancellable,
673 async_ready_close_callback_wrapper, user_data);
677 * g_output_stream_write_async:
678 * @stream: A #GOutputStream.
679 * @buffer: (array length=count) (element-type guint8): the buffer containing the data to write.
680 * @count: the number of bytes to write
681 * @io_priority: the io priority of the request.
682 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
683 * @callback: (scope async): callback to call when the request is satisfied
684 * @user_data: (closure): the data to pass to callback function
686 * Request an asynchronous write of @count bytes from @buffer into
687 * the stream. When the operation is finished @callback will be called.
688 * You can then call g_output_stream_write_finish() to get the result of the
691 * During an async request no other sync and async calls are allowed,
692 * and will result in %G_IO_ERROR_PENDING errors.
694 * A value of @count larger than %G_MAXSSIZE will cause a
695 * %G_IO_ERROR_INVALID_ARGUMENT error.
697 * On success, the number of bytes written will be passed to the
698 * @callback. It is not an error if this is not the same as the
699 * requested size, as it can happen e.g. on a partial I/O error,
700 * but generally we try to write as many bytes as requested.
702 * You are guaranteed that this method will never fail with
703 * %G_IO_ERROR_WOULD_BLOCK - if @stream can't accept more data, the
704 * method will just wait until this changes.
706 * Any outstanding I/O request with higher priority (lower numerical
707 * value) will be executed before an outstanding request with lower
708 * priority. Default priority is %G_PRIORITY_DEFAULT.
710 * The asyncronous methods have a default fallback that uses threads
711 * to implement asynchronicity, so they are optional for inheriting
712 * classes. However, if you override one you must override all.
714 * For the synchronous, blocking version of this function, see
715 * g_output_stream_write().
718 g_output_stream_write_async (GOutputStream *stream,
722 GCancellable *cancellable,
723 GAsyncReadyCallback callback,
726 GOutputStreamClass *class;
727 GSimpleAsyncResult *simple;
728 GError *error = NULL;
730 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
731 g_return_if_fail (buffer != NULL);
735 simple = g_simple_async_result_new (G_OBJECT (stream),
738 g_output_stream_write_async);
739 g_simple_async_result_complete_in_idle (simple);
740 g_object_unref (simple);
744 if (((gssize) count) < 0)
746 g_simple_async_report_error_in_idle (G_OBJECT (stream),
749 G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
750 _("Too large count value passed to %s"),
755 if (!g_output_stream_set_pending (stream, &error))
757 g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
764 class = G_OUTPUT_STREAM_GET_CLASS (stream);
766 stream->priv->outstanding_callback = callback;
767 g_object_ref (stream);
768 class->write_async (stream, buffer, count, io_priority, cancellable,
769 async_ready_callback_wrapper, user_data);
773 * g_output_stream_write_finish:
774 * @stream: a #GOutputStream.
775 * @result: a #GAsyncResult.
776 * @error: a #GError location to store the error occurring, or %NULL to
779 * Finishes a stream write operation.
781 * Returns: a #gssize containing the number of bytes written to the stream.
784 g_output_stream_write_finish (GOutputStream *stream,
785 GAsyncResult *result,
788 GSimpleAsyncResult *simple;
789 GOutputStreamClass *class;
791 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
792 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
794 if (G_IS_SIMPLE_ASYNC_RESULT (result))
796 simple = G_SIMPLE_ASYNC_RESULT (result);
797 if (g_simple_async_result_propagate_error (simple, error))
800 /* Special case writes of 0 bytes */
801 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_write_async)
805 class = G_OUTPUT_STREAM_GET_CLASS (stream);
806 return class->write_finish (stream, result, error);
810 GInputStream *source;
812 GAsyncReadyCallback callback;
816 async_ready_splice_callback_wrapper (GObject *source_object,
820 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
821 SpliceUserData *data = _data;
823 g_output_stream_clear_pending (stream);
826 (*data->callback) (source_object, res, data->user_data);
828 g_object_unref (stream);
829 g_object_unref (data->source);
834 * g_output_stream_splice_async:
835 * @stream: a #GOutputStream.
836 * @source: a #GInputStream.
837 * @flags: a set of #GOutputStreamSpliceFlags.
838 * @io_priority: the io priority of the request.
839 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
840 * @callback: (scope async): a #GAsyncReadyCallback.
841 * @user_data: (closure): user data passed to @callback.
843 * Splices a stream asynchronously.
844 * When the operation is finished @callback will be called.
845 * You can then call g_output_stream_splice_finish() to get the
846 * result of the operation.
848 * For the synchronous, blocking version of this function, see
849 * g_output_stream_splice().
852 g_output_stream_splice_async (GOutputStream *stream,
853 GInputStream *source,
854 GOutputStreamSpliceFlags flags,
856 GCancellable *cancellable,
857 GAsyncReadyCallback callback,
860 GOutputStreamClass *class;
861 SpliceUserData *data;
862 GError *error = NULL;
864 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
865 g_return_if_fail (G_IS_INPUT_STREAM (source));
867 if (g_input_stream_is_closed (source))
869 g_simple_async_report_error_in_idle (G_OBJECT (stream),
872 G_IO_ERROR, G_IO_ERROR_CLOSED,
873 _("Source stream is already closed"));
877 if (!g_output_stream_set_pending (stream, &error))
879 g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
886 class = G_OUTPUT_STREAM_GET_CLASS (stream);
888 data = g_new0 (SpliceUserData, 1);
889 data->callback = callback;
890 data->user_data = user_data;
891 data->source = g_object_ref (source);
893 g_object_ref (stream);
894 class->splice_async (stream, source, flags, io_priority, cancellable,
895 async_ready_splice_callback_wrapper, data);
899 * g_output_stream_splice_finish:
900 * @stream: a #GOutputStream.
901 * @result: a #GAsyncResult.
902 * @error: a #GError location to store the error occurring, or %NULL to
905 * Finishes an asynchronous stream splice operation.
907 * Returns: a #gssize of the number of bytes spliced. Note that if the
908 * number of bytes spliced is greater than %G_MAXSSIZE, then that
909 * will be returned, and there is no way to determine the actual
910 * number of bytes spliced.
913 g_output_stream_splice_finish (GOutputStream *stream,
914 GAsyncResult *result,
917 GSimpleAsyncResult *simple;
918 GOutputStreamClass *class;
920 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
921 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
923 if (G_IS_SIMPLE_ASYNC_RESULT (result))
925 simple = G_SIMPLE_ASYNC_RESULT (result);
926 if (g_simple_async_result_propagate_error (simple, error))
930 class = G_OUTPUT_STREAM_GET_CLASS (stream);
931 return class->splice_finish (stream, result, error);
935 * g_output_stream_flush_async:
936 * @stream: a #GOutputStream.
937 * @io_priority: the io priority of the request.
938 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
939 * @callback: (scope async): a #GAsyncReadyCallback to call when the request is satisfied
940 * @user_data: (closure): the data to pass to callback function
942 * Flushes a stream asynchronously.
943 * For behaviour details see g_output_stream_flush().
945 * When the operation is finished @callback will be
946 * called. You can then call g_output_stream_flush_finish() to get the
947 * result of the operation.
950 g_output_stream_flush_async (GOutputStream *stream,
952 GCancellable *cancellable,
953 GAsyncReadyCallback callback,
956 GOutputStreamClass *class;
957 GSimpleAsyncResult *simple;
958 GError *error = NULL;
960 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
962 if (!g_output_stream_set_pending (stream, &error))
964 g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
971 stream->priv->outstanding_callback = callback;
972 g_object_ref (stream);
974 class = G_OUTPUT_STREAM_GET_CLASS (stream);
976 if (class->flush_async == NULL)
978 simple = g_simple_async_result_new (G_OBJECT (stream),
979 async_ready_callback_wrapper,
981 g_output_stream_flush_async);
982 g_simple_async_result_complete_in_idle (simple);
983 g_object_unref (simple);
987 class->flush_async (stream, io_priority, cancellable,
988 async_ready_callback_wrapper, user_data);
992 * g_output_stream_flush_finish:
993 * @stream: a #GOutputStream.
994 * @result: a GAsyncResult.
995 * @error: a #GError location to store the error occurring, or %NULL to
998 * Finishes flushing an output stream.
1000 * Returns: %TRUE if flush operation succeeded, %FALSE otherwise.
1003 g_output_stream_flush_finish (GOutputStream *stream,
1004 GAsyncResult *result,
1007 GSimpleAsyncResult *simple;
1008 GOutputStreamClass *klass;
1010 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1011 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
1013 if (G_IS_SIMPLE_ASYNC_RESULT (result))
1015 simple = G_SIMPLE_ASYNC_RESULT (result);
1016 if (g_simple_async_result_propagate_error (simple, error))
1019 /* Special case default implementation */
1020 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_flush_async)
1024 klass = G_OUTPUT_STREAM_GET_CLASS (stream);
1025 return klass->flush_finish (stream, result, error);
1030 * g_output_stream_close_async:
1031 * @stream: A #GOutputStream.
1032 * @io_priority: the io priority of the request.
1033 * @cancellable: (allow-none): optional cancellable object
1034 * @callback: (scope async): callback to call when the request is satisfied
1035 * @user_data: (closure): the data to pass to callback function
1037 * Requests an asynchronous close of the stream, releasing resources
1038 * related to it. When the operation is finished @callback will be
1039 * called. You can then call g_output_stream_close_finish() to get
1040 * the result of the operation.
1042 * For behaviour details see g_output_stream_close().
1044 * The asyncronous methods have a default fallback that uses threads
1045 * to implement asynchronicity, so they are optional for inheriting
1046 * classes. However, if you override one you must override all.
1049 g_output_stream_close_async (GOutputStream *stream,
1051 GCancellable *cancellable,
1052 GAsyncReadyCallback callback,
1055 GOutputStreamClass *class;
1056 GSimpleAsyncResult *simple;
1057 GError *error = NULL;
1058 CloseUserData *data;
1060 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1062 if (stream->priv->closed)
1064 simple = g_simple_async_result_new (G_OBJECT (stream),
1067 g_output_stream_close_async);
1068 g_simple_async_result_complete_in_idle (simple);
1069 g_object_unref (simple);
1073 if (!g_output_stream_set_pending (stream, &error))
1075 g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
1082 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1083 stream->priv->closing = TRUE;
1084 stream->priv->outstanding_callback = callback;
1085 g_object_ref (stream);
1087 data = g_slice_new0 (CloseUserData);
1089 if (cancellable != NULL)
1090 data->cancellable = g_object_ref (cancellable);
1092 data->io_priority = io_priority;
1093 data->user_data = user_data;
1095 /* Call close_async directly if there is no need to flush, or if the flush
1096 can be done sync (in the output stream async close thread) */
1097 if (class->flush_async == NULL ||
1098 (class->flush_async == g_output_stream_real_flush_async &&
1099 (class->flush == NULL || class->close_async == g_output_stream_real_close_async)))
1101 class->close_async (stream, io_priority, cancellable,
1102 async_ready_close_callback_wrapper, data);
1106 /* First do an async flush, then do the async close in the callback
1107 wrapper (see async_ready_close_flushed_callback_wrapper) */
1108 class->flush_async (stream, io_priority, cancellable,
1109 async_ready_close_flushed_callback_wrapper, data);
1114 * g_output_stream_close_finish:
1115 * @stream: a #GOutputStream.
1116 * @result: a #GAsyncResult.
1117 * @error: a #GError location to store the error occurring, or %NULL to
1120 * Closes an output stream.
1122 * Returns: %TRUE if stream was successfully closed, %FALSE otherwise.
1125 g_output_stream_close_finish (GOutputStream *stream,
1126 GAsyncResult *result,
1129 GSimpleAsyncResult *simple;
1130 GOutputStreamClass *class;
1132 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1133 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
1135 if (G_IS_SIMPLE_ASYNC_RESULT (result))
1137 simple = G_SIMPLE_ASYNC_RESULT (result);
1138 if (g_simple_async_result_propagate_error (simple, error))
1141 /* Special case already closed */
1142 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_close_async)
1146 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1147 return class->close_finish (stream, result, error);
1151 * g_output_stream_is_closed:
1152 * @stream: a #GOutputStream.
1154 * Checks if an output stream has already been closed.
1156 * Returns: %TRUE if @stream is closed. %FALSE otherwise.
1159 g_output_stream_is_closed (GOutputStream *stream)
1161 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
1163 return stream->priv->closed;
1167 * g_output_stream_is_closing:
1168 * @stream: a #GOutputStream.
1170 * Checks if an output stream is being closed. This can be
1171 * used inside e.g. a flush implementation to see if the
1172 * flush (or other i/o operation) is called from within
1173 * the closing operation.
1175 * Returns: %TRUE if @stream is being closed. %FALSE otherwise.
1180 g_output_stream_is_closing (GOutputStream *stream)
1182 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
1184 return stream->priv->closing;
1188 * g_output_stream_has_pending:
1189 * @stream: a #GOutputStream.
1191 * Checks if an ouput stream has pending actions.
1193 * Returns: %TRUE if @stream has pending actions.
1196 g_output_stream_has_pending (GOutputStream *stream)
1198 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1200 return stream->priv->pending;
1204 * g_output_stream_set_pending:
1205 * @stream: a #GOutputStream.
1206 * @error: a #GError location to store the error occurring, or %NULL to
1209 * Sets @stream to have actions pending. If the pending flag is
1210 * already set or @stream is closed, it will return %FALSE and set
1213 * Return value: %TRUE if pending was previously unset and is now set.
1216 g_output_stream_set_pending (GOutputStream *stream,
1219 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1221 if (stream->priv->closed)
1223 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
1224 _("Stream is already closed"));
1228 if (stream->priv->pending)
1230 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
1231 /* Translators: This is an error you get if there is
1232 * already an operation running against this stream when
1233 * you try to start one */
1234 _("Stream has outstanding operation"));
1238 stream->priv->pending = TRUE;
1243 * g_output_stream_clear_pending:
1244 * @stream: output stream
1246 * Clears the pending flag on @stream.
1249 g_output_stream_clear_pending (GOutputStream *stream)
1251 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1253 stream->priv->pending = FALSE;
1257 /********************************************
1258 * Default implementation of async ops *
1259 ********************************************/
1263 gsize count_requested;
1264 gssize count_written;
1268 write_async_thread (GSimpleAsyncResult *res,
1270 GCancellable *cancellable)
1273 GOutputStreamClass *class;
1274 GError *error = NULL;
1276 class = G_OUTPUT_STREAM_GET_CLASS (object);
1277 op = g_simple_async_result_get_op_res_gpointer (res);
1278 op->count_written = class->write_fn (G_OUTPUT_STREAM (object), op->buffer, op->count_requested,
1279 cancellable, &error);
1280 if (op->count_written == -1)
1281 g_simple_async_result_take_error (res, error);
1285 g_output_stream_real_write_async (GOutputStream *stream,
1289 GCancellable *cancellable,
1290 GAsyncReadyCallback callback,
1293 GSimpleAsyncResult *res;
1296 op = g_new0 (WriteData, 1);
1297 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
1298 g_simple_async_result_set_op_res_gpointer (res, op, g_free);
1299 op->buffer = buffer;
1300 op->count_requested = count;
1302 g_simple_async_result_run_in_thread (res, write_async_thread, io_priority, cancellable);
1303 g_object_unref (res);
1307 g_output_stream_real_write_finish (GOutputStream *stream,
1308 GAsyncResult *result,
1311 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1314 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_write_async);
1315 op = g_simple_async_result_get_op_res_gpointer (simple);
1316 return op->count_written;
1320 GInputStream *source;
1321 GOutputStreamSpliceFlags flags;
1322 gssize bytes_copied;
1326 splice_async_thread (GSimpleAsyncResult *result,
1328 GCancellable *cancellable)
1331 GOutputStreamClass *class;
1332 GError *error = NULL;
1333 GOutputStream *stream;
1335 stream = G_OUTPUT_STREAM (object);
1336 class = G_OUTPUT_STREAM_GET_CLASS (object);
1337 op = g_simple_async_result_get_op_res_gpointer (result);
1339 op->bytes_copied = class->splice (stream,
1344 if (op->bytes_copied == -1)
1345 g_simple_async_result_take_error (result, error);
1349 g_output_stream_real_splice_async (GOutputStream *stream,
1350 GInputStream *source,
1351 GOutputStreamSpliceFlags flags,
1353 GCancellable *cancellable,
1354 GAsyncReadyCallback callback,
1357 GSimpleAsyncResult *res;
1360 op = g_new0 (SpliceData, 1);
1361 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_splice_async);
1362 g_simple_async_result_set_op_res_gpointer (res, op, g_free);
1364 op->source = source;
1366 /* TODO: In the case where both source and destintion have
1367 non-threadbased async calls we can use a true async copy here */
1369 g_simple_async_result_run_in_thread (res, splice_async_thread, io_priority, cancellable);
1370 g_object_unref (res);
1374 g_output_stream_real_splice_finish (GOutputStream *stream,
1375 GAsyncResult *result,
1378 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1381 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_splice_async);
1382 op = g_simple_async_result_get_op_res_gpointer (simple);
1383 return op->bytes_copied;
1388 flush_async_thread (GSimpleAsyncResult *res,
1390 GCancellable *cancellable)
1392 GOutputStreamClass *class;
1394 GError *error = NULL;
1396 class = G_OUTPUT_STREAM_GET_CLASS (object);
1399 result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error);
1402 g_simple_async_result_take_error (res, error);
1406 g_output_stream_real_flush_async (GOutputStream *stream,
1408 GCancellable *cancellable,
1409 GAsyncReadyCallback callback,
1412 GSimpleAsyncResult *res;
1414 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
1416 g_simple_async_result_run_in_thread (res, flush_async_thread, io_priority, cancellable);
1417 g_object_unref (res);
1421 g_output_stream_real_flush_finish (GOutputStream *stream,
1422 GAsyncResult *result,
1429 close_async_thread (GSimpleAsyncResult *res,
1431 GCancellable *cancellable)
1433 GOutputStreamClass *class;
1434 GError *error = NULL;
1435 gboolean result = TRUE;
1437 class = G_OUTPUT_STREAM_GET_CLASS (object);
1439 /* Do a flush here if there is a flush function, and we did not have to do
1440 an async flush before (see g_output_stream_close_async) */
1441 if (class->flush != NULL &&
1442 (class->flush_async == NULL ||
1443 class->flush_async == g_output_stream_real_flush_async))
1445 result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error);
1448 /* Auto handling of cancelation disabled, and ignore
1449 cancellation, since we want to close things anyway, although
1450 possibly in a quick-n-dirty way. At least we never want to leak
1453 if (class->close_fn)
1455 /* Make sure to close, even if the flush failed (see sync close) */
1457 class->close_fn (G_OUTPUT_STREAM (object), cancellable, NULL);
1459 result = class->close_fn (G_OUTPUT_STREAM (object), cancellable, &error);
1462 g_simple_async_result_take_error (res, error);
1467 g_output_stream_real_close_async (GOutputStream *stream,
1469 GCancellable *cancellable,
1470 GAsyncReadyCallback callback,
1473 GSimpleAsyncResult *res;
1475 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_close_async);
1477 g_simple_async_result_set_handle_cancellation (res, FALSE);
1479 g_simple_async_result_run_in_thread (res, close_async_thread, io_priority, cancellable);
1480 g_object_unref (res);
1484 g_output_stream_real_close_finish (GOutputStream *stream,
1485 GAsyncResult *result,
1488 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1489 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_close_async);