1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2006-2007 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: Alexander Larsson <alexl@redhat.com>
27 #include "ginputstream.h"
28 #include "gseekable.h"
29 #include "gsimpleasyncresult.h"
32 * SECTION:ginputstream
33 * @short_description: base class for implementing streaming input
39 G_DEFINE_TYPE (GInputStream, g_input_stream, G_TYPE_OBJECT);
41 struct _GInputStreamPrivate {
44 GAsyncReadyCallback outstanding_callback;
47 static gssize g_input_stream_real_skip (GInputStream *stream,
49 GCancellable *cancellable,
51 static void g_input_stream_real_read_async (GInputStream *stream,
55 GCancellable *cancellable,
56 GAsyncReadyCallback callback,
58 static gssize g_input_stream_real_read_finish (GInputStream *stream,
61 static void g_input_stream_real_skip_async (GInputStream *stream,
64 GCancellable *cancellable,
65 GAsyncReadyCallback callback,
67 static gssize g_input_stream_real_skip_finish (GInputStream *stream,
70 static void g_input_stream_real_close_async (GInputStream *stream,
72 GCancellable *cancellable,
73 GAsyncReadyCallback callback,
75 static gboolean g_input_stream_real_close_finish (GInputStream *stream,
80 g_input_stream_finalize (GObject *object)
84 stream = G_INPUT_STREAM (object);
86 if (!stream->priv->closed)
87 g_input_stream_close (stream, NULL, NULL);
89 if (G_OBJECT_CLASS (g_input_stream_parent_class)->finalize)
90 (*G_OBJECT_CLASS (g_input_stream_parent_class)->finalize) (object);
94 g_input_stream_dispose (GObject *object)
98 stream = G_INPUT_STREAM (object);
100 if (!stream->priv->closed)
101 g_input_stream_close (stream, NULL, NULL);
103 if (G_OBJECT_CLASS (g_input_stream_parent_class)->dispose)
104 (*G_OBJECT_CLASS (g_input_stream_parent_class)->dispose) (object);
109 g_input_stream_class_init (GInputStreamClass *klass)
111 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
113 g_type_class_add_private (klass, sizeof (GInputStreamPrivate));
115 gobject_class->finalize = g_input_stream_finalize;
116 gobject_class->dispose = g_input_stream_dispose;
118 klass->skip = g_input_stream_real_skip;
119 klass->read_async = g_input_stream_real_read_async;
120 klass->read_finish = g_input_stream_real_read_finish;
121 klass->skip_async = g_input_stream_real_skip_async;
122 klass->skip_finish = g_input_stream_real_skip_finish;
123 klass->close_async = g_input_stream_real_close_async;
124 klass->close_finish = g_input_stream_real_close_finish;
128 g_input_stream_init (GInputStream *stream)
130 stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
132 GInputStreamPrivate);
136 * g_input_stream_read:
137 * @stream: a #GInputStream.
138 * @buffer: a buffer to read data into (which should be at least count bytes long).
139 * @count: the number of bytes that will be read from the stream
140 * @cancellable: optional #GCancellable object, %NULL to ignore.
141 * @error: location to store the error occuring, or %NULL to ignore
143 * Tries to read @count bytes from the stream into the buffer starting at
144 * @buffer. Will block during this read.
146 * If count is zero returns zero and does nothing. A value of @count
147 * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
149 * On success, the number of bytes read into the buffer is returned.
150 * It is not an error if this is not the same as the requested size, as it
151 * can happen e.g. near the end of a file. Zero is returned on end of file
152 * (or if @count is zero), but never otherwise.
154 * If @cancellable is not NULL, then the operation can be cancelled by
155 * triggering the cancellable object from another thread. If the operation
156 * was cancelled, the error G_IO_ERROR_CANCELLED will be returned. If an
157 * operation was partially finished when the operation was cancelled the
158 * partial result will be returned, without an error.
160 * On error -1 is returned and @error is set accordingly.
162 * Return value: Number of bytes read, or -1 on error
165 g_input_stream_read (GInputStream *stream,
168 GCancellable *cancellable,
171 GInputStreamClass *class;
174 g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1);
175 g_return_val_if_fail (buffer != NULL, 0);
180 if (((gssize) count) < 0)
182 g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
183 _("Too large count value passed to g_input_stream_read"));
187 if (stream->priv->closed)
189 g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
190 _("Stream is already closed"));
194 if (stream->priv->pending)
196 g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
197 _("Stream has outstanding operation"));
201 class = G_INPUT_STREAM_GET_CLASS (stream);
203 if (class->read == NULL)
205 g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
206 _("Input stream doesn't implement read"));
211 g_push_current_cancellable (cancellable);
213 stream->priv->pending = TRUE;
214 res = class->read (stream, buffer, count, cancellable, error);
215 stream->priv->pending = FALSE;
218 g_pop_current_cancellable (cancellable);
224 * g_input_stream_read_all:
225 * @stream: a #GInputStream.
226 * @buffer: a buffer to read data into (which should be at least count bytes long).
227 * @count: the number of bytes that will be read from the stream
228 * @bytes_read: location to store the number of bytes that was read from the stream
229 * @cancellable: optional #GCancellable object, %NULL to ignore.
230 * @error: location to store the error occuring, or %NULL to ignore
232 * Tries to read @count bytes from the stream into the buffer starting at
233 * @buffer. Will block during this read.
235 * This function is similar to g_input_stream_read(), except it tries to
236 * read as many bytes as requested, only stopping on an error or end of stream.
238 * On a successful read of @count bytes, or if we reached the end of the
239 * stream, %TRUE is returned, and @bytes_read is set to the number of bytes
242 * If there is an error during the operation %FALSE is returned and @error
243 * is set to indicate the error status, @bytes_read is updated to contain
244 * the number of bytes read into @buffer before the error occured.
246 * Return value: %TRUE on success, %FALSE if there was an error
249 g_input_stream_read_all (GInputStream *stream,
253 GCancellable *cancellable,
259 g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
260 g_return_val_if_fail (buffer != NULL, FALSE);
263 while (_bytes_read < count)
265 res = g_input_stream_read (stream, (char *)buffer + _bytes_read, count - _bytes_read,
270 *bytes_read = _bytes_read;
281 *bytes_read = _bytes_read;
286 * g_input_stream_skip:
287 * @stream: a #GInputStream.
288 * @count: the number of bytes that will be skipped from the stream
289 * @cancellable: optional #GCancellable object, %NULL to ignore.
290 * @error: location to store the error occuring, or %NULL to ignore
292 * Tries to skip @count bytes from the stream. Will block during the operation.
294 * This is identical to g_input_stream_read(), from a behaviour standpoint,
295 * but the bytes that are skipped are not returned to the user. Some
296 * streams have an implementation that is more efficient than reading the data.
298 * This function is optional for inherited classes, as the default implementation
299 * emulates it using read.
301 * If @cancellable is not %NULL, then the operation can be cancelled by
302 * triggering the cancellable object from another thread. If the operation
303 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
304 * operation was partially finished when the operation was cancelled the
305 * partial result will be returned, without an error.
307 * Return value: Number of bytes skipped, or -1 on error
310 g_input_stream_skip (GInputStream *stream,
312 GCancellable *cancellable,
315 GInputStreamClass *class;
318 g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1);
323 if (((gssize) count) < 0)
325 g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
326 _("Too large count value passed to g_input_stream_skip"));
330 if (stream->priv->closed)
332 g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
333 _("Stream is already closed"));
337 if (stream->priv->pending)
339 g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
340 _("Stream has outstanding operation"));
344 class = G_INPUT_STREAM_GET_CLASS (stream);
347 g_push_current_cancellable (cancellable);
349 stream->priv->pending = TRUE;
350 res = class->skip (stream, count, cancellable, error);
351 stream->priv->pending = FALSE;
354 g_pop_current_cancellable (cancellable);
360 g_input_stream_real_skip (GInputStream *stream,
362 GCancellable *cancellable,
365 GInputStreamClass *class;
366 gssize ret, read_bytes;
370 class = G_INPUT_STREAM_GET_CLASS (stream);
372 if (G_IS_SEEKABLE (stream) && g_seekable_can_seek (G_SEEKABLE (stream)))
374 if (g_seekable_seek (G_SEEKABLE (stream),
382 /* If not seekable, or seek failed, fall back to reading data: */
384 class = G_INPUT_STREAM_GET_CLASS (stream);
391 ret = class->read (stream, buffer, MIN (sizeof (buffer), count),
392 cancellable, &my_error);
395 if (read_bytes > 0 &&
396 my_error->domain == G_IO_ERROR &&
397 my_error->code == G_IO_ERROR_CANCELLED)
399 g_error_free (my_error);
403 g_propagate_error (error, my_error);
410 if (ret == 0 || count == 0)
416 * g_input_stream_close:
417 * @stream: A #GInputStream.
418 * @cancellable: optional #GCancellable object, %NULL to ignore.
419 * @error: location to store the error occuring, or %NULL to ignore
421 * Closes the stream, releasing resources related to it.
423 * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED.
424 * Closing a stream multiple times will not return an error.
426 * Streams will be automatically closed when the last reference
427 * is dropped, but you might want to call make sure resources
428 * are released as early as possible.
430 * Some streams might keep the backing store of the stream (e.g. a file descriptor)
431 * open after the stream is closed. See the documentation for the individual
432 * stream for details.
434 * On failure the first error that happened will be reported, but the close
435 * operation will finish as much as possible. A stream that failed to
436 * close will still return %G_IO_ERROR_CLOSED all operations. Still, it
437 * is important to check and report the error to the user.
439 * If @cancellable is not NULL, then the operation can be cancelled by
440 * triggering the cancellable object from another thread. If the operation
441 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
442 * Cancelling a close will still leave the stream closed, but some streams
443 * can use a faster close that doesn't block to e.g. check errors.
445 * Return value: %TRUE on success, %FALSE on failure
448 g_input_stream_close (GInputStream *stream,
449 GCancellable *cancellable,
452 GInputStreamClass *class;
455 g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
457 class = G_INPUT_STREAM_GET_CLASS (stream);
459 if (stream->priv->closed)
462 if (stream->priv->pending)
464 g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
465 _("Stream has outstanding operation"));
471 stream->priv->pending = TRUE;
474 g_push_current_cancellable (cancellable);
477 res = class->close (stream, cancellable, error);
480 g_pop_current_cancellable (cancellable);
482 stream->priv->closed = TRUE;
484 stream->priv->pending = FALSE;
490 async_ready_callback_wrapper (GObject *source_object,
494 GInputStream *stream = G_INPUT_STREAM (source_object);
496 stream->priv->pending = FALSE;
497 if (stream->priv->outstanding_callback)
498 (*stream->priv->outstanding_callback) (source_object, res, user_data);
499 g_object_unref (stream);
503 async_ready_close_callback_wrapper (GObject *source_object,
507 GInputStream *stream = G_INPUT_STREAM (source_object);
509 stream->priv->pending = FALSE;
510 stream->priv->closed = TRUE;
511 if (stream->priv->outstanding_callback)
512 (*stream->priv->outstanding_callback) (source_object, res, user_data);
513 g_object_unref (stream);
517 * g_input_stream_read_async:
518 * @stream: A #GInputStream.
519 * @buffer: a buffer to read data into (which should be at least count bytes long).
520 * @count: the number of bytes that will be read from the stream
521 * @io_priority: the io priority of the request. the io priority of the request
522 * @cancellable: optional #GCancellable object, %NULL to ignore.
523 * @callback: callback to call when the request is satisfied
524 * @user_data: the data to pass to callback function
526 * Request an asynchronous read of @count bytes from the stream into the buffer
527 * starting at @buffer. When the operation is finished @callback will be called,
528 * giving the results.
530 * During an async request no other sync and async calls are allowed, and will
531 * result in %G_IO_ERROR_PENDING errors.
533 * A value of @count larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
535 * On success, the number of bytes read into the buffer will be passed to the
536 * callback. It is not an error if this is not the same as the requested size, as it
537 * can happen e.g. near the end of a file, but generally we try to read
538 * as many bytes as requested. Zero is returned on end of file
539 * (or if @count is zero), but never otherwise.
541 * Any outstanding i/o request with higher priority (lower numerical value) will
542 * be executed before an outstanding request with lower priority. Default
543 * priority is %G_PRIORITY_DEFAULT.
545 * The asyncronous methods have a default fallback that uses threads to implement
546 * asynchronicity, so they are optional for inheriting classes. However, if you
547 * override one you must override all.
550 g_input_stream_read_async (GInputStream *stream,
554 GCancellable *cancellable,
555 GAsyncReadyCallback callback,
558 GInputStreamClass *class;
559 GSimpleAsyncResult *simple;
561 g_return_if_fail (G_IS_INPUT_STREAM (stream));
562 g_return_if_fail (buffer != NULL);
566 simple = g_simple_async_result_new (G_OBJECT (stream),
569 g_input_stream_read_async);
570 g_simple_async_result_complete_in_idle (simple);
571 g_object_unref (simple);
575 if (((gssize) count) < 0)
577 g_simple_async_report_error_in_idle (G_OBJECT (stream),
580 G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
581 _("Too large count value passed to g_input_stream_read_async"));
585 if (stream->priv->closed)
587 g_simple_async_report_error_in_idle (G_OBJECT (stream),
590 G_IO_ERROR, G_IO_ERROR_CLOSED,
591 _("Stream is already closed"));
595 if (stream->priv->pending)
597 g_simple_async_report_error_in_idle (G_OBJECT (stream),
600 G_IO_ERROR, G_IO_ERROR_PENDING,
601 _("Stream has outstanding operation"));
605 class = G_INPUT_STREAM_GET_CLASS (stream);
607 stream->priv->pending = TRUE;
608 stream->priv->outstanding_callback = callback;
609 g_object_ref (stream);
610 class->read_async (stream, buffer, count, io_priority, cancellable,
611 async_ready_callback_wrapper, user_data);
615 * g_input_stream_read_finish:
616 * @stream: a #GInputStream.
617 * @result: a #GAsyncResult.
618 * @error: a #GError location to store the error occuring, or %NULL to
621 * Finishes an asynchronous stream read operation.
623 * Returns: number of bytes read in, or -1 on error.
626 g_input_stream_read_finish (GInputStream *stream,
627 GAsyncResult *result,
630 GSimpleAsyncResult *simple;
631 GInputStreamClass *class;
633 g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1);
634 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
636 if (G_IS_SIMPLE_ASYNC_RESULT (result))
638 simple = G_SIMPLE_ASYNC_RESULT (result);
639 if (g_simple_async_result_propagate_error (simple, error))
642 /* Special case read of 0 bytes */
643 if (g_simple_async_result_get_source_tag (simple) == g_input_stream_read_async)
647 class = G_INPUT_STREAM_GET_CLASS (stream);
648 return class->read_finish (stream, result, error);
652 * g_input_stream_skip_async:
653 * @stream: A #GInputStream.
654 * @count: the number of bytes that will be skipped from the stream
655 * @io_priority: the io priority of the request. the io priority of the request
656 * @cancellable: optional #GCancellable object, %NULL to ignore.
657 * @callback: callback to call when the request is satisfied
658 * @user_data: the data to pass to callback function
660 * Request an asynchronous skip of @count bytes from the stream into the buffer
661 * starting at @buffer. When the operation is finished @callback will be called,
662 * giving the results.
664 * During an async request no other sync and async calls are allowed, and will
665 * result in %G_IO_ERROR_PENDING errors.
667 * A value of @count larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
669 * On success, the number of bytes skipped will be passed to the
670 * callback. It is not an error if this is not the same as the requested size, as it
671 * can happen e.g. near the end of a file, but generally we try to skip
672 * as many bytes as requested. Zero is returned on end of file
673 * (or if @count is zero), but never otherwise.
675 * Any outstanding i/o request with higher priority (lower numerical value) will
676 * be executed before an outstanding request with lower priority. Default
677 * priority is %G_PRIORITY_DEFAULT.
679 * The asyncronous methods have a default fallback that uses threads to implement
680 * asynchronicity, so they are optional for inheriting classes. However, if you
681 * override one you must override all.
684 g_input_stream_skip_async (GInputStream *stream,
687 GCancellable *cancellable,
688 GAsyncReadyCallback callback,
691 GInputStreamClass *class;
692 GSimpleAsyncResult *simple;
694 g_return_if_fail (G_IS_INPUT_STREAM (stream));
698 simple = g_simple_async_result_new (G_OBJECT (stream),
701 g_input_stream_skip_async);
703 g_simple_async_result_complete_in_idle (simple);
704 g_object_unref (simple);
708 if (((gssize) count) < 0)
710 g_simple_async_report_error_in_idle (G_OBJECT (stream),
713 G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
714 _("Too large count value passed to g_input_stream_skip_async"));
718 if (stream->priv->closed)
720 g_simple_async_report_error_in_idle (G_OBJECT (stream),
723 G_IO_ERROR, G_IO_ERROR_CLOSED,
724 _("Stream is already closed"));
728 if (stream->priv->pending)
730 g_simple_async_report_error_in_idle (G_OBJECT (stream),
733 G_IO_ERROR, G_IO_ERROR_PENDING,
734 _("Stream has outstanding operation"));
738 class = G_INPUT_STREAM_GET_CLASS (stream);
739 stream->priv->pending = TRUE;
740 stream->priv->outstanding_callback = callback;
741 g_object_ref (stream);
742 class->skip_async (stream, count, io_priority, cancellable,
743 async_ready_callback_wrapper, user_data);
747 * g_input_stream_skip_finish:
748 * @stream: a #GInputStream.
749 * @result: a #GAsyncResult.
750 * @error: a #GError location to store the error occuring, or %NULL to
753 * Finishes a stream skip operation.
755 * Returns: the size of the bytes skipped, or %-1 on error.
758 g_input_stream_skip_finish (GInputStream *stream,
759 GAsyncResult *result,
762 GSimpleAsyncResult *simple;
763 GInputStreamClass *class;
765 g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1);
766 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
768 if (G_IS_SIMPLE_ASYNC_RESULT (result))
770 simple = G_SIMPLE_ASYNC_RESULT (result);
771 if (g_simple_async_result_propagate_error (simple, error))
774 /* Special case skip of 0 bytes */
775 if (g_simple_async_result_get_source_tag (simple) == g_input_stream_skip_async)
779 class = G_INPUT_STREAM_GET_CLASS (stream);
780 return class->skip_finish (stream, result, error);
784 * g_input_stream_close_async:
785 * @stream: A #GInputStream.
786 * @io_priority: the io priority of the request. the io priority of the request
787 * @cancellable: optional cancellable object
788 * @callback: callback to call when the request is satisfied
789 * @user_data: the data to pass to callback function
791 * Requests an asynchronous closes of the stream, releasing resources related to it.
792 * When the operation is finished @callback will be called, giving the results.
794 * For behaviour details see g_input_stream_close().
796 * The asyncronous methods have a default fallback that uses threads to implement
797 * asynchronicity, so they are optional for inheriting classes. However, if you
798 * override one you must override all.
801 g_input_stream_close_async (GInputStream *stream,
803 GCancellable *cancellable,
804 GAsyncReadyCallback callback,
807 GInputStreamClass *class;
808 GSimpleAsyncResult *simple;
810 g_return_if_fail (G_IS_INPUT_STREAM (stream));
812 if (stream->priv->closed)
814 simple = g_simple_async_result_new (G_OBJECT (stream),
817 g_input_stream_close_async);
819 g_simple_async_result_complete_in_idle (simple);
820 g_object_unref (simple);
824 if (stream->priv->pending)
826 g_simple_async_report_error_in_idle (G_OBJECT (stream),
829 G_IO_ERROR, G_IO_ERROR_PENDING,
830 _("Stream has outstanding operation"));
834 class = G_INPUT_STREAM_GET_CLASS (stream);
835 stream->priv->pending = TRUE;
836 stream->priv->outstanding_callback = callback;
837 g_object_ref (stream);
838 class->close_async (stream, io_priority, cancellable,
839 async_ready_close_callback_wrapper, user_data);
843 * g_input_stream_close_finish:
844 * @stream: a #GInputStream.
845 * @result: a #GAsyncResult.
846 * @error: a #GError location to store the error occuring, or %NULL to
849 * Finishes closing a stream asynchronously, started from g_input_stream_close_async().
851 * Returns: %TRUE if the stream was closed successfully.
854 g_input_stream_close_finish (GInputStream *stream,
855 GAsyncResult *result,
858 GSimpleAsyncResult *simple;
859 GInputStreamClass *class;
861 g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
862 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
864 if (G_IS_SIMPLE_ASYNC_RESULT (result))
866 simple = G_SIMPLE_ASYNC_RESULT (result);
867 if (g_simple_async_result_propagate_error (simple, error))
870 /* Special case already closed */
871 if (g_simple_async_result_get_source_tag (simple) == g_input_stream_close_async)
875 class = G_INPUT_STREAM_GET_CLASS (stream);
876 return class->close_finish (stream, result, error);
880 * g_input_stream_is_closed:
881 * @stream: input stream.
883 * Checks if an input stream is closed.
885 * Returns: %TRUE if the stream is closed.
888 g_input_stream_is_closed (GInputStream *stream)
890 g_return_val_if_fail (G_IS_INPUT_STREAM (stream), TRUE);
892 return stream->priv->closed;
896 * g_input_stream_has_pending:
897 * @stream: input stream.
899 * Checks if an input stream has pending actions.
901 * Returns: %TRUE if @stream has pending actions.
904 g_input_stream_has_pending (GInputStream *stream)
906 g_return_val_if_fail (G_IS_INPUT_STREAM (stream), TRUE);
908 return stream->priv->pending;
912 * g_input_stream_set_pending:
913 * @stream: input stream
916 * Sets @stream has actions pending.
919 g_input_stream_set_pending (GInputStream *stream,
922 g_return_if_fail (G_IS_INPUT_STREAM (stream));
924 stream->priv->pending = pending;
927 /********************************************
928 * Default implementation of async ops *
929 ********************************************/
933 gsize count_requested;
938 read_async_thread (GSimpleAsyncResult *res,
940 GCancellable *cancellable)
943 GInputStreamClass *class;
944 GError *error = NULL;
946 op = g_simple_async_result_get_op_res_gpointer (res);
948 class = G_INPUT_STREAM_GET_CLASS (object);
950 op->count_read = class->read (G_INPUT_STREAM (object),
951 op->buffer, op->count_requested,
952 cancellable, &error);
953 if (op->count_read == -1)
955 g_simple_async_result_set_from_error (res, error);
956 g_error_free (error);
961 g_input_stream_real_read_async (GInputStream *stream,
965 GCancellable *cancellable,
966 GAsyncReadyCallback callback,
969 GSimpleAsyncResult *res;
972 op = g_new (ReadData, 1);
973 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_input_stream_real_read_async);
974 g_simple_async_result_set_op_res_gpointer (res, op, g_free);
976 op->count_requested = count;
978 g_simple_async_result_run_in_thread (res, read_async_thread, io_priority, cancellable);
979 g_object_unref (res);
983 g_input_stream_real_read_finish (GInputStream *stream,
984 GAsyncResult *result,
987 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
990 g_assert (g_simple_async_result_get_source_tag (simple) ==
991 g_input_stream_real_read_async);
993 op = g_simple_async_result_get_op_res_gpointer (simple);
995 return op->count_read;
999 gsize count_requested;
1000 gssize count_skipped;
1005 skip_async_thread (GSimpleAsyncResult *res,
1007 GCancellable *cancellable)
1010 GInputStreamClass *class;
1011 GError *error = NULL;
1013 class = G_INPUT_STREAM_GET_CLASS (object);
1014 op = g_simple_async_result_get_op_res_gpointer (res);
1015 op->count_skipped = class->skip (G_INPUT_STREAM (object),
1016 op->count_requested,
1017 cancellable, &error);
1018 if (op->count_skipped == -1)
1020 g_simple_async_result_set_from_error (res, error);
1021 g_error_free (error);
1028 gsize count_skipped;
1030 GCancellable *cancellable;
1032 GAsyncReadyCallback callback;
1033 } SkipFallbackAsyncData;
1036 skip_callback_wrapper (GObject *source_object,
1040 GInputStreamClass *class;
1041 SkipFallbackAsyncData *data = user_data;
1043 GSimpleAsyncResult *simple;
1044 GError *error = NULL;
1047 ret = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
1052 data->count_skipped += ret;
1054 if (data->count > 0)
1056 class = G_INPUT_STREAM_GET_CLASS (source_object);
1057 class->read_async (G_INPUT_STREAM (source_object), data->buffer, MIN (8192, data->count), data->io_prio, data->cancellable,
1058 skip_callback_wrapper, data);
1063 op = g_new0 (SkipData, 1);
1064 op->count_skipped = data->count_skipped;
1065 simple = g_simple_async_result_new (source_object,
1066 data->callback, data->user_data,
1067 g_input_stream_real_skip_async);
1069 g_simple_async_result_set_op_res_gpointer (simple, op, g_free);
1073 if (data->count_skipped &&
1074 error->domain == G_IO_ERROR &&
1075 error->code == G_IO_ERROR_CANCELLED)
1076 { /* No error, return partial read */ }
1078 g_simple_async_result_set_from_error (simple, error);
1079 g_error_free (error);
1082 /* Complete immediately, not in idle, since we're already in a mainloop callout */
1083 g_simple_async_result_complete (simple);
1084 g_object_unref (simple);
1090 g_input_stream_real_skip_async (GInputStream *stream,
1093 GCancellable *cancellable,
1094 GAsyncReadyCallback callback,
1097 GInputStreamClass *class;
1099 SkipFallbackAsyncData *data;
1100 GSimpleAsyncResult *res;
1102 class = G_INPUT_STREAM_GET_CLASS (stream);
1104 if (class->read_async == g_input_stream_real_read_async)
1106 /* Read is thread-using async fallback.
1107 * Make skip use threads too, so that we can use a possible sync skip
1108 * implementation. */
1109 op = g_new0 (SkipData, 1);
1111 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
1112 g_input_stream_real_skip_async);
1114 g_simple_async_result_set_op_res_gpointer (res, op, g_free);
1116 op->count_requested = count;
1118 g_simple_async_result_run_in_thread (res, skip_async_thread, io_priority, cancellable);
1119 g_object_unref (res);
1123 /* TODO: Skip fallback uses too much memory, should do multiple read calls */
1125 /* There is a custom async read function, lets use that. */
1126 data = g_new (SkipFallbackAsyncData, 1);
1127 data->count = count;
1128 data->count_skipped = 0;
1129 data->io_prio = io_priority;
1130 data->cancellable = cancellable;
1131 data->callback = callback;
1132 data->user_data = user_data;
1133 class->read_async (stream, data->buffer, MIN (8192, count), io_priority, cancellable,
1134 skip_callback_wrapper, data);
1140 g_input_stream_real_skip_finish (GInputStream *stream,
1141 GAsyncResult *result,
1144 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1147 g_assert (g_simple_async_result_get_source_tag (simple) == g_input_stream_real_skip_async);
1148 op = g_simple_async_result_get_op_res_gpointer (simple);
1149 return op->count_skipped;
1153 close_async_thread (GSimpleAsyncResult *res,
1155 GCancellable *cancellable)
1157 GInputStreamClass *class;
1158 GError *error = NULL;
1161 /* Auto handling of cancelation disabled, and ignore
1162 cancellation, since we want to close things anyway, although
1163 possibly in a quick-n-dirty way. At least we never want to leak
1166 class = G_INPUT_STREAM_GET_CLASS (object);
1167 result = class->close (G_INPUT_STREAM (object), cancellable, &error);
1170 g_simple_async_result_set_from_error (res, error);
1171 g_error_free (error);
1176 g_input_stream_real_close_async (GInputStream *stream,
1178 GCancellable *cancellable,
1179 GAsyncReadyCallback callback,
1182 GSimpleAsyncResult *res;
1184 res = g_simple_async_result_new (G_OBJECT (stream),
1187 g_input_stream_real_close_async);
1189 g_simple_async_result_set_handle_cancellation (res, FALSE);
1191 g_simple_async_result_run_in_thread (res,
1195 g_object_unref (res);
1199 g_input_stream_real_close_finish (GInputStream *stream,
1200 GAsyncResult *result,
1203 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1204 g_assert (g_simple_async_result_get_source_tag (simple) == g_input_stream_real_close_async);