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