Use g_simple_async_result_{new_,}take_error
[platform/upstream/glib.git] / gio / gbufferedinputstream.c
index 62c96f9..78e61cb 100644 (file)
@@ -1,5 +1,5 @@
 /* GIO - GLib Input, Output and Streaming Library
- * 
+ *
  * Copyright (C) 2006-2007 Red Hat, Inc.
  * Copyright (C) 2007 Jürg Billeter
  *
  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  * Boston, MA 02111-1307, USA.
  *
- * Author: Christian Kellner <gicmo@gnome.org> 
+ * Author: Christian Kellner <gicmo@gnome.org>
  */
 
-#include <config.h>
+#include "config.h"
 #include "gbufferedinputstream.h"
 #include "ginputstream.h"
+#include "gcancellable.h"
+#include "gasyncresult.h"
 #include "gsimpleasyncresult.h"
+#include "gioerror.h"
 #include <string.h>
 #include "glibintl.h"
 
-#include "gioalias.h"
 
 /**
  * SECTION:gbufferedinputstream
  * @short_description: Buffered Input Stream
+ * @include: gio/gio.h
  * @see_also: #GFilterInputStream, #GInputStream
- * 
- * Buffered input stream implements #GFilterInputStream and provides 
- * for buffered reads. 
- * 
+ *
+ * Buffered input stream implements #GFilterInputStream and provides
+ * for buffered reads.
+ *
  * By default, #GBufferedInputStream's buffer size is set at 4 kilobytes.
- * 
- * To create a buffered input stream, use g_buffered_input_stream_new(), or 
- * g_buffered_input_stream_new_sized() to specify the buffer's size at construction.
- * 
- * To get the size of a buffer within a buffered input stream, use 
- * g_buffered_input_stream_get_buffer_size(). To change the size of a 
- * buffered input stream's buffer, use g_buffered_input_stream_set_buffer_size(). 
- * Note: the buffer's size cannot be reduced below the size of the data within the
- * buffer.
  *
- **/
-
+ * To create a buffered input stream, use g_buffered_input_stream_new(),
+ * or g_buffered_input_stream_new_sized() to specify the buffer's size at
+ * construction.
+ *
+ * To get the size of a buffer within a buffered input stream, use
+ * g_buffered_input_stream_get_buffer_size(). To change the size of a
+ * buffered input stream's buffer, use
+ * g_buffered_input_stream_set_buffer_size(). Note that the buffer's size
+ * cannot be reduced below the size of the data within the buffer.
+ */
 
 
 #define DEFAULT_BUFFER_SIZE 4096
@@ -81,46 +83,46 @@ static void g_buffered_input_stream_finalize      (GObject *object);
 
 
 static gssize g_buffered_input_stream_skip             (GInputStream          *stream,
-                                                       gsize                  count,
-                                                       GCancellable          *cancellable,
-                                                       GError               **error);
+                                                        gsize                  count,
+                                                        GCancellable          *cancellable,
+                                                        GError               **error);
 static void   g_buffered_input_stream_skip_async       (GInputStream          *stream,
-                                                       gsize                  count,
-                                                       int                    io_priority,
-                                                       GCancellable          *cancellable,
-                                                       GAsyncReadyCallback    callback,
-                                                       gpointer               user_data);
+                                                        gsize                  count,
+                                                        int                    io_priority,
+                                                        GCancellable          *cancellable,
+                                                        GAsyncReadyCallback    callback,
+                                                        gpointer               user_data);
 static gssize g_buffered_input_stream_skip_finish      (GInputStream          *stream,
-                                                       GAsyncResult          *result,
-                                                       GError               **error);
+                                                        GAsyncResult          *result,
+                                                        GError               **error);
 static gssize g_buffered_input_stream_read             (GInputStream          *stream,
-                                                       void                  *buffer,
-                                                       gsize                  count,
-                                                       GCancellable          *cancellable,
-                                                       GError               **error);
+                                                        void                  *buffer,
+                                                        gsize                  count,
+                                                        GCancellable          *cancellable,
+                                                        GError               **error);
 static void   g_buffered_input_stream_read_async       (GInputStream          *stream,
-                                                       void                  *buffer,
-                                                       gsize                  count,
-                                                       int                    io_priority,
-                                                       GCancellable          *cancellable,
-                                                       GAsyncReadyCallback    callback,
-                                                       gpointer               user_data);
+                                                        void                  *buffer,
+                                                        gsize                  count,
+                                                        int                    io_priority,
+                                                        GCancellable          *cancellable,
+                                                        GAsyncReadyCallback    callback,
+                                                        gpointer               user_data);
 static gssize g_buffered_input_stream_read_finish      (GInputStream          *stream,
-                                                       GAsyncResult          *result,
-                                                       GError               **error);
+                                                        GAsyncResult          *result,
+                                                        GError               **error);
 static gssize g_buffered_input_stream_real_fill        (GBufferedInputStream  *stream,
-                                                       gssize                 count,
-                                                       GCancellable          *cancellable,
-                                                       GError               **error);
+                                                        gssize                 count,
+                                                        GCancellable          *cancellable,
+                                                        GError               **error);
 static void   g_buffered_input_stream_real_fill_async  (GBufferedInputStream  *stream,
-                                                       gssize                 count,
-                                                       int                    io_priority,
-                                                       GCancellable          *cancellable,
-                                                       GAsyncReadyCallback    callback,
-                                                       gpointer               user_data);
+                                                        gssize                 count,
+                                                        int                    io_priority,
+                                                        GCancellable          *cancellable,
+                                                        GAsyncReadyCallback    callback,
+                                                        gpointer               user_data);
 static gssize g_buffered_input_stream_real_fill_finish (GBufferedInputStream  *stream,
-                                                       GAsyncResult          *result,
-                                                       GError               **error);
+                                                        GAsyncResult          *result,
+                                                        GError               **error);
 
 static void compact_buffer (GBufferedInputStream *stream);
 
@@ -147,7 +149,7 @@ g_buffered_input_stream_class_init (GBufferedInputStreamClass *klass)
   istream_class->skip = g_buffered_input_stream_skip;
   istream_class->skip_async  = g_buffered_input_stream_skip_async;
   istream_class->skip_finish = g_buffered_input_stream_skip_finish;
-  istream_class->read = g_buffered_input_stream_read;
+  istream_class->read_fn = g_buffered_input_stream_read;
   istream_class->read_async  = g_buffered_input_stream_read_async;
   istream_class->read_finish = g_buffered_input_stream_read_finish;
 
@@ -155,7 +157,7 @@ g_buffered_input_stream_class_init (GBufferedInputStreamClass *klass)
   bstream_class->fill = g_buffered_input_stream_real_fill;
   bstream_class->fill_async = g_buffered_input_stream_real_fill_async;
   bstream_class->fill_finish = g_buffered_input_stream_real_fill_finish;
-  
+
   g_object_class_install_property (object_class,
                                    PROP_BUFSIZE,
                                    g_param_spec_uint ("buffer-size",
@@ -172,41 +174,44 @@ g_buffered_input_stream_class_init (GBufferedInputStreamClass *klass)
 
 /**
  * g_buffered_input_stream_get_buffer_size:
- * @stream: #GBufferedInputStream.
- * 
+ * @stream: a #GBufferedInputStream
+ *
  * Gets the size of the input buffer.
- * 
- * Returns: the current buffer size, or %-1 on error.
- **/
+ *
+ * Returns: the current buffer size.
+ */
 gsize
 g_buffered_input_stream_get_buffer_size (GBufferedInputStream  *stream)
 {
-  g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1);
+  g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), 0);
 
   return stream->priv->len;
 }
 
 /**
  * g_buffered_input_stream_set_buffer_size:
- * @stream: #GBufferedInputStream.
- * @size: a #gsize.
+ * @stream: a #GBufferedInputStream
+ * @size: a #gsize
  *
- * Sets the size of the internal buffer of @stream to @size, or to the 
- * size of the contents of the buffer. The buffer can never be resized 
+ * Sets the size of the internal buffer of @stream to @size, or to the
+ * size of the contents of the buffer. The buffer can never be resized
  * smaller than its current contents.
- **/
+ */
 void
-g_buffered_input_stream_set_buffer_size (GBufferedInputStream  *stream,
-                                         gsize                  size)
+g_buffered_input_stream_set_buffer_size (GBufferedInputStream *stream,
+                                         gsize                 size)
 {
   GBufferedInputStreamPrivate *priv;
   gsize in_buffer;
   guint8 *buffer;
-  
+
   g_return_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream));
 
   priv = stream->priv;
 
+  if (priv->len == size)
+    return;
+
   if (priv->buffer)
     {
       in_buffer = priv->end - priv->pos;
@@ -229,6 +234,8 @@ g_buffered_input_stream_set_buffer_size (GBufferedInputStream  *stream,
       priv->end = 0;
       priv->buffer = g_malloc (size);
     }
+
+  g_object_notify (G_OBJECT (stream), "buffer-size");
 }
 
 static void
@@ -237,13 +244,11 @@ g_buffered_input_stream_set_property (GObject      *object,
                                       const GValue *value,
                                       GParamSpec   *pspec)
 {
-  GBufferedInputStreamPrivate *priv;
   GBufferedInputStream        *bstream;
 
   bstream = G_BUFFERED_INPUT_STREAM (object);
-  priv = bstream->priv;
 
-  switch (prop_id) 
+  switch (prop_id)
     {
     case PROP_BUFSIZE:
       g_buffered_input_stream_set_buffer_size (bstream, g_value_get_uint (value));
@@ -253,7 +258,6 @@ g_buffered_input_stream_set_property (GObject      *object,
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
     }
-
 }
 
 static void
@@ -269,7 +273,7 @@ g_buffered_input_stream_get_property (GObject    *object,
   priv = bstream->priv;
 
   switch (prop_id)
-    { 
+    {
     case PROP_BUFSIZE:
       g_value_set_uint (value, priv->len);
       break;
@@ -291,8 +295,7 @@ g_buffered_input_stream_finalize (GObject *object)
 
   g_free (priv->buffer);
 
-  if (G_OBJECT_CLASS (g_buffered_input_stream_parent_class)->finalize)
-    (*G_OBJECT_CLASS (g_buffered_input_stream_parent_class)->finalize) (object);
+  G_OBJECT_CLASS (g_buffered_input_stream_parent_class)->finalize (object);
 }
 
 static void
@@ -306,13 +309,13 @@ g_buffered_input_stream_init (GBufferedInputStream *stream)
 
 /**
  * g_buffered_input_stream_new:
- * @base_stream: a #GInputStream.
- * 
- * Creates a new #GInputStream from the given @base_stream, with 
+ * @base_stream: a #GInputStream
+ *
+ * Creates a new #GInputStream from the given @base_stream, with
  * a buffer set to the default size (4 kilobytes).
  *
  * Returns: a #GInputStream for the given @base_stream.
- **/
+ */
 GInputStream *
 g_buffered_input_stream_new (GInputStream *base_stream)
 {
@@ -329,14 +332,14 @@ g_buffered_input_stream_new (GInputStream *base_stream)
 
 /**
  * g_buffered_input_stream_new_sized:
- * @base_stream: a #GOutputStream.
- * @size: a #gsize.
- * 
- * Creates a new #GBufferedInputStream from the given @base_stream, 
+ * @base_stream: a #GInputStream
+ * @size: a #gsize
+ *
+ * Creates a new #GBufferedInputStream from the given @base_stream,
  * with a buffer set to @size.
  *
  * Returns: a #GInputStream.
- **/
+ */
 GInputStream *
 g_buffered_input_stream_new_sized (GInputStream *base_stream,
                                    gsize         size)
@@ -355,14 +358,14 @@ g_buffered_input_stream_new_sized (GInputStream *base_stream,
 
 /**
  * g_buffered_input_stream_fill:
- * @stream: #GBufferedInputStream.
- * @count: the number of bytes that will be read from the stream.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
- * @error: location to store the error occuring, or %NULL to ignore.
+ * @stream: a #GBufferedInputStream
+ * @count: the number of bytes that will be read from the stream
+ * @cancellable: optional #GCancellable object, %NULL to ignore
+ * @error: location to store the error occuring, or %NULL to ignore
  *
- * Tries to read @count bytes from the stream into the buffer. 
+ * Tries to read @count bytes from the stream into the buffer.
  * Will block during this read.
- * 
+ *
  * If @count is zero, returns zero and does nothing. A value of @count
  * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
  *
@@ -371,6 +374,9 @@ g_buffered_input_stream_new_sized (GInputStream *base_stream,
  * can happen e.g. near the end of a file. Zero is returned on end of file
  * (or if @count is zero),  but never otherwise.
  *
+ * If @count is -1 then the attempted read size is equal to the number of
+ * bytes that are required to fill the buffer.
+ *
  * If @cancellable is not %NULL, then the operation can be cancelled by
  * triggering the cancellable object from another thread. If the operation
  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
@@ -378,13 +384,13 @@ g_buffered_input_stream_new_sized (GInputStream *base_stream,
  * partial result will be returned, without an error.
  *
  * On error -1 is returned and @error is set accordingly.
- * 
- * For the asynchronous, non-blocking, version of this function, see 
+ *
+ * For the asynchronous, non-blocking, version of this function, see
  * g_buffered_input_stream_fill_async().
  *
- * Returns: the number of bytes read into @stream's buffer, up to @count, 
+ * Returns: the number of bytes read into @stream's buffer, up to @count,
  *     or -1 on error.
- **/
+ */
 gssize
 g_buffered_input_stream_fill (GBufferedInputStream  *stream,
                               gssize                 count,
@@ -396,36 +402,30 @@ g_buffered_input_stream_fill (GBufferedInputStream  *stream,
   gssize res;
 
   g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1);
-  
+
   input_stream = G_INPUT_STREAM (stream);
-  
-  if (g_input_stream_is_closed (input_stream))
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
-                  _("Stream is already closed"));
-      return -1;
-    }
-  
-  if (g_input_stream_has_pending (input_stream))
+
+  if (count < -1)
     {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
-                  _("Stream has outstanding operation"));
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+                   _("Too large count value passed to %s"), G_STRFUNC);
       return -1;
     }
-      
-  g_input_stream_set_pending (input_stream, TRUE);
+
+  if (!g_input_stream_set_pending (input_stream, error))
+    return -1;
 
   if (cancellable)
-    g_push_current_cancellable (cancellable);
-  
+    g_cancellable_push_current (cancellable);
+
   class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
   res = class->fill (stream, count, cancellable, error);
 
   if (cancellable)
-    g_pop_current_cancellable (cancellable);
-  
-  g_input_stream_set_pending (input_stream, FALSE);
-  
+    g_cancellable_pop_current (cancellable);
+
+  g_input_stream_clear_pending (input_stream);
+
   return res;
 }
 
@@ -436,25 +436,28 @@ async_fill_callback_wrapper (GObject      *source_object,
 {
   GBufferedInputStream *stream = G_BUFFERED_INPUT_STREAM (source_object);
 
-  g_input_stream_set_pending (G_INPUT_STREAM (stream), FALSE);
+  g_input_stream_clear_pending (G_INPUT_STREAM (stream));
   (*stream->priv->outstanding_callback) (source_object, res, user_data);
   g_object_unref (stream);
 }
 
 /**
  * g_buffered_input_stream_fill_async:
- * @stream: #GBufferedInputStream.
- * @count: a #gssize.
- * @io_priority: the <link linkend="io-priority">I/O priority</link> 
- *     of the request.
+ * @stream: a #GBufferedInputStream
+ * @count: the number of bytes that will be read from the stream
+ * @io_priority: the <link linkend="io-priority">I/O priority</link>
+ *     of the request
  * @cancellable: optional #GCancellable object
- * @callback: a #GAsyncReadyCallback.
- * @user_data: a #gpointer.
+ * @callback: a #GAsyncReadyCallback
+ * @user_data: a #gpointer
  *
  * Reads data into @stream's buffer asynchronously, up to @count size.
  * @io_priority can be used to prioritize reads. For the synchronous
  * version of this function, see g_buffered_input_stream_fill().
- **/
+ *
+ * If @count is -1 then the attempted read size is equal to the number
+ * of bytes that are required to fill the buffer.
+ */
 void
 g_buffered_input_stream_fill_async (GBufferedInputStream *stream,
                                     gssize                count,
@@ -465,53 +468,44 @@ g_buffered_input_stream_fill_async (GBufferedInputStream *stream,
 {
   GBufferedInputStreamClass *class;
   GSimpleAsyncResult *simple;
+  GError *error = NULL;
 
   g_return_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream));
 
   if (count == 0)
     {
       simple = g_simple_async_result_new (G_OBJECT (stream),
-                                         callback,
-                                         user_data,
-                                         g_buffered_input_stream_fill_async);
+                                          callback,
+                                          user_data,
+                                          g_buffered_input_stream_fill_async);
       g_simple_async_result_complete_in_idle (simple);
       g_object_unref (simple);
       return;
     }
-  
-  if (((gssize) count) < 0)
-    {
-      g_simple_async_report_error_in_idle (G_OBJECT (stream),
-                                          callback,
-                                          user_data,
-                                          G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
-                                          _("Too large count value passed to g_input_stream_read_async"));
-      return;
-    }
-  
-  if (g_input_stream_is_closed (G_INPUT_STREAM (stream)))
+
+  if (count < -1)
     {
       g_simple_async_report_error_in_idle (G_OBJECT (stream),
-                                          callback,
-                                          user_data,
-                                          G_IO_ERROR, G_IO_ERROR_CLOSED,
-                                          _("Stream is already closed"));
+                                           callback,
+                                           user_data,
+                                           G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+                                           _("Too large count value passed to %s"),
+                                           G_STRFUNC);
       return;
     }
-    
-  if (g_input_stream_has_pending (G_INPUT_STREAM (stream)))
+
+  if (!g_input_stream_set_pending (G_INPUT_STREAM (stream), &error))
     {
-      g_simple_async_report_error_in_idle (G_OBJECT (stream),
-                                          callback,
-                                          user_data,
-                                          G_IO_ERROR, G_IO_ERROR_PENDING,
-                                          _("Stream has outstanding operation"));
+      g_simple_async_report_gerror_in_idle (G_OBJECT (stream),
+                                            callback,
+                                            user_data,
+                                            error);
+      g_error_free (error);
       return;
     }
 
   class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
-  
-  g_input_stream_set_pending (G_INPUT_STREAM (stream), TRUE);
+
   stream->priv->outstanding_callback = callback;
   g_object_ref (stream);
   class->fill_async (stream, count, io_priority, cancellable,
@@ -520,14 +514,14 @@ g_buffered_input_stream_fill_async (GBufferedInputStream *stream,
 
 /**
  * g_buffered_input_stream_fill_finish:
- * @stream: a #GBufferedInputStream.
- * @result: a #GAsyncResult.
- * @error: a #GError.
+ * @stream: a #GBufferedInputStream
+ * @result: a #GAsyncResult
+ * @error: a #GError
  *
  * Finishes an asynchronous read.
- * 
- * Returns: a #gssize of the read stream, or %-1 on an error. 
- **/
+ *
+ * Returns: a #gssize of the read stream, or %-1 on an error.
+ */
 gssize
 g_buffered_input_stream_fill_finish (GBufferedInputStream  *stream,
                                      GAsyncResult          *result,
@@ -556,12 +550,12 @@ g_buffered_input_stream_fill_finish (GBufferedInputStream  *stream,
 
 /**
  * g_buffered_input_stream_get_available:
- * @stream: #GBufferedInputStream.
- * 
+ * @stream: #GBufferedInputStream
+ *
  * Gets the size of the available data within the stream.
- * 
- * Returns: size of the available stream. 
- **/
+ *
+ * Returns: size of the available stream.
+ */
 gsize
 g_buffered_input_stream_get_available (GBufferedInputStream *stream)
 {
@@ -572,16 +566,16 @@ g_buffered_input_stream_get_available (GBufferedInputStream *stream)
 
 /**
  * g_buffered_input_stream_peek:
- * @stream: a #GBufferedInputStream.
- * @buffer: a pointer to an allocated chunk of memory.
- * @offset: a #gsize.
- * @count: a #gsize.
- * 
- * Peeks in the buffer, copying data of size @count into @buffer, 
+ * @stream: a #GBufferedInputStream
+ * @buffer: a pointer to an allocated chunk of memory
+ * @offset: a #gsize
+ * @count: a #gsize
+ *
+ * Peeks in the buffer, copying data of size @count into @buffer,
  * offset @offset bytes.
- * 
- * Returns: a #gsize of the number of bytes peeked, or %-1 on error.
- **/
+ *
+ * Returns: a #gsize of the number of bytes peeked, or -1 on error.
+ */
 gsize
 g_buffered_input_stream_peek (GBufferedInputStream *stream,
                               void                 *buffer,
@@ -590,7 +584,7 @@ g_buffered_input_stream_peek (GBufferedInputStream *stream,
 {
   gsize available;
   gsize end;
-  
+
   g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1);
   g_return_val_if_fail (buffer != NULL, -1);
 
@@ -598,25 +592,25 @@ g_buffered_input_stream_peek (GBufferedInputStream *stream,
 
   if (offset > available)
     return 0;
-  
+
   end = MIN (offset + count, available);
   count = end - offset;
-  
+
   memcpy (buffer, stream->priv->buffer + stream->priv->pos + offset, count);
   return count;
 }
 
 /**
  * g_buffered_input_stream_peek_buffer:
- * @stream: a #GBufferedInputStream.
- * @count: a #gsize to get the number of bytes available in the buffer.
+ * @stream: a #GBufferedInputStream
+ * @count: a #gsize to get the number of bytes available in the buffer
  *
  * Returns the buffer with the currently available bytes. The returned
  * buffer must not be modified and will become invalid when reading from
  * the stream or filling the buffer.
  *
  * Returns: read-only buffer
- **/
+ */
 const void*
 g_buffered_input_stream_peek_buffer (GBufferedInputStream *stream,
                                      gsize                *count)
@@ -627,7 +621,7 @@ g_buffered_input_stream_peek_buffer (GBufferedInputStream *stream,
 
   priv = stream->priv;
 
-  if (count) 
+  if (count)
     *count = priv->end - priv->pos;
 
   return priv->buffer + priv->pos;
@@ -642,9 +636,9 @@ compact_buffer (GBufferedInputStream *stream)
   priv = stream->priv;
 
   current_size = priv->end - priv->pos;
-  
+
   g_memmove (priv->buffer, priv->buffer + priv->pos, current_size);
-  
+
   priv->pos = 0;
   priv->end = current_size;
 }
@@ -664,7 +658,7 @@ g_buffered_input_stream_real_fill (GBufferedInputStream  *stream,
 
   if (count == -1)
     count = priv->len;
-  
+
   in_buffer = priv->end - priv->pos;
 
   /* Never fill more than can fit in the buffer */
@@ -683,7 +677,7 @@ g_buffered_input_stream_real_fill (GBufferedInputStream  *stream,
 
   if (nread > 0)
     priv->end += nread;
-  
+
   return nread;
 }
 
@@ -695,6 +689,7 @@ g_buffered_input_stream_skip (GInputStream  *stream,
 {
   GBufferedInputStream        *bstream;
   GBufferedInputStreamPrivate *priv;
+  GBufferedInputStreamClass *class;
   GInputStream *base_stream;
   gsize available, bytes_skipped;
   gssize nread;
@@ -710,10 +705,10 @@ g_buffered_input_stream_skip (GInputStream  *stream,
       return count;
     }
 
-  /* Full request not available, skip all currently available and 
-   * request refill for more 
+  /* Full request not available, skip all currently available and
+   * request refill for more
    */
-  
+
   priv->pos = 0;
   priv->end = 0;
   bytes_skipped = available;
@@ -721,31 +716,30 @@ g_buffered_input_stream_skip (GInputStream  *stream,
 
   if (bytes_skipped > 0)
     error = NULL; /* Ignore further errors if we already read some data */
-  
+
   if (count > priv->len)
     {
       /* Large request, shortcut buffer */
-      
+
       base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
 
       nread = g_input_stream_skip (base_stream,
                                    count,
                                    cancellable,
                                    error);
-      
+
       if (nread < 0 && bytes_skipped == 0)
         return -1;
-      
+
       if (nread > 0)
         bytes_skipped += nread;
-      
+
       return bytes_skipped;
     }
-  
-  g_input_stream_set_pending (stream, FALSE); /* to avoid already pending error */
-  nread = g_buffered_input_stream_fill (bstream, priv->len, cancellable, error);
-  g_input_stream_set_pending (stream, TRUE); /* enable again */
-  
+
+  class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
+  nread = class->fill (bstream, priv->len, cancellable, error);
+
   if (nread < 0)
     {
       if (bytes_skipped == 0)
@@ -753,13 +747,13 @@ g_buffered_input_stream_skip (GInputStream  *stream,
       else
         return bytes_skipped;
     }
-  
+
   available = priv->end - priv->pos;
   count = MIN (count, available);
-  
+
   bytes_skipped += count;
   priv->pos += count;
-  
+
   return bytes_skipped;
 }
 
@@ -772,6 +766,7 @@ g_buffered_input_stream_read (GInputStream *stream,
 {
   GBufferedInputStream        *bstream;
   GBufferedInputStreamPrivate *priv;
+  GBufferedInputStreamClass *class;
   GInputStream *base_stream;
   gsize available, bytes_read;
   gssize nread;
@@ -787,9 +782,11 @@ g_buffered_input_stream_read (GInputStream *stream,
       priv->pos += count;
       return count;
     }
-  
-  /* Full request not available, read all currently availbile and request refill for more */
-  
+
+  /* Full request not available, read all currently available and
+   * request refill for more
+   */
+
   memcpy (buffer, priv->buffer + priv->pos, available);
   priv->pos = 0;
   priv->end = 0;
@@ -798,31 +795,30 @@ g_buffered_input_stream_read (GInputStream *stream,
 
   if (bytes_read > 0)
     error = NULL; /* Ignore further errors if we already read some data */
-  
+
   if (count > priv->len)
     {
       /* Large request, shortcut buffer */
-      
+
       base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
 
       nread = g_input_stream_read (base_stream,
-                                  (char *)buffer + bytes_read,
-                                  count,
-                                  cancellable,
-                                  error);
-      
+                                   (char *)buffer + bytes_read,
+                                   count,
+                                   cancellable,
+                                   error);
+
       if (nread < 0 && bytes_read == 0)
         return -1;
-      
+
       if (nread > 0)
         bytes_read += nread;
-      
+
       return bytes_read;
     }
-  
-  g_input_stream_set_pending (stream, FALSE); /* to avoid already pending error */
-  nread = g_buffered_input_stream_fill (bstream, priv->len, cancellable, error);
-  g_input_stream_set_pending (stream, TRUE); /* enable again */
+
+  class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
+  nread = class->fill (bstream, priv->len, cancellable, error);
   if (nread < 0)
     {
       if (bytes_read == 0)
@@ -830,29 +826,29 @@ g_buffered_input_stream_read (GInputStream *stream,
       else
         return bytes_read;
     }
-  
+
   available = priv->end - priv->pos;
   count = MIN (count, available);
-  
+
   memcpy ((char *)buffer + bytes_read, (char *)priv->buffer + priv->pos, count);
   bytes_read += count;
   priv->pos += count;
-  
+
   return bytes_read;
 }
 
 /**
  * g_buffered_input_stream_read_byte:
- * @stream: #GBufferedInputStream.
- * @cancellable: optional #GCancellable object, %NULL to ignore.
- * @error: location to store the error occuring, or %NULL to ignore.
+ * @stream: a #GBufferedInputStream
+ * @cancellable: optional #GCancellable object, %NULL to ignore
+ * @error: location to store the error occuring, or %NULL to ignore
  *
  * Tries to read a single byte from the stream or the buffer. Will block
  * during this read.
  *
  * On success, the byte read from the stream is returned. On end of stream
  * -1 is returned but it's not an exceptional error and @error is not set.
- * 
+ *
  * If @cancellable is not %NULL, then the operation can be cancelled by
  * triggering the cancellable object from another thread. If the operation
  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
@@ -860,15 +856,16 @@ g_buffered_input_stream_read (GInputStream *stream,
  * partial result will be returned, without an error.
  *
  * On error -1 is returned and @error is set accordingly.
- * 
+ *
  * Returns: the byte read from the @stream, or -1 on end of stream or error.
- **/
+ */
 int
 g_buffered_input_stream_read_byte (GBufferedInputStream  *stream,
                                    GCancellable          *cancellable,
                                    GError               **error)
 {
   GBufferedInputStreamPrivate *priv;
+  GBufferedInputStreamClass *class;
   GInputStream *input_stream;
   gsize available;
   gssize nread;
@@ -880,35 +877,37 @@ g_buffered_input_stream_read_byte (GBufferedInputStream  *stream,
 
   if (g_input_stream_is_closed (input_stream))
     {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
-       _("Stream is already closed"));
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
+                           _("Stream is already closed"));
       return -1;
     }
 
-  if (g_input_stream_has_pending (input_stream))
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
-       _("Stream has outstanding operation"));
-      return -1;
-    }
+  if (!g_input_stream_set_pending (input_stream, error))
+    return -1;
 
   available = priv->end - priv->pos;
 
-  if (available < 1)
-    return priv->buffer[priv->pos++];
+  if (available != 0)
+    {
+      g_input_stream_clear_pending (input_stream);
+      return priv->buffer[priv->pos++];
+    }
 
   /* Byte not available, request refill for more */
 
   if (cancellable)
-    g_push_current_cancellable (cancellable);
+    g_cancellable_push_current (cancellable);
 
   priv->pos = 0;
   priv->end = 0;
 
-  nread = g_buffered_input_stream_fill (stream, priv->len, cancellable, error);
+  class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
+  nread = class->fill (stream, priv->len, cancellable, error);
 
   if (cancellable)
-    g_pop_current_cancellable (cancellable);
+    g_cancellable_pop_current (cancellable);
+
+  g_input_stream_clear_pending (input_stream);
 
   if (nread <= 0)
     return -1; /* error or end of stream */
@@ -930,19 +929,33 @@ fill_async_callback (GObject      *source_object,
   GSimpleAsyncResult *simple;
 
   simple = user_data;
-  
+
   error = NULL;
   res = g_input_stream_read_finish (G_INPUT_STREAM (source_object),
-                                   result, &error);
+                                    result, &error);
 
   g_simple_async_result_set_op_res_gssize (simple, res);
   if (res == -1)
     {
-      g_simple_async_result_set_from_error (simple, error);
-      g_error_free (error);
+      g_simple_async_result_take_error (simple, error);
+    }
+  else
+    {
+      GBufferedInputStreamPrivate *priv;
+      GObject *object;
+
+      object = g_async_result_get_source_object (G_ASYNC_RESULT (simple));
+      priv = G_BUFFERED_INPUT_STREAM (object)->priv;
+
+      g_assert_cmpint (priv->end + res, <=, priv->len);
+      priv->end += res;
+
+      g_object_unref (object);
     }
-  
-  /* Complete immediately, not in idle, since we're already in a mainloop callout */
+
+  /* Complete immediately, not in idle, since we're already
+   * in a mainloop callout
+   */
   g_simple_async_result_complete (simple);
   g_object_unref (simple);
 }
@@ -964,7 +977,7 @@ g_buffered_input_stream_real_fill_async (GBufferedInputStream *stream,
 
   if (count == -1)
     count = priv->len;
-  
+
   in_buffer = priv->end - priv->pos;
 
   /* Never fill more than can fit in the buffer */
@@ -975,41 +988,42 @@ g_buffered_input_stream_real_fill_async (GBufferedInputStream *stream,
     compact_buffer (stream);
 
   simple = g_simple_async_result_new (G_OBJECT (stream),
-                                     callback, user_data,
-                                     g_buffered_input_stream_real_fill_async);
-  
+                                      callback, user_data,
+                                      g_buffered_input_stream_real_fill_async);
+
   base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
   g_input_stream_read_async (base_stream,
-                            priv->buffer + priv->end,
-                            count,
-                            io_priority,
-                            cancellable,
-                            fill_async_callback,
-                            simple);
+                             priv->buffer + priv->end,
+                             count,
+                             io_priority,
+                             cancellable,
+                             fill_async_callback,
+                             simple);
 }
 
 static gssize
 g_buffered_input_stream_real_fill_finish (GBufferedInputStream *stream,
-                                         GAsyncResult         *result,
-                                         GError              **error)
+                                          GAsyncResult         *result,
+                                          GError              **error)
 {
   GSimpleAsyncResult *simple;
   gssize nread;
 
   simple = G_SIMPLE_ASYNC_RESULT (result);
-  g_assert (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_real_fill_async);
-  
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_real_fill_async);
+
   nread = g_simple_async_result_get_op_res_gssize (simple);
   return nread;
 }
 
-typedef struct {
+typedef struct
+{
   gssize bytes_read;
   gssize count;
   void *buffer;
 } ReadAsyncData;
 
-static void 
+static void
 free_read_async_data (gpointer _data)
 {
   ReadAsyncData *data = _data;
@@ -1018,8 +1032,8 @@ free_read_async_data (gpointer _data)
 
 static void
 large_read_callback (GObject *source_object,
-                    GAsyncResult *result,
-                    gpointer user_data)
+                     GAsyncResult *result,
+                     gpointer user_data)
 {
   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
   ReadAsyncData *data;
@@ -1027,30 +1041,31 @@ large_read_callback (GObject *source_object,
   gssize nread;
 
   data = g_simple_async_result_get_op_res_gpointer (simple);
-  
+
   error = NULL;
   nread = g_input_stream_read_finish (G_INPUT_STREAM (source_object),
-                                     result, &error);
+                                      result, &error);
 
   /* Only report the error if we've not already read some data */
   if (nread < 0 && data->bytes_read == 0)
-    g_simple_async_result_set_from_error (simple, error);
-  
+    g_simple_async_result_take_error (simple, error);
+  else if (error)
+    g_error_free (error);
+
   if (nread > 0)
     data->bytes_read += nread;
-  
-  if (error)
-    g_error_free (error);
-  
-  /* Complete immediately, not in idle, since we're already in a mainloop callout */
+
+  /* Complete immediately, not in idle, since we're already
+   * in a mainloop callout
+   */
   g_simple_async_result_complete (simple);
   g_object_unref (simple);
 }
 
 static void
-read_fill_buffer_callback (GObject *source_object,
-                          GAsyncResult *result,
-                          gpointer user_data)
+read_fill_buffer_callback (GObject      *source_object,
+                           GAsyncResult *result,
+                           gpointer      user_data)
 {
   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
   GBufferedInputStream *bstream;
@@ -1062,48 +1077,47 @@ read_fill_buffer_callback (GObject *source_object,
 
   bstream = G_BUFFERED_INPUT_STREAM (source_object);
   priv = bstream->priv;
-  
-  g_input_stream_set_pending (G_INPUT_STREAM (bstream), TRUE); /* enable again */
-  
+
   data = g_simple_async_result_get_op_res_gpointer (simple);
-  
+
   error = NULL;
   nread = g_buffered_input_stream_fill_finish (bstream,
-                                              result, &error);
-  
-  if (nread < 0 && data->bytes_read == 0)
-    g_simple_async_result_set_from_error (simple, error);
+                                               result, &error);
 
+  if (nread < 0 && data->bytes_read == 0)
+    g_simple_async_result_take_error (simple, error);
+  else if (error)
+    g_error_free (error);
 
   if (nread > 0)
     {
       available = priv->end - priv->pos;
       data->count = MIN (data->count, available);
-      
+
       memcpy ((char *)data->buffer + data->bytes_read, (char *)priv->buffer + priv->pos, data->count);
       data->bytes_read += data->count;
       priv->pos += data->count;
     }
 
-  if (error)
-    g_error_free (error);
-  
-  /* Complete immediately, not in idle, since we're already in a mainloop callout */
+  /* Complete immediately, not in idle, since we're already
+   * in a mainloop callout
+   */
   g_simple_async_result_complete (simple);
   g_object_unref (simple);
 }
 
 static void
-g_buffered_input_stream_read_async (GInputStream              *stream,
-                                    void                      *buffer,
-                                    gsize                      count,
-                                    int                        io_priority,
-                                    GCancellable              *cancellable,
-                                    GAsyncReadyCallback        callback,
-                                    gpointer                   user_data)
+g_buffered_input_stream_read_async (GInputStream        *stream,
+                                    void                *buffer,
+                                    gsize                count,
+                                    int                  io_priority,
+                                    GCancellable        *cancellable,
+                                    GAsyncReadyCallback  callback,
+                                    gpointer             user_data)
 {
   GBufferedInputStream *bstream;
   GBufferedInputStreamPrivate *priv;
+  GBufferedInputStreamClass *class;
   GInputStream *base_stream;
   gsize available;
   GSimpleAsyncResult *simple;
@@ -1116,54 +1130,55 @@ g_buffered_input_stream_read_async (GInputStream              *stream,
   data->buffer = buffer;
   data->bytes_read = 0;
   simple = g_simple_async_result_new (G_OBJECT (stream),
-                                     callback, user_data,
-                                     g_buffered_input_stream_read_async);
+                                      callback, user_data,
+                                      g_buffered_input_stream_read_async);
   g_simple_async_result_set_op_res_gpointer (simple, data, free_read_async_data);
-  
+
   available = priv->end - priv->pos;
-  
+
   if (count <= available)
     {
       memcpy (buffer, priv->buffer + priv->pos, count);
       priv->pos += count;
       data->bytes_read = count;
-      
+
       g_simple_async_result_complete_in_idle (simple);
       g_object_unref (simple);
       return;
     }
 
 
-  /* Full request not available, read all currently availbile and request refill for more */
-  
+  /* Full request not available, read all currently available
+   * and request refill for more
+   */
+
   memcpy (buffer, priv->buffer + priv->pos, available);
   priv->pos = 0;
   priv->end = 0;
-  
+
   count -= available;
-  
+
   data->bytes_read = available;
   data->count = count;
 
   if (count > priv->len)
     {
       /* Large request, shortcut buffer */
-      
+
       base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
-      
+
       g_input_stream_read_async (base_stream,
-                                (char *)buffer + data->bytes_read,
-                                count,
-                                io_priority, cancellable,
-                                large_read_callback,
-                                simple);
+                                 (char *)buffer + data->bytes_read,
+                                 count,
+                                 io_priority, cancellable,
+                                 large_read_callback,
+                                 simple);
     }
   else
     {
-      g_input_stream_set_pending (stream, FALSE); /* to avoid already pending error */
-      g_buffered_input_stream_fill_async (bstream, priv->len,
-                                         io_priority, cancellable,
-                                         read_fill_buffer_callback, simple);
+      class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
+      class->fill_async (bstream, priv->len, io_priority, cancellable,
+                         read_fill_buffer_callback, simple);
     }
 }
 
@@ -1174,22 +1189,23 @@ g_buffered_input_stream_read_finish (GInputStream   *stream,
 {
   GSimpleAsyncResult *simple;
   ReadAsyncData *data;
-  
+
   simple = G_SIMPLE_ASYNC_RESULT (result);
-  
-  g_assert (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_read_async);
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_read_async);
 
   data = g_simple_async_result_get_op_res_gpointer (simple);
-  
+
   return data->bytes_read;
 }
 
-typedef struct {
+typedef struct
+{
   gssize bytes_skipped;
   gssize count;
 } SkipAsyncData;
 
-static void 
+static void
 free_skip_async_data (gpointer _data)
 {
   SkipAsyncData *data = _data;
@@ -1197,9 +1213,9 @@ free_skip_async_data (gpointer _data)
 }
 
 static void
-large_skip_callback (GObject *source_object,
-                    GAsyncResult *result,
-                    gpointer user_data)
+large_skip_callback (GObject      *source_object,
+                     GAsyncResult *result,
+                     gpointer      user_data)
 {
   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
   SkipAsyncData *data;
@@ -1207,30 +1223,31 @@ large_skip_callback (GObject *source_object,
   gssize nread;
 
   data = g_simple_async_result_get_op_res_gpointer (simple);
-  
+
   error = NULL;
   nread = g_input_stream_skip_finish (G_INPUT_STREAM (source_object),
-                                     result, &error);
+                                      result, &error);
 
   /* Only report the error if we've not already read some data */
   if (nread < 0 && data->bytes_skipped == 0)
-    g_simple_async_result_set_from_error (simple, error);
-  
+    g_simple_async_result_take_error (simple, error);
+  else if (error)
+    g_error_free (error);
+
   if (nread > 0)
     data->bytes_skipped += nread;
-  
-  if (error)
-    g_error_free (error);
-  
-  /* Complete immediately, not in idle, since we're already in a mainloop callout */
+
+  /* Complete immediately, not in idle, since we're already
+   * in a mainloop callout
+   */
   g_simple_async_result_complete (simple);
   g_object_unref (simple);
 }
 
 static void
-skip_fill_buffer_callback (GObject *source_object,
-                          GAsyncResult *result,
-                          gpointer user_data)
+skip_fill_buffer_callback (GObject      *source_object,
+                           GAsyncResult *result,
+                           gpointer      user_data)
 {
   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
   GBufferedInputStream *bstream;
@@ -1242,46 +1259,45 @@ skip_fill_buffer_callback (GObject *source_object,
 
   bstream = G_BUFFERED_INPUT_STREAM (source_object);
   priv = bstream->priv;
-  
-  g_input_stream_set_pending (G_INPUT_STREAM (bstream), TRUE); /* enable again */
-  
+
   data = g_simple_async_result_get_op_res_gpointer (simple);
-  
+
   error = NULL;
   nread = g_buffered_input_stream_fill_finish (bstream,
-                                              result, &error);
-  
-  if (nread < 0 && data->bytes_skipped == 0)
-    g_simple_async_result_set_from_error (simple, error);
+                                               result, &error);
 
+  if (nread < 0 && data->bytes_skipped == 0)
+    g_simple_async_result_take_error (simple, error);
+  else if (error)
+    g_error_free (error);
 
   if (nread > 0)
     {
       available = priv->end - priv->pos;
       data->count = MIN (data->count, available);
-      
+
       data->bytes_skipped += data->count;
       priv->pos += data->count;
     }
 
-  if (error)
-    g_error_free (error);
-  
-  /* Complete immediately, not in idle, since we're already in a mainloop callout */
+  /* Complete immediately, not in idle, since we're already
+   * in a mainloop callout
+   */
   g_simple_async_result_complete (simple);
   g_object_unref (simple);
 }
 
 static void
-g_buffered_input_stream_skip_async (GInputStream              *stream,
-                                    gsize                      count,
-                                    int                        io_priority,
-                                    GCancellable              *cancellable,
-                                    GAsyncReadyCallback        callback,
-                                    gpointer                   user_data)
+g_buffered_input_stream_skip_async (GInputStream        *stream,
+                                    gsize                count,
+                                    int                  io_priority,
+                                    GCancellable        *cancellable,
+                                    GAsyncReadyCallback  callback,
+                                    gpointer             user_data)
 {
   GBufferedInputStream *bstream;
   GBufferedInputStreamPrivate *priv;
+  GBufferedInputStreamClass *class;
   GInputStream *base_stream;
   gsize available;
   GSimpleAsyncResult *simple;
@@ -1293,51 +1309,51 @@ g_buffered_input_stream_skip_async (GInputStream              *stream,
   data = g_slice_new (SkipAsyncData);
   data->bytes_skipped = 0;
   simple = g_simple_async_result_new (G_OBJECT (stream),
-                                     callback, user_data,
-                                     g_buffered_input_stream_skip_async);
+                                      callback, user_data,
+                                      g_buffered_input_stream_skip_async);
   g_simple_async_result_set_op_res_gpointer (simple, data, free_skip_async_data);
-  
+
   available = priv->end - priv->pos;
-  
+
   if (count <= available)
     {
       priv->pos += count;
       data->bytes_skipped = count;
-      
+
       g_simple_async_result_complete_in_idle (simple);
       g_object_unref (simple);
       return;
     }
 
+  /* Full request not available, skip all currently available
+   * and request refill for more
+   */
 
-  /* Full request not available, skip all currently availbile and request refill for more */
-  
   priv->pos = 0;
   priv->end = 0;
-  
+
   count -= available;
-  
+
   data->bytes_skipped = available;
   data->count = count;
 
   if (count > priv->len)
     {
       /* Large request, shortcut buffer */
-      
+
       base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
-      
+
       g_input_stream_skip_async (base_stream,
-                                count,
-                                io_priority, cancellable,
-                                large_skip_callback,
-                                simple);
+                                 count,
+                                 io_priority, cancellable,
+                                 large_skip_callback,
+                                 simple);
     }
   else
     {
-      g_input_stream_set_pending (stream, FALSE); /* to avoid already pending error */
-      g_buffered_input_stream_fill_async (bstream, priv->len,
-                                         io_priority, cancellable,
-                                         skip_fill_buffer_callback, simple);
+      class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
+      class->fill_async (bstream, priv->len, io_priority, cancellable,
+                         skip_fill_buffer_callback, simple);
     }
 }
 
@@ -1348,16 +1364,12 @@ g_buffered_input_stream_skip_finish (GInputStream   *stream,
 {
   GSimpleAsyncResult *simple;
   SkipAsyncData *data;
-  
+
   simple = G_SIMPLE_ASYNC_RESULT (result);
-  
-  g_assert (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_skip_async);
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_skip_async);
 
   data = g_simple_async_result_get_op_res_gpointer (simple);
-  
+
   return data->bytes_skipped;
 }
-
-
-#define __G_BUFFERED_INPUT_STREAM_C__
-#include "gioaliasdef.c"