1 /* GIO - GLib Input, Output and Streaming Library
2 *
3 * Copyright (C) 2006-2007 Red Hat, Inc.
4 *
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.
9 *
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.
14 *
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.
19 *
20 * Author: Alexander Larsson <alexl@redhat.com>
21 */
22
23 #include "config.h"
24 #include "goutputstream.h"
25 #include "gcancellable.h"
26 #include "gasyncresult.h"
27 #include "gsimpleasyncresult.h"
28 #include "ginputstream.h"
29 #include "gioerror.h"
30 #include "glibintl.h"
31
32 #include "gioalias.h"
33
34 /**
35 * SECTION:goutputstream
36 * @short_description: Base class for implementing streaming output
37 * @include: gio/gio.h
38 *
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()).
42 *
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().
45 *
46 * All of these functions have async variants too.
47 **/
48
49 G_DEFINE_TYPE (GOutputStream, g_output_stream, G_TYPE_OBJECT);
50
51 struct _GOutputStreamPrivate {
52 guint closed : 1;
53 guint pending : 1;
54 guint cancelled : 1;
55 GAsyncReadyCallback outstanding_callback;
56 };
57
58 static gssize g_output_stream_real_splice (GOutputStream *stream,
59 GInputStream *source,
60 GOutputStreamSpliceFlags flags,
61 GCancellable *cancellable,
62 GError **error);
63 static void g_output_stream_real_write_async (GOutputStream *stream,
64 const void *buffer,
65 gsize count,
66 int io_priority,
67 GCancellable *cancellable,
68 GAsyncReadyCallback callback,
69 gpointer data);
70 static gssize g_output_stream_real_write_finish (GOutputStream *stream,
71 GAsyncResult *result,
72 GError **error);
73 static void g_output_stream_real_splice_async (GOutputStream *stream,
74 GInputStream *source,
75 GOutputStreamSpliceFlags flags,
76 int io_priority,
77 GCancellable *cancellable,
78 GAsyncReadyCallback callback,
79 gpointer data);
80 static gssize g_output_stream_real_splice_finish (GOutputStream *stream,
81 GAsyncResult *result,
82 GError **error);
83 static void g_output_stream_real_flush_async (GOutputStream *stream,
84 int io_priority,
85 GCancellable *cancellable,
86 GAsyncReadyCallback callback,
87 gpointer data);
88 static gboolean g_output_stream_real_flush_finish (GOutputStream *stream,
89 GAsyncResult *result,
90 GError **error);
91 static void g_output_stream_real_close_async (GOutputStream *stream,
92 int io_priority,
93 GCancellable *cancellable,
94 GAsyncReadyCallback callback,
95 gpointer data);
96 static gboolean g_output_stream_real_close_finish (GOutputStream *stream,
97 GAsyncResult *result,
98 GError **error);
99
100 static void
g_output_stream_finalize(GObject * object)101 g_output_stream_finalize (GObject *object)
102 {
103 GOutputStream *stream;
104
105 stream = G_OUTPUT_STREAM (object);
106
107 G_OBJECT_CLASS (g_output_stream_parent_class)->finalize (object);
108 }
109
110 static void
g_output_stream_dispose(GObject * object)111 g_output_stream_dispose (GObject *object)
112 {
113 GOutputStream *stream;
114
115 stream = G_OUTPUT_STREAM (object);
116
117 if (!stream->priv->closed)
118 g_output_stream_close (stream, NULL, NULL);
119
120 G_OBJECT_CLASS (g_output_stream_parent_class)->dispose (object);
121 }
122
123 static void
g_output_stream_class_init(GOutputStreamClass * klass)124 g_output_stream_class_init (GOutputStreamClass *klass)
125 {
126 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
127
128 g_type_class_add_private (klass, sizeof (GOutputStreamPrivate));
129
130 gobject_class->finalize = g_output_stream_finalize;
131 gobject_class->dispose = g_output_stream_dispose;
132
133 klass->splice = g_output_stream_real_splice;
134
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;
143 }
144
145 static void
g_output_stream_init(GOutputStream * stream)146 g_output_stream_init (GOutputStream *stream)
147 {
148 stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
149 G_TYPE_OUTPUT_STREAM,
150 GOutputStreamPrivate);
151 }
152
153 /**
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
160 *
161 * Tries to write @count bytes from @buffer into the stream. Will block
162 * during the operation.
163 *
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.
166 *
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).
172 *
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.
178 *
179 * On error -1 is returned and @error is set accordingly.
180 *
181 * Return value: Number of bytes written, or -1 on error
182 **/
183 gssize
g_output_stream_write(GOutputStream * stream,const void * buffer,gsize count,GCancellable * cancellable,GError ** error)184 g_output_stream_write (GOutputStream *stream,
185 const void *buffer,
186 gsize count,
187 GCancellable *cancellable,
188 GError **error)
189 {
190 GOutputStreamClass *class;
191 gssize res;
192
193 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
194 g_return_val_if_fail (buffer != NULL, 0);
195
196 if (count == 0)
197 return 0;
198
199 if (((gssize) count) < 0)
200 {
201 g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
202 _("Too large count value passed to %s"), G_STRFUNC);
203 return -1;
204 }
205
206 class = G_OUTPUT_STREAM_GET_CLASS (stream);
207
208 if (class->write_fn == NULL)
209 {
210 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
211 _("Output stream doesn't implement write"));
212 return -1;
213 }
214
215 if (!g_output_stream_set_pending (stream, error))
216 return -1;
217
218 if (cancellable)
219 g_cancellable_push_current (cancellable);
220
221 res = class->write_fn (stream, buffer, count, cancellable, error);
222
223 if (cancellable)
224 g_cancellable_pop_current (cancellable);
225
226 g_output_stream_clear_pending (stream);
227
228 return res;
229 }
230
231 /**
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
240 *
241 * Tries to write @count bytes from @buffer into the stream. Will block
242 * during the operation.
243 *
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.
246 *
247 * On a successful write of @count bytes, %TRUE is returned, and @bytes_written
248 * is set to @count.
249 *
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.
253 *
254 * Return value: %TRUE on success, %FALSE if there was an error
255 **/
256 gboolean
g_output_stream_write_all(GOutputStream * stream,const void * buffer,gsize count,gsize * bytes_written,GCancellable * cancellable,GError ** error)257 g_output_stream_write_all (GOutputStream *stream,
258 const void *buffer,
259 gsize count,
260 gsize *bytes_written,
261 GCancellable *cancellable,
262 GError **error)
263 {
264 gsize _bytes_written;
265 gssize res;
266
267 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
268 g_return_val_if_fail (buffer != NULL, FALSE);
269
270 _bytes_written = 0;
271 while (_bytes_written < count)
272 {
273 res = g_output_stream_write (stream, (char *)buffer + _bytes_written, count - _bytes_written,
274 cancellable, error);
275 if (res == -1)
276 {
277 if (bytes_written)
278 *bytes_written = _bytes_written;
279 return FALSE;
280 }
281
282 if (res == 0)
283 g_warning ("Write returned zero without error");
284
285 _bytes_written += res;
286 }
287
288 if (bytes_written)
289 *bytes_written = _bytes_written;
290
291 return TRUE;
292 }
293
294 /**
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
299 *
300 * Flushed any outstanding buffers in the stream. Will block during
301 * the operation. Closing the stream will implicitly cause a flush.
302 *
303 * This function is optional for inherited classes.
304 *
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.
308 *
309 * Return value: %TRUE on success, %FALSE on error
310 **/
311 gboolean
g_output_stream_flush(GOutputStream * stream,GCancellable * cancellable,GError ** error)312 g_output_stream_flush (GOutputStream *stream,
313 GCancellable *cancellable,
314 GError **error)
315 {
316 GOutputStreamClass *class;
317 gboolean res;
318
319 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
320
321 if (!g_output_stream_set_pending (stream, error))
322 return FALSE;
323
324 class = G_OUTPUT_STREAM_GET_CLASS (stream);
325
326 res = TRUE;
327 if (class->flush)
328 {
329 if (cancellable)
330 g_cancellable_push_current (cancellable);
331
332 res = class->flush (stream, cancellable, error);
333
334 if (cancellable)
335 g_cancellable_pop_current (cancellable);
336 }
337
338 g_output_stream_clear_pending (stream);
339
340 return res;
341 }
342
343 /**
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
350 * ignore.
351 *
352 * Splices an input stream into an output stream.
353 *
354 * Returns: a #gssize containing the size of the data spliced.
355 **/
356 gssize
g_output_stream_splice(GOutputStream * stream,GInputStream * source,GOutputStreamSpliceFlags flags,GCancellable * cancellable,GError ** error)357 g_output_stream_splice (GOutputStream *stream,
358 GInputStream *source,
359 GOutputStreamSpliceFlags flags,
360 GCancellable *cancellable,
361 GError **error)
362 {
363 GOutputStreamClass *class;
364 gboolean res;
365
366 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
367 g_return_val_if_fail (G_IS_INPUT_STREAM (source), -1);
368
369 if (g_input_stream_is_closed (source))
370 {
371 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
372 _("Source stream is already closed"));
373 return -1;
374 }
375
376 if (!g_output_stream_set_pending (stream, error))
377 return -1;
378
379 class = G_OUTPUT_STREAM_GET_CLASS (stream);
380
381 res = TRUE;
382 if (cancellable)
383 g_cancellable_push_current (cancellable);
384
385 res = class->splice (stream, source, flags, cancellable, error);
386
387 if (cancellable)
388 g_cancellable_pop_current (cancellable);
389
390 g_output_stream_clear_pending (stream);
391
392 return res;
393 }
394
395 static gssize
g_output_stream_real_splice(GOutputStream * stream,GInputStream * source,GOutputStreamSpliceFlags flags,GCancellable * cancellable,GError ** error)396 g_output_stream_real_splice (GOutputStream *stream,
397 GInputStream *source,
398 GOutputStreamSpliceFlags flags,
399 GCancellable *cancellable,
400 GError **error)
401 {
402 GOutputStreamClass *class = G_OUTPUT_STREAM_GET_CLASS (stream);
403 gssize n_read, n_written;
404 gssize bytes_copied;
405 char buffer[8192], *p;
406 gboolean res;
407
408 bytes_copied = 0;
409 if (class->write_fn == NULL)
410 {
411 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
412 _("Output stream doesn't implement write"));
413 res = FALSE;
414 goto notsupported;
415 }
416
417 res = TRUE;
418 do
419 {
420 n_read = g_input_stream_read (source, buffer, sizeof (buffer), cancellable, error);
421 if (n_read == -1)
422 {
423 res = FALSE;
424 break;
425 }
426
427 if (n_read == 0)
428 break;
429
430 p = buffer;
431 while (n_read > 0)
432 {
433 n_written = class->write_fn (stream, p, n_read, cancellable, error);
434 if (n_written == -1)
435 {
436 res = FALSE;
437 break;
438 }
439
440 p += n_written;
441 n_read -= n_written;
442 bytes_copied += n_written;
443 }
444 }
445 while (res);
446
447 notsupported:
448 if (!res)
449 error = NULL; /* Ignore further errors */
450
451 if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE)
452 {
453 /* Don't care about errors in source here */
454 g_input_stream_close (source, cancellable, NULL);
455 }
456
457 if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET)
458 {
459 /* But write errors on close are bad! */
460 if (!class->close_fn (stream, cancellable, error))
461 res = FALSE;
462 }
463
464 if (res)
465 return bytes_copied;
466
467 return -1;
468 }
469
470
471 /**
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
476 *
477 * Closes the stream, releasing resources related to it.
478 *
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.
481 *
482 * Closing a stream will automatically flush any outstanding buffers in the
483 * stream.
484 *
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.
488 *
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.
492 *
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.
498 *
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.
506 *
507 * Return value: %TRUE on success, %FALSE on failure
508 **/
509 gboolean
g_output_stream_close(GOutputStream * stream,GCancellable * cancellable,GError ** error)510 g_output_stream_close (GOutputStream *stream,
511 GCancellable *cancellable,
512 GError **error)
513 {
514 GOutputStreamClass *class;
515 gboolean res;
516
517 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
518
519 class = G_OUTPUT_STREAM_GET_CLASS (stream);
520
521 if (stream->priv->closed)
522 return TRUE;
523
524 if (!g_output_stream_set_pending (stream, error))
525 return FALSE;
526
527 if (cancellable)
528 g_cancellable_push_current (cancellable);
529
530 if (class->flush)
531 res = class->flush (stream, cancellable, error);
532 else
533 res = TRUE;
534
535 if (!res)
536 {
537 /* flushing caused the error that we want to return,
538 * but we still want to close the underlying stream if possible
539 */
540 if (class->close_fn)
541 class->close_fn (stream, cancellable, NULL);
542 }
543 else
544 {
545 res = TRUE;
546 if (class->close_fn)
547 res = class->close_fn (stream, cancellable, error);
548 }
549
550 if (cancellable)
551 g_cancellable_pop_current (cancellable);
552
553 stream->priv->closed = TRUE;
554 g_output_stream_clear_pending (stream);
555
556 return res;
557 }
558
559 static void
async_ready_callback_wrapper(GObject * source_object,GAsyncResult * res,gpointer user_data)560 async_ready_callback_wrapper (GObject *source_object,
561 GAsyncResult *res,
562 gpointer user_data)
563 {
564 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
565
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);
570 }
571
572 static void
async_ready_close_callback_wrapper(GObject * source_object,GAsyncResult * res,gpointer user_data)573 async_ready_close_callback_wrapper (GObject *source_object,
574 GAsyncResult *res,
575 gpointer user_data)
576 {
577 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
578
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);
584 }
585
586 /**
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
595 *
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
599 * operation.
600 *
601 * During an async request no other sync and async calls are allowed,
602 * and will result in %G_IO_ERROR_PENDING errors.
603 *
604 * A value of @count larger than %G_MAXSSIZE will cause a
605 * %G_IO_ERROR_INVALID_ARGUMENT error.
606 *
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.
611 *
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.
615 *
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.
619 *
620 * For the synchronous, blocking version of this function, see
621 * g_output_stream_write().
622 **/
623 void
g_output_stream_write_async(GOutputStream * stream,const void * buffer,gsize count,int io_priority,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)624 g_output_stream_write_async (GOutputStream *stream,
625 const void *buffer,
626 gsize count,
627 int io_priority,
628 GCancellable *cancellable,
629 GAsyncReadyCallback callback,
630 gpointer user_data)
631 {
632 GOutputStreamClass *class;
633 GSimpleAsyncResult *simple;
634 GError *error = NULL;
635
636 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
637 g_return_if_fail (buffer != NULL);
638
639 if (count == 0)
640 {
641 simple = g_simple_async_result_new (G_OBJECT (stream),
642 callback,
643 user_data,
644 g_output_stream_write_async);
645 g_simple_async_result_complete_in_idle (simple);
646 g_object_unref (simple);
647 return;
648 }
649
650 if (((gssize) count) < 0)
651 {
652 g_simple_async_report_error_in_idle (G_OBJECT (stream),
653 callback,
654 user_data,
655 G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
656 _("Too large count value passed to %s"),
657 G_STRFUNC);
658 return;
659 }
660
661 if (!g_output_stream_set_pending (stream, &error))
662 {
663 g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
664 callback,
665 user_data,
666 error);
667 g_error_free (error);
668 return;
669 }
670
671 class = G_OUTPUT_STREAM_GET_CLASS (stream);
672
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);
677 }
678
679 /**
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
684 * ignore.
685 *
686 * Finishes a stream write operation.
687 *
688 * Returns: a #gssize containing the number of bytes written to the stream.
689 **/
690 gssize
g_output_stream_write_finish(GOutputStream * stream,GAsyncResult * result,GError ** error)691 g_output_stream_write_finish (GOutputStream *stream,
692 GAsyncResult *result,
693 GError **error)
694 {
695 GSimpleAsyncResult *simple;
696 GOutputStreamClass *class;
697
698 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
699 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
700
701 if (G_IS_SIMPLE_ASYNC_RESULT (result))
702 {
703 simple = G_SIMPLE_ASYNC_RESULT (result);
704 if (g_simple_async_result_propagate_error (simple, error))
705 return -1;
706
707 /* Special case writes of 0 bytes */
708 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_write_async)
709 return 0;
710 }
711
712 class = G_OUTPUT_STREAM_GET_CLASS (stream);
713 return class->write_finish (stream, result, error);
714 }
715
716 typedef struct {
717 GInputStream *source;
718 gpointer user_data;
719 GAsyncReadyCallback callback;
720 } SpliceUserData;
721
722 static void
async_ready_splice_callback_wrapper(GObject * source_object,GAsyncResult * res,gpointer _data)723 async_ready_splice_callback_wrapper (GObject *source_object,
724 GAsyncResult *res,
725 gpointer _data)
726 {
727 GOutputStream *stream = G_OUTPUT_STREAM (source_object);
728 SpliceUserData *data = _data;
729
730 g_output_stream_clear_pending (stream);
731
732 if (data->callback)
733 (*data->callback) (source_object, res, data->user_data);
734
735 g_object_unref (stream);
736 g_object_unref (data->source);
737 g_free (data);
738 }
739
740 /**
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.
749 *
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.
754 *
755 * For the synchronous, blocking version of this function, see
756 * g_output_stream_splice().
757 **/
758 void
g_output_stream_splice_async(GOutputStream * stream,GInputStream * source,GOutputStreamSpliceFlags flags,int io_priority,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)759 g_output_stream_splice_async (GOutputStream *stream,
760 GInputStream *source,
761 GOutputStreamSpliceFlags flags,
762 int io_priority,
763 GCancellable *cancellable,
764 GAsyncReadyCallback callback,
765 gpointer user_data)
766 {
767 GOutputStreamClass *class;
768 SpliceUserData *data;
769 GError *error = NULL;
770
771 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
772 g_return_if_fail (G_IS_INPUT_STREAM (source));
773
774 if (g_input_stream_is_closed (source))
775 {
776 g_simple_async_report_error_in_idle (G_OBJECT (stream),
777 callback,
778 user_data,
779 G_IO_ERROR, G_IO_ERROR_CLOSED,
780 _("Source stream is already closed"));
781 return;
782 }
783
784 if (!g_output_stream_set_pending (stream, &error))
785 {
786 g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
787 callback,
788 user_data,
789 error);
790 g_error_free (error);
791 return;
792 }
793
794 class = G_OUTPUT_STREAM_GET_CLASS (stream);
795
796 data = g_new0 (SpliceUserData, 1);
797 data->callback = callback;
798 data->user_data = user_data;
799 data->source = g_object_ref (source);
800
801 g_object_ref (stream);
802 class->splice_async (stream, source, flags, io_priority, cancellable,
803 async_ready_splice_callback_wrapper, data);
804 }
805
806 /**
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
811 * ignore.
812 *
813 * Finishes an asynchronous stream splice operation.
814 *
815 * Returns: a #gssize of the number of bytes spliced.
816 **/
817 gssize
g_output_stream_splice_finish(GOutputStream * stream,GAsyncResult * result,GError ** error)818 g_output_stream_splice_finish (GOutputStream *stream,
819 GAsyncResult *result,
820 GError **error)
821 {
822 GSimpleAsyncResult *simple;
823 GOutputStreamClass *class;
824
825 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
826 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
827
828 if (G_IS_SIMPLE_ASYNC_RESULT (result))
829 {
830 simple = G_SIMPLE_ASYNC_RESULT (result);
831 if (g_simple_async_result_propagate_error (simple, error))
832 return -1;
833 }
834
835 class = G_OUTPUT_STREAM_GET_CLASS (stream);
836 return class->splice_finish (stream, result, error);
837 }
838
839 /**
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
846 *
847 * Flushes a stream asynchronously.
848 * For behaviour details see g_output_stream_flush().
849 *
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.
853 **/
854 void
g_output_stream_flush_async(GOutputStream * stream,int io_priority,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)855 g_output_stream_flush_async (GOutputStream *stream,
856 int io_priority,
857 GCancellable *cancellable,
858 GAsyncReadyCallback callback,
859 gpointer user_data)
860 {
861 GOutputStreamClass *class;
862 GSimpleAsyncResult *simple;
863 GError *error = NULL;
864
865 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
866
867 if (!g_output_stream_set_pending (stream, &error))
868 {
869 g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
870 callback,
871 user_data,
872 error);
873 g_error_free (error);
874 return;
875 }
876
877 stream->priv->outstanding_callback = callback;
878 g_object_ref (stream);
879
880 class = G_OUTPUT_STREAM_GET_CLASS (stream);
881
882 if (class->flush_async == NULL)
883 {
884 simple = g_simple_async_result_new (G_OBJECT (stream),
885 async_ready_callback_wrapper,
886 user_data,
887 g_output_stream_flush_async);
888 g_simple_async_result_complete_in_idle (simple);
889 g_object_unref (simple);
890 return;
891 }
892
893 class->flush_async (stream, io_priority, cancellable,
894 async_ready_callback_wrapper, user_data);
895 }
896
897 /**
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
902 * ignore.
903 *
904 * Finishes flushing an output stream.
905 *
906 * Returns: %TRUE if flush operation suceeded, %FALSE otherwise.
907 **/
908 gboolean
g_output_stream_flush_finish(GOutputStream * stream,GAsyncResult * result,GError ** error)909 g_output_stream_flush_finish (GOutputStream *stream,
910 GAsyncResult *result,
911 GError **error)
912 {
913 GSimpleAsyncResult *simple;
914 GOutputStreamClass *klass;
915
916 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
917 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
918
919 if (G_IS_SIMPLE_ASYNC_RESULT (result))
920 {
921 simple = G_SIMPLE_ASYNC_RESULT (result);
922 if (g_simple_async_result_propagate_error (simple, error))
923 return FALSE;
924
925 /* Special case default implementation */
926 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_flush_async)
927 return TRUE;
928 }
929
930 klass = G_OUTPUT_STREAM_GET_CLASS (stream);
931 return klass->flush_finish (stream, result, error);
932 }
933
934
935 /**
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
942 *
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.
947 *
948 * For behaviour details see g_output_stream_close().
949 *
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.
953 **/
954 void
g_output_stream_close_async(GOutputStream * stream,int io_priority,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)955 g_output_stream_close_async (GOutputStream *stream,
956 int io_priority,
957 GCancellable *cancellable,
958 GAsyncReadyCallback callback,
959 gpointer user_data)
960 {
961 GOutputStreamClass *class;
962 GSimpleAsyncResult *simple;
963 GError *error = NULL;
964
965 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
966
967 if (stream->priv->closed)
968 {
969 simple = g_simple_async_result_new (G_OBJECT (stream),
970 callback,
971 user_data,
972 g_output_stream_close_async);
973 g_simple_async_result_complete_in_idle (simple);
974 g_object_unref (simple);
975 return;
976 }
977
978 if (!g_output_stream_set_pending (stream, &error))
979 {
980 g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
981 callback,
982 user_data,
983 error);
984 g_error_free (error);
985 return;
986 }
987
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);
993 }
994
995 /**
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
1000 * ignore.
1001 *
1002 * Closes an output stream.
1003 *
1004 * Returns: %TRUE if stream was successfully closed, %FALSE otherwise.
1005 **/
1006 gboolean
g_output_stream_close_finish(GOutputStream * stream,GAsyncResult * result,GError ** error)1007 g_output_stream_close_finish (GOutputStream *stream,
1008 GAsyncResult *result,
1009 GError **error)
1010 {
1011 GSimpleAsyncResult *simple;
1012 GOutputStreamClass *class;
1013
1014 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1015 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
1016
1017 if (G_IS_SIMPLE_ASYNC_RESULT (result))
1018 {
1019 simple = G_SIMPLE_ASYNC_RESULT (result);
1020 if (g_simple_async_result_propagate_error (simple, error))
1021 return FALSE;
1022
1023 /* Special case already closed */
1024 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_close_async)
1025 return TRUE;
1026 }
1027
1028 class = G_OUTPUT_STREAM_GET_CLASS (stream);
1029 return class->close_finish (stream, result, error);
1030 }
1031
1032 /**
1033 * g_output_stream_is_closed:
1034 * @stream: a #GOutputStream.
1035 *
1036 * Checks if an output stream has already been closed.
1037 *
1038 * Returns: %TRUE if @stream is closed. %FALSE otherwise.
1039 **/
1040 gboolean
g_output_stream_is_closed(GOutputStream * stream)1041 g_output_stream_is_closed (GOutputStream *stream)
1042 {
1043 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
1044
1045 return stream->priv->closed;
1046 }
1047
1048 /**
1049 * g_output_stream_has_pending:
1050 * @stream: a #GOutputStream.
1051 *
1052 * Checks if an ouput stream has pending actions.
1053 *
1054 * Returns: %TRUE if @stream has pending actions.
1055 **/
1056 gboolean
g_output_stream_has_pending(GOutputStream * stream)1057 g_output_stream_has_pending (GOutputStream *stream)
1058 {
1059 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1060
1061 return stream->priv->pending;
1062 }
1063
1064 /**
1065 * g_output_stream_set_pending:
1066 * @stream: a #GOutputStream.
1067 * @error: a #GError location to store the error occuring, or %NULL to
1068 * ignore.
1069 *
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
1072 * @error.
1073 *
1074 * Return value: %TRUE if pending was previously unset and is now set.
1075 **/
1076 gboolean
g_output_stream_set_pending(GOutputStream * stream,GError ** error)1077 g_output_stream_set_pending (GOutputStream *stream,
1078 GError **error)
1079 {
1080 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1081
1082 if (stream->priv->closed)
1083 {
1084 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
1085 _("Stream is already closed"));
1086 return FALSE;
1087 }
1088
1089 if (stream->priv->pending)
1090 {
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"));
1096 return FALSE;
1097 }
1098
1099 stream->priv->pending = TRUE;
1100 return TRUE;
1101 }
1102
1103 /**
1104 * g_output_stream_clear_pending:
1105 * @stream: output stream
1106 *
1107 * Clears the pending flag on @stream.
1108 **/
1109 void
g_output_stream_clear_pending(GOutputStream * stream)1110 g_output_stream_clear_pending (GOutputStream *stream)
1111 {
1112 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1113
1114 stream->priv->pending = FALSE;
1115 }
1116
1117
1118 /********************************************
1119 * Default implementation of async ops *
1120 ********************************************/
1121
1122 typedef struct {
1123 const void *buffer;
1124 gsize count_requested;
1125 gssize count_written;
1126 } WriteData;
1127
1128 static void
write_async_thread(GSimpleAsyncResult * res,GObject * object,GCancellable * cancellable)1129 write_async_thread (GSimpleAsyncResult *res,
1130 GObject *object,
1131 GCancellable *cancellable)
1132 {
1133 WriteData *op;
1134 GOutputStreamClass *class;
1135 GError *error = NULL;
1136
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)
1142 {
1143 g_simple_async_result_set_from_error (res, error);
1144 g_error_free (error);
1145 }
1146 }
1147
1148 static void
g_output_stream_real_write_async(GOutputStream * stream,const void * buffer,gsize count,int io_priority,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1149 g_output_stream_real_write_async (GOutputStream *stream,
1150 const void *buffer,
1151 gsize count,
1152 int io_priority,
1153 GCancellable *cancellable,
1154 GAsyncReadyCallback callback,
1155 gpointer user_data)
1156 {
1157 GSimpleAsyncResult *res;
1158 WriteData *op;
1159
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;
1165
1166 g_simple_async_result_run_in_thread (res, write_async_thread, io_priority, cancellable);
1167 g_object_unref (res);
1168 }
1169
1170 static gssize
g_output_stream_real_write_finish(GOutputStream * stream,GAsyncResult * result,GError ** error)1171 g_output_stream_real_write_finish (GOutputStream *stream,
1172 GAsyncResult *result,
1173 GError **error)
1174 {
1175 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1176 WriteData *op;
1177
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;
1181 }
1182
1183 typedef struct {
1184 GInputStream *source;
1185 GOutputStreamSpliceFlags flags;
1186 gssize bytes_copied;
1187 } SpliceData;
1188
1189 static void
splice_async_thread(GSimpleAsyncResult * result,GObject * object,GCancellable * cancellable)1190 splice_async_thread (GSimpleAsyncResult *result,
1191 GObject *object,
1192 GCancellable *cancellable)
1193 {
1194 SpliceData *op;
1195 GOutputStreamClass *class;
1196 GError *error = NULL;
1197 GOutputStream *stream;
1198
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);
1202
1203 op->bytes_copied = class->splice (stream,
1204 op->source,
1205 op->flags,
1206 cancellable,
1207 &error);
1208 if (op->bytes_copied == -1)
1209 {
1210 g_simple_async_result_set_from_error (result, error);
1211 g_error_free (error);
1212 }
1213 }
1214
1215 static void
g_output_stream_real_splice_async(GOutputStream * stream,GInputStream * source,GOutputStreamSpliceFlags flags,int io_priority,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1216 g_output_stream_real_splice_async (GOutputStream *stream,
1217 GInputStream *source,
1218 GOutputStreamSpliceFlags flags,
1219 int io_priority,
1220 GCancellable *cancellable,
1221 GAsyncReadyCallback callback,
1222 gpointer user_data)
1223 {
1224 GSimpleAsyncResult *res;
1225 SpliceData *op;
1226
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);
1230 op->flags = flags;
1231 op->source = source;
1232
1233 /* TODO: In the case where both source and destintion have
1234 non-threadbased async calls we can use a true async copy here */
1235
1236 g_simple_async_result_run_in_thread (res, splice_async_thread, io_priority, cancellable);
1237 g_object_unref (res);
1238 }
1239
1240 static gssize
g_output_stream_real_splice_finish(GOutputStream * stream,GAsyncResult * result,GError ** error)1241 g_output_stream_real_splice_finish (GOutputStream *stream,
1242 GAsyncResult *result,
1243 GError **error)
1244 {
1245 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1246 SpliceData *op;
1247
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;
1251 }
1252
1253
1254 static void
flush_async_thread(GSimpleAsyncResult * res,GObject * object,GCancellable * cancellable)1255 flush_async_thread (GSimpleAsyncResult *res,
1256 GObject *object,
1257 GCancellable *cancellable)
1258 {
1259 GOutputStreamClass *class;
1260 gboolean result;
1261 GError *error = NULL;
1262
1263 class = G_OUTPUT_STREAM_GET_CLASS (object);
1264 result = TRUE;
1265 if (class->flush)
1266 result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error);
1267
1268 if (!result)
1269 {
1270 g_simple_async_result_set_from_error (res, error);
1271 g_error_free (error);
1272 }
1273 }
1274
1275 static void
g_output_stream_real_flush_async(GOutputStream * stream,int io_priority,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1276 g_output_stream_real_flush_async (GOutputStream *stream,
1277 int io_priority,
1278 GCancellable *cancellable,
1279 GAsyncReadyCallback callback,
1280 gpointer user_data)
1281 {
1282 GSimpleAsyncResult *res;
1283
1284 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
1285
1286 g_simple_async_result_run_in_thread (res, flush_async_thread, io_priority, cancellable);
1287 g_object_unref (res);
1288 }
1289
1290 static gboolean
g_output_stream_real_flush_finish(GOutputStream * stream,GAsyncResult * result,GError ** error)1291 g_output_stream_real_flush_finish (GOutputStream *stream,
1292 GAsyncResult *result,
1293 GError **error)
1294 {
1295 return TRUE;
1296 }
1297
1298 static void
close_async_thread(GSimpleAsyncResult * res,GObject * object,GCancellable * cancellable)1299 close_async_thread (GSimpleAsyncResult *res,
1300 GObject *object,
1301 GCancellable *cancellable)
1302 {
1303 GOutputStreamClass *class;
1304 GError *error = NULL;
1305 gboolean result;
1306
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
1310 open handles */
1311
1312 class = G_OUTPUT_STREAM_GET_CLASS (object);
1313 result = class->close_fn (G_OUTPUT_STREAM (object), cancellable, &error);
1314 if (!result)
1315 {
1316 g_simple_async_result_set_from_error (res, error);
1317 g_error_free (error);
1318 }
1319 }
1320
1321 static void
g_output_stream_real_close_async(GOutputStream * stream,int io_priority,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1322 g_output_stream_real_close_async (GOutputStream *stream,
1323 int io_priority,
1324 GCancellable *cancellable,
1325 GAsyncReadyCallback callback,
1326 gpointer user_data)
1327 {
1328 GSimpleAsyncResult *res;
1329
1330 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_close_async);
1331
1332 g_simple_async_result_set_handle_cancellation (res, FALSE);
1333
1334 g_simple_async_result_run_in_thread (res, close_async_thread, io_priority, cancellable);
1335 g_object_unref (res);
1336 }
1337
1338 static gboolean
g_output_stream_real_close_finish(GOutputStream * stream,GAsyncResult * result,GError ** error)1339 g_output_stream_real_close_finish (GOutputStream *stream,
1340 GAsyncResult *result,
1341 GError **error)
1342 {
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);
1345 return TRUE;
1346 }
1347
1348 #define __G_OUTPUT_STREAM_C__
1349 #include "gioaliasdef.c"
1350