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 {
55 GAsyncReadyCallback outstanding_callback;
58 static gssize g_output_stream_real_splice (GOutputStream *stream,
60 GOutputStreamSpliceFlags flags,
61 GCancellable *cancellable,
63 static void g_output_stream_real_write_async (GOutputStream *stream,
67 GCancellable *cancellable,
68 GAsyncReadyCallback callback,
70 static gssize g_output_stream_real_write_finish (GOutputStream *stream,
73 static void g_output_stream_real_splice_async (GOutputStream *stream,
75 GOutputStreamSpliceFlags flags,
77 GCancellable *cancellable,
78 GAsyncReadyCallback callback,
80 static gssize g_output_stream_real_splice_finish (GOutputStream *stream,
83 static void g_output_stream_real_flush_async (GOutputStream *stream,
85 GCancellable *cancellable,
86 GAsyncReadyCallback callback,
88 static gboolean g_output_stream_real_flush_finish (GOutputStream *stream,
91 static void g_output_stream_real_close_async (GOutputStream *stream,
93 GCancellable *cancellable,
94 GAsyncReadyCallback callback,
96 static gboolean g_output_stream_real_close_finish (GOutputStream *stream,
101 g_output_stream_finalize (GObject *object)
103 GOutputStream *stream;
105 stream = G_OUTPUT_STREAM (object);
107 G_OBJECT_CLASS (g_output_stream_parent_class)->finalize (object);
111 g_output_stream_dispose (GObject *object)
113 GOutputStream *stream;
115 stream = G_OUTPUT_STREAM (object);
117 if (!stream->priv->closed)
118 g_output_stream_close (stream, NULL, NULL);
120 G_OBJECT_CLASS (g_output_stream_parent_class)->dispose (object);
124 g_output_stream_class_init (GOutputStreamClass *klass)
126 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
128 g_type_class_add_private (klass, sizeof (GOutputStreamPrivate));
130 gobject_class->finalize = g_output_stream_finalize;
131 gobject_class->dispose = g_output_stream_dispose;
133 klass->splice = g_output_stream_real_splice;
135 klass->write_async = g_output_stream_real_write_async;
136 klass->write_finish = g_output_stream_real_write_finish;
137 klass->splice_async = g_output_stream_real_splice_async;
138 klass->splice_finish = g_output_stream_real_splice_finish;
139 klass->flush_async = g_output_stream_real_flush_async;
140 klass->flush_finish = g_output_stream_real_flush_finish;
141 klass->close_async = g_output_stream_real_close_async;
142 klass->close_finish = g_output_stream_real_close_finish;
146 g_output_stream_init (GOutputStream *stream)
148 stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
149 G_TYPE_OUTPUT_STREAM,
150 GOutputStreamPrivate);
154 * g_output_stream_write:
155 * @stream: a #GOutputStream.
156 * @buffer: the buffer containing the data to write.
157 * @count: the number of bytes to write
158 * @cancellable: optional cancellable object
159 * @error: location to store the error occuring, or %NULL to ignore
161 * Tries to write @count bytes from @buffer into the stream. Will block
162 * during the operation.
164 * If count is zero returns zero and does nothing. A value of @count
165 * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
167 * On success, the number of bytes written to the stream is returned.
168 * It is not an error if this is not the same as the requested size, as it
169 * can happen e.g. on a partial i/o error, or if there is not enough
170 * storage in the stream. All writes either block until at least one byte
171 * is written, so zero is never returned (unless @count is zero).
173 * If @cancellable is not NULL, then the operation can be cancelled by
174 * triggering the cancellable object from another thread. If the operation
175 * was cancelled, the error G_IO_ERROR_CANCELLED will be returned. If an
176 * operation was partially finished when the operation was cancelled the
177 * partial result will be returned, without an error.
179 * On error -1 is returned and @error is set accordingly.
181 * Return value: Number of bytes written, or -1 on error
184 g_output_stream_write (GOutputStream *stream,
187 GCancellable *cancellable,
190 GOutputStreamClass *class;
193 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
194 g_return_val_if_fail (buffer != NULL, 0);
199 if (((gssize) count) < 0)
201 g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
202 _("Too large count value passed to %s"), G_STRFUNC);
206 class = G_OUTPUT_STREAM_GET_CLASS (stream);
208 if (class->write_fn == NULL)
210 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
211 _("Output stream doesn't implement write"));
215 if (!g_output_stream_set_pending (stream, error))
219 g_cancellable_push_current (cancellable);
221 res = class->write_fn (stream, buffer, count, cancellable, error);
224 g_cancellable_pop_current (cancellable);
226 g_output_stream_clear_pending (stream);
232 * g_output_stream_write_all:
233 * @stream: a #GOutputStream.
234 * @buffer: the buffer containing the data to write.
235 * @count: the number of bytes to write
236 * @bytes_written: location to store the number of bytes that was
237 * written to the stream
238 * @cancellable: optional #GCancellable object, %NULL to ignore.
239 * @error: location to store the error occuring, or %NULL to ignore
241 * Tries to write @count bytes from @buffer into the stream. Will block
242 * during the operation.
244 * This function is similar to g_output_stream_write(), except it tries to
245 * write as many bytes as requested, only stopping on an error.
247 * On a successful write of @count bytes, %TRUE is returned, and @bytes_written
250 * If there is an error during the operation FALSE is returned and @error
251 * is set to indicate the error status, @bytes_written is updated to contain
252 * the number of bytes written into the stream before the error occurred.
254 * Return value: %TRUE on success, %FALSE if there was an error
257 g_output_stream_write_all (GOutputStream *stream,
260 gsize *bytes_written,
261 GCancellable *cancellable,
264 gsize _bytes_written;
267 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
268 g_return_val_if_fail (buffer != NULL, FALSE);
271 while (_bytes_written < count)
273 res = g_output_stream_write (stream, (char *)buffer + _bytes_written, count - _bytes_written,
278 *bytes_written = _bytes_written;
283 g_warning ("Write returned zero without error");
285 _bytes_written += res;
289 *bytes_written = _bytes_written;
295 * g_output_stream_flush:
296 * @stream: a #GOutputStream.
297 * @cancellable: optional cancellable object
298 * @error: location to store the error occuring, or %NULL to ignore
300 * Flushed any outstanding buffers in the stream. Will block during
301 * the operation. Closing the stream will implicitly cause a flush.
303 * This function is optional for inherited classes.
305 * If @cancellable is not %NULL, then the operation can be cancelled by
306 * triggering the cancellable object from another thread. If the operation
307 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
309 * Return value: %TRUE on success, %FALSE on error
312 g_output_stream_flush (GOutputStream *stream,
313 GCancellable *cancellable,
316 GOutputStreamClass *class;
319 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
321 if (!g_output_stream_set_pending (stream, error))
324 class = G_OUTPUT_STREAM_GET_CLASS (stream);
330 g_cancellable_push_current (cancellable);
332 res = class->flush (stream, cancellable, error);
335 g_cancellable_pop_current (cancellable);
338 g_output_stream_clear_pending (stream);
344 * g_output_stream_splice:
345 * @stream: a #GOutputStream.
346 * @source: a #GInputStream.
347 * @flags: a set of #GOutputStreamSpliceFlags.
348 * @cancellable: optional #GCancellable object, %NULL to ignore.
349 * @error: a #GError location to store the error occuring, or %NULL to
352 * Splices an input stream into an output stream.
354 * Returns: a #gssize containing the size of the data spliced.
357 g_output_stream_splice (GOutputStream *stream,
358 GInputStream *source,
359 GOutputStreamSpliceFlags flags,
360 GCancellable *cancellable,
363 GOutputStreamClass *class;
366 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
367 g_return_val_if_fail (G_IS_INPUT_STREAM (source), -1);
369 if (g_input_stream_is_closed (source))
371 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
372 _("Source stream is already closed"));
376 if (!g_output_stream_set_pending (stream, error))
379 class = G_OUTPUT_STREAM_GET_CLASS (stream);
383 g_cancellable_push_current (cancellable);
385 res = class->splice (stream, source, flags, cancellable, error);
388 g_cancellable_pop_current (cancellable);
390 g_output_stream_clear_pending (stream);
396 g_output_stream_real_splice (GOutputStream *stream,
397 GInputStream *source,
398 GOutputStreamSpliceFlags flags,
399 GCancellable *cancellable,
402 GOutputStreamClass *class = G_OUTPUT_STREAM_GET_CLASS (stream);
403 gssize n_read, n_written;
405 char buffer[8192], *p;
409 if (class->write_fn == NULL)
411 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
412 _("Output stream doesn't implement write"));
420 n_read = g_input_stream_read (source, buffer, sizeof (buffer), cancellable, error);
433 n_written = class->write_fn (stream, p, n_read, cancellable, error);
442 bytes_copied += n_written;
449 error = NULL; /* Ignore further errors */
451 if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE)
453 /* Don't care about errors in source here */
454 g_input_stream_close (source, cancellable, NULL);
457 if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET)
459 /* But write errors on close are bad! */
460 if (!class->close_fn (stream, cancellable, error))
472 * g_output_stream_close:
473 * @stream: A #GOutputStream.
474 * @cancellable: optional cancellable object
475 * @error: location to store the error occuring, or %NULL to ignore
477 * Closes the stream, releasing resources related to it.
479 * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED.
480 * Closing a stream multiple times will not return an error.
482 * Closing a stream will automatically flush any outstanding buffers in the
485 * Streams will be automatically closed when the last reference
486 * is dropped, but you might want to call this function to make sure
487 * resources are released as early as possible.
489 * Some streams might keep the backing store of the stream (e.g. a file descriptor)
490 * open after the stream is closed. See the documentation for the individual
491 * stream for details.
493 * On failure the first error that happened will be reported, but the close
494 * operation will finish as much as possible. A stream that failed to
495 * close will still return %G_IO_ERROR_CLOSED for all operations. Still, it
496 * is important to check and report the error to the user, otherwise
497 * there might be a loss of data as all data might not be written.
499 * If @cancellable is not NULL, then the operation can be cancelled by
500 * triggering the cancellable object from another thread. If the operation
501 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
502 * Cancelling a close will still leave the stream closed, but there some streams
503 * can use a faster close that doesn't block to e.g. check errors. On
504 * cancellation (as with any error) there is no guarantee that all written
505 * data will reach the target.
507 * Return value: %TRUE on success, %FALSE on failure
510 g_output_stream_close (GOutputStream *stream,
511 GCancellable *cancellable,
514 GOutputStreamClass *class;
517 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
519 class = G_OUTPUT_STREAM_GET_CLASS (stream);
521 if (stream->priv->closed)
524 if (!g_output_stream_set_pending (stream, error))
528 g_cancellable_push_current (cancellable);
531 res = class->flush (stream, cancellable, error);
537 /* flushing caused the error that we want to return,
538 * but we still want to close the underlying stream if possible
541 class->close_fn (stream, cancellable, NULL);
547 res = class->close_fn (stream, cancellable, error);
551 g_cancellable_pop_current (cancellable);
553 stream->priv->closed = TRUE;
554 g_output_stream_clear_pending (stream);
560 async_ready_callback_wrapper (GObject *source_object,
564 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
566 g_output_stream_clear_pending (stream);
567 if (stream->priv->outstanding_callback)
568 (*stream->priv->outstanding_callback) (source_object, res, user_data);
569 g_object_unref (stream);
573 async_ready_close_callback_wrapper (GObject *source_object,
577 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
579 stream->priv->closed = TRUE;
580 g_output_stream_clear_pending (stream);
581 if (stream->priv->outstanding_callback)
582 (*stream->priv->outstanding_callback) (source_object, res, user_data);
583 g_object_unref (stream);
587 * g_output_stream_write_async:
588 * @stream: A #GOutputStream.
589 * @buffer: the buffer containing the data to write.
590 * @count: the number of bytes to write
591 * @io_priority: the io priority of the request.
592 * @cancellable: optional #GCancellable object, %NULL to ignore.
593 * @callback: callback to call when the request is satisfied
594 * @user_data: the data to pass to callback function
596 * Request an asynchronous write of @count bytes from @buffer into
597 * the stream. When the operation is finished @callback will be called.
598 * You can then call g_output_stream_write_finish() to get the result of the
601 * During an async request no other sync and async calls are allowed,
602 * and will result in %G_IO_ERROR_PENDING errors.
604 * A value of @count larger than %G_MAXSSIZE will cause a
605 * %G_IO_ERROR_INVALID_ARGUMENT error.
607 * On success, the number of bytes written will be passed to the
608 * @callback. It is not an error if this is not the same as the
609 * requested size, as it can happen e.g. on a partial I/O error,
610 * but generally we try to write as many bytes as requested.
612 * Any outstanding I/O request with higher priority (lower numerical
613 * value) will be executed before an outstanding request with lower
614 * priority. Default priority is %G_PRIORITY_DEFAULT.
616 * The asyncronous methods have a default fallback that uses threads
617 * to implement asynchronicity, so they are optional for inheriting
618 * classes. However, if you override one you must override all.
620 * For the synchronous, blocking version of this function, see
621 * g_output_stream_write().
624 g_output_stream_write_async (GOutputStream *stream,
628 GCancellable *cancellable,
629 GAsyncReadyCallback callback,
632 GOutputStreamClass *class;
633 GSimpleAsyncResult *simple;
634 GError *error = NULL;
636 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
637 g_return_if_fail (buffer != NULL);
641 simple = g_simple_async_result_new (G_OBJECT (stream),
644 g_output_stream_write_async);
645 g_simple_async_result_complete_in_idle (simple);
646 g_object_unref (simple);
650 if (((gssize) count) < 0)
652 g_simple_async_report_error_in_idle (G_OBJECT (stream),
655 G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
656 _("Too large count value passed to %s"),
661 if (!g_output_stream_set_pending (stream, &error))
663 g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
667 g_error_free (error);
671 class = G_OUTPUT_STREAM_GET_CLASS (stream);
673 stream->priv->outstanding_callback = callback;
674 g_object_ref (stream);
675 class->write_async (stream, buffer, count, io_priority, cancellable,
676 async_ready_callback_wrapper, user_data);
680 * g_output_stream_write_finish:
681 * @stream: a #GOutputStream.
682 * @result: a #GAsyncResult.
683 * @error: a #GError location to store the error occuring, or %NULL to
686 * Finishes a stream write operation.
688 * Returns: a #gssize containing the number of bytes written to the stream.
691 g_output_stream_write_finish (GOutputStream *stream,
692 GAsyncResult *result,
695 GSimpleAsyncResult *simple;
696 GOutputStreamClass *class;
698 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
699 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
701 if (G_IS_SIMPLE_ASYNC_RESULT (result))
703 simple = G_SIMPLE_ASYNC_RESULT (result);
704 if (g_simple_async_result_propagate_error (simple, error))
707 /* Special case writes of 0 bytes */
708 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_write_async)
712 class = G_OUTPUT_STREAM_GET_CLASS (stream);
713 return class->write_finish (stream, result, error);
717 GInputStream *source;
719 GAsyncReadyCallback callback;
723 async_ready_splice_callback_wrapper (GObject *source_object,
727 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
728 SpliceUserData *data = _data;
730 g_output_stream_clear_pending (stream);
733 (*data->callback) (source_object, res, data->user_data);
735 g_object_unref (stream);
736 g_object_unref (data->source);
741 * g_output_stream_splice_async:
742 * @stream: a #GOutputStream.
743 * @source: a #GInputStream.
744 * @flags: a set of #GOutputStreamSpliceFlags.
745 * @io_priority: the io priority of the request.
746 * @cancellable: optional #GCancellable object, %NULL to ignore.
747 * @callback: a #GAsyncReadyCallback.
748 * @user_data: user data passed to @callback.
750 * Splices a stream asynchronously.
751 * When the operation is finished @callback will be called.
752 * You can then call g_output_stream_splice_finish() to get the
753 * result of the operation.
755 * For the synchronous, blocking version of this function, see
756 * g_output_stream_splice().
759 g_output_stream_splice_async (GOutputStream *stream,
760 GInputStream *source,
761 GOutputStreamSpliceFlags flags,
763 GCancellable *cancellable,
764 GAsyncReadyCallback callback,
767 GOutputStreamClass *class;
768 SpliceUserData *data;
769 GError *error = NULL;
771 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
772 g_return_if_fail (G_IS_INPUT_STREAM (source));
774 if (g_input_stream_is_closed (source))
776 g_simple_async_report_error_in_idle (G_OBJECT (stream),
779 G_IO_ERROR, G_IO_ERROR_CLOSED,
780 _("Source stream is already closed"));
784 if (!g_output_stream_set_pending (stream, &error))
786 g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
790 g_error_free (error);
794 class = G_OUTPUT_STREAM_GET_CLASS (stream);
796 data = g_new0 (SpliceUserData, 1);
797 data->callback = callback;
798 data->user_data = user_data;
799 data->source = g_object_ref (source);
801 g_object_ref (stream);
802 class->splice_async (stream, source, flags, io_priority, cancellable,
803 async_ready_splice_callback_wrapper, data);
807 * g_output_stream_splice_finish:
808 * @stream: a #GOutputStream.
809 * @result: a #GAsyncResult.
810 * @error: a #GError location to store the error occuring, or %NULL to
813 * Finishes an asynchronous stream splice operation.
815 * Returns: a #gssize of the number of bytes spliced.
818 g_output_stream_splice_finish (GOutputStream *stream,
819 GAsyncResult *result,
822 GSimpleAsyncResult *simple;
823 GOutputStreamClass *class;
825 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
826 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
828 if (G_IS_SIMPLE_ASYNC_RESULT (result))
830 simple = G_SIMPLE_ASYNC_RESULT (result);
831 if (g_simple_async_result_propagate_error (simple, error))
835 class = G_OUTPUT_STREAM_GET_CLASS (stream);
836 return class->splice_finish (stream, result, error);
840 * g_output_stream_flush_async:
841 * @stream: a #GOutputStream.
842 * @io_priority: the io priority of the request.
843 * @cancellable: optional #GCancellable object, %NULL to ignore.
844 * @callback: a #GAsyncReadyCallback to call when the request is satisfied
845 * @user_data: the data to pass to callback function
847 * Flushes a stream asynchronously.
848 * For behaviour details see g_output_stream_flush().
850 * When the operation is finished @callback will be
851 * called. You can then call g_output_stream_flush_finish() to get the
852 * result of the operation.
855 g_output_stream_flush_async (GOutputStream *stream,
857 GCancellable *cancellable,
858 GAsyncReadyCallback callback,
861 GOutputStreamClass *class;
862 GSimpleAsyncResult *simple;
863 GError *error = NULL;
865 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
867 if (!g_output_stream_set_pending (stream, &error))
869 g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
873 g_error_free (error);
877 stream->priv->outstanding_callback = callback;
878 g_object_ref (stream);
880 class = G_OUTPUT_STREAM_GET_CLASS (stream);
882 if (class->flush_async == NULL)
884 simple = g_simple_async_result_new (G_OBJECT (stream),
885 async_ready_callback_wrapper,
887 g_output_stream_flush_async);
888 g_simple_async_result_complete_in_idle (simple);
889 g_object_unref (simple);
893 class->flush_async (stream, io_priority, cancellable,
894 async_ready_callback_wrapper, user_data);
898 * g_output_stream_flush_finish:
899 * @stream: a #GOutputStream.
900 * @result: a GAsyncResult.
901 * @error: a #GError location to store the error occuring, or %NULL to
904 * Finishes flushing an output stream.
906 * Returns: %TRUE if flush operation suceeded, %FALSE otherwise.
909 g_output_stream_flush_finish (GOutputStream *stream,
910 GAsyncResult *result,
913 GSimpleAsyncResult *simple;
914 GOutputStreamClass *klass;
916 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
917 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
919 if (G_IS_SIMPLE_ASYNC_RESULT (result))
921 simple = G_SIMPLE_ASYNC_RESULT (result);
922 if (g_simple_async_result_propagate_error (simple, error))
925 /* Special case default implementation */
926 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_flush_async)
930 klass = G_OUTPUT_STREAM_GET_CLASS (stream);
931 return klass->flush_finish (stream, result, error);
936 * g_output_stream_close_async:
937 * @stream: A #GOutputStream.
938 * @io_priority: the io priority of the request.
939 * @callback: callback to call when the request is satisfied
940 * @user_data: the data to pass to callback function
941 * @cancellable: optional cancellable object
943 * Requests an asynchronous close of the stream, releasing resources
944 * related to it. When the operation is finished @callback will be
945 * called. You can then call g_output_stream_close_finish() to get
946 * the result of the operation.
948 * For behaviour details see g_output_stream_close().
950 * The asyncronous methods have a default fallback that uses threads
951 * to implement asynchronicity, so they are optional for inheriting
952 * classes. However, if you override one you must override all.
955 g_output_stream_close_async (GOutputStream *stream,
957 GCancellable *cancellable,
958 GAsyncReadyCallback callback,
961 GOutputStreamClass *class;
962 GSimpleAsyncResult *simple;
963 GError *error = NULL;
965 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
967 if (stream->priv->closed)
969 simple = g_simple_async_result_new (G_OBJECT (stream),
972 g_output_stream_close_async);
973 g_simple_async_result_complete_in_idle (simple);
974 g_object_unref (simple);
978 if (!g_output_stream_set_pending (stream, &error))
980 g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
984 g_error_free (error);
988 class = G_OUTPUT_STREAM_GET_CLASS (stream);
989 stream->priv->outstanding_callback = callback;
990 g_object_ref (stream);
991 class->close_async (stream, io_priority, cancellable,
992 async_ready_close_callback_wrapper, user_data);
996 * g_output_stream_close_finish:
997 * @stream: a #GOutputStream.
998 * @result: a #GAsyncResult.
999 * @error: a #GError location to store the error occuring, or %NULL to
1002 * Closes an output stream.
1004 * Returns: %TRUE if stream was successfully closed, %FALSE otherwise.
1007 g_output_stream_close_finish (GOutputStream *stream,
1008 GAsyncResult *result,
1011 GSimpleAsyncResult *simple;
1012 GOutputStreamClass *class;
1014 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1015 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
1017 if (G_IS_SIMPLE_ASYNC_RESULT (result))
1019 simple = G_SIMPLE_ASYNC_RESULT (result);
1020 if (g_simple_async_result_propagate_error (simple, error))
1023 /* Special case already closed */
1024 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_close_async)
1028 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1029 return class->close_finish (stream, result, error);
1033 * g_output_stream_is_closed:
1034 * @stream: a #GOutputStream.
1036 * Checks if an output stream has already been closed.
1038 * Returns: %TRUE if @stream is closed. %FALSE otherwise.
1041 g_output_stream_is_closed (GOutputStream *stream)
1043 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
1045 return stream->priv->closed;
1049 * g_output_stream_has_pending:
1050 * @stream: a #GOutputStream.
1052 * Checks if an ouput stream has pending actions.
1054 * Returns: %TRUE if @stream has pending actions.
1057 g_output_stream_has_pending (GOutputStream *stream)
1059 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1061 return stream->priv->pending;
1065 * g_output_stream_set_pending:
1066 * @stream: a #GOutputStream.
1067 * @error: a #GError location to store the error occuring, or %NULL to
1070 * Sets @stream to have actions pending. If the pending flag is
1071 * already set or @stream is closed, it will return %FALSE and set
1074 * Return value: %TRUE if pending was previously unset and is now set.
1077 g_output_stream_set_pending (GOutputStream *stream,
1080 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1082 if (stream->priv->closed)
1084 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
1085 _("Stream is already closed"));
1089 if (stream->priv->pending)
1091 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
1092 /* Translators: This is an error you get if there is
1093 * already an operation running against this stream when
1094 * you try to start one */
1095 _("Stream has outstanding operation"));
1099 stream->priv->pending = TRUE;
1104 * g_output_stream_clear_pending:
1105 * @stream: output stream
1107 * Clears the pending flag on @stream.
1110 g_output_stream_clear_pending (GOutputStream *stream)
1112 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1114 stream->priv->pending = FALSE;
1118 /********************************************
1119 * Default implementation of async ops *
1120 ********************************************/
1124 gsize count_requested;
1125 gssize count_written;
1129 write_async_thread (GSimpleAsyncResult *res,
1131 GCancellable *cancellable)
1134 GOutputStreamClass *class;
1135 GError *error = NULL;
1137 class = G_OUTPUT_STREAM_GET_CLASS (object);
1138 op = g_simple_async_result_get_op_res_gpointer (res);
1139 op->count_written = class->write_fn (G_OUTPUT_STREAM (object), op->buffer, op->count_requested,
1140 cancellable, &error);
1141 if (op->count_written == -1)
1143 g_simple_async_result_set_from_error (res, error);
1144 g_error_free (error);
1149 g_output_stream_real_write_async (GOutputStream *stream,
1153 GCancellable *cancellable,
1154 GAsyncReadyCallback callback,
1157 GSimpleAsyncResult *res;
1160 op = g_new0 (WriteData, 1);
1161 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
1162 g_simple_async_result_set_op_res_gpointer (res, op, g_free);
1163 op->buffer = buffer;
1164 op->count_requested = count;
1166 g_simple_async_result_run_in_thread (res, write_async_thread, io_priority, cancellable);
1167 g_object_unref (res);
1171 g_output_stream_real_write_finish (GOutputStream *stream,
1172 GAsyncResult *result,
1175 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1178 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_write_async);
1179 op = g_simple_async_result_get_op_res_gpointer (simple);
1180 return op->count_written;
1184 GInputStream *source;
1185 GOutputStreamSpliceFlags flags;
1186 gssize bytes_copied;
1190 splice_async_thread (GSimpleAsyncResult *result,
1192 GCancellable *cancellable)
1195 GOutputStreamClass *class;
1196 GError *error = NULL;
1197 GOutputStream *stream;
1199 stream = G_OUTPUT_STREAM (object);
1200 class = G_OUTPUT_STREAM_GET_CLASS (object);
1201 op = g_simple_async_result_get_op_res_gpointer (result);
1203 op->bytes_copied = class->splice (stream,
1208 if (op->bytes_copied == -1)
1210 g_simple_async_result_set_from_error (result, error);
1211 g_error_free (error);
1216 g_output_stream_real_splice_async (GOutputStream *stream,
1217 GInputStream *source,
1218 GOutputStreamSpliceFlags flags,
1220 GCancellable *cancellable,
1221 GAsyncReadyCallback callback,
1224 GSimpleAsyncResult *res;
1227 op = g_new0 (SpliceData, 1);
1228 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_splice_async);
1229 g_simple_async_result_set_op_res_gpointer (res, op, g_free);
1231 op->source = source;
1233 /* TODO: In the case where both source and destintion have
1234 non-threadbased async calls we can use a true async copy here */
1236 g_simple_async_result_run_in_thread (res, splice_async_thread, io_priority, cancellable);
1237 g_object_unref (res);
1241 g_output_stream_real_splice_finish (GOutputStream *stream,
1242 GAsyncResult *result,
1245 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1248 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_splice_async);
1249 op = g_simple_async_result_get_op_res_gpointer (simple);
1250 return op->bytes_copied;
1255 flush_async_thread (GSimpleAsyncResult *res,
1257 GCancellable *cancellable)
1259 GOutputStreamClass *class;
1261 GError *error = NULL;
1263 class = G_OUTPUT_STREAM_GET_CLASS (object);
1266 result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error);
1270 g_simple_async_result_set_from_error (res, error);
1271 g_error_free (error);
1276 g_output_stream_real_flush_async (GOutputStream *stream,
1278 GCancellable *cancellable,
1279 GAsyncReadyCallback callback,
1282 GSimpleAsyncResult *res;
1284 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
1286 g_simple_async_result_run_in_thread (res, flush_async_thread, io_priority, cancellable);
1287 g_object_unref (res);
1291 g_output_stream_real_flush_finish (GOutputStream *stream,
1292 GAsyncResult *result,
1299 close_async_thread (GSimpleAsyncResult *res,
1301 GCancellable *cancellable)
1303 GOutputStreamClass *class;
1304 GError *error = NULL;
1307 /* Auto handling of cancelation disabled, and ignore
1308 cancellation, since we want to close things anyway, although
1309 possibly in a quick-n-dirty way. At least we never want to leak
1312 class = G_OUTPUT_STREAM_GET_CLASS (object);
1313 result = class->close_fn (G_OUTPUT_STREAM (object), cancellable, &error);
1316 g_simple_async_result_set_from_error (res, error);
1317 g_error_free (error);
1322 g_output_stream_real_close_async (GOutputStream *stream,
1324 GCancellable *cancellable,
1325 GAsyncReadyCallback callback,
1328 GSimpleAsyncResult *res;
1330 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_close_async);
1332 g_simple_async_result_set_handle_cancellation (res, FALSE);
1334 g_simple_async_result_run_in_thread (res, close_async_thread, io_priority, cancellable);
1335 g_object_unref (res);
1339 g_output_stream_real_close_finish (GOutputStream *stream,
1340 GAsyncResult *result,
1343 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1344 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_close_async);
1348 #define __G_OUTPUT_STREAM_C__
1349 #include "gioaliasdef.c"