(root)/
glib-2.79.0/
gio/
gdatainputstream.c
       1  /* GIO - GLib Input, Output and Streaming Library
       2   * 
       3   * Copyright (C) 2006-2007 Red Hat, Inc.
       4   * Copyright (C) 2007 Jürg Billeter
       5   * Copyright © 2009 Codethink Limited
       6   *
       7   * SPDX-License-Identifier: LGPL-2.1-or-later
       8   *
       9   * This library is free software; you can redistribute it and/or
      10   * modify it under the terms of the GNU Lesser General Public
      11   * License as published by the Free Software Foundation; either
      12   * version 2.1 of the License, or (at your option) any later version.
      13   *
      14   * This library is distributed in the hope that it will be useful,
      15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17   * Lesser General Public License for more details.
      18   *
      19   * You should have received a copy of the GNU Lesser General
      20   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      21   *
      22   * Author: Alexander Larsson <alexl@redhat.com>
      23   */
      24  
      25  #include "config.h"
      26  #include "gdatainputstream.h"
      27  #include "gtask.h"
      28  #include "gcancellable.h"
      29  #include "gioenumtypes.h"
      30  #include "gioerror.h"
      31  #include "glibintl.h"
      32  
      33  #include <string.h>
      34  
      35  /**
      36   * GDataInputStream:
      37   *
      38   * Data input stream implements [class@Gio.InputStream] and includes functions
      39   * for reading structured data directly from a binary input stream.
      40   */
      41  
      42  struct _GDataInputStreamPrivate {
      43    GDataStreamByteOrder byte_order;
      44    GDataStreamNewlineType newline_type;
      45  };
      46  
      47  enum {
      48    PROP_0,
      49    PROP_BYTE_ORDER,
      50    PROP_NEWLINE_TYPE
      51  };
      52  
      53  static void g_data_input_stream_set_property (GObject      *object,
      54  					      guint         prop_id,
      55  					      const GValue *value,
      56  					      GParamSpec   *pspec);
      57  static void g_data_input_stream_get_property (GObject      *object,
      58  					      guint         prop_id,
      59  					      GValue       *value,
      60  					      GParamSpec   *pspec);
      61  
      62  G_DEFINE_TYPE_WITH_PRIVATE (GDataInputStream,
      63                              g_data_input_stream,
      64                              G_TYPE_BUFFERED_INPUT_STREAM)
      65  
      66  
      67  static void
      68  g_data_input_stream_class_init (GDataInputStreamClass *klass)
      69  {
      70    GObjectClass *object_class;
      71  
      72    object_class = G_OBJECT_CLASS (klass);
      73    object_class->get_property = g_data_input_stream_get_property;
      74    object_class->set_property = g_data_input_stream_set_property;
      75  
      76    /**
      77     * GDataInputStream:byte-order:
      78     *
      79     * The :byte-order property determines the byte ordering that
      80     * is used when reading multi-byte entities (such as integers)
      81     * from the stream.
      82     */ 
      83    g_object_class_install_property (object_class,
      84                                     PROP_BYTE_ORDER,
      85                                     g_param_spec_enum ("byte-order", NULL, NULL,
      86                                                        G_TYPE_DATA_STREAM_BYTE_ORDER,
      87                                                        G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN,
      88                                                        G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB));
      89  
      90    /**
      91     * GDataInputStream:newline-type:
      92     *
      93     * The :newline-type property determines what is considered
      94     * as a line ending when reading complete lines from the stream.
      95     */ 
      96    g_object_class_install_property (object_class,
      97                                     PROP_NEWLINE_TYPE,
      98                                     g_param_spec_enum ("newline-type", NULL, NULL,
      99                                                        G_TYPE_DATA_STREAM_NEWLINE_TYPE,
     100                                                        G_DATA_STREAM_NEWLINE_TYPE_LF,
     101                                                        G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_BLURB));
     102  }
     103  
     104  static void
     105  g_data_input_stream_set_property (GObject      *object,
     106  				  guint         prop_id,
     107  				  const GValue *value,
     108  				  GParamSpec   *pspec)
     109  {
     110    GDataInputStream        *dstream;
     111  
     112    dstream = G_DATA_INPUT_STREAM (object);
     113  
     114     switch (prop_id)
     115      {
     116      case PROP_BYTE_ORDER:
     117        g_data_input_stream_set_byte_order (dstream, g_value_get_enum (value));
     118        break;
     119  
     120      case PROP_NEWLINE_TYPE:
     121        g_data_input_stream_set_newline_type (dstream, g_value_get_enum (value));
     122        break;
     123  
     124      default:
     125        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     126        break;
     127      }
     128  
     129  }
     130  
     131  static void
     132  g_data_input_stream_get_property (GObject    *object,
     133                                    guint       prop_id,
     134                                    GValue     *value,
     135                                    GParamSpec *pspec)
     136  {
     137    GDataInputStreamPrivate *priv;
     138    GDataInputStream        *dstream;
     139  
     140    dstream = G_DATA_INPUT_STREAM (object);
     141    priv = dstream->priv;
     142  
     143    switch (prop_id)
     144      { 
     145      case PROP_BYTE_ORDER:
     146        g_value_set_enum (value, priv->byte_order);
     147        break;
     148  
     149      case PROP_NEWLINE_TYPE:
     150        g_value_set_enum (value, priv->newline_type);
     151        break;
     152  
     153      default:
     154        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     155        break;
     156      }
     157  
     158  }
     159  static void
     160  g_data_input_stream_init (GDataInputStream *stream)
     161  {
     162    stream->priv = g_data_input_stream_get_instance_private (stream);
     163    stream->priv->byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
     164    stream->priv->newline_type = G_DATA_STREAM_NEWLINE_TYPE_LF;
     165  }
     166  
     167  /**
     168   * g_data_input_stream_new:
     169   * @base_stream: a #GInputStream.
     170   * 
     171   * Creates a new data input stream for the @base_stream.
     172   * 
     173   * Returns: a new #GDataInputStream.
     174   **/
     175  GDataInputStream *
     176  g_data_input_stream_new (GInputStream *base_stream)
     177  {
     178    GDataInputStream *stream;
     179  
     180    g_return_val_if_fail (G_IS_INPUT_STREAM (base_stream), NULL);
     181  
     182    stream = g_object_new (G_TYPE_DATA_INPUT_STREAM,
     183                           "base-stream", base_stream,
     184                           NULL);
     185  
     186    return stream;
     187  }
     188  
     189  /**
     190   * g_data_input_stream_set_byte_order:
     191   * @stream: a given #GDataInputStream.
     192   * @order: a #GDataStreamByteOrder to set.
     193   * 
     194   * This function sets the byte order for the given @stream. All subsequent
     195   * reads from the @stream will be read in the given @order.
     196   *  
     197   **/
     198  void
     199  g_data_input_stream_set_byte_order (GDataInputStream     *stream,
     200  				    GDataStreamByteOrder  order)
     201  {
     202    GDataInputStreamPrivate *priv;
     203  
     204    g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
     205  
     206    priv = stream->priv;
     207  
     208    if (priv->byte_order != order)
     209      {
     210        priv->byte_order = order;
     211        
     212        g_object_notify (G_OBJECT (stream), "byte-order");
     213      }
     214  }
     215  
     216  /**
     217   * g_data_input_stream_get_byte_order:
     218   * @stream: a given #GDataInputStream.
     219   * 
     220   * Gets the byte order for the data input stream.
     221   * 
     222   * Returns: the @stream's current #GDataStreamByteOrder. 
     223   **/
     224  GDataStreamByteOrder
     225  g_data_input_stream_get_byte_order (GDataInputStream *stream)
     226  {
     227    g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN);
     228  
     229    return stream->priv->byte_order;
     230  }
     231  
     232  /**
     233   * g_data_input_stream_set_newline_type:
     234   * @stream: a #GDataInputStream.
     235   * @type: the type of new line return as #GDataStreamNewlineType.
     236   * 
     237   * Sets the newline type for the @stream.
     238   * 
     239   * Note that using G_DATA_STREAM_NEWLINE_TYPE_ANY is slightly unsafe. If a read
     240   * chunk ends in "CR" we must read an additional byte to know if this is "CR" or
     241   * "CR LF", and this might block if there is no more data available.
     242   *  
     243   **/
     244  void
     245  g_data_input_stream_set_newline_type (GDataInputStream       *stream,
     246  				      GDataStreamNewlineType  type)
     247  {
     248    GDataInputStreamPrivate *priv;
     249  
     250    g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
     251  
     252    priv = stream->priv;
     253    
     254    if (priv->newline_type != type)
     255      {
     256        priv->newline_type = type;
     257  
     258        g_object_notify (G_OBJECT (stream), "newline-type");
     259      }
     260  }
     261  
     262  /**
     263   * g_data_input_stream_get_newline_type:
     264   * @stream: a given #GDataInputStream.
     265   * 
     266   * Gets the current newline type for the @stream.
     267   * 
     268   * Returns: #GDataStreamNewlineType for the given @stream.
     269   **/
     270  GDataStreamNewlineType
     271  g_data_input_stream_get_newline_type (GDataInputStream *stream)
     272  {
     273    g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), G_DATA_STREAM_NEWLINE_TYPE_ANY);
     274  
     275    return stream->priv->newline_type;
     276  }
     277  
     278  static gboolean
     279  read_data (GDataInputStream  *stream,
     280             void              *buffer,
     281             gsize              size,
     282             GCancellable      *cancellable,
     283             GError           **error)
     284  {
     285    gsize available;
     286    gssize res;
     287  
     288    while ((available = g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (stream))) < size)
     289      {
     290        res = g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (stream),
     291  					  size - available,
     292  					  cancellable, error);
     293        if (res < 0)
     294  	return FALSE;
     295        if (res == 0)
     296  	{
     297  	  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
     298                                 _("Unexpected early end-of-stream"));
     299  	  return FALSE;
     300  	}
     301      }
     302    
     303    /* This should always succeed, since it's in the buffer */
     304    res = g_input_stream_read (G_INPUT_STREAM (stream),
     305  			     buffer, size,
     306  			     NULL, NULL);
     307    g_warn_if_fail (res >= 0 && (gsize) res == size);
     308    return TRUE;
     309  }
     310  
     311  
     312  /**
     313   * g_data_input_stream_read_byte:
     314   * @stream: a given #GDataInputStream.
     315   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
     316   * @error: #GError for error reporting.
     317   * 
     318   * Reads an unsigned 8-bit/1-byte value from @stream.
     319   *
     320   * Returns: an unsigned 8-bit/1-byte value read from the @stream or `0`
     321   * if an error occurred.
     322   **/
     323  guchar
     324  g_data_input_stream_read_byte (GDataInputStream  *stream,
     325  			       GCancellable       *cancellable,
     326  			       GError            **error)
     327  {
     328    guchar c;
     329    
     330    g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), '\0');
     331    
     332    if (read_data (stream, &c, 1, cancellable, error))
     333        return c;
     334    
     335    return 0;
     336  }
     337  
     338  
     339  /**
     340   * g_data_input_stream_read_int16:
     341   * @stream: a given #GDataInputStream.
     342   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
     343   * @error: #GError for error reporting.
     344   * 
     345   * Reads a 16-bit/2-byte value from @stream.
     346   *
     347   * In order to get the correct byte order for this read operation, 
     348   * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order().
     349   * 
     350   * Returns: a signed 16-bit/2-byte value read from @stream or `0` if
     351   * an error occurred.
     352   **/
     353  gint16
     354  g_data_input_stream_read_int16 (GDataInputStream  *stream,
     355  			       GCancellable       *cancellable,
     356  			       GError            **error)
     357  {
     358    gint16 v;
     359    
     360    g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
     361    
     362    if (read_data (stream, &v, 2, cancellable, error))
     363      {
     364        switch (stream->priv->byte_order)
     365  	{
     366  	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
     367  	  v = GINT16_FROM_BE (v);
     368  	  break;
     369  	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
     370  	  v = GINT16_FROM_LE (v);
     371  	  break;
     372  	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
     373  	default:
     374  	  break;
     375  	}
     376        return v;
     377      }
     378    
     379    return 0;
     380  }
     381  
     382  
     383  /**
     384   * g_data_input_stream_read_uint16:
     385   * @stream: a given #GDataInputStream.
     386   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
     387   * @error: #GError for error reporting.
     388   *
     389   * Reads an unsigned 16-bit/2-byte value from @stream.
     390   *
     391   * In order to get the correct byte order for this read operation, 
     392   * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order(). 
     393   * 
     394   * Returns: an unsigned 16-bit/2-byte value read from the @stream or `0` if
     395   * an error occurred. 
     396   **/
     397  guint16
     398  g_data_input_stream_read_uint16 (GDataInputStream  *stream,
     399  				 GCancellable       *cancellable,
     400  				 GError            **error)
     401  {
     402    guint16 v;
     403    
     404    g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
     405    
     406    if (read_data (stream, &v, 2, cancellable, error))
     407      {
     408        switch (stream->priv->byte_order)
     409  	{
     410  	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
     411  	  v = GUINT16_FROM_BE (v);
     412  	  break;
     413  	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
     414  	  v = GUINT16_FROM_LE (v);
     415  	  break;
     416  	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
     417  	default:
     418  	  break;
     419  	}
     420        return v;
     421      }
     422    
     423    return 0;
     424  }
     425  
     426  
     427  /**
     428   * g_data_input_stream_read_int32:
     429   * @stream: a given #GDataInputStream.
     430   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
     431   * @error: #GError for error reporting.
     432   * 
     433   * Reads a signed 32-bit/4-byte value from @stream.
     434   *
     435   * In order to get the correct byte order for this read operation, 
     436   * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order().
     437   *
     438   * If @cancellable is not %NULL, then the operation can be cancelled by
     439   * triggering the cancellable object from another thread. If the operation
     440   * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
     441   *   
     442   * Returns: a signed 32-bit/4-byte value read from the @stream or `0` if
     443   * an error occurred. 
     444   **/
     445  gint32
     446  g_data_input_stream_read_int32 (GDataInputStream  *stream,
     447  				GCancellable       *cancellable,
     448  				GError            **error)
     449  {
     450    gint32 v;
     451    
     452    g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
     453    
     454    if (read_data (stream, &v, 4, cancellable, error))
     455      {
     456        switch (stream->priv->byte_order)
     457  	{
     458  	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
     459  	  v = GINT32_FROM_BE (v);
     460  	  break;
     461  	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
     462  	  v = GINT32_FROM_LE (v);
     463  	  break;
     464  	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
     465  	default:
     466  	  break;
     467  	}
     468        return v;
     469      }
     470    
     471    return 0;
     472  }
     473  
     474  
     475  /**
     476   * g_data_input_stream_read_uint32:
     477   * @stream: a given #GDataInputStream.
     478   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
     479   * @error: #GError for error reporting.
     480   * 
     481   * Reads an unsigned 32-bit/4-byte value from @stream.
     482   *
     483   * In order to get the correct byte order for this read operation, 
     484   * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order().
     485   *
     486   * If @cancellable is not %NULL, then the operation can be cancelled by
     487   * triggering the cancellable object from another thread. If the operation
     488   * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
     489   * 
     490   * Returns: an unsigned 32-bit/4-byte value read from the @stream or `0` if
     491   * an error occurred. 
     492   **/
     493  guint32
     494  g_data_input_stream_read_uint32 (GDataInputStream  *stream,
     495  				 GCancellable       *cancellable,
     496  				 GError            **error)
     497  {
     498    guint32 v;
     499    
     500    g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
     501    
     502    if (read_data (stream, &v, 4, cancellable, error))
     503      {
     504        switch (stream->priv->byte_order)
     505  	{
     506  	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
     507  	  v = GUINT32_FROM_BE (v);
     508  	  break;
     509  	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
     510  	  v = GUINT32_FROM_LE (v);
     511  	  break;
     512  	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
     513  	default:
     514  	  break;
     515  	}
     516        return v;
     517      }
     518    
     519    return 0;
     520  }
     521  
     522  
     523  /**
     524   * g_data_input_stream_read_int64:
     525   * @stream: a given #GDataInputStream.
     526   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
     527   * @error: #GError for error reporting.
     528   * 
     529   * Reads a 64-bit/8-byte value from @stream.
     530   *
     531   * In order to get the correct byte order for this read operation, 
     532   * see g_data_input_stream_get_byte_order() and g_data_input_stream_set_byte_order().
     533   *
     534   * If @cancellable is not %NULL, then the operation can be cancelled by
     535   * triggering the cancellable object from another thread. If the operation
     536   * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
     537   * 
     538   * Returns: a signed 64-bit/8-byte value read from @stream or `0` if
     539   * an error occurred.  
     540   **/
     541  gint64
     542  g_data_input_stream_read_int64 (GDataInputStream  *stream,
     543  			       GCancellable       *cancellable,
     544  			       GError            **error)
     545  {
     546    gint64 v;
     547    
     548    g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
     549    
     550    if (read_data (stream, &v, 8, cancellable, error))
     551      {
     552        switch (stream->priv->byte_order)
     553  	{
     554  	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
     555  	  v = GINT64_FROM_BE (v);
     556  	  break;
     557  	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
     558  	  v = GINT64_FROM_LE (v);
     559  	  break;
     560  	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
     561  	default:
     562  	  break;
     563  	}
     564        return v;
     565      }
     566    
     567    return 0;
     568  }
     569  
     570  
     571  /**
     572   * g_data_input_stream_read_uint64:
     573   * @stream: a given #GDataInputStream.
     574   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
     575   * @error: #GError for error reporting.
     576   * 
     577   * Reads an unsigned 64-bit/8-byte value from @stream.
     578   *
     579   * In order to get the correct byte order for this read operation, 
     580   * see g_data_input_stream_get_byte_order().
     581   *
     582   * If @cancellable is not %NULL, then the operation can be cancelled by
     583   * triggering the cancellable object from another thread. If the operation
     584   * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
     585   * 
     586   * Returns: an unsigned 64-bit/8-byte read from @stream or `0` if
     587   * an error occurred. 
     588   **/
     589  guint64
     590  g_data_input_stream_read_uint64 (GDataInputStream  *stream,
     591  				GCancellable       *cancellable,
     592  				GError            **error)
     593  {
     594    guint64 v;
     595    
     596    g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
     597    
     598    if (read_data (stream, &v, 8, cancellable, error))
     599      {
     600        switch (stream->priv->byte_order)
     601  	{
     602  	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
     603  	  v = GUINT64_FROM_BE (v);
     604  	  break;
     605  	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
     606  	  v = GUINT64_FROM_LE (v);
     607  	  break;
     608  	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
     609  	default:
     610  	  break;
     611  	}
     612        return v;
     613      }
     614    
     615    return 0;
     616  }
     617  
     618  static gssize
     619  scan_for_newline (GDataInputStream *stream,
     620  		  gsize            *checked_out,
     621  		  gboolean         *last_saw_cr_out,
     622  		  int              *newline_len_out)
     623  {
     624    GBufferedInputStream *bstream;
     625    GDataInputStreamPrivate *priv;
     626    const char *buffer;
     627    gsize start, end, peeked;
     628    gsize i;
     629    gssize found_pos;
     630    int newline_len;
     631    gsize available, checked;
     632    gboolean last_saw_cr;
     633  
     634    priv = stream->priv;
     635    
     636    bstream = G_BUFFERED_INPUT_STREAM (stream);
     637  
     638    checked = *checked_out;
     639    last_saw_cr = *last_saw_cr_out;
     640    found_pos = -1;
     641    newline_len = 0;
     642    
     643    start = checked;
     644    buffer = (const char*)g_buffered_input_stream_peek_buffer (bstream, &available) + start;
     645    end = available;
     646    peeked = end - start;
     647  
     648    for (i = 0; checked < available && i < peeked; i++)
     649      {
     650        switch (priv->newline_type)
     651  	{
     652  	case G_DATA_STREAM_NEWLINE_TYPE_LF:
     653  	  if (buffer[i] == 10)
     654  	    {
     655  	      found_pos = start + i;
     656  	      newline_len = 1;
     657  	    }
     658  	  break;
     659  	case G_DATA_STREAM_NEWLINE_TYPE_CR:
     660  	  if (buffer[i] == 13)
     661  	    {
     662  	      found_pos = start + i;
     663  	      newline_len = 1;
     664  	    }
     665  	  break;
     666  	case G_DATA_STREAM_NEWLINE_TYPE_CR_LF:
     667  	  if (last_saw_cr && buffer[i] == 10)
     668  	    {
     669  	      found_pos = start + i - 1;
     670  	      newline_len = 2;
     671  	    }
     672  	  break;
     673  	default:
     674  	case G_DATA_STREAM_NEWLINE_TYPE_ANY:
     675  	  if (buffer[i] == 10) /* LF */
     676  	    {
     677  	      if (last_saw_cr)
     678  		{
     679  		  /* CR LF */
     680  		  found_pos = start + i - 1;
     681  		  newline_len = 2;
     682  		}
     683  	      else
     684  		{
     685  		  /* LF */
     686  		  found_pos = start + i;
     687  		  newline_len = 1;
     688  		}
     689  	    }
     690  	  else if (last_saw_cr)
     691  	    {
     692  	      /* Last was cr, this is not LF, end is CR */
     693  	      found_pos = start + i - 1;
     694  	      newline_len = 1;
     695  	    }
     696  	  /* Don't check for CR here, instead look at last_saw_cr on next byte */
     697  	  break;
     698  	}
     699  	
     700        last_saw_cr = (buffer[i] == 13);
     701  
     702        if (found_pos != -1)
     703  	{
     704  	  *newline_len_out = newline_len;
     705  	  return found_pos;
     706  	}
     707      }
     708  
     709    checked = end;
     710  
     711    *checked_out = checked;
     712    *last_saw_cr_out = last_saw_cr;
     713    return -1;
     714  }
     715  		  
     716  
     717  /**
     718   * g_data_input_stream_read_line:
     719   * @stream: a given #GDataInputStream.
     720   * @length: (out) (optional): a #gsize to get the length of the data read in.
     721   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
     722   * @error: #GError for error reporting.
     723   *
     724   * Reads a line from the data input stream.  Note that no encoding
     725   * checks or conversion is performed; the input is not guaranteed to
     726   * be UTF-8, and may in fact have embedded NUL characters.
     727   *
     728   * If @cancellable is not %NULL, then the operation can be cancelled by
     729   * triggering the cancellable object from another thread. If the operation
     730   * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
     731   *
     732   * Returns: (nullable) (transfer full) (array zero-terminated=1) (element-type guint8):
     733   *  a NUL terminated byte array with the line that was read in
     734   *  (without the newlines).  Set @length to a #gsize to get the length
     735   *  of the read line.  On an error, it will return %NULL and @error
     736   *  will be set. If there's no content to read, it will still return
     737   *  %NULL, but @error won't be set.
     738   **/
     739  char *
     740  g_data_input_stream_read_line (GDataInputStream  *stream,
     741  			       gsize             *length,
     742  			       GCancellable      *cancellable,
     743  			       GError           **error)
     744  {
     745    GBufferedInputStream *bstream;
     746    gsize checked;
     747    gboolean last_saw_cr;
     748    gssize found_pos;
     749    gssize res;
     750    int newline_len;
     751    char *line;
     752    
     753    g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);  
     754  
     755    bstream = G_BUFFERED_INPUT_STREAM (stream);
     756  
     757    newline_len = 0;
     758    checked = 0;
     759    last_saw_cr = FALSE;
     760  
     761    while ((found_pos = scan_for_newline (stream, &checked, &last_saw_cr, &newline_len)) == -1)
     762      {
     763        if (g_buffered_input_stream_get_available (bstream) ==
     764  	  g_buffered_input_stream_get_buffer_size (bstream))
     765  	g_buffered_input_stream_set_buffer_size (bstream,
     766  						 2 * g_buffered_input_stream_get_buffer_size (bstream));
     767  
     768        res = g_buffered_input_stream_fill (bstream, -1, cancellable, error);
     769        if (res < 0)
     770  	return NULL;
     771        if (res == 0)
     772  	{
     773  	  /* End of stream */
     774  	  if (g_buffered_input_stream_get_available (bstream) == 0)
     775  	    {
     776  	      if (length)
     777  		*length = 0;
     778  	      return NULL;
     779  	    }
     780  	  else
     781  	    {
     782  	      found_pos = checked;
     783  	      newline_len = 0;
     784  	      break;
     785  	    }
     786  	}
     787      }
     788  
     789    line = g_malloc (found_pos + newline_len + 1);
     790  
     791    res = g_input_stream_read (G_INPUT_STREAM (stream),
     792  			     line,
     793  			     found_pos + newline_len,
     794  			     NULL, NULL);
     795    if (length)
     796      *length = (gsize)found_pos;
     797    g_warn_if_fail (res == found_pos + newline_len);
     798    line[found_pos] = 0;
     799    
     800    return line;
     801  }
     802  
     803  /**
     804   * g_data_input_stream_read_line_utf8:
     805   * @stream: a given #GDataInputStream.
     806   * @length: (out) (optional): a #gsize to get the length of the data read in.
     807   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
     808   * @error: #GError for error reporting.
     809   *
     810   * Reads a UTF-8 encoded line from the data input stream.
     811   *
     812   * If @cancellable is not %NULL, then the operation can be cancelled by
     813   * triggering the cancellable object from another thread. If the operation
     814   * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
     815   *
     816   * Returns: (nullable) (transfer full): a NUL terminated UTF-8 string
     817   *  with the line that was read in (without the newlines).  Set
     818   *  @length to a #gsize to get the length of the read line.  On an
     819   *  error, it will return %NULL and @error will be set.  For UTF-8
     820   *  conversion errors, the set error domain is %G_CONVERT_ERROR.  If
     821   *  there's no content to read, it will still return %NULL, but @error
     822   *  won't be set.
     823   *
     824   * Since: 2.30
     825   **/
     826  char *
     827  g_data_input_stream_read_line_utf8 (GDataInputStream  *stream,
     828  				    gsize             *length,
     829  				    GCancellable      *cancellable,
     830  				    GError           **error)
     831  {
     832    char *res;
     833  
     834    res = g_data_input_stream_read_line (stream, length, cancellable, error);
     835    if (!res)
     836      return NULL;
     837    
     838    if (!g_utf8_validate (res, -1, NULL))
     839      {
     840        g_set_error_literal (error, G_CONVERT_ERROR,
     841  			   G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
     842  			   _("Invalid byte sequence in conversion input"));
     843        g_free (res);
     844        return NULL;
     845      }
     846    return res;
     847  }
     848  
     849  static gssize
     850  scan_for_chars (GDataInputStream *stream,
     851  		gsize            *checked_out,
     852  		const char       *stop_chars,
     853                  gsize             stop_chars_len)
     854  {
     855    GBufferedInputStream *bstream;
     856    const char *buffer;
     857    gsize start, end, peeked;
     858    gsize i;
     859    gsize available, checked;
     860    const char *stop_char;
     861    const char *stop_end;
     862  
     863    bstream = G_BUFFERED_INPUT_STREAM (stream);
     864    stop_end = stop_chars + stop_chars_len;
     865  
     866    checked = *checked_out;
     867  
     868    start = checked;
     869    buffer = (const char *)g_buffered_input_stream_peek_buffer (bstream, &available) + start;
     870    end = available;
     871    peeked = end - start;
     872  
     873    for (i = 0; checked < available && i < peeked; i++)
     874      {
     875        for (stop_char = stop_chars; stop_char != stop_end; stop_char++)
     876  	{
     877  	  if (buffer[i] == *stop_char)
     878  	    return (start + i);
     879  	}
     880      }
     881  
     882    checked = end;
     883  
     884    *checked_out = checked;
     885    return -1;
     886  }
     887  
     888  /**
     889   * g_data_input_stream_read_until:
     890   * @stream: a given #GDataInputStream.
     891   * @stop_chars: characters to terminate the read.
     892   * @length: (out) (optional): a #gsize to get the length of the data read in.
     893   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
     894   * @error: #GError for error reporting.
     895   *
     896   * Reads a string from the data input stream, up to the first
     897   * occurrence of any of the stop characters.
     898   *
     899   * Note that, in contrast to g_data_input_stream_read_until_async(),
     900   * this function consumes the stop character that it finds.
     901   *
     902   * Don't use this function in new code.  Its functionality is
     903   * inconsistent with g_data_input_stream_read_until_async().  Both
     904   * functions will be marked as deprecated in a future release.  Use
     905   * g_data_input_stream_read_upto() instead, but note that that function
     906   * does not consume the stop character.
     907   *
     908   * Returns: (transfer full): a string with the data that was read
     909   *     before encountering any of the stop characters. Set @length to
     910   *     a #gsize to get the length of the string. This function will
     911   *     return %NULL on an error.
     912   * Deprecated: 2.56: Use g_data_input_stream_read_upto() instead, which has more
     913   *     consistent behaviour regarding the stop character.
     914   */
     915  char *
     916  g_data_input_stream_read_until (GDataInputStream  *stream,
     917  			       const gchar        *stop_chars,
     918  			       gsize              *length,
     919  			       GCancellable       *cancellable,
     920  			       GError            **error)
     921  {
     922    GBufferedInputStream *bstream;
     923    gchar *result;
     924  
     925    bstream = G_BUFFERED_INPUT_STREAM (stream);
     926  
     927    result = g_data_input_stream_read_upto (stream, stop_chars, -1,
     928                                            length, cancellable, error);
     929  
     930    /* If we're not at end of stream then we have a stop_char to consume. */
     931    if (result != NULL && g_buffered_input_stream_get_available (bstream) > 0)
     932      {
     933        gsize res G_GNUC_UNUSED  /* when compiling with G_DISABLE_ASSERT */;
     934        gchar b;
     935  
     936        res = g_input_stream_read (G_INPUT_STREAM (stream), &b, 1, NULL, NULL);
     937        g_assert (res == 1);
     938      }
     939  
     940    return result;
     941  }
     942  
     943  typedef struct
     944  {
     945    gboolean last_saw_cr;
     946    gsize checked;
     947  
     948    gchar *stop_chars;
     949    gsize stop_chars_len;
     950    gsize length;
     951  } GDataInputStreamReadData;
     952  
     953  static void
     954  g_data_input_stream_read_complete (GTask *task,
     955                                     gsize  read_length,
     956                                     gsize  skip_length)
     957  {
     958    GDataInputStreamReadData *data = g_task_get_task_data (task);
     959    GInputStream *stream = g_task_get_source_object (task);
     960    char *line = NULL;
     961  
     962    if (read_length || skip_length)
     963      {
     964        gssize bytes;
     965  
     966        data->length = read_length;
     967        line = g_malloc (read_length + 1);
     968        line[read_length] = '\0';
     969  
     970        /* we already checked the buffer.  this shouldn't fail. */
     971        bytes = g_input_stream_read (stream, line, read_length, NULL, NULL);
     972        g_assert_cmpint (bytes, ==, read_length);
     973  
     974        bytes = g_input_stream_skip (stream, skip_length, NULL, NULL);
     975        g_assert_cmpint (bytes, ==, skip_length);
     976      }
     977  
     978    g_task_return_pointer (task, line, g_free);
     979    g_object_unref (task);
     980  }
     981  
     982  static void
     983  g_data_input_stream_read_line_ready (GObject      *object,
     984                                       GAsyncResult *result,
     985                                       gpointer      user_data)
     986  {
     987    GTask *task = user_data;
     988    GDataInputStreamReadData *data = g_task_get_task_data (task);
     989    GBufferedInputStream *buffer = g_task_get_source_object (task);
     990    gssize found_pos;
     991    gint newline_len;
     992  
     993    if (result)
     994      /* this is a callback.  finish the async call. */
     995      {
     996        GError *error = NULL;
     997        gssize bytes;
     998  
     999        bytes = g_buffered_input_stream_fill_finish (buffer, result, &error);
    1000  
    1001        if (bytes <= 0)
    1002          {
    1003            if (bytes < 0)
    1004              /* stream error. */
    1005              {
    1006                g_task_return_error (task, error);
    1007                g_object_unref (task);
    1008                return;
    1009              }
    1010  
    1011            g_data_input_stream_read_complete (task, data->checked, 0);
    1012            return;
    1013          }
    1014  
    1015        /* only proceed if we got more bytes... */
    1016      }
    1017  
    1018    if (data->stop_chars)
    1019      {
    1020        found_pos = scan_for_chars (G_DATA_INPUT_STREAM (buffer),
    1021                                    &data->checked,
    1022                                    data->stop_chars,
    1023                                    data->stop_chars_len);
    1024        newline_len = 0;
    1025      }
    1026    else
    1027      found_pos = scan_for_newline (G_DATA_INPUT_STREAM (buffer), &data->checked,
    1028                                    &data->last_saw_cr, &newline_len);
    1029  
    1030    if (found_pos == -1)
    1031      /* didn't find a full line; need to buffer some more bytes */
    1032      {
    1033        gsize size;
    1034  
    1035        size = g_buffered_input_stream_get_buffer_size (buffer);
    1036  
    1037        if (g_buffered_input_stream_get_available (buffer) == size)
    1038          /* need to grow the buffer */
    1039          g_buffered_input_stream_set_buffer_size (buffer, size * 2);
    1040  
    1041        /* try again */
    1042        g_buffered_input_stream_fill_async (buffer, -1,
    1043                                            g_task_get_priority (task),
    1044                                            g_task_get_cancellable (task),
    1045                                            g_data_input_stream_read_line_ready,
    1046                                            user_data);
    1047      }
    1048    else
    1049      {
    1050        /* read the line and the EOL.  no error is possible. */
    1051        g_data_input_stream_read_complete (task, found_pos, newline_len);
    1052      }
    1053  }
    1054  
    1055  static void
    1056  g_data_input_stream_read_data_free (gpointer user_data)
    1057  {
    1058    GDataInputStreamReadData *data = user_data;
    1059  
    1060    g_free (data->stop_chars);
    1061    g_slice_free (GDataInputStreamReadData, data);
    1062  }
    1063  
    1064  static void
    1065  g_data_input_stream_read_async (GDataInputStream    *stream,
    1066                                  const gchar         *stop_chars,
    1067                                  gssize               stop_chars_len,
    1068                                  gint                 io_priority,
    1069                                  GCancellable        *cancellable,
    1070                                  GAsyncReadyCallback  callback,
    1071                                  gpointer             user_data)
    1072  {
    1073    GDataInputStreamReadData *data;
    1074    GTask *task;
    1075    gsize stop_chars_len_unsigned;
    1076  
    1077    data = g_slice_new0 (GDataInputStreamReadData);
    1078  
    1079    if (stop_chars_len < 0)
    1080      stop_chars_len_unsigned = strlen (stop_chars);
    1081    else
    1082      stop_chars_len_unsigned = (gsize) stop_chars_len;
    1083  
    1084    data->stop_chars = g_memdup2 (stop_chars, stop_chars_len_unsigned);
    1085    data->stop_chars_len = stop_chars_len_unsigned;
    1086    data->last_saw_cr = FALSE;
    1087  
    1088    task = g_task_new (stream, cancellable, callback, user_data);
    1089    g_task_set_source_tag (task, g_data_input_stream_read_async);
    1090    g_task_set_task_data (task, data, g_data_input_stream_read_data_free);
    1091    g_task_set_priority (task, io_priority);
    1092  
    1093    g_data_input_stream_read_line_ready (NULL, NULL, task);
    1094  }
    1095  
    1096  static gchar *
    1097  g_data_input_stream_read_finish (GDataInputStream  *stream,
    1098                                   GAsyncResult      *result,
    1099                                   gsize             *length,
    1100                                   GError           **error)
    1101  {
    1102    GTask *task = G_TASK (result);
    1103    gchar *line;
    1104  
    1105    line = g_task_propagate_pointer (task, error);
    1106  
    1107    if (length && line)
    1108      {
    1109        GDataInputStreamReadData *data = g_task_get_task_data (task);
    1110  
    1111        *length = data->length;
    1112      }
    1113  
    1114    return line;
    1115  }
    1116  
    1117  /**
    1118   * g_data_input_stream_read_line_async:
    1119   * @stream: a given #GDataInputStream.
    1120   * @io_priority: the [I/O priority][io-priority] of the request
    1121   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
    1122   * @callback: (scope async) (closure user_data): callback to call when the request is satisfied.
    1123   * @user_data: the data to pass to callback function.
    1124   *
    1125   * The asynchronous version of g_data_input_stream_read_line().  It is
    1126   * an error to have two outstanding calls to this function.
    1127   *
    1128   * When the operation is finished, @callback will be called. You
    1129   * can then call g_data_input_stream_read_line_finish() to get
    1130   * the result of the operation.
    1131   *
    1132   * Since: 2.20
    1133   */
    1134  void
    1135  g_data_input_stream_read_line_async (GDataInputStream    *stream,
    1136                                       gint                 io_priority,
    1137                                       GCancellable        *cancellable,
    1138                                       GAsyncReadyCallback  callback,
    1139                                       gpointer             user_data)
    1140  {
    1141    g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
    1142    g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
    1143  
    1144    g_data_input_stream_read_async (stream, NULL, 0, io_priority,
    1145                                    cancellable, callback, user_data);
    1146  }
    1147  
    1148  /**
    1149   * g_data_input_stream_read_until_async:
    1150   * @stream: a given #GDataInputStream.
    1151   * @stop_chars: characters to terminate the read.
    1152   * @io_priority: the [I/O priority][io-priority] of the request
    1153   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
    1154   * @callback: (scope async): callback to call when the request is satisfied.
    1155   * @user_data: (closure): the data to pass to callback function.
    1156   *
    1157   * The asynchronous version of g_data_input_stream_read_until().
    1158   * It is an error to have two outstanding calls to this function.
    1159   *
    1160   * Note that, in contrast to g_data_input_stream_read_until(),
    1161   * this function does not consume the stop character that it finds.  You
    1162   * must read it for yourself.
    1163   *
    1164   * When the operation is finished, @callback will be called. You
    1165   * can then call g_data_input_stream_read_until_finish() to get
    1166   * the result of the operation.
    1167   *
    1168   * Don't use this function in new code.  Its functionality is
    1169   * inconsistent with g_data_input_stream_read_until().  Both functions
    1170   * will be marked as deprecated in a future release.  Use
    1171   * g_data_input_stream_read_upto_async() instead.
    1172   *
    1173   * Since: 2.20
    1174   * Deprecated: 2.56: Use g_data_input_stream_read_upto_async() instead, which
    1175   *     has more consistent behaviour regarding the stop character.
    1176   */
    1177  void
    1178  g_data_input_stream_read_until_async (GDataInputStream    *stream,
    1179                                        const gchar         *stop_chars,
    1180                                        gint                 io_priority,
    1181                                        GCancellable        *cancellable,
    1182                                        GAsyncReadyCallback  callback,
    1183                                        gpointer             user_data)
    1184  {
    1185    g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
    1186    g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
    1187    g_return_if_fail (stop_chars != NULL);
    1188  
    1189    g_data_input_stream_read_async (stream, stop_chars, -1, io_priority,
    1190                                    cancellable, callback, user_data);
    1191  }
    1192  
    1193  /**
    1194   * g_data_input_stream_read_line_finish:
    1195   * @stream: a given #GDataInputStream.
    1196   * @result: the #GAsyncResult that was provided to the callback.
    1197   * @length: (out) (optional): a #gsize to get the length of the data read in.
    1198   * @error: #GError for error reporting.
    1199   *
    1200   * Finish an asynchronous call started by
    1201   * g_data_input_stream_read_line_async().  Note the warning about
    1202   * string encoding in g_data_input_stream_read_line() applies here as
    1203   * well.
    1204   *
    1205   * Returns: (nullable) (transfer full) (array zero-terminated=1) (element-type guint8):
    1206   *  a NUL-terminated byte array with the line that was read in
    1207   *  (without the newlines).  Set @length to a #gsize to get the length
    1208   *  of the read line.  On an error, it will return %NULL and @error
    1209   *  will be set. If there's no content to read, it will still return
    1210   *  %NULL, but @error won't be set.
    1211   *
    1212   * Since: 2.20
    1213   */
    1214  gchar *
    1215  g_data_input_stream_read_line_finish (GDataInputStream  *stream,
    1216                                        GAsyncResult      *result,
    1217                                        gsize             *length,
    1218                                        GError           **error)
    1219  {
    1220    g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
    1221  
    1222    return g_data_input_stream_read_finish (stream, result, length, error);
    1223  }
    1224  
    1225  /**
    1226   * g_data_input_stream_read_line_finish_utf8:
    1227   * @stream: a given #GDataInputStream.
    1228   * @result: the #GAsyncResult that was provided to the callback.
    1229   * @length: (out) (optional): a #gsize to get the length of the data read in.
    1230   * @error: #GError for error reporting.
    1231   *
    1232   * Finish an asynchronous call started by
    1233   * g_data_input_stream_read_line_async().
    1234   *
    1235   * Returns: (nullable) (transfer full): a string with the line that
    1236   *  was read in (without the newlines).  Set @length to a #gsize to
    1237   *  get the length of the read line.  On an error, it will return
    1238   *  %NULL and @error will be set. For UTF-8 conversion errors, the set
    1239   *  error domain is %G_CONVERT_ERROR.  If there's no content to read,
    1240   *  it will still return %NULL, but @error won't be set.
    1241   *
    1242   * Since: 2.30
    1243   */
    1244  gchar *
    1245  g_data_input_stream_read_line_finish_utf8 (GDataInputStream  *stream,
    1246  					   GAsyncResult      *result,
    1247  					   gsize             *length,
    1248  					   GError           **error)
    1249  {
    1250    gchar *res;
    1251  
    1252    res = g_data_input_stream_read_line_finish (stream, result, length, error);
    1253    if (!res)
    1254      return NULL;
    1255  
    1256    if (!g_utf8_validate (res, -1, NULL))
    1257      {
    1258        g_set_error_literal (error, G_CONVERT_ERROR,
    1259  			   G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
    1260  			   _("Invalid byte sequence in conversion input"));
    1261        g_free (res);
    1262        return NULL;
    1263      }
    1264    return res;
    1265  }
    1266  
    1267  /**
    1268   * g_data_input_stream_read_until_finish:
    1269   * @stream: a given #GDataInputStream.
    1270   * @result: the #GAsyncResult that was provided to the callback.
    1271   * @length: (out) (optional): a #gsize to get the length of the data read in.
    1272   * @error: #GError for error reporting.
    1273   *
    1274   * Finish an asynchronous call started by
    1275   * g_data_input_stream_read_until_async().
    1276   *
    1277   * Since: 2.20
    1278   *
    1279   * Returns: (transfer full): a string with the data that was read
    1280   *     before encountering any of the stop characters. Set @length to
    1281   *     a #gsize to get the length of the string. This function will
    1282   *     return %NULL on an error.
    1283   * Deprecated: 2.56: Use g_data_input_stream_read_upto_finish() instead, which
    1284   *     has more consistent behaviour regarding the stop character.
    1285   */
    1286  gchar *
    1287  g_data_input_stream_read_until_finish (GDataInputStream  *stream,
    1288                                         GAsyncResult      *result,
    1289                                         gsize             *length,
    1290                                         GError           **error)
    1291  {
    1292    g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
    1293  
    1294    return g_data_input_stream_read_finish (stream, result, length, error);
    1295  }
    1296  
    1297  /**
    1298   * g_data_input_stream_read_upto:
    1299   * @stream: a #GDataInputStream
    1300   * @stop_chars: characters to terminate the read
    1301   * @stop_chars_len: length of @stop_chars. May be -1 if @stop_chars is
    1302   *     nul-terminated
    1303   * @length: (out) (optional): a #gsize to get the length of the data read in
    1304   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
    1305   * @error: #GError for error reporting
    1306   *
    1307   * Reads a string from the data input stream, up to the first
    1308   * occurrence of any of the stop characters.
    1309   *
    1310   * In contrast to g_data_input_stream_read_until(), this function
    1311   * does not consume the stop character. You have to use
    1312   * g_data_input_stream_read_byte() to get it before calling
    1313   * g_data_input_stream_read_upto() again.
    1314   *
    1315   * Note that @stop_chars may contain '\0' if @stop_chars_len is
    1316   * specified.
    1317   *
    1318   * The returned string will always be nul-terminated on success.
    1319   *
    1320   * Returns: (transfer full): a string with the data that was read
    1321   *     before encountering any of the stop characters. Set @length to
    1322   *     a #gsize to get the length of the string. This function will
    1323   *     return %NULL on an error
    1324   *
    1325   * Since: 2.26
    1326   */
    1327  char *
    1328  g_data_input_stream_read_upto (GDataInputStream  *stream,
    1329                                 const gchar       *stop_chars,
    1330                                 gssize             stop_chars_len,
    1331                                 gsize             *length,
    1332                                 GCancellable      *cancellable,
    1333                                 GError           **error)
    1334  {
    1335    GBufferedInputStream *bstream;
    1336    gsize checked;
    1337    gssize found_pos;
    1338    gssize res;
    1339    char *data_until;
    1340    gsize stop_chars_len_unsigned;
    1341  
    1342    g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
    1343  
    1344    if (stop_chars_len < 0)
    1345      stop_chars_len_unsigned = strlen (stop_chars);
    1346    else
    1347      stop_chars_len_unsigned = (gsize) stop_chars_len;
    1348  
    1349    bstream = G_BUFFERED_INPUT_STREAM (stream);
    1350  
    1351    checked = 0;
    1352  
    1353    while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len_unsigned)) == -1)
    1354      {
    1355        if (g_buffered_input_stream_get_available (bstream) ==
    1356            g_buffered_input_stream_get_buffer_size (bstream))
    1357          g_buffered_input_stream_set_buffer_size (bstream,
    1358                                                   2 * g_buffered_input_stream_get_buffer_size (bstream));
    1359  
    1360        res = g_buffered_input_stream_fill (bstream, -1, cancellable, error);
    1361        if (res < 0)
    1362          return NULL;
    1363        if (res == 0)
    1364          {
    1365            /* End of stream */
    1366            if (g_buffered_input_stream_get_available (bstream) == 0)
    1367              {
    1368                if (length)
    1369                  *length = 0;
    1370                return NULL;
    1371              }
    1372            else
    1373              {
    1374                found_pos = checked;
    1375                break;
    1376              }
    1377          }
    1378      }
    1379  
    1380    data_until = g_malloc (found_pos + 1);
    1381  
    1382    res = g_input_stream_read (G_INPUT_STREAM (stream),
    1383                               data_until,
    1384                               found_pos,
    1385                               NULL, NULL);
    1386    if (length)
    1387      *length = (gsize)found_pos;
    1388    g_warn_if_fail (res == found_pos);
    1389    data_until[found_pos] = 0;
    1390  
    1391    return data_until;
    1392  }
    1393  
    1394  /**
    1395   * g_data_input_stream_read_upto_async:
    1396   * @stream: a #GDataInputStream
    1397   * @stop_chars: characters to terminate the read
    1398   * @stop_chars_len: length of @stop_chars. May be -1 if @stop_chars is
    1399   *     nul-terminated
    1400   * @io_priority: the [I/O priority][io-priority] of the request
    1401   * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
    1402   * @callback: (scope async): callback to call when the request is satisfied
    1403   * @user_data: (closure): the data to pass to callback function
    1404   *
    1405   * The asynchronous version of g_data_input_stream_read_upto().
    1406   * It is an error to have two outstanding calls to this function.
    1407   *
    1408   * In contrast to g_data_input_stream_read_until(), this function
    1409   * does not consume the stop character. You have to use
    1410   * g_data_input_stream_read_byte() to get it before calling
    1411   * g_data_input_stream_read_upto() again.
    1412   *
    1413   * Note that @stop_chars may contain '\0' if @stop_chars_len is
    1414   * specified.
    1415   *
    1416   * When the operation is finished, @callback will be called. You
    1417   * can then call g_data_input_stream_read_upto_finish() to get
    1418   * the result of the operation.
    1419   *
    1420   * Since: 2.26
    1421   */
    1422  void
    1423  g_data_input_stream_read_upto_async (GDataInputStream    *stream,
    1424                                       const gchar         *stop_chars,
    1425                                       gssize               stop_chars_len,
    1426                                       gint                 io_priority,
    1427                                       GCancellable        *cancellable,
    1428                                       GAsyncReadyCallback  callback,
    1429                                       gpointer             user_data)
    1430  {
    1431    g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
    1432    g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
    1433    g_return_if_fail (stop_chars != NULL);
    1434  
    1435    g_data_input_stream_read_async (stream, stop_chars, stop_chars_len, io_priority,
    1436                                    cancellable, callback, user_data);
    1437  }
    1438  
    1439  /**
    1440   * g_data_input_stream_read_upto_finish:
    1441   * @stream: a #GDataInputStream
    1442   * @result: the #GAsyncResult that was provided to the callback
    1443   * @length: (out) (optional): a #gsize to get the length of the data read in
    1444   * @error: #GError for error reporting
    1445   *
    1446   * Finish an asynchronous call started by
    1447   * g_data_input_stream_read_upto_async().
    1448   *
    1449   * Note that this function does not consume the stop character. You
    1450   * have to use g_data_input_stream_read_byte() to get it before calling
    1451   * g_data_input_stream_read_upto_async() again.
    1452   *
    1453   * The returned string will always be nul-terminated on success.
    1454   *
    1455   * Returns: (transfer full): a string with the data that was read
    1456   *     before encountering any of the stop characters. Set @length to
    1457   *     a #gsize to get the length of the string. This function will
    1458   *     return %NULL on an error.
    1459   *
    1460   * Since: 2.24
    1461   */
    1462  gchar *
    1463  g_data_input_stream_read_upto_finish (GDataInputStream  *stream,
    1464                                        GAsyncResult      *result,
    1465                                        gsize             *length,
    1466                                        GError           **error)
    1467  {
    1468    g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
    1469  
    1470    return g_data_input_stream_read_finish (stream, result, length, error);
    1471  }