tests: Fix for non-GCC
[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  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General
18  * Public License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
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    * GDataStream: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    * GDataStream: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 == size);
316   return TRUE;
317 }
318
319
320 /**
321  * g_data_input_stream_read_byte:
322  * @stream: a given #GDataInputStream.
323  * @cancellable: (allow-none): 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: (allow-none): 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: (allow-none): 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: (allow-none): 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: (allow-none): 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: (allow-none): 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: (allow-none): 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   int 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): a #gsize to get the length of the data read in.
729  * @cancellable: (allow-none): 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: (transfer full) (array zero-terminated=1) (element-type guint8): a
741  *  NUL terminated byte array with the line that was read in (without
742  *  the newlines).  Set @length to a #gsize to get the length of the
743  *  read line.  On an error, it will return %NULL and @error will be
744  *  set. If there's no content to read, it will still return %NULL,
745  *  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): a #gsize to get the length of the data read in.
815  * @cancellable: (allow-none): 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: (transfer full): a NUL terminated UTF-8 string with the
825  *  line that was read in (without the newlines).  Set @length to a
826  *  #gsize to get the length of the read line.  On an error, it will
827  *  return %NULL and @error will be set.  For UTF-8 conversion errors,
828  *  the set error domain is %G_CONVERT_ERROR.  If there's no content to
829  *  read, it will still return %NULL, but @error won't be set.
830  *
831  * Since: 2.30
832  **/
833 char *
834 g_data_input_stream_read_line_utf8 (GDataInputStream  *stream,
835                                     gsize             *length,
836                                     GCancellable      *cancellable,
837                                     GError           **error)
838 {
839   char *res;
840
841   res = g_data_input_stream_read_line (stream, length, cancellable, error);
842   if (!res)
843     return NULL;
844   
845   if (!g_utf8_validate (res, -1, NULL))
846     {
847       g_set_error_literal (error, G_CONVERT_ERROR,
848                            G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
849                            _("Invalid byte sequence in conversion input"));
850       g_free (res);
851       return NULL;
852     }
853   return res;
854 }
855
856 static gssize
857 scan_for_chars (GDataInputStream *stream,
858                 gsize            *checked_out,
859                 const char       *stop_chars,
860                 gssize            stop_chars_len)
861 {
862   GBufferedInputStream *bstream;
863   const char *buffer;
864   gsize start, end, peeked;
865   int i;
866   gsize available, checked;
867   const char *stop_char;
868   const char *stop_end;
869
870   bstream = G_BUFFERED_INPUT_STREAM (stream);
871   stop_end = stop_chars + stop_chars_len;
872
873   checked = *checked_out;
874
875   start = checked;
876   buffer = (const char *)g_buffered_input_stream_peek_buffer (bstream, &available) + start;
877   end = available;
878   peeked = end - start;
879
880   for (i = 0; checked < available && i < peeked; i++)
881     {
882       for (stop_char = stop_chars; stop_char != stop_end; stop_char++)
883         {
884           if (buffer[i] == *stop_char)
885             return (start + i);
886         }
887     }
888
889   checked = end;
890
891   *checked_out = checked;
892   return -1;
893 }
894
895 /**
896  * g_data_input_stream_read_until:
897  * @stream: a given #GDataInputStream.
898  * @stop_chars: characters to terminate the read.
899  * @length: (out): a #gsize to get the length of the data read in.
900  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
901  * @error: #GError for error reporting.
902  *
903  * Reads a string from the data input stream, up to the first
904  * occurrence of any of the stop characters.
905  *
906  * Note that, in contrast to g_data_input_stream_read_until_async(),
907  * this function consumes the stop character that it finds.
908  *
909  * Don't use this function in new code.  Its functionality is
910  * inconsistent with g_data_input_stream_read_until_async().  Both
911  * functions will be marked as deprecated in a future release.  Use
912  * g_data_input_stream_read_upto() instead, but note that that function
913  * does not consume the stop character.
914  *
915  * Returns: (transfer full): a string with the data that was read
916  *     before encountering any of the stop characters. Set @length to
917  *     a #gsize to get the length of the string. This function will
918  *     return %NULL on an error.
919  */
920 char *
921 g_data_input_stream_read_until (GDataInputStream  *stream,
922                                const gchar        *stop_chars,
923                                gsize              *length,
924                                GCancellable       *cancellable,
925                                GError            **error)
926 {
927   GBufferedInputStream *bstream;
928   gchar *result;
929
930   bstream = G_BUFFERED_INPUT_STREAM (stream);
931
932   result = g_data_input_stream_read_upto (stream, stop_chars, -1,
933                                           length, cancellable, error);
934
935   /* If we're not at end of stream then we have a stop_char to consume. */
936   if (result != NULL && g_buffered_input_stream_get_available (bstream) > 0)
937     {
938       gsize res;
939       gchar b;
940
941       res = g_input_stream_read (G_INPUT_STREAM (stream), &b, 1, NULL, NULL);
942       g_assert (res == 1);
943     }
944
945   return result;
946 }
947
948 typedef struct
949 {
950   gboolean last_saw_cr;
951   gsize checked;
952
953   gchar *stop_chars;
954   gssize stop_chars_len;
955   gsize length;
956 } GDataInputStreamReadData;
957
958 static void
959 g_data_input_stream_read_complete (GTask *task,
960                                    gsize  read_length,
961                                    gsize  skip_length)
962 {
963   GDataInputStreamReadData *data = g_task_get_task_data (task);
964   GInputStream *stream = g_task_get_source_object (task);
965   char *line = NULL;
966
967   if (read_length || skip_length)
968     {
969       gssize bytes;
970
971       data->length = read_length;
972       line = g_malloc (read_length + 1);
973       line[read_length] = '\0';
974
975       /* we already checked the buffer.  this shouldn't fail. */
976       bytes = g_input_stream_read (stream, line, read_length, NULL, NULL);
977       g_assert_cmpint (bytes, ==, read_length);
978
979       bytes = g_input_stream_skip (stream, skip_length, NULL, NULL);
980       g_assert_cmpint (bytes, ==, skip_length);
981     }
982
983   g_task_return_pointer (task, line, g_free);
984   g_object_unref (task);
985 }
986
987 static void
988 g_data_input_stream_read_line_ready (GObject      *object,
989                                      GAsyncResult *result,
990                                      gpointer      user_data)
991 {
992   GTask *task = user_data;
993   GDataInputStreamReadData *data = g_task_get_task_data (task);
994   GBufferedInputStream *buffer = g_task_get_source_object (task);
995   gssize found_pos;
996   gint newline_len;
997
998   if (result)
999     /* this is a callback.  finish the async call. */
1000     {
1001       GError *error = NULL;
1002       gssize bytes;
1003
1004       bytes = g_buffered_input_stream_fill_finish (buffer, result, &error);
1005
1006       if (bytes <= 0)
1007         {
1008           if (bytes < 0)
1009             /* stream error. */
1010             {
1011               g_task_return_error (task, error);
1012               g_object_unref (task);
1013               return;
1014             }
1015
1016           g_data_input_stream_read_complete (task, data->checked, 0);
1017           return;
1018         }
1019
1020       /* only proceed if we got more bytes... */
1021     }
1022
1023   if (data->stop_chars)
1024     {
1025       found_pos = scan_for_chars (G_DATA_INPUT_STREAM (buffer),
1026                                   &data->checked,
1027                                   data->stop_chars,
1028                                   data->stop_chars_len);
1029       newline_len = 0;
1030     }
1031   else
1032     found_pos = scan_for_newline (G_DATA_INPUT_STREAM (buffer), &data->checked,
1033                                   &data->last_saw_cr, &newline_len);
1034
1035   if (found_pos == -1)
1036     /* didn't find a full line; need to buffer some more bytes */
1037     {
1038       gsize size;
1039
1040       size = g_buffered_input_stream_get_buffer_size (buffer);
1041
1042       if (g_buffered_input_stream_get_available (buffer) == size)
1043         /* need to grow the buffer */
1044         g_buffered_input_stream_set_buffer_size (buffer, size * 2);
1045
1046       /* try again */
1047       g_buffered_input_stream_fill_async (buffer, -1,
1048                                           g_task_get_priority (task),
1049                                           g_task_get_cancellable (task),
1050                                           g_data_input_stream_read_line_ready,
1051                                           user_data);
1052     }
1053   else
1054     {
1055       /* read the line and the EOL.  no error is possible. */
1056       g_data_input_stream_read_complete (task, found_pos, newline_len);
1057     }
1058 }
1059
1060 static void
1061 g_data_input_stream_read_data_free (gpointer user_data)
1062 {
1063   GDataInputStreamReadData *data = user_data;
1064
1065   g_free (data->stop_chars);
1066   g_slice_free (GDataInputStreamReadData, data);
1067 }
1068
1069 static void
1070 g_data_input_stream_read_async (GDataInputStream    *stream,
1071                                 const gchar         *stop_chars,
1072                                 gssize               stop_chars_len,
1073                                 gint                 io_priority,
1074                                 GCancellable        *cancellable,
1075                                 GAsyncReadyCallback  callback,
1076                                 gpointer             user_data)
1077 {
1078   GDataInputStreamReadData *data;
1079   GTask *task;
1080
1081   data = g_slice_new0 (GDataInputStreamReadData);
1082   if (stop_chars_len == -1)
1083     stop_chars_len = strlen (stop_chars);
1084   data->stop_chars = g_memdup (stop_chars, stop_chars_len);
1085   data->stop_chars_len = stop_chars_len;
1086   data->last_saw_cr = FALSE;
1087
1088   task = g_task_new (stream, cancellable, callback, user_data);
1089   g_task_set_task_data (task, data, g_data_input_stream_read_data_free);
1090   g_task_set_priority (task, io_priority);
1091
1092   g_data_input_stream_read_line_ready (NULL, NULL, task);
1093 }
1094
1095 static gchar *
1096 g_data_input_stream_read_finish (GDataInputStream  *stream,
1097                                  GAsyncResult      *result,
1098                                  gsize             *length,
1099                                  GError           **error)
1100 {
1101   GTask *task = G_TASK (result);
1102   gchar *line;
1103
1104   line = g_task_propagate_pointer (task, error);
1105
1106   if (length && line)
1107     {
1108       GDataInputStreamReadData *data = g_task_get_task_data (task);
1109
1110       *length = data->length;
1111     }
1112
1113   return line;
1114 }
1115
1116 /**
1117  * g_data_input_stream_read_line_async:
1118  * @stream: a given #GDataInputStream.
1119  * @io_priority: the <link linkend="io-priority">I/O priority</link>
1120  *     of the request.
1121  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
1122  * @callback: (scope async): callback to call when the request is satisfied.
1123  * @user_data: (closure): 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 <link linkend="io-priority">I/O priority</link>
1153  *     of the request.
1154  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
1155  * @callback: (scope async): callback to call when the request is satisfied.
1156  * @user_data: (closure): the data to pass to callback function.
1157  *
1158  * The asynchronous version of g_data_input_stream_read_until().
1159  * It is an error to have two outstanding calls to this function.
1160  *
1161  * Note that, in contrast to g_data_input_stream_read_until(),
1162  * this function does not consume the stop character that it finds.  You
1163  * must read it for yourself.
1164  *
1165  * When the operation is finished, @callback will be called. You
1166  * can then call g_data_input_stream_read_until_finish() to get
1167  * the result of the operation.
1168  *
1169  * Don't use this function in new code.  Its functionality is
1170  * inconsistent with g_data_input_stream_read_until().  Both functions
1171  * will be marked as deprecated in a future release.  Use
1172  * g_data_input_stream_read_upto_async() instead.
1173  *
1174  * Since: 2.20
1175  */
1176 void
1177 g_data_input_stream_read_until_async (GDataInputStream    *stream,
1178                                       const gchar         *stop_chars,
1179                                       gint                 io_priority,
1180                                       GCancellable        *cancellable,
1181                                       GAsyncReadyCallback  callback,
1182                                       gpointer             user_data)
1183 {
1184   g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
1185   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1186   g_return_if_fail (stop_chars != NULL);
1187
1188   g_data_input_stream_read_async (stream, stop_chars, -1, io_priority,
1189                                   cancellable, callback, user_data);
1190 }
1191
1192 /**
1193  * g_data_input_stream_read_line_finish:
1194  * @stream: a given #GDataInputStream.
1195  * @result: the #GAsyncResult that was provided to the callback.
1196  * @length: (out): a #gsize to get the length of the data read in.
1197  * @error: #GError for error reporting.
1198  *
1199  * Finish an asynchronous call started by
1200  * g_data_input_stream_read_line_async().  Note the warning about
1201  * string encoding in g_data_input_stream_read_line() applies here as
1202  * well.
1203  *
1204  * Returns: (transfer full) (array zero-terminated=1) (element-type guint8):  a 
1205  *  NUL-terminated byte array with the line that was read in
1206  *  (without the newlines).  Set @length to a #gsize to get the
1207  *  length of the read line.  On an error, it will return %NULL and
1208  *  @error will be set. If there's no content to read, it will
1209  *  still return %NULL, but @error won't be set.
1210  *
1211  * Since: 2.20
1212  */
1213 gchar *
1214 g_data_input_stream_read_line_finish (GDataInputStream  *stream,
1215                                       GAsyncResult      *result,
1216                                       gsize             *length,
1217                                       GError           **error)
1218 {
1219   g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
1220
1221   return g_data_input_stream_read_finish (stream, result, length, error);
1222 }
1223
1224 /**
1225  * g_data_input_stream_read_line_finish_utf8:
1226  * @stream: a given #GDataInputStream.
1227  * @result: the #GAsyncResult that was provided to the callback.
1228  * @length: (out): a #gsize to get the length of the data read in.
1229  * @error: #GError for error reporting.
1230  *
1231  * Finish an asynchronous call started by
1232  * g_data_input_stream_read_line_async().
1233  *
1234  * Returns: (transfer full): a string with the line that was read in
1235  *  (without the newlines).  Set @length to a #gsize to get the length
1236  *  of the read line.  On an error, it will return %NULL and @error
1237  *  will be set. For UTF-8 conversion errors, the set error domain is
1238  *  %G_CONVERT_ERROR.  If there's no content to read, it will still
1239  *  return %NULL, but @error won't be set.
1240  *
1241  * Since: 2.30
1242  */
1243 gchar *
1244 g_data_input_stream_read_line_finish_utf8 (GDataInputStream  *stream,
1245                                            GAsyncResult      *result,
1246                                            gsize             *length,
1247                                            GError           **error)
1248 {
1249   gchar *res;
1250
1251   res = g_data_input_stream_read_line_finish (stream, result, length, error);
1252   if (!res)
1253     return NULL;
1254
1255   if (!g_utf8_validate (res, -1, NULL))
1256     {
1257       g_set_error_literal (error, G_CONVERT_ERROR,
1258                            G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
1259                            _("Invalid byte sequence in conversion input"));
1260       g_free (res);
1261       return NULL;
1262     }
1263   return res;
1264 }
1265
1266 /**
1267  * g_data_input_stream_read_until_finish:
1268  * @stream: a given #GDataInputStream.
1269  * @result: the #GAsyncResult that was provided to the callback.
1270  * @length: (out): a #gsize to get the length of the data read in.
1271  * @error: #GError for error reporting.
1272  *
1273  * Finish an asynchronous call started by
1274  * g_data_input_stream_read_until_async().
1275  *
1276  * Since: 2.20
1277  *
1278  * Returns: (transfer full): a string with the data that was read
1279  *     before encountering any of the stop characters. Set @length to
1280  *     a #gsize to get the length of the string. This function will
1281  *     return %NULL on an error.
1282  */
1283 gchar *
1284 g_data_input_stream_read_until_finish (GDataInputStream  *stream,
1285                                        GAsyncResult      *result,
1286                                        gsize             *length,
1287                                        GError           **error)
1288 {
1289   g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
1290
1291   return g_data_input_stream_read_finish (stream, result, length, error);
1292 }
1293
1294 /**
1295  * g_data_input_stream_read_upto:
1296  * @stream: a #GDataInputStream
1297  * @stop_chars: characters to terminate the read
1298  * @stop_chars_len: length of @stop_chars. May be -1 if @stop_chars is
1299  *     nul-terminated
1300  * @length: (out): a #gsize to get the length of the data read in
1301  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
1302  * @error: #GError for error reporting
1303  *
1304  * Reads a string from the data input stream, up to the first
1305  * occurrence of any of the stop characters.
1306  *
1307  * In contrast to g_data_input_stream_read_until(), this function
1308  * does <emphasis>not</emphasis> consume the stop character. You have
1309  * to use g_data_input_stream_read_byte() to get it before calling
1310  * g_data_input_stream_read_upto() again.
1311  *
1312  * Note that @stop_chars may contain '\0' if @stop_chars_len is
1313  * specified.
1314  *
1315  * Returns: (transfer full): a string with the data that was read
1316  *     before encountering any of the stop characters. Set @length to
1317  *     a #gsize to get the length of the string. This function will
1318  *     return %NULL on an error
1319  *
1320  * Since: 2.26
1321  */
1322 char *
1323 g_data_input_stream_read_upto (GDataInputStream  *stream,
1324                                const gchar       *stop_chars,
1325                                gssize             stop_chars_len,
1326                                gsize             *length,
1327                                GCancellable      *cancellable,
1328                                GError           **error)
1329 {
1330   GBufferedInputStream *bstream;
1331   gsize checked;
1332   gssize found_pos;
1333   gssize res;
1334   char *data_until;
1335
1336   g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
1337
1338   if (stop_chars_len < 0)
1339     stop_chars_len = strlen (stop_chars);
1340
1341   bstream = G_BUFFERED_INPUT_STREAM (stream);
1342
1343   checked = 0;
1344
1345   while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len)) == -1)
1346     {
1347       if (g_buffered_input_stream_get_available (bstream) ==
1348           g_buffered_input_stream_get_buffer_size (bstream))
1349         g_buffered_input_stream_set_buffer_size (bstream,
1350                                                  2 * g_buffered_input_stream_get_buffer_size (bstream));
1351
1352       res = g_buffered_input_stream_fill (bstream, -1, cancellable, error);
1353       if (res < 0)
1354         return NULL;
1355       if (res == 0)
1356         {
1357           /* End of stream */
1358           if (g_buffered_input_stream_get_available (bstream) == 0)
1359             {
1360               if (length)
1361                 *length = 0;
1362               return NULL;
1363             }
1364           else
1365             {
1366               found_pos = checked;
1367               break;
1368             }
1369         }
1370     }
1371
1372   data_until = g_malloc (found_pos + 1);
1373
1374   res = g_input_stream_read (G_INPUT_STREAM (stream),
1375                              data_until,
1376                              found_pos,
1377                              NULL, NULL);
1378   if (length)
1379     *length = (gsize)found_pos;
1380   g_warn_if_fail (res == found_pos);
1381   data_until[found_pos] = 0;
1382
1383   return data_until;
1384 }
1385
1386 /**
1387  * g_data_input_stream_read_upto_async:
1388  * @stream: a #GDataInputStream
1389  * @stop_chars: characters to terminate the read
1390  * @stop_chars_len: length of @stop_chars. May be -1 if @stop_chars is
1391  *     nul-terminated
1392  * @io_priority: the <link linkend="io-priority">I/O priority</link>
1393  *     of the request.
1394  * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
1395  * @callback: (scope async): callback to call when the request is satisfied
1396  * @user_data: (closure): the data to pass to callback function
1397  *
1398  * The asynchronous version of g_data_input_stream_read_upto().
1399  * It is an error to have two outstanding calls to this function.
1400  *
1401  * In contrast to g_data_input_stream_read_until(), this function
1402  * does <emphasis>not</emphasis> consume the stop character. You have
1403  * to use g_data_input_stream_read_byte() to get it before calling
1404  * g_data_input_stream_read_upto() again.
1405  *
1406  * Note that @stop_chars may contain '\0' if @stop_chars_len is
1407  * specified.
1408  *
1409  * When the operation is finished, @callback will be called. You
1410  * can then call g_data_input_stream_read_upto_finish() to get
1411  * the result of the operation.
1412  *
1413  * Since: 2.26
1414  */
1415 void
1416 g_data_input_stream_read_upto_async (GDataInputStream    *stream,
1417                                      const gchar         *stop_chars,
1418                                      gssize               stop_chars_len,
1419                                      gint                 io_priority,
1420                                      GCancellable        *cancellable,
1421                                      GAsyncReadyCallback  callback,
1422                                      gpointer             user_data)
1423 {
1424   g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
1425   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1426   g_return_if_fail (stop_chars != NULL);
1427
1428   g_data_input_stream_read_async (stream, stop_chars, stop_chars_len, io_priority,
1429                                   cancellable, callback, user_data);
1430 }
1431
1432 /**
1433  * g_data_input_stream_read_upto_finish:
1434  * @stream: a #GDataInputStream
1435  * @result: the #GAsyncResult that was provided to the callback
1436  * @length: (out): a #gsize to get the length of the data read in
1437  * @error: #GError for error reporting
1438  *
1439  * Finish an asynchronous call started by
1440  * g_data_input_stream_read_upto_async().
1441  *
1442  * Note that this function does <emphasis>not</emphasis> consume the
1443  * stop character. You have to use g_data_input_stream_read_byte() to
1444  * get it before calling g_data_input_stream_read_upto_async() again.
1445  *
1446  * Returns: (transfer full): a string with the data that was read
1447  *     before encountering any of the stop characters. Set @length to
1448  *     a #gsize to get the length of the string. This function will
1449  *     return %NULL on an error.
1450  *
1451  * Since: 2.24
1452  */
1453 gchar *
1454 g_data_input_stream_read_upto_finish (GDataInputStream  *stream,
1455                                       GAsyncResult      *result,
1456                                       gsize             *length,
1457                                       GError           **error)
1458 {
1459   g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
1460
1461   return g_data_input_stream_read_finish (stream, result, length, error);
1462 }