More coding style fixes
[platform/upstream/glib.git] / gio / goutputstream.c
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 "gsimpleasyncresult.h"
26 #include "glibintl.h"
27
28 #include "gioalias.h"
29
30 /**
31  * SECTION:goutputstream
32  * @short_description: base class for implementing streaming output
33  * 
34  * 
35  *
36  **/
37
38 G_DEFINE_TYPE (GOutputStream, g_output_stream, G_TYPE_OBJECT);
39
40 struct _GOutputStreamPrivate {
41   guint closed : 1;
42   guint pending : 1;
43   guint cancelled : 1;
44   GAsyncReadyCallback outstanding_callback;
45 };
46
47 static gssize   g_output_stream_real_splice        (GOutputStream             *stream,
48                                                     GInputStream              *source,
49                                                     GOutputStreamSpliceFlags   flags,
50                                                     GCancellable              *cancellable,
51                                                     GError                   **error);
52 static void     g_output_stream_real_write_async   (GOutputStream             *stream,
53                                                     const void                *buffer,
54                                                     gsize                      count,
55                                                     int                        io_priority,
56                                                     GCancellable              *cancellable,
57                                                     GAsyncReadyCallback        callback,
58                                                     gpointer                   data);
59 static gssize   g_output_stream_real_write_finish  (GOutputStream             *stream,
60                                                     GAsyncResult              *result,
61                                                     GError                   **error);
62 static void     g_output_stream_real_splice_async  (GOutputStream             *stream,
63                                                     GInputStream              *source,
64                                                     GOutputStreamSpliceFlags   flags,
65                                                     int                        io_priority,
66                                                     GCancellable              *cancellable,
67                                                     GAsyncReadyCallback        callback,
68                                                     gpointer                   data);
69 static gssize   g_output_stream_real_splice_finish (GOutputStream             *stream,
70                                                     GAsyncResult              *result,
71                                                     GError                   **error);
72 static void     g_output_stream_real_flush_async   (GOutputStream             *stream,
73                                                     int                        io_priority,
74                                                     GCancellable              *cancellable,
75                                                     GAsyncReadyCallback        callback,
76                                                     gpointer                   data);
77 static gboolean g_output_stream_real_flush_finish  (GOutputStream             *stream,
78                                                     GAsyncResult              *result,
79                                                     GError                   **error);
80 static void     g_output_stream_real_close_async   (GOutputStream             *stream,
81                                                     int                        io_priority,
82                                                     GCancellable              *cancellable,
83                                                     GAsyncReadyCallback        callback,
84                                                     gpointer                   data);
85 static gboolean g_output_stream_real_close_finish  (GOutputStream             *stream,
86                                                     GAsyncResult              *result,
87                                                     GError                   **error);
88
89 static void
90 g_output_stream_finalize (GObject *object)
91 {
92   GOutputStream *stream;
93
94   stream = G_OUTPUT_STREAM (object);
95   
96   if (G_OBJECT_CLASS (g_output_stream_parent_class)->finalize)
97     (*G_OBJECT_CLASS (g_output_stream_parent_class)->finalize) (object);
98 }
99
100 static void
101 g_output_stream_dispose (GObject *object)
102 {
103   GOutputStream *stream;
104
105   stream = G_OUTPUT_STREAM (object);
106   
107   if (!stream->priv->closed)
108     g_output_stream_close (stream, NULL, NULL);
109   
110   if (G_OBJECT_CLASS (g_output_stream_parent_class)->dispose)
111     (*G_OBJECT_CLASS (g_output_stream_parent_class)->dispose) (object);
112 }
113
114 static void
115 g_output_stream_class_init (GOutputStreamClass *klass)
116 {
117   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
118   
119   g_type_class_add_private (klass, sizeof (GOutputStreamPrivate));
120   
121   gobject_class->finalize = g_output_stream_finalize;
122   gobject_class->dispose = g_output_stream_dispose;
123
124   klass->splice = g_output_stream_real_splice;
125   
126   klass->write_async = g_output_stream_real_write_async;
127   klass->write_finish = g_output_stream_real_write_finish;
128   klass->splice_async = g_output_stream_real_splice_async;
129   klass->splice_finish = g_output_stream_real_splice_finish;
130   klass->flush_async = g_output_stream_real_flush_async;
131   klass->flush_finish = g_output_stream_real_flush_finish;
132   klass->close_async = g_output_stream_real_close_async;
133   klass->close_finish = g_output_stream_real_close_finish;
134 }
135
136 static void
137 g_output_stream_init (GOutputStream *stream)
138 {
139   stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
140                                               G_TYPE_OUTPUT_STREAM,
141                                               GOutputStreamPrivate);
142 }
143
144 /**
145  * g_output_stream_write:
146  * @stream: a #GOutputStream.
147  * @buffer: the buffer containing the data to write. 
148  * @count: the number of bytes to write
149  * @cancellable: optional cancellable object
150  * @error: location to store the error occuring, or %NULL to ignore
151  *
152  * Tries to write @count bytes from @buffer into the stream. Will block
153  * during the operation.
154  * 
155  * If count is zero returns zero and does nothing. A value of @count
156  * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
157  *
158  * On success, the number of bytes written to the stream is returned.
159  * It is not an error if this is not the same as the requested size, as it
160  * can happen e.g. on a partial i/o error, or if the there is not enough
161  * storage in the stream. All writes either block until at least one byte
162  * is written, so zero is never returned (unless @count is zero).
163  * 
164  * If @cancellable is not NULL, then the operation can be cancelled by
165  * triggering the cancellable object from another thread. If the operation
166  * was cancelled, the error G_IO_ERROR_CANCELLED will be returned. If an
167  * operation was partially finished when the operation was cancelled the
168  * partial result will be returned, without an error.
169  *
170  * On error -1 is returned and @error is set accordingly.
171  * 
172  * Return value: Number of bytes written, or -1 on error
173  **/
174 gssize
175 g_output_stream_write (GOutputStream  *stream,
176                        const void     *buffer,
177                        gsize           count,
178                        GCancellable   *cancellable,
179                        GError        **error)
180 {
181   GOutputStreamClass *class;
182   gssize res;
183
184   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
185   g_return_val_if_fail (buffer != NULL, 0);
186
187   if (count == 0)
188     return 0;
189   
190   if (((gssize) count) < 0)
191     {
192       g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
193                    _("Too large count value passed to g_output_stream_write"));
194       return -1;
195     }
196
197   if (stream->priv->closed)
198     {
199       g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
200                    _("Stream is already closed"));
201       return -1;
202     }
203   
204   if (stream->priv->pending)
205     {
206       g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
207                    _("Stream has outstanding operation"));
208       return -1;
209     }
210   
211   class = G_OUTPUT_STREAM_GET_CLASS (stream);
212
213   if (class->write == NULL) 
214     {
215       g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
216                    _("Output stream doesn't implement write"));
217       return -1;
218     }
219   
220   if (cancellable)
221     g_push_current_cancellable (cancellable);
222   
223   stream->priv->pending = TRUE;
224   res = class->write (stream, buffer, count, cancellable, error);
225   stream->priv->pending = FALSE;
226   
227   if (cancellable)
228     g_pop_current_cancellable (cancellable);
229   
230   return res; 
231 }
232
233 /**
234  * g_output_stream_write_all:
235  * @stream: a #GOutputStream.
236  * @buffer: the buffer containing the data to write. 
237  * @count: the number of bytes to write
238  * @bytes_written: location to store the number of bytes that was 
239  *     written to the stream
240  * @cancellable: optional #GCancellable object, %NULL to ignore.
241  * @error: location to store the error occuring, or %NULL to ignore
242  *
243  * Tries to write @count bytes from @buffer into the stream. Will block
244  * during the operation.
245  * 
246  * This function is similar to g_output_stream_write(), except it tries to
247  * write as many bytes as requested, only stopping on an error.
248  *
249  * On a successful write of @count bytes, %TRUE is returned, and @bytes_written
250  * is set to @count.
251  * 
252  * If there is an error during the operation FALSE is returned and @error
253  * is set to indicate the error status, @bytes_written is updated to contain
254  * the number of bytes written into the stream before the error occured.
255  *
256  * Return value: %TRUE on success, %FALSE if there was an error
257  **/
258 gboolean
259 g_output_stream_write_all (GOutputStream  *stream,
260                            const void     *buffer,
261                            gsize           count,
262                            gsize          *bytes_written,
263                            GCancellable   *cancellable,
264                            GError        **error)
265 {
266   gsize _bytes_written;
267   gssize res;
268
269   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
270   g_return_val_if_fail (buffer != NULL, FALSE);
271
272   _bytes_written = 0;
273   while (_bytes_written < count)
274     {
275       res = g_output_stream_write (stream, (char *)buffer + _bytes_written, count - _bytes_written,
276                                    cancellable, error);
277       if (res == -1)
278         {
279           if (bytes_written)
280             *bytes_written = _bytes_written;
281           return FALSE;
282         }
283       
284       if (res == 0)
285         g_warning ("Write returned zero without error");
286
287       _bytes_written += res;
288     }
289   
290   if (bytes_written)
291     *bytes_written = _bytes_written;
292
293   return TRUE;
294 }
295
296 /**
297  * g_output_stream_flush:
298  * @stream: a #GOutputStream.
299  * @cancellable: optional cancellable object
300  * @error: location to store the error occuring, or %NULL to ignore
301  *
302  * Flushed any outstanding buffers in the stream. Will block during 
303  * the operation. Closing the stream will implicitly cause a flush.
304  *
305  * This function is optional for inherited classes.
306  * 
307  * If @cancellable is not %NULL, then the operation can be cancelled by
308  * triggering the cancellable object from another thread. If the operation
309  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
310  *
311  * Return value: %TRUE on success, %FALSE on error
312  **/
313 gboolean
314 g_output_stream_flush (GOutputStream  *stream,
315                        GCancellable   *cancellable,
316                        GError        **error)
317 {
318   GOutputStreamClass *class;
319   gboolean res;
320
321   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
322
323   if (stream->priv->closed)
324     {
325       g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
326                    _("Stream is already closed"));
327       return FALSE;
328     }
329
330   if (stream->priv->pending)
331     {
332       g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
333                    _("Stream has outstanding operation"));
334       return FALSE;
335     }
336   
337   class = G_OUTPUT_STREAM_GET_CLASS (stream);
338
339   res = TRUE;
340   if (class->flush)
341     {
342       if (cancellable)
343         g_push_current_cancellable (cancellable);
344       
345       stream->priv->pending = TRUE;
346       res = class->flush (stream, cancellable, error);
347       stream->priv->pending = FALSE;
348       
349       if (cancellable)
350         g_pop_current_cancellable (cancellable);
351     }
352   
353   return res;
354 }
355
356 /**
357  * g_output_stream_splice:
358  * @stream: a #GOutputStream.
359  * @source: a #GInputStream.
360  * @flags: a set of #GOutputStreamSpliceFlags.
361  * @cancellable: optional #GCancellable object, %NULL to ignore. 
362  * @error: a #GError location to store the error occuring, or %NULL to 
363  * ignore.
364  *
365  * Splices an input stream into an output stream.
366  *
367  * Returns: a #gssize containig the size of the data spliced.
368  **/
369 gssize
370 g_output_stream_splice (GOutputStream             *stream,
371                         GInputStream              *source,
372                         GOutputStreamSpliceFlags   flags,
373                         GCancellable              *cancellable,
374                         GError                   **error)
375 {
376   GOutputStreamClass *class;
377   gboolean res;
378
379   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
380   g_return_val_if_fail (G_IS_INPUT_STREAM (source), -1);
381
382   if (stream->priv->closed)
383     {
384       g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
385                    _("Target stream is already closed"));
386       return -1;
387     }
388
389   if (g_input_stream_is_closed (source))
390     {
391       g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
392                    _("Source stream is already closed"));
393       return -1;
394     }
395
396   if (stream->priv->pending)
397     {
398       g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
399                    _("Stream has outstanding operation"));
400       return -1;
401     }
402   
403   class = G_OUTPUT_STREAM_GET_CLASS (stream);
404
405   res = TRUE;
406   if (cancellable)
407     g_push_current_cancellable (cancellable);
408       
409   stream->priv->pending = TRUE;
410   res = class->splice (stream, source, flags, cancellable, error);
411   stream->priv->pending = FALSE;
412       
413   if (cancellable)
414     g_pop_current_cancellable (cancellable);
415   
416   return res;
417 }
418
419 static gssize
420 g_output_stream_real_splice (GOutputStream             *stream,
421                              GInputStream              *source,
422                              GOutputStreamSpliceFlags   flags,
423                              GCancellable              *cancellable,
424                              GError                   **error)
425 {
426   gssize n_read, n_written;
427   gssize bytes_copied;
428   char buffer[8192], *p;
429   gboolean res;
430
431   bytes_copied = 0;
432   res = TRUE;
433   do 
434     {
435       n_read = g_input_stream_read (source, buffer, sizeof (buffer), cancellable, error);
436       if (n_read == -1)
437         {
438           res = FALSE;
439           break;
440         }
441         
442       if (n_read == 0)
443         break;
444
445       p = buffer;
446       while (n_read > 0)
447         {
448           stream->priv->pending = FALSE;
449           n_written = g_output_stream_write (stream, p, n_read, cancellable, error);
450           stream->priv->pending = TRUE;
451           if (n_written == -1)
452             {
453               res = FALSE;
454               break;
455             }
456
457           p += n_written;
458           n_read -= n_written;
459           bytes_copied += n_written;
460         }
461     }
462   while (res);
463
464   if (!res)
465     error = NULL; /* Ignore further errors */
466
467   if (flags & G_OUTPUT_STREAM_SPLICE_FLAGS_CLOSE_SOURCE)
468     {
469       /* Don't care about errors in source here */
470       g_input_stream_close (source, cancellable, NULL);
471     }
472
473   if (flags & G_OUTPUT_STREAM_SPLICE_FLAGS_CLOSE_TARGET)
474     {
475       /* But write errors on close are bad! */
476       stream->priv->pending = FALSE;
477       if (!g_output_stream_close (stream, cancellable, error))
478         res = FALSE;
479       stream->priv->pending = TRUE;
480     }
481
482   if (res)
483     return bytes_copied;
484   
485   return -1;
486 }
487
488
489 /**
490  * g_output_stream_close:
491  * @stream: A #GOutputStream.
492  * @cancellable: optional cancellable object
493  * @error: location to store the error occuring, or %NULL to ignore
494  *
495  * Closes the stream, releasing resources related to it.
496  *
497  * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED.
498  * Closing a stream multiple times will not return an error.
499  *
500  * Closing a stream will automatically flush any outstanding buffers in the
501  * stream.
502  *
503  * Streams will be automatically closed when the last reference
504  * is dropped, but you might want to call make sure resources
505  * are released as early as possible.
506  *
507  * Some streams might keep the backing store of the stream (e.g. a file descriptor)
508  * open after the stream is closed. See the documentation for the individual
509  * stream for details.
510  *
511  * On failure the first error that happened will be reported, but the close
512  * operation will finish as much as possible. A stream that failed to
513  * close will still return %G_IO_ERROR_CLOSED all operations. Still, it
514  * is important to check and report the error to the user, otherwise
515  * there might be a loss of data as all data might not be written.
516  * 
517  * If @cancellable is not NULL, then the operation can be cancelled by
518  * triggering the cancellable object from another thread. If the operation
519  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
520  * Cancelling a close will still leave the stream closed, but there some streams
521  * can use a faster close that doesn't block to e.g. check errors. On
522  * cancellation (as with any error) there is no guarantee that all written
523  * data will reach the target. 
524  *
525  * Return value: %TRUE on success, %FALSE on failure
526  **/
527 gboolean
528 g_output_stream_close (GOutputStream  *stream,
529                        GCancellable   *cancellable,
530                        GError        **error)
531 {
532   GOutputStreamClass *class;
533   gboolean res;
534
535   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
536
537   class = G_OUTPUT_STREAM_GET_CLASS (stream);
538
539   if (stream->priv->closed)
540     return TRUE;
541
542   if (stream->priv->pending)
543     {
544       g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
545                    _("Stream has outstanding operation"));
546       return FALSE;
547     }
548
549   res = g_output_stream_flush (stream, cancellable, error);
550
551   stream->priv->pending = TRUE;
552   
553   if (cancellable)
554     g_push_current_cancellable (cancellable);
555
556   if (!res)
557     {
558       /* flushing caused the error that we want to return,
559        * but we still want to close the underlying stream if possible
560        */
561       if (class->close)
562         class->close (stream, cancellable, NULL);
563     }
564   else
565     {
566       res = TRUE;
567       if (class->close)
568         res = class->close (stream, cancellable, error);
569     }
570   
571   if (cancellable)
572     g_pop_current_cancellable (cancellable);
573   
574   stream->priv->closed = TRUE;
575   stream->priv->pending = FALSE;
576   
577   return res;
578 }
579
580 static void
581 async_ready_callback_wrapper (GObject      *source_object,
582                               GAsyncResult *res,
583                               gpointer      user_data)
584 {
585   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
586
587   stream->priv->pending = FALSE;
588   if (stream->priv->outstanding_callback)
589     (*stream->priv->outstanding_callback) (source_object, res, user_data);
590   g_object_unref (stream);
591 }
592
593 static void
594 async_ready_close_callback_wrapper (GObject      *source_object,
595                                     GAsyncResult *res,
596                                     gpointer      user_data)
597 {
598   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
599
600   stream->priv->pending = FALSE;
601   stream->priv->closed = TRUE;
602   if (stream->priv->outstanding_callback)
603     (*stream->priv->outstanding_callback) (source_object, res, user_data);
604   g_object_unref (stream);
605 }
606
607 /**
608  * g_output_stream_write_async:
609  * @stream: A #GOutputStream.
610  * @buffer: the buffer containing the data to write. 
611  * @count: the number of bytes to write
612  * @io_priority: the io priority of the request.
613  * @cancellable: optional #GCancellable object, %NULL to ignore.
614  * @callback: callback to call when the request is satisfied
615  * @user_data: the data to pass to callback function
616  *
617  * Request an asynchronous write of @count bytes from @buffer into 
618  * the stream. When the operation is finished @callback will be called, 
619  * giving the results.
620  *
621  * During an async request no other sync and async calls are allowed, 
622  * and will result in %G_IO_ERROR_PENDING errors. 
623  *
624  * A value of @count larger than %G_MAXSSIZE will cause a 
625  * %G_IO_ERROR_INVALID_ARGUMENT error.
626  *
627  * On success, the number of bytes written will be passed to the
628  * @callback. It is not an error if this is not the same as the 
629  * requested size, as it can happen e.g. on a partial I/O error, 
630  * but generally we try to write as many bytes as requested. 
631  *
632  * Any outstanding I/O request with higher priority (lower numerical 
633  * value) will be executed before an outstanding request with lower 
634  * priority. Default priority is %G_PRIORITY_DEFAULT.
635  *
636  * The asyncronous methods have a default fallback that uses threads 
637  * to implement asynchronicity, so they are optional for inheriting 
638  * classes. However, if you override one you must override all.
639  *
640  * For the synchronous, blocking version of this function, see 
641  * g_output_stream_write().
642  **/
643 void
644 g_output_stream_write_async (GOutputStream       *stream,
645                              const void          *buffer,
646                              gsize                count,
647                              int                  io_priority,
648                              GCancellable        *cancellable,
649                              GAsyncReadyCallback  callback,
650                              gpointer             user_data)
651 {
652   GOutputStreamClass *class;
653   GSimpleAsyncResult *simple;
654
655   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
656   g_return_if_fail (buffer != NULL);
657
658   if (count == 0)
659     {
660       simple = g_simple_async_result_new (G_OBJECT (stream),
661                                           callback,
662                                           user_data,
663                                           g_output_stream_write_async);
664       g_simple_async_result_complete_in_idle (simple);
665       g_object_unref (simple);
666       return;
667     }
668
669   if (((gssize) count) < 0)
670     {
671       g_simple_async_report_error_in_idle (G_OBJECT (stream),
672                                            callback,
673                                            user_data,
674                                            G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
675                                            _("Too large count value passed to g_output_stream_write_async"));
676       return;
677     }
678
679   if (stream->priv->closed)
680     {
681       g_simple_async_report_error_in_idle (G_OBJECT (stream),
682                                            callback,
683                                            user_data,
684                                            G_IO_ERROR, G_IO_ERROR_CLOSED,
685                                            _("Stream is already closed"));
686       return;
687     }
688   
689   if (stream->priv->pending)
690     {
691       g_simple_async_report_error_in_idle (G_OBJECT (stream),
692                                            callback,
693                                            user_data,
694                                            G_IO_ERROR, G_IO_ERROR_PENDING,
695                                            _("Stream has outstanding operation"));
696       return;
697     }
698
699   class = G_OUTPUT_STREAM_GET_CLASS (stream);
700
701   stream->priv->pending = TRUE;
702   stream->priv->outstanding_callback = callback;
703   g_object_ref (stream);
704   class->write_async (stream, buffer, count, io_priority, cancellable,
705                       async_ready_callback_wrapper, user_data);
706 }
707
708 /**
709  * g_output_stream_write_finish:
710  * @stream: a #GOutputStream.
711  * @result: a #GAsyncResult.
712  * @error: a #GError location to store the error occuring, or %NULL to 
713  * ignore.
714  * 
715  * Finishes a stream write operation.
716  * 
717  * Returns: a #gssize containing the number of bytes written to the stream.
718  **/
719 gssize
720 g_output_stream_write_finish (GOutputStream  *stream,
721                               GAsyncResult   *result,
722                               GError        **error)
723 {
724   GSimpleAsyncResult *simple;
725   GOutputStreamClass *class;
726
727   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
728   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
729
730   if (G_IS_SIMPLE_ASYNC_RESULT (result))
731     {
732       simple = G_SIMPLE_ASYNC_RESULT (result);
733       if (g_simple_async_result_propagate_error (simple, error))
734         return -1;
735
736       /* Special case writes of 0 bytes */
737       if (g_simple_async_result_get_source_tag (simple) == g_output_stream_write_async)
738         return 0;
739     }
740   
741   class = G_OUTPUT_STREAM_GET_CLASS (stream);
742   return class->write_finish (stream, result, error);
743 }
744
745 typedef struct {
746   GInputStream *source;
747   gpointer user_data;
748   GAsyncReadyCallback callback;
749 } SpliceUserData;
750
751 static void
752 async_ready_splice_callback_wrapper (GObject      *source_object,
753                                      GAsyncResult *res,
754                                      gpointer     _data)
755 {
756   GOutputStream *stream = G_OUTPUT_STREAM (source_object);
757   SpliceUserData *data = _data;
758   
759   stream->priv->pending = FALSE;
760   
761   if (data->callback)
762     (*data->callback) (source_object, res, data->user_data);
763   
764   g_object_unref (stream);
765   g_object_unref (data->source);
766   g_free (data);
767 }
768
769 /**
770  * g_output_stream_splice_async:
771  * @stream: a #GOutputStream.
772  * @source: a #GInputStream. 
773  * @flags: a set of #GOutputStreamSpliceFlags.
774  * @io_priority: the io priority of the request.
775  * @cancellable: optional #GCancellable object, %NULL to ignore. 
776  * @callback: a #GAsyncReadyCallback. 
777  * @user_data: user data passed to @callback.
778  * 
779  * Splices a stream asynchronously.
780  * 
781  **/
782 void
783 g_output_stream_splice_async (GOutputStream            *stream,
784                               GInputStream             *source,
785                               GOutputStreamSpliceFlags  flags,
786                               int                       io_priority,
787                               GCancellable             *cancellable,
788                               GAsyncReadyCallback       callback,
789                               gpointer                  user_data)
790 {
791   GOutputStreamClass *class;
792   SpliceUserData *data;
793
794   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
795   g_return_if_fail (G_IS_INPUT_STREAM (source));
796
797   if (stream->priv->closed)
798     {
799       g_simple_async_report_error_in_idle (G_OBJECT (stream),
800                                            callback,
801                                            user_data,
802                                            G_IO_ERROR, G_IO_ERROR_CLOSED,
803                                            _("Target stream is already closed"));
804       return;
805     }
806
807   if (g_input_stream_is_closed (source))
808     {
809       g_simple_async_report_error_in_idle (G_OBJECT (stream),
810                                            callback,
811                                            user_data,
812                                            G_IO_ERROR, G_IO_ERROR_CLOSED,
813                                            _("Source stream is already closed"));
814       return;
815     }
816   
817   if (stream->priv->pending)
818     {
819       g_simple_async_report_error_in_idle (G_OBJECT (stream),
820                                            callback,
821                                            user_data,
822                                            G_IO_ERROR, G_IO_ERROR_PENDING,
823                                            _("Stream has outstanding operation"));
824       return;
825     }
826
827   class = G_OUTPUT_STREAM_GET_CLASS (stream);
828
829   stream->priv->pending = TRUE;
830
831   data = g_new0 (SpliceUserData, 1);
832   data->callback = callback;
833   data->user_data = user_data;
834   data->source = g_object_ref (source);
835   
836   g_object_ref (stream);
837   class->splice_async (stream, source, flags, io_priority, cancellable,
838                       async_ready_splice_callback_wrapper, data);
839 }
840
841 /**
842  * g_output_stream_splice_finish:
843  * @stream: a #GOutputStream.
844  * @result: a #GAsyncResult.
845  * @error: a #GError location to store the error occuring, or %NULL to 
846  * ignore.
847  *
848  * Finishes an asynchronous stream splice operation.
849  * 
850  * Returns: a #gssize of the number of bytes spliced.
851  **/
852 gssize
853 g_output_stream_splice_finish (GOutputStream  *stream,
854                                GAsyncResult   *result,
855                                GError        **error)
856 {
857   GSimpleAsyncResult *simple;
858   GOutputStreamClass *class;
859
860   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1);
861   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
862
863   if (G_IS_SIMPLE_ASYNC_RESULT (result))
864     {
865       simple = G_SIMPLE_ASYNC_RESULT (result);
866       if (g_simple_async_result_propagate_error (simple, error))
867         return -1;
868     }
869   
870   class = G_OUTPUT_STREAM_GET_CLASS (stream);
871   return class->splice_finish (stream, result, error);
872 }
873
874 /**
875  * g_output_stream_flush_async:
876  * @stream: a #GOutputStream.
877  * @io_priority: the io priority of the request.
878  * @cancellable: optional #GCancellable object, %NULL to ignore.
879  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
880  * @user_data: the data to pass to callback function
881  * 
882  * Flushes a stream asynchronously.
883  * 
884  **/
885 void
886 g_output_stream_flush_async (GOutputStream       *stream,
887                              int                  io_priority,
888                              GCancellable        *cancellable,
889                              GAsyncReadyCallback  callback,
890                              gpointer             user_data)
891 {
892   GOutputStreamClass *class;
893   GSimpleAsyncResult *simple;
894
895   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
896
897   if (stream->priv->closed)
898     {
899       g_simple_async_report_error_in_idle (G_OBJECT (stream),
900                                            callback,
901                                            user_data,
902                                            G_IO_ERROR, G_IO_ERROR_CLOSED,
903                                            _("Stream is already closed"));
904       return;
905     }
906   
907   if (stream->priv->pending)
908     {
909       g_simple_async_report_error_in_idle (G_OBJECT (stream),
910                                            callback,
911                                            user_data,
912                                            G_IO_ERROR, G_IO_ERROR_PENDING,
913                                            _("Stream has outstanding operation"));
914       return;
915     }
916
917   class = G_OUTPUT_STREAM_GET_CLASS (stream);
918   
919   if (class->flush_async == NULL)
920     {
921       simple = g_simple_async_result_new (G_OBJECT (stream),
922                                           callback,
923                                           user_data,
924                                           g_output_stream_flush_async);
925       g_simple_async_result_complete_in_idle (simple);
926       g_object_unref (simple);
927       return;
928     }
929       
930   stream->priv->pending = TRUE;
931   stream->priv->outstanding_callback = callback;
932   g_object_ref (stream);
933   class->flush_async (stream, io_priority, cancellable,
934                       async_ready_callback_wrapper, user_data);
935 }
936
937 /**
938  * g_output_stream_flush_finish:
939  * @stream: a #GOutputStream.
940  * @result: a GAsyncResult.
941  * @error: a #GError location to store the error occuring, or %NULL to 
942  * ignore.
943  * 
944  * Finishes flushing an output stream.
945  * 
946  * Returns: %TRUE if flush operation suceeded, %FALSE otherwise.
947  **/
948 gboolean
949 g_output_stream_flush_finish (GOutputStream  *stream,
950                               GAsyncResult   *result,
951                               GError        **error)
952 {
953   GSimpleAsyncResult *simple;
954   GOutputStreamClass *klass;
955
956   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
957   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
958
959   if (G_IS_SIMPLE_ASYNC_RESULT (result))
960     {
961       simple = G_SIMPLE_ASYNC_RESULT (result);
962       if (g_simple_async_result_propagate_error (simple, error))
963         return FALSE;
964
965       /* Special case default implementation */
966       if (g_simple_async_result_get_source_tag (simple) == g_output_stream_flush_async)
967         return TRUE;
968     }
969
970   klass = G_OUTPUT_STREAM_GET_CLASS (stream);
971   return klass->flush_finish (stream, result, error);
972 }
973
974
975 /**
976  * g_output_stream_close_async:
977  * @stream: A #GOutputStream.
978  * @io_priority: the io priority of the request.
979  * @callback: callback to call when the request is satisfied
980  * @user_data: the data to pass to callback function
981  * @cancellable: optional cancellable object
982  *
983  * Requests an asynchronous close of the stream, releasing resources 
984  * related to it. When the operation is finished @callback will be 
985  * called, giving the results.
986  *
987  * For behaviour details see g_output_stream_close().
988  *
989  * The asyncronous methods have a default fallback that uses threads 
990  * to implement asynchronicity, so they are optional for inheriting 
991  * classes. However, if you override one you must override all.
992  **/
993 void
994 g_output_stream_close_async (GOutputStream       *stream,
995                              int                  io_priority,
996                              GCancellable        *cancellable,
997                              GAsyncReadyCallback  callback,
998                              gpointer             user_data)
999 {
1000   GOutputStreamClass *class;
1001   GSimpleAsyncResult *simple;
1002
1003   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1004   
1005   if (stream->priv->closed)
1006     {
1007       simple = g_simple_async_result_new (G_OBJECT (stream),
1008                                           callback,
1009                                           user_data,
1010                                           g_output_stream_close_async);
1011       g_simple_async_result_complete_in_idle (simple);
1012       g_object_unref (simple);
1013       return;
1014     }
1015
1016   if (stream->priv->pending)
1017     {
1018       g_simple_async_report_error_in_idle (G_OBJECT (stream),
1019                                            callback,
1020                                            user_data,
1021                                            G_IO_ERROR, G_IO_ERROR_PENDING,
1022                                            _("Stream has outstanding operation"));
1023       return;
1024     }
1025   
1026   class = G_OUTPUT_STREAM_GET_CLASS (stream);
1027   stream->priv->pending = TRUE;
1028   stream->priv->outstanding_callback = callback;
1029   g_object_ref (stream);
1030   class->close_async (stream, io_priority, cancellable,
1031                       async_ready_close_callback_wrapper, user_data);
1032 }
1033
1034 /**
1035  * g_output_stream_close_finish:
1036  * @stream: a #GOutputStream.
1037  * @result: a #GAsyncResult.
1038  * @error: a #GError location to store the error occuring, or %NULL to 
1039  * ignore.
1040  * 
1041  * Closes an output stream.
1042  * 
1043  * Returns: %TRUE if stream was successfully closed, %FALSE otherwise.
1044  **/
1045 gboolean
1046 g_output_stream_close_finish (GOutputStream  *stream,
1047                               GAsyncResult   *result,
1048                               GError        **error)
1049 {
1050   GSimpleAsyncResult *simple;
1051   GOutputStreamClass *class;
1052
1053   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1054   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
1055
1056   if (G_IS_SIMPLE_ASYNC_RESULT (result))
1057     {
1058       simple = G_SIMPLE_ASYNC_RESULT (result);
1059       if (g_simple_async_result_propagate_error (simple, error))
1060         return FALSE;
1061
1062       /* Special case already closed */
1063       if (g_simple_async_result_get_source_tag (simple) == g_output_stream_close_async)
1064         return TRUE;
1065     }
1066
1067   class = G_OUTPUT_STREAM_GET_CLASS (stream);
1068   return class->close_finish (stream, result, error);
1069 }
1070
1071 /**
1072  * g_output_stream_is_closed:
1073  * @stream: a #GOutputStream.
1074  * 
1075  * Checks if an output stream has already been closed.
1076  * 
1077  * Returns: %TRUE if @stream is closed. %FALSE otherwise. 
1078  **/
1079 gboolean
1080 g_output_stream_is_closed (GOutputStream *stream)
1081 {
1082   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE);
1083   
1084   return stream->priv->closed;
1085 }
1086
1087 /**
1088  * g_output_stream_has_pending:
1089  * @stream: a #GOutputStream.
1090  * 
1091  * Checks if an ouput stream has pending actions.
1092  * 
1093  * Returns: %TRUE if @stream has pending actions. 
1094  **/
1095 gboolean
1096 g_output_stream_has_pending (GOutputStream *stream)
1097 {
1098   g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE);
1099   
1100   return stream->priv->pending;
1101 }
1102
1103 /**
1104  * g_output_stream_set_pending:
1105  * @stream: a #GOutputStream.
1106  * @pending: a #gboolean.
1107  * 
1108  * Sets the @stream as having pending actions if @pending is %TRUE. 
1109  **/
1110 void
1111 g_output_stream_set_pending (GOutputStream *stream,
1112                             gboolean        pending)
1113 {
1114   g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
1115   
1116   stream->priv->pending = pending;
1117 }
1118
1119
1120 /********************************************
1121  *   Default implementation of async ops    *
1122  ********************************************/
1123
1124 typedef struct {
1125   const void         *buffer;
1126   gsize               count_requested;
1127   gssize              count_written;
1128 } WriteData;
1129
1130 static void
1131 write_async_thread (GSimpleAsyncResult *res,
1132                     GObject            *object,
1133                     GCancellable       *cancellable)
1134 {
1135   WriteData *op;
1136   GOutputStreamClass *class;
1137   GError *error = NULL;
1138
1139   class = G_OUTPUT_STREAM_GET_CLASS (object);
1140   op = g_simple_async_result_get_op_res_gpointer (res);
1141   op->count_written = class->write (G_OUTPUT_STREAM (object), op->buffer, op->count_requested,
1142                                     cancellable, &error);
1143   if (op->count_written == -1)
1144     {
1145       g_simple_async_result_set_from_error (res, error);
1146       g_error_free (error);
1147     }
1148 }
1149
1150 static void
1151 g_output_stream_real_write_async (GOutputStream       *stream,
1152                                   const void          *buffer,
1153                                   gsize                count,
1154                                   int                  io_priority,
1155                                   GCancellable        *cancellable,
1156                                   GAsyncReadyCallback  callback,
1157                                   gpointer             user_data)
1158 {
1159   GSimpleAsyncResult *res;
1160   WriteData *op;
1161
1162   op = g_new0 (WriteData, 1);
1163   res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
1164   g_simple_async_result_set_op_res_gpointer (res, op, g_free);
1165   op->buffer = buffer;
1166   op->count_requested = count;
1167   
1168   g_simple_async_result_run_in_thread (res, write_async_thread, io_priority, cancellable);
1169   g_object_unref (res);
1170 }
1171
1172 static gssize
1173 g_output_stream_real_write_finish (GOutputStream  *stream,
1174                                    GAsyncResult   *result,
1175                                    GError        **error)
1176 {
1177   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1178   WriteData *op;
1179
1180   g_assert (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_write_async);
1181   op = g_simple_async_result_get_op_res_gpointer (simple);
1182   return op->count_written;
1183 }
1184
1185 typedef struct {
1186   GInputStream *source;
1187   GOutputStreamSpliceFlags flags;
1188   gssize bytes_copied;
1189 } SpliceData;
1190
1191 static void
1192 splice_async_thread (GSimpleAsyncResult *result,
1193                      GObject            *object,
1194                      GCancellable       *cancellable)
1195 {
1196   SpliceData *op;
1197   GOutputStreamClass *class;
1198   GError *error = NULL;
1199   GOutputStream *stream;
1200
1201   stream = G_OUTPUT_STREAM (object);
1202   class = G_OUTPUT_STREAM_GET_CLASS (object);
1203   op = g_simple_async_result_get_op_res_gpointer (result);
1204   
1205   stream->priv->pending = FALSE;
1206   op->bytes_copied =
1207     g_output_stream_splice (stream,
1208                             op->source,
1209                             op->flags,
1210                             cancellable,
1211                             &error);
1212   stream->priv->pending = TRUE;
1213
1214   if (op->bytes_copied == -1)
1215     {
1216       g_simple_async_result_set_from_error (result, error);
1217       g_error_free (error);
1218     }
1219 }
1220
1221 static void
1222 g_output_stream_real_splice_async (GOutputStream             *stream,
1223                                    GInputStream              *source,
1224                                    GOutputStreamSpliceFlags   flags,
1225                                    int                        io_priority,
1226                                    GCancellable              *cancellable,
1227                                    GAsyncReadyCallback        callback,
1228                                    gpointer                   user_data)
1229 {
1230   GSimpleAsyncResult *res;
1231   SpliceData *op;
1232
1233   op = g_new0 (SpliceData, 1);
1234   res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_splice_async);
1235   g_simple_async_result_set_op_res_gpointer (res, op, g_free);
1236   op->flags = flags;
1237   op->source = source;
1238
1239   /* TODO: In the case where both source and destintion have
1240      non-threadbased async calls we can use a true async copy here */
1241   
1242   g_simple_async_result_run_in_thread (res, splice_async_thread, io_priority, cancellable);
1243   g_object_unref (res);
1244 }
1245
1246 static gssize
1247 g_output_stream_real_splice_finish (GOutputStream  *stream,
1248                                     GAsyncResult   *result,
1249                                     GError        **error)
1250 {
1251   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1252   SpliceData *op;
1253
1254   g_assert (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_splice_async);
1255   op = g_simple_async_result_get_op_res_gpointer (simple);
1256   return op->bytes_copied;
1257 }
1258
1259
1260 static void
1261 flush_async_thread (GSimpleAsyncResult *res,
1262                     GObject            *object,
1263                     GCancellable       *cancellable)
1264 {
1265   GOutputStreamClass *class;
1266   gboolean result;
1267   GError *error = NULL;
1268
1269   class = G_OUTPUT_STREAM_GET_CLASS (object);
1270   result = TRUE;
1271   if (class->flush)
1272     result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error);
1273
1274   if (!result)
1275     {
1276       g_simple_async_result_set_from_error (res, error);
1277       g_error_free (error);
1278     }
1279 }
1280
1281 static void
1282 g_output_stream_real_flush_async (GOutputStream       *stream,
1283                                   int                  io_priority,
1284                                   GCancellable        *cancellable,
1285                                   GAsyncReadyCallback  callback,
1286                                   gpointer             user_data)
1287 {
1288   GSimpleAsyncResult *res;
1289
1290   res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async);
1291   
1292   g_simple_async_result_run_in_thread (res, flush_async_thread, io_priority, cancellable);
1293   g_object_unref (res);
1294 }
1295
1296 static gboolean
1297 g_output_stream_real_flush_finish (GOutputStream  *stream,
1298                                    GAsyncResult   *result,
1299                                    GError        **error)
1300 {
1301   return TRUE;
1302 }
1303
1304 static void
1305 close_async_thread (GSimpleAsyncResult *res,
1306                     GObject            *object,
1307                     GCancellable       *cancellable)
1308 {
1309   GOutputStreamClass *class;
1310   GError *error = NULL;
1311   gboolean result;
1312
1313   /* Auto handling of cancelation disabled, and ignore
1314      cancellation, since we want to close things anyway, although
1315      possibly in a quick-n-dirty way. At least we never want to leak
1316      open handles */
1317   
1318   class = G_OUTPUT_STREAM_GET_CLASS (object);
1319   result = class->close (G_OUTPUT_STREAM (object), cancellable, &error);
1320   if (!result)
1321     {
1322       g_simple_async_result_set_from_error (res, error);
1323       g_error_free (error);
1324     }
1325 }
1326
1327 static void
1328 g_output_stream_real_close_async (GOutputStream       *stream,
1329                                   int                  io_priority,
1330                                   GCancellable        *cancellable,
1331                                   GAsyncReadyCallback  callback,
1332                                   gpointer             user_data)
1333 {
1334   GSimpleAsyncResult *res;
1335   
1336   res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_close_async);
1337
1338   g_simple_async_result_set_handle_cancellation (res, FALSE);
1339   
1340   g_simple_async_result_run_in_thread (res, close_async_thread, io_priority, cancellable);
1341   g_object_unref (res);
1342 }
1343
1344 static gboolean
1345 g_output_stream_real_close_finish (GOutputStream  *stream,
1346                                    GAsyncResult   *result,
1347                                    GError        **error)
1348 {
1349   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1350   g_assert (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_close_async);
1351   return TRUE;
1352 }
1353
1354 #define __G_OUTPUT_STREAM_C__
1355 #include "gioaliasdef.c"