Doc fixes
[platform/upstream/glib.git] / gio / gdatainputstream.c
index 54a4678..9d3abef 100644 (file)
@@ -1,6 +1,7 @@
 /* GIO - GLib Input, Output and Streaming Library
  * 
  * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright (C) 2007 Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 
 #include <config.h>
 #include "gdatainputstream.h"
+#include "gioenumtypes.h"
 #include "glibintl.h"
 
+#include "gioalias.h"
+
+/**
+ * SECTION:gdatainputstream
+ * @short_description: Data Input Stream
+ * @include: gio/gio.h
+ * @see_also: #GInputStream
+ * 
+ * Data input stream implements #GInputStream and includes functions for 
+ * reading structured data directly from a binary input stream.
+ *
+ **/
+
 struct _GDataInputStreamPrivate {
   GDataStreamByteOrder byte_order;
   GDataStreamNewlineType newline_type;
 };
 
 enum {
-  PROP_0
+  PROP_0,
+  PROP_BYTE_ORDER,
+  PROP_NEWLINE_TYPE
 };
 
 static void g_data_input_stream_set_property (GObject      *object,
@@ -57,13 +74,44 @@ g_data_input_stream_class_init (GDataInputStreamClass *klass)
   object_class = G_OBJECT_CLASS (klass);
   object_class->get_property = g_data_input_stream_get_property;
   object_class->set_property = g_data_input_stream_set_property;
+
+  /**
+   * GDataStream:byte-order:
+   *
+   * The ::byte-order property determines the byte ordering that
+   * is used when reading multi-byte entities (such as integers)
+   * from the stream.
+   */ 
+  g_object_class_install_property (object_class,
+                                   PROP_BYTE_ORDER,
+                                   g_param_spec_enum ("byte-order",
+                                                      P_("Byte order"),
+                                                      P_("The byte order"),
+                                                      G_TYPE_DATA_STREAM_BYTE_ORDER,
+                                                      G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN,
+                                                      G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB));
+
+  /**
+   * GDataStream:newline-type:
+   *
+   * The :newline-type property determines what is considered
+   * as a line ending when reading complete lines from the stream.
+   */ 
+  g_object_class_install_property (object_class,
+                                   PROP_NEWLINE_TYPE,
+                                   g_param_spec_enum ("newline-type",
+                                                      P_("Newline type"),
+                                                      P_("The accepted types of line ending"),
+                                                      G_TYPE_DATA_STREAM_NEWLINE_TYPE,
+                                                      G_DATA_STREAM_NEWLINE_TYPE_LF,
+                                                      G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB));
 }
 
 static void
-g_data_input_stream_set_property (GObject         *object,
-                                 guint            prop_id,
-                                 const GValue    *value,
-                                 GParamSpec      *pspec)
+g_data_input_stream_set_property (GObject      *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
 {
   GDataInputStreamPrivate *priv;
   GDataInputStream        *dstream;
@@ -71,8 +119,15 @@ g_data_input_stream_set_property (GObject         *object,
   dstream = G_DATA_INPUT_STREAM (object);
   priv = dstream->priv;
 
-  switch (prop_id) 
+   switch (prop_id) 
     {
+    case PROP_BYTE_ORDER:
+      g_data_input_stream_set_byte_order (dstream, g_value_get_enum (value));
+      break;
+
+    case PROP_NEWLINE_TYPE:
+      g_data_input_stream_set_newline_type (dstream, g_value_get_enum (value));
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -83,9 +138,9 @@ g_data_input_stream_set_property (GObject         *object,
 
 static void
 g_data_input_stream_get_property (GObject    *object,
-                                      guint       prop_id,
-                                      GValue     *value,
-                                      GParamSpec *pspec)
+                                  guint       prop_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
 {
   GDataInputStreamPrivate *priv;
   GDataInputStream        *dstream;
@@ -95,7 +150,14 @@ g_data_input_stream_get_property (GObject    *object,
 
   switch (prop_id)
     { 
-  
+    case PROP_BYTE_ORDER:
+      g_value_set_enum (value, priv->byte_order);
+      break;
+
+    case PROP_NEWLINE_TYPE:
+      g_value_set_enum (value, priv->newline_type);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -115,7 +177,9 @@ g_data_input_stream_init (GDataInputStream *stream)
 
 /**
  * g_data_input_stream_new:
- * @base_stream: a given #GInputStream.
+ * @base_stream: a #GInputStream.
+ * 
+ * Creates a new data input stream for the @base_stream.
  * 
  * Returns: a new #GDataInputStream.
  **/
@@ -143,19 +207,30 @@ g_data_input_stream_new (GInputStream *base_stream)
  *  
  **/
 void
-g_data_input_stream_set_byte_order (GDataInputStream *stream,
-                                   GDataStreamByteOrder order)
+g_data_input_stream_set_byte_order (GDataInputStream     *stream,
+                                   GDataStreamByteOrder  order)
 {
+  GDataInputStreamPrivate *priv;
+
   g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
 
-  stream->priv->byte_order = order;
+  priv = stream->priv;
+
+  if (priv->byte_order != order)
+    {
+      priv->byte_order = order;
+      
+      g_object_notify (G_OBJECT (stream), "byte-order");
+    }
 }
 
 /**
  * g_data_input_stream_get_byte_order:
  * @stream: a given #GDataInputStream.
  * 
- * Returns the @stream's current #GDataStreamByteOrder. 
+ * Gets the byte order for the data input stream.
+ * 
+ * Returns: the @stream's current #GDataStreamByteOrder. 
  **/
 GDataStreamByteOrder
 g_data_input_stream_get_byte_order (GDataInputStream *stream)
@@ -167,22 +242,32 @@ g_data_input_stream_get_byte_order (GDataInputStream *stream)
 
 /**
  * g_data_input_stream_set_newline_type:
- * @stream: a given #GDataInputStream.
+ * @stream: a #GDataInputStream.
  * @type: the type of new line return as #GDataStreamNewlineType.
  * 
  * Sets the newline type for the @stream.
  * 
- * TODO: is it valid to set this to G_DATA_STREAM_NEWLINE_TYPE_ANY, or
- * should it always be set to {_LF, _CR, _CR_LF}
+ * Note that using G_DATA_STREAM_NEWLINE_TYPE_ANY is slightly unsafe. If a read
+ * chunk ends in "CR" we must read an additional byte to know if this is "CR" or
+ * "CR LF", and this might block if there is no more data availible.
  *  
  **/
 void
-g_data_input_stream_set_newline_type (GDataInputStream        *stream,
-                                     GDataStreamNewlineType   type)
+g_data_input_stream_set_newline_type (GDataInputStream       *stream,
+                                     GDataStreamNewlineType  type)
 {
+  GDataInputStreamPrivate *priv;
+
   g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
 
-  stream->priv->newline_type = type;
+  priv = stream->priv;
+  
+  if (priv->newline_type != type)
+    {
+      priv->newline_type = type;
+
+      g_object_notify (G_OBJECT (stream), "newline-type");
+    }
 }
 
 /**
@@ -202,11 +287,11 @@ g_data_input_stream_get_newline_type (GDataInputStream *stream)
 }
 
 static gboolean
-read_data (GDataInputStream *stream,
-         void *buffer,
-         gsize size,
-         GCancellable *cancellable,
-         GError **error)
+read_data (GDataInputStream  *stream,
+           void              *buffer,
+           gsize              size,
+           GCancellable      *cancellable,
+           GError           **error)
 {
   gsize available;
   gssize res;
@@ -230,7 +315,7 @@ read_data (GDataInputStream *stream,
   res = g_input_stream_read (G_INPUT_STREAM (stream),
                             buffer, size,
                             NULL, NULL);
-  g_assert (res == size);
+  g_warn_if_fail (res == size);
   return TRUE;
 }
 
@@ -241,17 +326,15 @@ read_data (GDataInputStream *stream,
  * @cancellable: optional #GCancellable object, %NULL to ignore.
  * @error: #GError for error reporting.
  * 
- * In order to get the correct byte order for this read operation, 
- * see g_data_stream_get_byte_order() and g_data_stream_set_byte_order().
- * 
+ * Reads an unsigned 8-bit/1-byte value from @stream.
+ *
  * Returns: an unsigned 8-bit/1-byte value read from the @stream or %0 
- * if an error occured.
+ * if an error occurred.
  **/
-
 guchar
-g_data_input_stream_read_byte (GDataInputStream        *stream,
-                             GCancellable            *cancellable,
-                             GError                 **error)
+g_data_input_stream_read_byte (GDataInputStream  *stream,
+                              GCancellable       *cancellable,
+                              GError            **error)
 {
   guchar c;
   
@@ -270,16 +353,18 @@ g_data_input_stream_read_byte (GDataInputStream        *stream,
  * @cancellable: optional #GCancellable object, %NULL to ignore.
  * @error: #GError for error reporting.
  * 
+ * Reads a 16-bit/2-byte value from @stream.
+ *
  * In order to get the correct byte order for this read operation, 
  * see g_data_stream_get_byte_order() and g_data_stream_set_byte_order().
  * 
- * Returns a signed 16-bit/2-byte value read from @stream or %0 if 
- * an error occured.
+ * Returns: a signed 16-bit/2-byte value read from @stream or %0 if 
+ * an error occurred.
  **/
 gint16
-g_data_input_stream_read_int16 (GDataInputStream        *stream,
-                              GCancellable            *cancellable,
-                              GError                 **error)
+g_data_input_stream_read_int16 (GDataInputStream  *stream,
+                              GCancellable       *cancellable,
+                              GError            **error)
 {
   gint16 v;
   
@@ -312,16 +397,18 @@ g_data_input_stream_read_int16 (GDataInputStream        *stream,
  * @cancellable: optional #GCancellable object, %NULL to ignore.
  * @error: #GError for error reporting.
  *
+ * Reads an unsigned 16-bit/2-byte value from @stream.
+ *
  * In order to get the correct byte order for this read operation, 
  * see g_data_stream_get_byte_order() and g_data_stream_set_byte_order(). 
  * 
- * Returns an unsigned 16-bit/2-byte value read from the @stream or %0 if 
- * an error occured. 
+ * Returns: an unsigned 16-bit/2-byte value read from the @stream or %0 if 
+ * an error occurred. 
  **/
 guint16
-g_data_input_stream_read_uint16 (GDataInputStream        *stream,
-                               GCancellable            *cancellable,
-                               GError                 **error)
+g_data_input_stream_read_uint16 (GDataInputStream  *stream,
+                                GCancellable       *cancellable,
+                                GError            **error)
 {
   guint16 v;
   
@@ -354,16 +441,22 @@ g_data_input_stream_read_uint16 (GDataInputStream        *stream,
  * @cancellable: optional #GCancellable object, %NULL to ignore.
  * @error: #GError for error reporting.
  * 
+ * Reads a signed 32-bit/4-byte value from @stream.
+ *
  * In order to get the correct byte order for this read operation, 
  * see g_data_stream_get_byte_order() and g_data_stream_set_byte_order().
+ *
+ * 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. 
  *   
- * Returns a signed 32-bit/4-byte value read from the @stream or %0 if 
- * an error occured. 
+ * Returns: a signed 32-bit/4-byte value read from the @stream or %0 if 
+ * an error occurred. 
  **/
 gint32
-g_data_input_stream_read_int32 (GDataInputStream        *stream,
-                              GCancellable            *cancellable,
-                              GError                 **error)
+g_data_input_stream_read_int32 (GDataInputStream  *stream,
+                               GCancellable       *cancellable,
+                               GError            **error)
 {
   gint32 v;
   
@@ -396,16 +489,22 @@ g_data_input_stream_read_int32 (GDataInputStream        *stream,
  * @cancellable: optional #GCancellable object, %NULL to ignore.
  * @error: #GError for error reporting.
  * 
+ * Reads an unsigned 32-bit/4-byte value from @stream.
+ *
  * In order to get the correct byte order for this read operation, 
  * see g_data_stream_get_byte_order() and g_data_stream_set_byte_order().
+ *
+ * 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. 
  * 
- * Returns an unsigned 32-bit/4-byte value read from the @stream or %0 if 
- * an error occured. 
+ * Returns: an unsigned 32-bit/4-byte value read from the @stream or %0 if 
+ * an error occurred. 
  **/
 guint32
-g_data_input_stream_read_uint32 (GDataInputStream        *stream,
-                               GCancellable            *cancellable,
-                               GError                 **error)
+g_data_input_stream_read_uint32 (GDataInputStream  *stream,
+                                GCancellable       *cancellable,
+                                GError            **error)
 {
   guint32 v;
   
@@ -438,16 +537,22 @@ g_data_input_stream_read_uint32 (GDataInputStream        *stream,
  * @cancellable: optional #GCancellable object, %NULL to ignore.
  * @error: #GError for error reporting.
  * 
+ * Reads a 64-bit/8-byte value from @stream.
+ *
  * In order to get the correct byte order for this read operation, 
  * see g_data_stream_get_byte_order() and g_data_stream_set_byte_order().
+ *
+ * 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. 
  * 
- * Returns a signed 64-bit/8-byte value read from @stream or %0 if 
- * an error occured.  
+ * Returns: a signed 64-bit/8-byte value read from @stream or %0 if 
+ * an error occurred.  
  **/
 gint64
-g_data_input_stream_read_int64 (GDataInputStream        *stream,
-                              GCancellable            *cancellable,
-                              GError                 **error)
+g_data_input_stream_read_int64 (GDataInputStream  *stream,
+                              GCancellable       *cancellable,
+                              GError            **error)
 {
   gint64 v;
   
@@ -480,16 +585,22 @@ g_data_input_stream_read_int64 (GDataInputStream        *stream,
  * @cancellable: optional #GCancellable object, %NULL to ignore.
  * @error: #GError for error reporting.
  * 
+ * Reads an unsigned 64-bit/8-byte value from @stream.
+ *
  * In order to get the correct byte order for this read operation, 
  * see g_data_stream_get_byte_order().
+ *
+ * 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. 
  * 
- * Returns an unsigned 64-bit/8-byte read from @stream or %0 if 
- * an error occured. 
+ * Returns: an unsigned 64-bit/8-byte read from @stream or %0 if 
+ * an error occurred. 
  **/
 guint64
-g_data_input_stream_read_uint64 (GDataInputStream        *stream,
-                               GCancellable            *cancellable,
-                               GError                 **error)
+g_data_input_stream_read_uint64 (GDataInputStream  *stream,
+                               GCancellable       *cancellable,
+                               GError            **error)
 {
   guint64 v;
   
@@ -517,13 +628,13 @@ g_data_input_stream_read_uint64 (GDataInputStream        *stream,
 
 static gssize
 scan_for_newline (GDataInputStream *stream,
-                 gsize *checked_out,
-                 gboolean *last_saw_cr_out,
-                 int *newline_len_out)
+                 gsize            *checked_out,
+                 gboolean         *last_saw_cr_out,
+                 int              *newline_len_out)
 {
   GBufferedInputStream *bstream;
   GDataInputStreamPrivate *priv;
-  char buffer[100];
+  const char *buffer;
   gsize start, end, peeked;
   int i;
   gssize found_pos;
@@ -534,84 +645,80 @@ scan_for_newline (GDataInputStream *stream,
   priv = stream->priv;
   
   bstream = G_BUFFERED_INPUT_STREAM (stream);
-  
-  available = g_buffered_input_stream_get_available (bstream);
 
   checked = *checked_out;
   last_saw_cr = *last_saw_cr_out;
   found_pos = -1;
   newline_len = 0;
   
-  while (checked < available)
-    {
-      start = checked;
-      end = MIN (start + sizeof(buffer), available);
-      peeked = g_buffered_input_stream_peek (bstream, buffer, start, end - start);
-      end = start + peeked;
+  start = checked;
+  buffer = (const char*)g_buffered_input_stream_peek_buffer (bstream, &available) + start;
+  end = available;
+  peeked = end - start;
 
-      for (i = 0; i < peeked; i++)
+  for (i = 0; checked < available && i < peeked; i++)
+    {
+      switch (priv->newline_type)
        {
-         switch (priv->newline_type)
+       case G_DATA_STREAM_NEWLINE_TYPE_LF:
+         if (buffer[i] == 10)
            {
-           case G_DATA_STREAM_NEWLINE_TYPE_LF:
-             if (buffer[i] == 10)
-               {
-                 found_pos = start + i;
-                 newline_len = 1;
-               }
-             break;
-           case G_DATA_STREAM_NEWLINE_TYPE_CR:
-             if (buffer[i] == 13)
-               {
-                 found_pos = start + i;
-                 newline_len = 1;
-               }
-             break;
-           case G_DATA_STREAM_NEWLINE_TYPE_CR_LF:
-             if (last_saw_cr && buffer[i] == 10)
+             found_pos = start + i;
+             newline_len = 1;
+           }
+         break;
+       case G_DATA_STREAM_NEWLINE_TYPE_CR:
+         if (buffer[i] == 13)
+           {
+             found_pos = start + i;
+             newline_len = 1;
+           }
+         break;
+       case G_DATA_STREAM_NEWLINE_TYPE_CR_LF:
+         if (last_saw_cr && buffer[i] == 10)
+           {
+             found_pos = start + i - 1;
+             newline_len = 2;
+           }
+         break;
+       default:
+       case G_DATA_STREAM_NEWLINE_TYPE_ANY:
+         if (buffer[i] == 10) /* LF */
+           {
+             if (last_saw_cr)
                {
+                 /* CR LF */
                  found_pos = start + i - 1;
                  newline_len = 2;
                }
-             break;
-           default:
-           case G_DATA_STREAM_NEWLINE_TYPE_ANY:
-             if (buffer[i] == 10) /* LF */
-               {
-                 if (last_saw_cr)
-                   {
-                     /* CR LF */
-                     found_pos = start + i - 1;
-                     newline_len = 2;
-                   }
-                 else
-                   {
-                     /* LF */
-                     found_pos = start + i;
-                     newline_len = 1;
-                   }
-               }
-             else if (last_saw_cr)
+             else
                {
-                 /* Last was cr, this is not LF, end is CR */
-                 found_pos = start + i - 1;
+                 /* LF */
+                 found_pos = start + i;
                  newline_len = 1;
                }
-             /* Don't check for CR here, instead look at last_saw_cr on next byte */
-             break;
            }
-         
-         last_saw_cr = (buffer[i] == 13);
-
-         if (found_pos != -1)
+         else if (last_saw_cr)
            {
-             *newline_len_out = newline_len;
-             return found_pos;
+             /* Last was cr, this is not LF, end is CR */
+             found_pos = start + i - 1;
+             newline_len = 1;
            }
+         /* Don't check for CR here, instead look at last_saw_cr on next byte */
+         break;
+       }
+       
+      last_saw_cr = (buffer[i] == 13);
+
+      if (found_pos != -1)
+       {
+         *newline_len_out = newline_len;
+         return found_pos;
        }
-      checked = end;
     }
 
+  checked = end;
+
   *checked_out = checked;
   *last_saw_cr_out = last_saw_cr;
   return -1;
@@ -624,16 +731,21 @@ scan_for_newline (GDataInputStream *stream,
  * @length: a #gsize to get the length of the data read in.
  * @cancellable: optional #GCancellable object, %NULL to ignore.
  * @error: #GError for error reporting.
+ *
+ * Reads a line from the data input stream.
+ * 
+ * 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. 
  * 
- * Returns a string with the line that was read in. Set @length to 
- * a #gsize to get the length of the read line. This function will 
- * return %NULL on an error.
+ * Returns: a string with the line that was read in (including the newlines).
+ * Set @length to a #gsize to get the length of the read line. Returns %NULL on an error.
  **/
 char *
-g_data_input_stream_read_line (GDataInputStream        *stream,
-                             gsize                   *length,
-                             GCancellable            *cancellable,
-                             GError                 **error)
+g_data_input_stream_read_line (GDataInputStream  *stream,
+                              gsize             *length,
+                              GCancellable      *cancellable,
+                              GError           **error)
 {
   GBufferedInputStream *bstream;
   gsize checked;
@@ -687,32 +799,131 @@ g_data_input_stream_read_line (GDataInputStream        *stream,
                             NULL, NULL);
   if (length)
     *length = (gsize)found_pos;
-  g_assert (res == found_pos + newline_len);
+  g_warn_if_fail (res == found_pos + newline_len);
   line[found_pos] = 0;
   
   return line;
 }
 
 
+static gssize
+scan_for_chars (GDataInputStream *stream,
+               gsize            *checked_out,
+               const char       *stop_chars)
+{
+  GBufferedInputStream *bstream;
+  GDataInputStreamPrivate *priv;
+  const char *buffer;
+  gsize start, end, peeked;
+  int i;
+  gssize found_pos;
+  gsize available, checked;
+  const char *stop_char;
+
+  priv = stream->priv;
+  
+  bstream = G_BUFFERED_INPUT_STREAM (stream);
+
+  checked = *checked_out;
+  found_pos = -1;
+  
+  start = checked;
+  buffer = (const char *)g_buffered_input_stream_peek_buffer (bstream, &available) + start;
+  end = available;
+  peeked = end - start;
+
+  for (i = 0; checked < available && i < peeked; i++)
+    {
+      for (stop_char = stop_chars; *stop_char != '\0'; stop_char++)
+       {
+         if (buffer[i] == *stop_char)
+           return (start + i);
+       }
+    }
+
+  checked = end;
+
+  *checked_out = checked;
+  return -1;
+}
+
 /**
  * g_data_input_stream_read_until:
  * @stream: a given #GDataInputStream.
- * @stop_char: character to terminate the read.
+ * @stop_chars: characters to terminate the read.
  * @length: a #gsize to get the length of the data read in.
  * @cancellable: optional #GCancellable object, %NULL to ignore.
  * @error: #GError for error reporting.
  * 
- * NOTE: not supported for #GDataInputStream.
- * Returns %NULL.
+ * Reads a string from the data input stream, up to the first 
+ * occurrance of any of the stop characters.
+ *
+ * Returns: a string with the data that was read before encountering 
+ * any of the stop characters. Set @length to a #gsize to get the length 
+ * of the string. This function will return %NULL on an error.
  **/
 char *
-g_data_input_stream_read_until (GDataInputStream        *stream,
-                              gchar                    stop_char,
-                              gsize                   *length,
-                              GCancellable            *cancellable,
-                              GError                 **error)
+g_data_input_stream_read_until (GDataInputStream  *stream,
+                              const gchar        *stop_chars,
+                              gsize              *length,
+                              GCancellable       *cancellable,
+                              GError            **error)
 {
-  /* TODO: should be implemented */
-  g_assert_not_reached ();
-  return NULL;
+  GBufferedInputStream *bstream;
+  gsize checked;
+  gssize found_pos;
+  gssize res;
+  int stop_char_len;
+  char *data_until;
+  
+  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);  
+
+  bstream = G_BUFFERED_INPUT_STREAM (stream);
+
+  stop_char_len = 1;
+  checked = 0;
+
+  while ((found_pos = scan_for_chars (stream, &checked, stop_chars)) == -1)
+    {
+      if (g_buffered_input_stream_get_available (bstream) ==
+         g_buffered_input_stream_get_buffer_size (bstream))
+       g_buffered_input_stream_set_buffer_size (bstream,
+                                                2 * g_buffered_input_stream_get_buffer_size (bstream));
+
+      res = g_buffered_input_stream_fill (bstream, -1, cancellable, error);
+      if (res < 0)
+       return NULL;
+      if (res == 0)
+       {
+         /* End of stream */
+         if (g_buffered_input_stream_get_available (bstream) == 0)
+           {
+             if (length)
+               *length = 0;
+             return NULL;
+           }
+         else
+           {
+             found_pos = checked;
+             stop_char_len = 0;
+             break;
+           }
+       }
+    }
+
+  data_until = g_malloc (found_pos + stop_char_len + 1);
+
+  res = g_input_stream_read (G_INPUT_STREAM (stream),
+                            data_until,
+                            found_pos + stop_char_len,
+                            NULL, NULL);
+  if (length)
+    *length = (gsize)found_pos;
+  g_warn_if_fail (res == found_pos + stop_char_len);
+  data_until[found_pos] = 0;
+  
+  return data_until;
 }
+
+#define __G_DATA_INPUT_STREAM_C__
+#include "gioaliasdef.c"