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