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