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"
35 * SECTION:goutputstream
36 * @short_description: Base class for implementing streaming output
39 * GOutputStream has functions to write to a stream (g_output_stream_write()),
40 * to close a stream (g_output_stream_close()) and to flush pending writes
41 * (g_output_stream_flush()).
43 * To copy the content of an input stream to an output stream without
44 * manually handling the reads and writes, use g_output_stream_splice().
46 * All of these functions have async variants too.
49 G_DEFINE_TYPE (GOutputStream, g_output_stream, G_TYPE_OBJECT);
51 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,
100 g_output_stream_finalize (GObject *object)
102 G_OBJECT_CLASS (g_output_stream_parent_class)->finalize (object);
106 g_output_stream_dispose (GObject *object)
108 GOutputStream *stream;
110 stream = G_OUTPUT_STREAM (object);
112 if (!stream->priv->closed)
113 g_output_stream_close (stream, NULL, NULL);
115 G_OBJECT_CLASS (g_output_stream_parent_class)->dispose (object);
119 g_output_stream_class_init (GOutputStreamClass *klass)
121 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
123 g_type_class_add_private (klass, sizeof (GOutputStreamPrivate));
125 gobject_class->finalize = g_output_stream_finalize;
126 gobject_class->dispose = g_output_stream_dispose;
128 klass->splice = g_output_stream_real_splice;
130 klass->write_async = g_output_stream_real_write_async;
131 klass->write_finish = g_output_stream_real_write_finish;
132 klass->splice_async = g_output_stream_real_splice_async;
133 klass->splice_finish = g_output_stream_real_splice_finish;
134 klass->flush_async = g_output_stream_real_flush_async;
135 klass->flush_finish = g_output_stream_real_flush_finish;
136 klass->close_async = g_output_stream_real_close_async;
137 klass->close_finish = g_output_stream_real_close_finish;
141 g_output_stream_init (GOutputStream *stream)
143 stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
144 G_TYPE_OUTPUT_STREAM,
145 GOutputStreamPrivate);
149 * g_output_stream_write:
150 * @stream: a #GOutputStream.
151 * @buffer: the buffer containing the data to write.
152 * @count: the number of bytes to write
153 * @cancellable: optional cancellable object
154 * @error: location to store the error occuring, or %NULL to ignore
156 * Tries to write @count bytes from @buffer into the stream. Will block
157 * during the operation.
159 * If count is zero returns zero and does nothing. A value of @count
160 * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
162 * On success, the number of bytes written to the stream is returned.
163 * It is not an error if this is not the same as the requested size, as it
164 * can happen e.g. on a partial i/o error, or if there is not enough
165 * storage in the stream. All writes either block until at least one byte
166 * is written, so zero is never returned (unless @count is zero).
168 * If @cancellable is not NULL, then the operation can be cancelled by
169 * triggering the cancellable object from another thread. If the operation
170 * was cancelled, the error G_IO_ERROR_CANCELLED will be returned. If an
171 * operation was partially finished when the operation was cancelled the
172 * partial result will be returned, without an error.
174 * On error -1 is returned and @error is set accordingly.
176 * Return value: Number of bytes written, or -1 on error
179 g_output_stream_write (GOutputStream *stream,
182 GCancellable *cancellable,
185 GOutputStreamClass *class;
188 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
189 g_return_val_if_fail (buffer != NULL, 0);
194 if (((gssize) count) < 0)
196 g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
197 _("Too large count value passed to %s"), G_STRFUNC);
201 class = G_OUTPUT_STREAM_GET_CLASS (stream);
203 if (class->write_fn == NULL)
205 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
206 _("Output stream doesn't implement write"));
210 if (!g_output_stream_set_pending (stream, error))
214 g_cancellable_push_current (cancellable);
216 res = class->write_fn (stream, buffer, count, cancellable, error);
219 g_cancellable_pop_current (cancellable);
221 g_output_stream_clear_pending (stream);
227 * g_output_stream_write_all:
228 * @stream: a #GOutputStream.
229 * @buffer: the buffer containing the data to write.
230 * @count: the number of bytes to write
231 * @bytes_written: location to store the number of bytes that was
232 * written to the stream
233 * @cancellable: optional #GCancellable object, %NULL to ignore.
234 * @error: location to store the error occuring, or %NULL to ignore
236 * Tries to write @count bytes from @buffer into the stream. Will block
237 * during the operation.
239 * This function is similar to g_output_stream_write(), except it tries to
240 * write as many bytes as requested, only stopping on an error.
242 * On a successful write of @count bytes, %TRUE is returned, and @bytes_written
245 * If there is an error during the operation FALSE is returned and @error
246 * is set to indicate the error status, @bytes_written is updated to contain
247 * the number of bytes written into the stream before the error occurred.
249 * Return value: %TRUE on success, %FALSE if there was an error
252 g_output_stream_write_all (GOutputStream *stream,
255 gsize *bytes_written,
256 GCancellable *cancellable,
259 gsize _bytes_written;
262 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
263 g_return_val_if_fail (buffer != NULL, FALSE);
266 while (_bytes_written < count)
268 res = g_output_stream_write (stream, (char *)buffer + _bytes_written, count - _bytes_written,
273 *bytes_written = _bytes_written;
278 g_warning ("Write returned zero without error");
280 _bytes_written += res;
284 *bytes_written = _bytes_written;
290 * g_output_stream_flush:
291 * @stream: a #GOutputStream.
292 * @cancellable: optional cancellable object
293 * @error: location to store the error occuring, or %NULL to ignore
295 * Flushed any outstanding buffers in the stream. Will block during
296 * the operation. Closing the stream will implicitly cause a flush.
298 * This function is optional for inherited classes.
300 * If @cancellable is not %NULL, then the operation can be cancelled by
301 * triggering the cancellable object from another thread. If the operation
302 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
304 * Return value: %TRUE on success, %FALSE on error
307 g_output_stream_flush (GOutputStream *stream,
308 GCancellable *cancellable,
311 GOutputStreamClass *class;
314 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
316 if (!g_output_stream_set_pending (stream, error))
319 class = G_OUTPUT_STREAM_GET_CLASS (stream);
325 g_cancellable_push_current (cancellable);
327 res = class->flush (stream, cancellable, error);
330 g_cancellable_pop_current (cancellable);
333 g_output_stream_clear_pending (stream);
339 * g_output_stream_splice:
340 * @stream: a #GOutputStream.
341 * @source: a #GInputStream.
342 * @flags: a set of #GOutputStreamSpliceFlags.
343 * @cancellable: optional #GCancellable object, %NULL to ignore.
344 * @error: a #GError location to store the error occuring, or %NULL to
347 * Splices an input stream into an output stream.
349 * Returns: a #gssize containing the size of the data spliced, or
350 * -1 if an error occurred.
353 g_output_stream_splice (GOutputStream *stream,
354 GInputStream *source,
355 GOutputStreamSpliceFlags flags,
356 GCancellable *cancellable,
359 GOutputStreamClass *class;
362 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
363 g_return_val_if_fail (G_IS_INPUT_STREAM (source), -1);
365 if (g_input_stream_is_closed (source))
367 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
368 _("Source stream is already closed"));
372 if (!g_output_stream_set_pending (stream, error))
375 class = G_OUTPUT_STREAM_GET_CLASS (stream);
378 g_cancellable_push_current (cancellable);
380 bytes_copied = class->splice (stream, source, flags, cancellable, error);
383 g_cancellable_pop_current (cancellable);
385 g_output_stream_clear_pending (stream);
391 g_output_stream_real_splice (GOutputStream *stream,
392 GInputStream *source,
393 GOutputStreamSpliceFlags flags,
394 GCancellable *cancellable,
397 GOutputStreamClass *class = G_OUTPUT_STREAM_GET_CLASS (stream);
398 gssize n_read, n_written;
400 char buffer[8192], *p;
404 if (class->write_fn == NULL)
406 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
407 _("Output stream doesn't implement write"));
415 n_read = g_input_stream_read (source, buffer, sizeof (buffer), cancellable, error);
428 n_written = class->write_fn (stream, p, n_read, cancellable, error);
437 bytes_copied += n_written;
444 error = NULL; /* Ignore further errors */
446 if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE)
448 /* Don't care about errors in source here */
449 g_input_stream_close (source, cancellable, NULL);
452 if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET)
454 /* But write errors on close are bad! */
455 if (class->close_fn &&
456 !class->close_fn (stream, cancellable, error))
468 * g_output_stream_close:
469 * @stream: A #GOutputStream.
470 * @cancellable: optional cancellable object
471 * @error: location to store the error occuring, or %NULL to ignore
473 * Closes the stream, releasing resources related to it.
475 * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED.
476 * Closing a stream multiple times will not return an error.
478 * Closing a stream will automatically flush any outstanding buffers in the
481 * Streams will be automatically closed when the last reference
482 * is dropped, but you might want to call this function to make sure
483 * resources are released as early as possible.
485 * Some streams might keep the backing store of the stream (e.g. a file descriptor)
486 * open after the stream is closed. See the documentation for the individual
487 * stream for details.
489 * On failure the first error that happened will be reported, but the close
490 * operation will finish as much as possible. A stream that failed to
491 * close will still return %G_IO_ERROR_CLOSED for all operations. Still, it
492 * is important to check and report the error to the user, otherwise
493 * there might be a loss of data as all data might not be written.
495 * If @cancellable is not NULL, then the operation can be cancelled by
496 * triggering the cancellable object from another thread. If the operation
497 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
498 * Cancelling a close will still leave the stream closed, but there some streams
499 * can use a faster close that doesn't block to e.g. check errors. On
500 * cancellation (as with any error) there is no guarantee that all written
501 * data will reach the target.
503 * Return value: %TRUE on success, %FALSE on failure
506 g_output_stream_close (GOutputStream *stream,
507 GCancellable *cancellable,
510 GOutputStreamClass *class;
513 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
515 class = G_OUTPUT_STREAM_GET_CLASS (stream);
517 if (stream->priv->closed)
520 if (!g_output_stream_set_pending (stream, error))
524 g_cancellable_push_current (cancellable);
527 res = class->flush (stream, cancellable, error);
533 /* flushing caused the error that we want to return,
534 * but we still want to close the underlying stream if possible
537 class->close_fn (stream, cancellable, NULL);
543 res = class->close_fn (stream, cancellable, error);
547 g_cancellable_pop_current (cancellable);
549 stream->priv->closed = TRUE;
550 g_output_stream_clear_pending (stream);
556 async_ready_callback_wrapper (GObject *source_object,
560 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
562 g_output_stream_clear_pending (stream);
563 if (stream->priv->outstanding_callback)
564 (*stream->priv->outstanding_callback) (source_object, res, user_data);
565 g_object_unref (stream);
569 async_ready_close_callback_wrapper (GObject *source_object,
573 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
575 stream->priv->closed = TRUE;
576 g_output_stream_clear_pending (stream);
577 if (stream->priv->outstanding_callback)
578 (*stream->priv->outstanding_callback) (source_object, res, user_data);
579 g_object_unref (stream);
583 * g_output_stream_write_async:
584 * @stream: A #GOutputStream.
585 * @buffer: the buffer containing the data to write.
586 * @count: the number of bytes to write
587 * @io_priority: the io priority of the request.
588 * @cancellable: optional #GCancellable object, %NULL to ignore.
589 * @callback: callback to call when the request is satisfied
590 * @user_data: the data to pass to callback function
592 * Request an asynchronous write of @count bytes from @buffer into
593 * the stream. When the operation is finished @callback will be called.
594 * You can then call g_output_stream_write_finish() to get the result of the
597 * During an async request no other sync and async calls are allowed,
598 * and will result in %G_IO_ERROR_PENDING errors.
600 * A value of @count larger than %G_MAXSSIZE will cause a
601 * %G_IO_ERROR_INVALID_ARGUMENT error.
603 * On success, the number of bytes written will be passed to the
604 * @callback. It is not an error if this is not the same as the
605 * requested size, as it can happen e.g. on a partial I/O error,
606 * but generally we try to write as many bytes as requested.
608 * Any outstanding I/O request with higher priority (lower numerical
609 * value) will be executed before an outstanding request with lower
610 * priority. Default priority is %G_PRIORITY_DEFAULT.
612 * The asyncronous methods have a default fallback that uses threads
613 * to implement asynchronicity, so they are optional for inheriting
614 * classes. However, if you override one you must override all.
616 * For the synchronous, blocking version of this function, see
617 * g_output_stream_write().
620 g_output_stream_write_async (GOutputStream *stream,
624 GCancellable *cancellable,
625 GAsyncReadyCallback callback,
628 GOutputStreamClass *class;
629 GSimpleAsyncResult *simple;
630 GError *error = NULL;
632 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
633 g_return_if_fail (buffer != NULL);
637 simple = g_simple_async_result_new (G_OBJECT (stream),
640 g_output_stream_write_async);
641 g_simple_async_result_complete_in_idle (simple);
642 g_object_unref (simple);
646 if (((gssize) count) < 0)
648 g_simple_async_report_error_in_idle (G_OBJECT (stream),
651 G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
652 _("Too large count value passed to %s"),
657 if (!g_output_stream_set_pending (stream, &error))
659 g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
663 g_error_free (error);
667 class = G_OUTPUT_STREAM_GET_CLASS (stream);
669 stream->priv->outstanding_callback = callback;
670 g_object_ref (stream);
671 class->write_async (stream, buffer, count, io_priority, cancellable,
672 async_ready_callback_wrapper, user_data);
676 * g_output_stream_write_finish:
677 * @stream: a #GOutputStream.
678 * @result: a #GAsyncResult.
679 * @error: a #GError location to store the error occuring, or %NULL to
682 * Finishes a stream write operation.
684 * Returns: a #gssize containing the number of bytes written to the stream.
687 g_output_stream_write_finish (GOutputStream *stream,
688 GAsyncResult *result,
691 GSimpleAsyncResult *simple;
692 GOutputStreamClass *class;
694 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
695 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
697 if (G_IS_SIMPLE_ASYNC_RESULT (result))
699 simple = G_SIMPLE_ASYNC_RESULT (result);
700 if (g_simple_async_result_propagate_error (simple, error))
703 /* Special case writes of 0 bytes */
704 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_write_async)
708 class = G_OUTPUT_STREAM_GET_CLASS (stream);
709 return class->write_finish (stream, result, error);
713 GInputStream *source;
715 GAsyncReadyCallback callback;
719 async_ready_splice_callback_wrapper (GObject *source_object,
723 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
724 SpliceUserData *data = _data;
726 g_output_stream_clear_pending (stream);
729 (*data->callback) (source_object, res, data->user_data);
731 g_object_unref (stream);
732 g_object_unref (data->source);
737 * g_output_stream_splice_async:
738 * @stream: a #GOutputStream.
739 * @source: a #GInputStream.
740 * @flags: a set of #GOutputStreamSpliceFlags.
741 * @io_priority: the io priority of the request.
742 * @cancellable: optional #GCancellable object, %NULL to ignore.
743 * @callback: a #GAsyncReadyCallback.
744 * @user_data: user data passed to @callback.
746 * Splices a stream asynchronously.
747 * When the operation is finished @callback will be called.
748 * You can then call g_output_stream_splice_finish() to get the
749 * result of the operation.
751 * For the synchronous, blocking version of this function, see
752 * g_output_stream_splice().
755 g_output_stream_splice_async (GOutputStream *stream,
756 GInputStream *source,
757 GOutputStreamSpliceFlags flags,
759 GCancellable *cancellable,
760 GAsyncReadyCallback callback,
763 GOutputStreamClass *class;
764 SpliceUserData *data;
765 GError *error = NULL;
767 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
768 g_return_if_fail (G_IS_INPUT_STREAM (source));
770 if (g_input_stream_is_closed (source))
772 g_simple_async_report_error_in_idle (G_OBJECT (stream),
775 G_IO_ERROR, G_IO_ERROR_CLOSED,
776 _("Source stream is already closed"));
780 if (!g_output_stream_set_pending (stream, &error))
782 g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
786 g_error_free (error);
790 class = G_OUTPUT_STREAM_GET_CLASS (stream);
792 data = g_new0 (SpliceUserData, 1);
793 data->callback = callback;
794 data->user_data = user_data;
795 data->source = g_object_ref (source);
797 g_object_ref (stream);
798 class->splice_async (stream, source, flags, io_priority, cancellable,
799 async_ready_splice_callback_wrapper, data);
803 * g_output_stream_splice_finish:
804 * @stream: a #GOutputStream.
805 * @result: a #GAsyncResult.
806 * @error: a #GError location to store the error occuring, or %NULL to
809 * Finishes an asynchronous stream splice operation.
811 * Returns: a #gssize of the number of bytes spliced.
814 g_output_stream_splice_finish (GOutputStream *stream,
815 GAsyncResult *result,
818 GSimpleAsyncResult *simple;
819 GOutputStreamClass *class;
821 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
822 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
824 if (G_IS_SIMPLE_ASYNC_RESULT (result))
826 simple = G_SIMPLE_ASYNC_RESULT (result);
827 if (g_simple_async_result_propagate_error (simple, error))
831 class = G_OUTPUT_STREAM_GET_CLASS (stream);
832 return class->splice_finish (stream, result, error);
836 * g_output_stream_flush_async:
837 * @stream: a #GOutputStream.
838 * @io_priority: the io priority of the request.
839 * @cancellable: optional #GCancellable object, %NULL to ignore.
840 * @callback: a #GAsyncReadyCallback to call when the request is satisfied
841 * @user_data: the data to pass to callback function
843 * Flushes a stream asynchronously.
844 * For behaviour details see g_output_stream_flush().
846 * When the operation is finished @callback will be
847 * called. You can then call g_output_stream_flush_finish() to get the
848 * result of the operation.
851 g_output_stream_flush_async (GOutputStream *stream,
853 GCancellable *cancellable,
854 GAsyncReadyCallback callback,
857 GOutputStreamClass *class;
858 GSimpleAsyncResult *simple;
859 GError *error = NULL;
861 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
863 if (!g_output_stream_set_pending (stream, &error))
865 g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
869 g_error_free (error);
873 stream->priv->outstanding_callback = callback;
874 g_object_ref (stream);
876 class = G_OUTPUT_STREAM_GET_CLASS (stream);
878 if (class->flush_async == NULL)
880 simple = g_simple_async_result_new (G_OBJECT (stream),
881 async_ready_callback_wrapper,
883 g_output_stream_flush_async);
884 g_simple_async_result_complete_in_idle (simple);
885 g_object_unref (simple);
889 class->flush_async (stream, io_priority, cancellable,
890 async_ready_callback_wrapper, user_data);
894 * g_output_stream_flush_finish:
895 * @stream: a #GOutputStream.
896 * @result: a GAsyncResult.
897 * @error: a #GError location to store the error occuring, or %NULL to
900 * Finishes flushing an output stream.
902 * Returns: %TRUE if flush operation suceeded, %FALSE otherwise.
905 g_output_stream_flush_finish (GOutputStream *stream,
906 GAsyncResult *result,
909 GSimpleAsyncResult *simple;
910 GOutputStreamClass *klass;
912 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
913 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
915 if (G_IS_SIMPLE_ASYNC_RESULT (result))
917 simple = G_SIMPLE_ASYNC_RESULT (result);
918 if (g_simple_async_result_propagate_error (simple, error))
921 /* Special case default implementation */
922 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_flush_async)
926 klass = G_OUTPUT_STREAM_GET_CLASS (stream);
927 return klass->flush_finish (stream, result, error);
932 * g_output_stream_close_async:
933 * @stream: A #GOutputStream.
934 * @io_priority: the io priority of the request.
935 * @callback: callback to call when the request is satisfied
936 * @user_data: the data to pass to callback function
937 * @cancellable: optional cancellable object
939 * Requests an asynchronous close of the stream, releasing resources
940 * related to it. When the operation is finished @callback will be
941 * called. You can then call g_output_stream_close_finish() to get
942 * the result of the operation.
944 * For behaviour details see g_output_stream_close().
946 * The asyncronous methods have a default fallback that uses threads
947 * to implement asynchronicity, so they are optional for inheriting
948 * classes. However, if you override one you must override all.
951 g_output_stream_close_async (GOutputStream *stream,
953 GCancellable *cancellable,
954 GAsyncReadyCallback callback,
957 GOutputStreamClass *class;
958 GSimpleAsyncResult *simple;
959 GError *error = NULL;
961 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
963 if (stream->priv->closed)
965 simple = g_simple_async_result_new (G_OBJECT (stream),
968 g_output_stream_close_async);
969 g_simple_async_result_complete_in_idle (simple);
970 g_object_unref (simple);
974 if (!g_output_stream_set_pending (stream, &error))
976 g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
980 g_error_free (error);
984 class = G_OUTPUT_STREAM_GET_CLASS (stream);
985 stream->priv->outstanding_callback = callback;
986 g_object_ref (stream);
987 class->close_async (stream, io_priority, cancellable,
988 async_ready_close_callback_wrapper, user_data);
992 * g_output_stream_close_finish:
993 * @stream: a #GOutputStream.
994 * @result: a #GAsyncResult.
995 * @error: a #GError location to store the error occuring, or %NULL to
998 * Closes an output stream.
1000 * Returns: %TRUE if stream was successfully closed, %FALSE otherwise.
1003 g_output_stream_close_finish (GOutputStream *stream,
1004 GAsyncResult *result,
1007 GSimpleAsyncResult *simple;
1008 GOutputStreamClass *class;
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 already closed */
1020 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_close_async)
1024 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1025 return class->close_finish (stream, result, error);
1029 * g_output_stream_is_closed:
1030 * @stream: a #GOutputStream.
1032 * Checks if an output stream has already been closed.
1034 * Returns: %TRUE if @stream is closed. %FALSE otherwise.
1037 g_output_stream_is_closed (GOutputStream *stream)
1039 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
1041 return stream->priv->closed;
1045 * g_output_stream_has_pending:
1046 * @stream: a #GOutputStream.
1048 * Checks if an ouput stream has pending actions.
1050 * Returns: %TRUE if @stream has pending actions.
1053 g_output_stream_has_pending (GOutputStream *stream)
1055 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1057 return stream->priv->pending;
1061 * g_output_stream_set_pending:
1062 * @stream: a #GOutputStream.
1063 * @error: a #GError location to store the error occuring, or %NULL to
1066 * Sets @stream to have actions pending. If the pending flag is
1067 * already set or @stream is closed, it will return %FALSE and set
1070 * Return value: %TRUE if pending was previously unset and is now set.
1073 g_output_stream_set_pending (GOutputStream *stream,
1076 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1078 if (stream->priv->closed)
1080 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
1081 _("Stream is already closed"));
1085 if (stream->priv->pending)
1087 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
1088 /* Translators: This is an error you get if there is
1089 * already an operation running against this stream when
1090 * you try to start one */
1091 _("Stream has outstanding operation"));
1095 stream->priv->pending = TRUE;
1100 * g_output_stream_clear_pending:
1101 * @stream: output stream
1103 * Clears the pending flag on @stream.
1106 g_output_stream_clear_pending (GOutputStream *stream)
1108 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1110 stream->priv->pending = FALSE;
1114 /********************************************
1115 * Default implementation of async ops *
1116 ********************************************/
1120 gsize count_requested;
1121 gssize count_written;
1125 write_async_thread (GSimpleAsyncResult *res,
1127 GCancellable *cancellable)
1130 GOutputStreamClass *class;
1131 GError *error = NULL;
1133 class = G_OUTPUT_STREAM_GET_CLASS (object);
1134 op = g_simple_async_result_get_op_res_gpointer (res);
1135 op->count_written = class->write_fn (G_OUTPUT_STREAM (object), op->buffer, op->count_requested,
1136 cancellable, &error);
1137 if (op->count_written == -1)
1139 g_simple_async_result_set_from_error (res, error);
1140 g_error_free (error);
1145 g_output_stream_real_write_async (GOutputStream *stream,
1149 GCancellable *cancellable,
1150 GAsyncReadyCallback callback,
1153 GSimpleAsyncResult *res;
1156 op = g_new0 (WriteData, 1);
1157 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
1158 g_simple_async_result_set_op_res_gpointer (res, op, g_free);
1159 op->buffer = buffer;
1160 op->count_requested = count;
1162 g_simple_async_result_run_in_thread (res, write_async_thread, io_priority, cancellable);
1163 g_object_unref (res);
1167 g_output_stream_real_write_finish (GOutputStream *stream,
1168 GAsyncResult *result,
1171 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1174 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_write_async);
1175 op = g_simple_async_result_get_op_res_gpointer (simple);
1176 return op->count_written;
1180 GInputStream *source;
1181 GOutputStreamSpliceFlags flags;
1182 gssize bytes_copied;
1186 splice_async_thread (GSimpleAsyncResult *result,
1188 GCancellable *cancellable)
1191 GOutputStreamClass *class;
1192 GError *error = NULL;
1193 GOutputStream *stream;
1195 stream = G_OUTPUT_STREAM (object);
1196 class = G_OUTPUT_STREAM_GET_CLASS (object);
1197 op = g_simple_async_result_get_op_res_gpointer (result);
1199 op->bytes_copied = class->splice (stream,
1204 if (op->bytes_copied == -1)
1206 g_simple_async_result_set_from_error (result, error);
1207 g_error_free (error);
1212 g_output_stream_real_splice_async (GOutputStream *stream,
1213 GInputStream *source,
1214 GOutputStreamSpliceFlags flags,
1216 GCancellable *cancellable,
1217 GAsyncReadyCallback callback,
1220 GSimpleAsyncResult *res;
1223 op = g_new0 (SpliceData, 1);
1224 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_splice_async);
1225 g_simple_async_result_set_op_res_gpointer (res, op, g_free);
1227 op->source = source;
1229 /* TODO: In the case where both source and destintion have
1230 non-threadbased async calls we can use a true async copy here */
1232 g_simple_async_result_run_in_thread (res, splice_async_thread, io_priority, cancellable);
1233 g_object_unref (res);
1237 g_output_stream_real_splice_finish (GOutputStream *stream,
1238 GAsyncResult *result,
1241 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1244 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_splice_async);
1245 op = g_simple_async_result_get_op_res_gpointer (simple);
1246 return op->bytes_copied;
1251 flush_async_thread (GSimpleAsyncResult *res,
1253 GCancellable *cancellable)
1255 GOutputStreamClass *class;
1257 GError *error = NULL;
1259 class = G_OUTPUT_STREAM_GET_CLASS (object);
1262 result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error);
1266 g_simple_async_result_set_from_error (res, error);
1267 g_error_free (error);
1272 g_output_stream_real_flush_async (GOutputStream *stream,
1274 GCancellable *cancellable,
1275 GAsyncReadyCallback callback,
1278 GSimpleAsyncResult *res;
1280 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
1282 g_simple_async_result_run_in_thread (res, flush_async_thread, io_priority, cancellable);
1283 g_object_unref (res);
1287 g_output_stream_real_flush_finish (GOutputStream *stream,
1288 GAsyncResult *result,
1295 close_async_thread (GSimpleAsyncResult *res,
1297 GCancellable *cancellable)
1299 GOutputStreamClass *class;
1300 GError *error = NULL;
1303 /* Auto handling of cancelation disabled, and ignore
1304 cancellation, since we want to close things anyway, although
1305 possibly in a quick-n-dirty way. At least we never want to leak
1308 class = G_OUTPUT_STREAM_GET_CLASS (object);
1309 if (class->close_fn)
1311 result = class->close_fn (G_OUTPUT_STREAM (object), cancellable, &error);
1314 g_simple_async_result_set_from_error (res, error);
1315 g_error_free (error);
1321 g_output_stream_real_close_async (GOutputStream *stream,
1323 GCancellable *cancellable,
1324 GAsyncReadyCallback callback,
1327 GSimpleAsyncResult *res;
1329 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_close_async);
1331 g_simple_async_result_set_handle_cancellation (res, FALSE);
1333 g_simple_async_result_run_in_thread (res, close_async_thread, io_priority, cancellable);
1334 g_object_unref (res);
1338 g_output_stream_real_close_finish (GOutputStream *stream,
1339 GAsyncResult *result,
1342 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1343 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_close_async);
1347 #define __G_OUTPUT_STREAM_C__
1348 #include "gioaliasdef.c"