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