1 /* GIO - GLib Input, Output and Streaming Library 2 * 3 * Copyright (C) 2006-2007 Red Hat, Inc. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General 16 * Public License along with this library; if not, write to the 17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 18 * Boston, MA 02111-1307, USA. 19 * 20 * Author: Alexander Larsson <alexl (at) redhat.com> 21 */ 22 23 #include "config.h" 24 #include "goutputstream.h" 25 #include "gcancellable.h" 26 #include "gasyncresult.h" 27 #include "gsimpleasyncresult.h" 28 #include "ginputstream.h" 29 #include "gioerror.h" 30 #include "glibintl.h" 31 32 #include "gioalias.h" 33 34 /** 35 * SECTION:goutputstream 36 * @short_description: Base class for implementing streaming output 37 * @include: gio/gio.h 38 * 39 * GOutputStream has functions to write to a stream (g_output_stream_write()), 40 * to close a stream (g_output_stream_close()) and to flush pending writes 41 * (g_output_stream_flush()). 42 * 43 * To copy the content of an input stream to an output stream without 44 * manually handling the reads and writes, use g_output_stream_splice(). 45 * 46 * All of these functions have async variants too. 47 **/ 48 49 G_DEFINE_TYPE (GOutputStream, g_output_stream, G_TYPE_OBJECT); 50 51 struct _GOutputStreamPrivate { 52 guint closed : 1; 53 guint pending : 1; 54 guint cancelled : 1; 55 GAsyncReadyCallback outstanding_callback; 56 }; 57 58 static gssize g_output_stream_real_splice (GOutputStream *stream, 59 GInputStream *source, 60 GOutputStreamSpliceFlags flags, 61 GCancellable *cancellable, 62 GError **error); 63 static void g_output_stream_real_write_async (GOutputStream *stream, 64 const void *buffer, 65 gsize count, 66 int io_priority, 67 GCancellable *cancellable, 68 GAsyncReadyCallback callback, 69 gpointer data); 70 static gssize g_output_stream_real_write_finish (GOutputStream *stream, 71 GAsyncResult *result, 72 GError **error); 73 static void g_output_stream_real_splice_async (GOutputStream *stream, 74 GInputStream *source, 75 GOutputStreamSpliceFlags flags, 76 int io_priority, 77 GCancellable *cancellable, 78 GAsyncReadyCallback callback, 79 gpointer data); 80 static gssize g_output_stream_real_splice_finish (GOutputStream *stream, 81 GAsyncResult *result, 82 GError **error); 83 static void g_output_stream_real_flush_async (GOutputStream *stream, 84 int io_priority, 85 GCancellable *cancellable, 86 GAsyncReadyCallback callback, 87 gpointer data); 88 static gboolean g_output_stream_real_flush_finish (GOutputStream *stream, 89 GAsyncResult *result, 90 GError **error); 91 static void g_output_stream_real_close_async (GOutputStream *stream, 92 int io_priority, 93 GCancellable *cancellable, 94 GAsyncReadyCallback callback, 95 gpointer data); 96 static gboolean g_output_stream_real_close_finish (GOutputStream *stream, 97 GAsyncResult *result, 98 GError **error); 99 100 static void 101 g_output_stream_finalize (GObject *object) 102 { 103 GOutputStream *stream; 104 105 stream = G_OUTPUT_STREAM (object); 106 107 G_OBJECT_CLASS (g_output_stream_parent_class)->finalize (object); 108 } 109 110 static void 111 g_output_stream_dispose (GObject *object) 112 { 113 GOutputStream *stream; 114 115 stream = G_OUTPUT_STREAM (object); 116 117 if (!stream->priv->closed) 118 g_output_stream_close (stream, NULL, NULL); 119 120 G_OBJECT_CLASS (g_output_stream_parent_class)->dispose (object); 121 } 122 123 static void 124 g_output_stream_class_init (GOutputStreamClass *klass) 125 { 126 GObjectClass *gobject_class = G_OBJECT_CLASS (klass); 127 128 g_type_class_add_private (klass, sizeof (GOutputStreamPrivate)); 129 130 gobject_class->finalize = g_output_stream_finalize; 131 gobject_class->dispose = g_output_stream_dispose; 132 133 klass->splice = g_output_stream_real_splice; 134 135 klass->write_async = g_output_stream_real_write_async; 136 klass->write_finish = g_output_stream_real_write_finish; 137 klass->splice_async = g_output_stream_real_splice_async; 138 klass->splice_finish = g_output_stream_real_splice_finish; 139 klass->flush_async = g_output_stream_real_flush_async; 140 klass->flush_finish = g_output_stream_real_flush_finish; 141 klass->close_async = g_output_stream_real_close_async; 142 klass->close_finish = g_output_stream_real_close_finish; 143 } 144 145 static void 146 g_output_stream_init (GOutputStream *stream) 147 { 148 stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, 149 G_TYPE_OUTPUT_STREAM, 150 GOutputStreamPrivate); 151 } 152 153 /** 154 * g_output_stream_write: 155 * @stream: a #GOutputStream. 156 * @buffer: the buffer containing the data to write. 157 * @count: the number of bytes to write 158 * @cancellable: optional cancellable object 159 * @error: location to store the error occuring, or %NULL to ignore 160 * 161 * Tries to write @count bytes from @buffer into the stream. Will block 162 * during the operation. 163 * 164 * If count is zero returns zero and does nothing. A value of @count 165 * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error. 166 * 167 * On success, the number of bytes written to the stream is returned. 168 * It is not an error if this is not the same as the requested size, as it 169 * can happen e.g. on a partial i/o error, or if there is not enough 170 * storage in the stream. All writes either block until at least one byte 171 * is written, so zero is never returned (unless @count is zero). 172 * 173 * If @cancellable is not NULL, then the operation can be cancelled by 174 * triggering the cancellable object from another thread. If the operation 175 * was cancelled, the error G_IO_ERROR_CANCELLED will be returned. If an 176 * operation was partially finished when the operation was cancelled the 177 * partial result will be returned, without an error. 178 * 179 * On error -1 is returned and @error is set accordingly. 180 * 181 * Return value: Number of bytes written, or -1 on error 182 **/ 183 gssize 184 g_output_stream_write (GOutputStream *stream, 185 const void *buffer, 186 gsize count, 187 GCancellable *cancellable, 188 GError **error) 189 { 190 GOutputStreamClass *class; 191 gssize res; 192 193 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1); 194 g_return_val_if_fail (buffer != NULL, 0); 195 196 if (count == 0) 197 return 0; 198 199 if (((gssize) count) < 0) 200 { 201 g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, 202 _("Too large count value passed to %s"), G_STRFUNC); 203 return -1; 204 } 205 206 class = G_OUTPUT_STREAM_GET_CLASS (stream); 207 208 if (class->write_fn == NULL) 209 { 210 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, 211 _("Output stream doesn't implement write")); 212 return -1; 213 } 214 215 if (!g_output_stream_set_pending (stream, error)) 216 return -1; 217 218 if (cancellable) 219 g_cancellable_push_current (cancellable); 220 221 res = class->write_fn (stream, buffer, count, cancellable, error); 222 223 if (cancellable) 224 g_cancellable_pop_current (cancellable); 225 226 g_output_stream_clear_pending (stream); 227 228 return res; 229 } 230 231 /** 232 * g_output_stream_write_all: 233 * @stream: a #GOutputStream. 234 * @buffer: the buffer containing the data to write. 235 * @count: the number of bytes to write 236 * @bytes_written: location to store the number of bytes that was 237 * written to the stream 238 * @cancellable: optional #GCancellable object, %NULL to ignore. 239 * @error: location to store the error occuring, or %NULL to ignore 240 * 241 * Tries to write @count bytes from @buffer into the stream. Will block 242 * during the operation. 243 * 244 * This function is similar to g_output_stream_write(), except it tries to 245 * write as many bytes as requested, only stopping on an error. 246 * 247 * On a successful write of @count bytes, %TRUE is returned, and @bytes_written 248 * is set to @count. 249 * 250 * If there is an error during the operation FALSE is returned and @error 251 * is set to indicate the error status, @bytes_written is updated to contain 252 * the number of bytes written into the stream before the error occurred. 253 * 254 * Return value: %TRUE on success, %FALSE if there was an error 255 **/ 256 gboolean 257 g_output_stream_write_all (GOutputStream *stream, 258 const void *buffer, 259 gsize count, 260 gsize *bytes_written, 261 GCancellable *cancellable, 262 GError **error) 263 { 264 gsize _bytes_written; 265 gssize res; 266 267 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); 268 g_return_val_if_fail (buffer != NULL, FALSE); 269 270 _bytes_written = 0; 271 while (_bytes_written < count) 272 { 273 res = g_output_stream_write (stream, (char *)buffer + _bytes_written, count - _bytes_written, 274 cancellable, error); 275 if (res == -1) 276 { 277 if (bytes_written) 278 *bytes_written = _bytes_written; 279 return FALSE; 280 } 281 282 if (res == 0) 283 g_warning ("Write returned zero without error"); 284 285 _bytes_written += res; 286 } 287 288 if (bytes_written) 289 *bytes_written = _bytes_written; 290 291 return TRUE; 292 } 293 294 /** 295 * g_output_stream_flush: 296 * @stream: a #GOutputStream. 297 * @cancellable: optional cancellable object 298 * @error: location to store the error occuring, or %NULL to ignore 299 * 300 * Flushed any outstanding buffers in the stream. Will block during 301 * the operation. Closing the stream will implicitly cause a flush. 302 * 303 * This function is optional for inherited classes. 304 * 305 * If @cancellable is not %NULL, then the operation can be cancelled by 306 * triggering the cancellable object from another thread. If the operation 307 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 308 * 309 * Return value: %TRUE on success, %FALSE on error 310 **/ 311 gboolean 312 g_output_stream_flush (GOutputStream *stream, 313 GCancellable *cancellable, 314 GError **error) 315 { 316 GOutputStreamClass *class; 317 gboolean res; 318 319 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); 320 321 if (!g_output_stream_set_pending (stream, error)) 322 return FALSE; 323 324 class = G_OUTPUT_STREAM_GET_CLASS (stream); 325 326 res = TRUE; 327 if (class->flush) 328 { 329 if (cancellable) 330 g_cancellable_push_current (cancellable); 331 332 res = class->flush (stream, cancellable, error); 333 334 if (cancellable) 335 g_cancellable_pop_current (cancellable); 336 } 337 338 g_output_stream_clear_pending (stream); 339 340 return res; 341 } 342 343 /** 344 * g_output_stream_splice: 345 * @stream: a #GOutputStream. 346 * @source: a #GInputStream. 347 * @flags: a set of #GOutputStreamSpliceFlags. 348 * @cancellable: optional #GCancellable object, %NULL to ignore. 349 * @error: a #GError location to store the error occuring, or %NULL to 350 * ignore. 351 * 352 * Splices an input stream into an output stream. 353 * 354 * Returns: a #gssize containing the size of the data spliced. 355 **/ 356 gssize 357 g_output_stream_splice (GOutputStream *stream, 358 GInputStream *source, 359 GOutputStreamSpliceFlags flags, 360 GCancellable *cancellable, 361 GError **error) 362 { 363 GOutputStreamClass *class; 364 gboolean res; 365 366 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1); 367 g_return_val_if_fail (G_IS_INPUT_STREAM (source), -1); 368 369 if (g_input_stream_is_closed (source)) 370 { 371 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, 372 _("Source stream is already closed")); 373 return -1; 374 } 375 376 if (!g_output_stream_set_pending (stream, error)) 377 return -1; 378 379 class = G_OUTPUT_STREAM_GET_CLASS (stream); 380 381 res = TRUE; 382 if (cancellable) 383 g_cancellable_push_current (cancellable); 384 385 res = class->splice (stream, source, flags, cancellable, error); 386 387 if (cancellable) 388 g_cancellable_pop_current (cancellable); 389 390 g_output_stream_clear_pending (stream); 391 392 return res; 393 } 394 395 static gssize 396 g_output_stream_real_splice (GOutputStream *stream, 397 GInputStream *source, 398 GOutputStreamSpliceFlags flags, 399 GCancellable *cancellable, 400 GError **error) 401 { 402 GOutputStreamClass *class = G_OUTPUT_STREAM_GET_CLASS (stream); 403 gssize n_read, n_written; 404 gssize bytes_copied; 405 char buffer[8192], *p; 406 gboolean res; 407 408 bytes_copied = 0; 409 if (class->write_fn == NULL) 410 { 411 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, 412 _("Output stream doesn't implement write")); 413 res = FALSE; 414 goto notsupported; 415 } 416 417 res = TRUE; 418 do 419 { 420 n_read = g_input_stream_read (source, buffer, sizeof (buffer), cancellable, error); 421 if (n_read == -1) 422 { 423 res = FALSE; 424 break; 425 } 426 427 if (n_read == 0) 428 break; 429 430 p = buffer; 431 while (n_read > 0) 432 { 433 n_written = class->write_fn (stream, p, n_read, cancellable, error); 434 if (n_written == -1) 435 { 436 res = FALSE; 437 break; 438 } 439 440 p += n_written; 441 n_read -= n_written; 442 bytes_copied += n_written; 443 } 444 } 445 while (res); 446 447 notsupported: 448 if (!res) 449 error = NULL; /* Ignore further errors */ 450 451 if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE) 452 { 453 /* Don't care about errors in source here */ 454 g_input_stream_close (source, cancellable, NULL); 455 } 456 457 if (flags & G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET) 458 { 459 /* But write errors on close are bad! */ 460 if (!class->close_fn (stream, cancellable, error)) 461 res = FALSE; 462 } 463 464 if (res) 465 return bytes_copied; 466 467 return -1; 468 } 469 470 471 /** 472 * g_output_stream_close: 473 * @stream: A #GOutputStream. 474 * @cancellable: optional cancellable object 475 * @error: location to store the error occuring, or %NULL to ignore 476 * 477 * Closes the stream, releasing resources related to it. 478 * 479 * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED. 480 * Closing a stream multiple times will not return an error. 481 * 482 * Closing a stream will automatically flush any outstanding buffers in the 483 * stream. 484 * 485 * Streams will be automatically closed when the last reference 486 * is dropped, but you might want to call this function to make sure 487 * resources are released as early as possible. 488 * 489 * Some streams might keep the backing store of the stream (e.g. a file descriptor) 490 * open after the stream is closed. See the documentation for the individual 491 * stream for details. 492 * 493 * On failure the first error that happened will be reported, but the close 494 * operation will finish as much as possible. A stream that failed to 495 * close will still return %G_IO_ERROR_CLOSED for all operations. Still, it 496 * is important to check and report the error to the user, otherwise 497 * there might be a loss of data as all data might not be written. 498 * 499 * If @cancellable is not NULL, then the operation can be cancelled by 500 * triggering the cancellable object from another thread. If the operation 501 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 502 * Cancelling a close will still leave the stream closed, but there some streams 503 * can use a faster close that doesn't block to e.g. check errors. On 504 * cancellation (as with any error) there is no guarantee that all written 505 * data will reach the target. 506 * 507 * Return value: %TRUE on success, %FALSE on failure 508 **/ 509 gboolean 510 g_output_stream_close (GOutputStream *stream, 511 GCancellable *cancellable, 512 GError **error) 513 { 514 GOutputStreamClass *class; 515 gboolean res; 516 517 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); 518 519 class = G_OUTPUT_STREAM_GET_CLASS (stream); 520 521 if (stream->priv->closed) 522 return TRUE; 523 524 if (!g_output_stream_set_pending (stream, error)) 525 return FALSE; 526 527 if (cancellable) 528 g_cancellable_push_current (cancellable); 529 530 if (class->flush) 531 res = class->flush (stream, cancellable, error); 532 else 533 res = TRUE; 534 535 if (!res) 536 { 537 /* flushing caused the error that we want to return, 538 * but we still want to close the underlying stream if possible 539 */ 540 if (class->close_fn) 541 class->close_fn (stream, cancellable, NULL); 542 } 543 else 544 { 545 res = TRUE; 546 if (class->close_fn) 547 res = class->close_fn (stream, cancellable, error); 548 } 549 550 if (cancellable) 551 g_cancellable_pop_current (cancellable); 552 553 stream->priv->closed = TRUE; 554 g_output_stream_clear_pending (stream); 555 556 return res; 557 } 558 559 static void 560 async_ready_callback_wrapper (GObject *source_object, 561 GAsyncResult *res, 562 gpointer user_data) 563 { 564 GOutputStream *stream = G_OUTPUT_STREAM (source_object); 565 566 g_output_stream_clear_pending (stream); 567 if (stream->priv->outstanding_callback) 568 (*stream->priv->outstanding_callback) (source_object, res, user_data); 569 g_object_unref (stream); 570 } 571 572 static void 573 async_ready_close_callback_wrapper (GObject *source_object, 574 GAsyncResult *res, 575 gpointer user_data) 576 { 577 GOutputStream *stream = G_OUTPUT_STREAM (source_object); 578 579 stream->priv->closed = TRUE; 580 g_output_stream_clear_pending (stream); 581 if (stream->priv->outstanding_callback) 582 (*stream->priv->outstanding_callback) (source_object, res, user_data); 583 g_object_unref (stream); 584 } 585 586 /** 587 * g_output_stream_write_async: 588 * @stream: A #GOutputStream. 589 * @buffer: the buffer containing the data to write. 590 * @count: the number of bytes to write 591 * @io_priority: the io priority of the request. 592 * @cancellable: optional #GCancellable object, %NULL to ignore. 593 * @callback: callback to call when the request is satisfied 594 * @user_data: the data to pass to callback function 595 * 596 * Request an asynchronous write of @count bytes from @buffer into 597 * the stream. When the operation is finished @callback will be called. 598 * You can then call g_output_stream_write_finish() to get the result of the 599 * operation. 600 * 601 * During an async request no other sync and async calls are allowed, 602 * and will result in %G_IO_ERROR_PENDING errors. 603 * 604 * A value of @count larger than %G_MAXSSIZE will cause a 605 * %G_IO_ERROR_INVALID_ARGUMENT error. 606 * 607 * On success, the number of bytes written will be passed to the 608 * @callback. It is not an error if this is not the same as the 609 * requested size, as it can happen e.g. on a partial I/O error, 610 * but generally we try to write as many bytes as requested. 611 * 612 * Any outstanding I/O request with higher priority (lower numerical 613 * value) will be executed before an outstanding request with lower 614 * priority. Default priority is %G_PRIORITY_DEFAULT. 615 * 616 * The asyncronous methods have a default fallback that uses threads 617 * to implement asynchronicity, so they are optional for inheriting 618 * classes. However, if you override one you must override all. 619 * 620 * For the synchronous, blocking version of this function, see 621 * g_output_stream_write(). 622 **/ 623 void 624 g_output_stream_write_async (GOutputStream *stream, 625 const void *buffer, 626 gsize count, 627 int io_priority, 628 GCancellable *cancellable, 629 GAsyncReadyCallback callback, 630 gpointer user_data) 631 { 632 GOutputStreamClass *class; 633 GSimpleAsyncResult *simple; 634 GError *error = NULL; 635 636 g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); 637 g_return_if_fail (buffer != NULL); 638 639 if (count == 0) 640 { 641 simple = g_simple_async_result_new (G_OBJECT (stream), 642 callback, 643 user_data, 644 g_output_stream_write_async); 645 g_simple_async_result_complete_in_idle (simple); 646 g_object_unref (simple); 647 return; 648 } 649 650 if (((gssize) count) < 0) 651 { 652 g_simple_async_report_error_in_idle (G_OBJECT (stream), 653 callback, 654 user_data, 655 G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, 656 _("Too large count value passed to %s"), 657 G_STRFUNC); 658 return; 659 } 660 661 if (!g_output_stream_set_pending (stream, &error)) 662 { 663 g_simple_async_report_gerror_in_idle (G_OBJECT (stream), 664 callback, 665 user_data, 666 error); 667 g_error_free (error); 668 return; 669 } 670 671 class = G_OUTPUT_STREAM_GET_CLASS (stream); 672 673 stream->priv->outstanding_callback = callback; 674 g_object_ref (stream); 675 class->write_async (stream, buffer, count, io_priority, cancellable, 676 async_ready_callback_wrapper, user_data); 677 } 678 679 /** 680 * g_output_stream_write_finish: 681 * @stream: a #GOutputStream. 682 * @result: a #GAsyncResult. 683 * @error: a #GError location to store the error occuring, or %NULL to 684 * ignore. 685 * 686 * Finishes a stream write operation. 687 * 688 * Returns: a #gssize containing the number of bytes written to the stream. 689 **/ 690 gssize 691 g_output_stream_write_finish (GOutputStream *stream, 692 GAsyncResult *result, 693 GError **error) 694 { 695 GSimpleAsyncResult *simple; 696 GOutputStreamClass *class; 697 698 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1); 699 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1); 700 701 if (G_IS_SIMPLE_ASYNC_RESULT (result)) 702 { 703 simple = G_SIMPLE_ASYNC_RESULT (result); 704 if (g_simple_async_result_propagate_error (simple, error)) 705 return -1; 706 707 /* Special case writes of 0 bytes */ 708 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_write_async) 709 return 0; 710 } 711 712 class = G_OUTPUT_STREAM_GET_CLASS (stream); 713 return class->write_finish (stream, result, error); 714 } 715 716 typedef struct { 717 GInputStream *source; 718 gpointer user_data; 719 GAsyncReadyCallback callback; 720 } SpliceUserData; 721 722 static void 723 async_ready_splice_callback_wrapper (GObject *source_object, 724 GAsyncResult *res, 725 gpointer _data) 726 { 727 GOutputStream *stream = G_OUTPUT_STREAM (source_object); 728 SpliceUserData *data = _data; 729 730 g_output_stream_clear_pending (stream); 731 732 if (data->callback) 733 (*data->callback) (source_object, res, data->user_data); 734 735 g_object_unref (stream); 736 g_object_unref (data->source); 737 g_free (data); 738 } 739 740 /** 741 * g_output_stream_splice_async: 742 * @stream: a #GOutputStream. 743 * @source: a #GInputStream. 744 * @flags: a set of #GOutputStreamSpliceFlags. 745 * @io_priority: the io priority of the request. 746 * @cancellable: optional #GCancellable object, %NULL to ignore. 747 * @callback: a #GAsyncReadyCallback. 748 * @user_data: user data passed to @callback. 749 * 750 * Splices a stream asynchronously. 751 * When the operation is finished @callback will be called. 752 * You can then call g_output_stream_splice_finish() to get the 753 * result of the operation. 754 * 755 * For the synchronous, blocking version of this function, see 756 * g_output_stream_splice(). 757 **/ 758 void 759 g_output_stream_splice_async (GOutputStream *stream, 760 GInputStream *source, 761 GOutputStreamSpliceFlags flags, 762 int io_priority, 763 GCancellable *cancellable, 764 GAsyncReadyCallback callback, 765 gpointer user_data) 766 { 767 GOutputStreamClass *class; 768 SpliceUserData *data; 769 GError *error = NULL; 770 771 g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); 772 g_return_if_fail (G_IS_INPUT_STREAM (source)); 773 774 if (g_input_stream_is_closed (source)) 775 { 776 g_simple_async_report_error_in_idle (G_OBJECT (stream), 777 callback, 778 user_data, 779 G_IO_ERROR, G_IO_ERROR_CLOSED, 780 _("Source stream is already closed")); 781 return; 782 } 783 784 if (!g_output_stream_set_pending (stream, &error)) 785 { 786 g_simple_async_report_gerror_in_idle (G_OBJECT (stream), 787 callback, 788 user_data, 789 error); 790 g_error_free (error); 791 return; 792 } 793 794 class = G_OUTPUT_STREAM_GET_CLASS (stream); 795 796 data = g_new0 (SpliceUserData, 1); 797 data->callback = callback; 798 data->user_data = user_data; 799 data->source = g_object_ref (source); 800 801 g_object_ref (stream); 802 class->splice_async (stream, source, flags, io_priority, cancellable, 803 async_ready_splice_callback_wrapper, data); 804 } 805 806 /** 807 * g_output_stream_splice_finish: 808 * @stream: a #GOutputStream. 809 * @result: a #GAsyncResult. 810 * @error: a #GError location to store the error occuring, or %NULL to 811 * ignore. 812 * 813 * Finishes an asynchronous stream splice operation. 814 * 815 * Returns: a #gssize of the number of bytes spliced. 816 **/ 817 gssize 818 g_output_stream_splice_finish (GOutputStream *stream, 819 GAsyncResult *result, 820 GError **error) 821 { 822 GSimpleAsyncResult *simple; 823 GOutputStreamClass *class; 824 825 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), -1); 826 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1); 827 828 if (G_IS_SIMPLE_ASYNC_RESULT (result)) 829 { 830 simple = G_SIMPLE_ASYNC_RESULT (result); 831 if (g_simple_async_result_propagate_error (simple, error)) 832 return -1; 833 } 834 835 class = G_OUTPUT_STREAM_GET_CLASS (stream); 836 return class->splice_finish (stream, result, error); 837 } 838 839 /** 840 * g_output_stream_flush_async: 841 * @stream: a #GOutputStream. 842 * @io_priority: the io priority of the request. 843 * @cancellable: optional #GCancellable object, %NULL to ignore. 844 * @callback: a #GAsyncReadyCallback to call when the request is satisfied 845 * @user_data: the data to pass to callback function 846 * 847 * Flushes a stream asynchronously. 848 * For behaviour details see g_output_stream_flush(). 849 * 850 * When the operation is finished @callback will be 851 * called. You can then call g_output_stream_flush_finish() to get the 852 * result of the operation. 853 **/ 854 void 855 g_output_stream_flush_async (GOutputStream *stream, 856 int io_priority, 857 GCancellable *cancellable, 858 GAsyncReadyCallback callback, 859 gpointer user_data) 860 { 861 GOutputStreamClass *class; 862 GSimpleAsyncResult *simple; 863 GError *error = NULL; 864 865 g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); 866 867 if (!g_output_stream_set_pending (stream, &error)) 868 { 869 g_simple_async_report_gerror_in_idle (G_OBJECT (stream), 870 callback, 871 user_data, 872 error); 873 g_error_free (error); 874 return; 875 } 876 877 stream->priv->outstanding_callback = callback; 878 g_object_ref (stream); 879 880 class = G_OUTPUT_STREAM_GET_CLASS (stream); 881 882 if (class->flush_async == NULL) 883 { 884 simple = g_simple_async_result_new (G_OBJECT (stream), 885 async_ready_callback_wrapper, 886 user_data, 887 g_output_stream_flush_async); 888 g_simple_async_result_complete_in_idle (simple); 889 g_object_unref (simple); 890 return; 891 } 892 893 class->flush_async (stream, io_priority, cancellable, 894 async_ready_callback_wrapper, user_data); 895 } 896 897 /** 898 * g_output_stream_flush_finish: 899 * @stream: a #GOutputStream. 900 * @result: a GAsyncResult. 901 * @error: a #GError location to store the error occuring, or %NULL to 902 * ignore. 903 * 904 * Finishes flushing an output stream. 905 * 906 * Returns: %TRUE if flush operation suceeded, %FALSE otherwise. 907 **/ 908 gboolean 909 g_output_stream_flush_finish (GOutputStream *stream, 910 GAsyncResult *result, 911 GError **error) 912 { 913 GSimpleAsyncResult *simple; 914 GOutputStreamClass *klass; 915 916 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); 917 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); 918 919 if (G_IS_SIMPLE_ASYNC_RESULT (result)) 920 { 921 simple = G_SIMPLE_ASYNC_RESULT (result); 922 if (g_simple_async_result_propagate_error (simple, error)) 923 return FALSE; 924 925 /* Special case default implementation */ 926 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_flush_async) 927 return TRUE; 928 } 929 930 klass = G_OUTPUT_STREAM_GET_CLASS (stream); 931 return klass->flush_finish (stream, result, error); 932 } 933 934 935 /** 936 * g_output_stream_close_async: 937 * @stream: A #GOutputStream. 938 * @io_priority: the io priority of the request. 939 * @callback: callback to call when the request is satisfied 940 * @user_data: the data to pass to callback function 941 * @cancellable: optional cancellable object 942 * 943 * Requests an asynchronous close of the stream, releasing resources 944 * related to it. When the operation is finished @callback will be 945 * called. You can then call g_output_stream_close_finish() to get 946 * the result of the operation. 947 * 948 * For behaviour details see g_output_stream_close(). 949 * 950 * The asyncronous methods have a default fallback that uses threads 951 * to implement asynchronicity, so they are optional for inheriting 952 * classes. However, if you override one you must override all. 953 **/ 954 void 955 g_output_stream_close_async (GOutputStream *stream, 956 int io_priority, 957 GCancellable *cancellable, 958 GAsyncReadyCallback callback, 959 gpointer user_data) 960 { 961 GOutputStreamClass *class; 962 GSimpleAsyncResult *simple; 963 GError *error = NULL; 964 965 g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); 966 967 if (stream->priv->closed) 968 { 969 simple = g_simple_async_result_new (G_OBJECT (stream), 970 callback, 971 user_data, 972 g_output_stream_close_async); 973 g_simple_async_result_complete_in_idle (simple); 974 g_object_unref (simple); 975 return; 976 } 977 978 if (!g_output_stream_set_pending (stream, &error)) 979 { 980 g_simple_async_report_gerror_in_idle (G_OBJECT (stream), 981 callback, 982 user_data, 983 error); 984 g_error_free (error); 985 return; 986 } 987 988 class = G_OUTPUT_STREAM_GET_CLASS (stream); 989 stream->priv->outstanding_callback = callback; 990 g_object_ref (stream); 991 class->close_async (stream, io_priority, cancellable, 992 async_ready_close_callback_wrapper, user_data); 993 } 994 995 /** 996 * g_output_stream_close_finish: 997 * @stream: a #GOutputStream. 998 * @result: a #GAsyncResult. 999 * @error: a #GError location to store the error occuring, or %NULL to 1000 * ignore. 1001 * 1002 * Closes an output stream. 1003 * 1004 * Returns: %TRUE if stream was successfully closed, %FALSE otherwise. 1005 **/ 1006 gboolean 1007 g_output_stream_close_finish (GOutputStream *stream, 1008 GAsyncResult *result, 1009 GError **error) 1010 { 1011 GSimpleAsyncResult *simple; 1012 GOutputStreamClass *class; 1013 1014 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); 1015 g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE); 1016 1017 if (G_IS_SIMPLE_ASYNC_RESULT (result)) 1018 { 1019 simple = G_SIMPLE_ASYNC_RESULT (result); 1020 if (g_simple_async_result_propagate_error (simple, error)) 1021 return FALSE; 1022 1023 /* Special case already closed */ 1024 if (g_simple_async_result_get_source_tag (simple) == g_output_stream_close_async) 1025 return TRUE; 1026 } 1027 1028 class = G_OUTPUT_STREAM_GET_CLASS (stream); 1029 return class->close_finish (stream, result, error); 1030 } 1031 1032 /** 1033 * g_output_stream_is_closed: 1034 * @stream: a #GOutputStream. 1035 * 1036 * Checks if an output stream has already been closed. 1037 * 1038 * Returns: %TRUE if @stream is closed. %FALSE otherwise. 1039 **/ 1040 gboolean 1041 g_output_stream_is_closed (GOutputStream *stream) 1042 { 1043 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), TRUE); 1044 1045 return stream->priv->closed; 1046 } 1047 1048 /** 1049 * g_output_stream_has_pending: 1050 * @stream: a #GOutputStream. 1051 * 1052 * Checks if an ouput stream has pending actions. 1053 * 1054 * Returns: %TRUE if @stream has pending actions. 1055 **/ 1056 gboolean 1057 g_output_stream_has_pending (GOutputStream *stream) 1058 { 1059 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); 1060 1061 return stream->priv->pending; 1062 } 1063 1064 /** 1065 * g_output_stream_set_pending: 1066 * @stream: a #GOutputStream. 1067 * @error: a #GError location to store the error occuring, or %NULL to 1068 * ignore. 1069 * 1070 * Sets @stream to have actions pending. If the pending flag is 1071 * already set or @stream is closed, it will return %FALSE and set 1072 * @error. 1073 * 1074 * Return value: %TRUE if pending was previously unset and is now set. 1075 **/ 1076 gboolean 1077 g_output_stream_set_pending (GOutputStream *stream, 1078 GError **error) 1079 { 1080 g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); 1081 1082 if (stream->priv->closed) 1083 { 1084 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED, 1085 _("Stream is already closed")); 1086 return FALSE; 1087 } 1088 1089 if (stream->priv->pending) 1090 { 1091 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING, 1092 /* Translators: This is an error you get if there is 1093 * already an operation running against this stream when 1094 * you try to start one */ 1095 _("Stream has outstanding operation")); 1096 return FALSE; 1097 } 1098 1099 stream->priv->pending = TRUE; 1100 return TRUE; 1101 } 1102 1103 /** 1104 * g_output_stream_clear_pending: 1105 * @stream: output stream 1106 * 1107 * Clears the pending flag on @stream. 1108 **/ 1109 void 1110 g_output_stream_clear_pending (GOutputStream *stream) 1111 { 1112 g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); 1113 1114 stream->priv->pending = FALSE; 1115 } 1116 1117 1118 /******************************************** 1119 * Default implementation of async ops * 1120 ********************************************/ 1121 1122 typedef struct { 1123 const void *buffer; 1124 gsize count_requested; 1125 gssize count_written; 1126 } WriteData; 1127 1128 static void 1129 write_async_thread (GSimpleAsyncResult *res, 1130 GObject *object, 1131 GCancellable *cancellable) 1132 { 1133 WriteData *op; 1134 GOutputStreamClass *class; 1135 GError *error = NULL; 1136 1137 class = G_OUTPUT_STREAM_GET_CLASS (object); 1138 op = g_simple_async_result_get_op_res_gpointer (res); 1139 op->count_written = class->write_fn (G_OUTPUT_STREAM (object), op->buffer, op->count_requested, 1140 cancellable, &error); 1141 if (op->count_written == -1) 1142 { 1143 g_simple_async_result_set_from_error (res, error); 1144 g_error_free (error); 1145 } 1146 } 1147 1148 static void 1149 g_output_stream_real_write_async (GOutputStream *stream, 1150 const void *buffer, 1151 gsize count, 1152 int io_priority, 1153 GCancellable *cancellable, 1154 GAsyncReadyCallback callback, 1155 gpointer user_data) 1156 { 1157 GSimpleAsyncResult *res; 1158 WriteData *op; 1159 1160 op = g_new0 (WriteData, 1); 1161 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async); 1162 g_simple_async_result_set_op_res_gpointer (res, op, g_free); 1163 op->buffer = buffer; 1164 op->count_requested = count; 1165 1166 g_simple_async_result_run_in_thread (res, write_async_thread, io_priority, cancellable); 1167 g_object_unref (res); 1168 } 1169 1170 static gssize 1171 g_output_stream_real_write_finish (GOutputStream *stream, 1172 GAsyncResult *result, 1173 GError **error) 1174 { 1175 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); 1176 WriteData *op; 1177 1178 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_write_async); 1179 op = g_simple_async_result_get_op_res_gpointer (simple); 1180 return op->count_written; 1181 } 1182 1183 typedef struct { 1184 GInputStream *source; 1185 GOutputStreamSpliceFlags flags; 1186 gssize bytes_copied; 1187 } SpliceData; 1188 1189 static void 1190 splice_async_thread (GSimpleAsyncResult *result, 1191 GObject *object, 1192 GCancellable *cancellable) 1193 { 1194 SpliceData *op; 1195 GOutputStreamClass *class; 1196 GError *error = NULL; 1197 GOutputStream *stream; 1198 1199 stream = G_OUTPUT_STREAM (object); 1200 class = G_OUTPUT_STREAM_GET_CLASS (object); 1201 op = g_simple_async_result_get_op_res_gpointer (result); 1202 1203 op->bytes_copied = class->splice (stream, 1204 op->source, 1205 op->flags, 1206 cancellable, 1207 &error); 1208 if (op->bytes_copied == -1) 1209 { 1210 g_simple_async_result_set_from_error (result, error); 1211 g_error_free (error); 1212 } 1213 } 1214 1215 static void 1216 g_output_stream_real_splice_async (GOutputStream *stream, 1217 GInputStream *source, 1218 GOutputStreamSpliceFlags flags, 1219 int io_priority, 1220 GCancellable *cancellable, 1221 GAsyncReadyCallback callback, 1222 gpointer user_data) 1223 { 1224 GSimpleAsyncResult *res; 1225 SpliceData *op; 1226 1227 op = g_new0 (SpliceData, 1); 1228 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_splice_async); 1229 g_simple_async_result_set_op_res_gpointer (res, op, g_free); 1230 op->flags = flags; 1231 op->source = source; 1232 1233 /* TODO: In the case where both source and destintion have 1234 non-threadbased async calls we can use a true async copy here */ 1235 1236 g_simple_async_result_run_in_thread (res, splice_async_thread, io_priority, cancellable); 1237 g_object_unref (res); 1238 } 1239 1240 static gssize 1241 g_output_stream_real_splice_finish (GOutputStream *stream, 1242 GAsyncResult *result, 1243 GError **error) 1244 { 1245 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); 1246 SpliceData *op; 1247 1248 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_splice_async); 1249 op = g_simple_async_result_get_op_res_gpointer (simple); 1250 return op->bytes_copied; 1251 } 1252 1253 1254 static void 1255 flush_async_thread (GSimpleAsyncResult *res, 1256 GObject *object, 1257 GCancellable *cancellable) 1258 { 1259 GOutputStreamClass *class; 1260 gboolean result; 1261 GError *error = NULL; 1262 1263 class = G_OUTPUT_STREAM_GET_CLASS (object); 1264 result = TRUE; 1265 if (class->flush) 1266 result = class->flush (G_OUTPUT_STREAM (object), cancellable, &error); 1267 1268 if (!result) 1269 { 1270 g_simple_async_result_set_from_error (res, error); 1271 g_error_free (error); 1272 } 1273 } 1274 1275 static void 1276 g_output_stream_real_flush_async (GOutputStream *stream, 1277 int io_priority, 1278 GCancellable *cancellable, 1279 GAsyncReadyCallback callback, 1280 gpointer user_data) 1281 { 1282 GSimpleAsyncResult *res; 1283 1284 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_write_async); 1285 1286 g_simple_async_result_run_in_thread (res, flush_async_thread, io_priority, cancellable); 1287 g_object_unref (res); 1288 } 1289 1290 static gboolean 1291 g_output_stream_real_flush_finish (GOutputStream *stream, 1292 GAsyncResult *result, 1293 GError **error) 1294 { 1295 return TRUE; 1296 } 1297 1298 static void 1299 close_async_thread (GSimpleAsyncResult *res, 1300 GObject *object, 1301 GCancellable *cancellable) 1302 { 1303 GOutputStreamClass *class; 1304 GError *error = NULL; 1305 gboolean result; 1306 1307 /* Auto handling of cancelation disabled, and ignore 1308 cancellation, since we want to close things anyway, although 1309 possibly in a quick-n-dirty way. At least we never want to leak 1310 open handles */ 1311 1312 class = G_OUTPUT_STREAM_GET_CLASS (object); 1313 result = class->close_fn (G_OUTPUT_STREAM (object), cancellable, &error); 1314 if (!result) 1315 { 1316 g_simple_async_result_set_from_error (res, error); 1317 g_error_free (error); 1318 } 1319 } 1320 1321 static void 1322 g_output_stream_real_close_async (GOutputStream *stream, 1323 int io_priority, 1324 GCancellable *cancellable, 1325 GAsyncReadyCallback callback, 1326 gpointer user_data) 1327 { 1328 GSimpleAsyncResult *res; 1329 1330 res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_output_stream_real_close_async); 1331 1332 g_simple_async_result_set_handle_cancellation (res, FALSE); 1333 1334 g_simple_async_result_run_in_thread (res, close_async_thread, io_priority, cancellable); 1335 g_object_unref (res); 1336 } 1337 1338 static gboolean 1339 g_output_stream_real_close_finish (GOutputStream *stream, 1340 GAsyncResult *result, 1341 GError **error) 1342 { 1343 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); 1344 g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_output_stream_real_close_async); 1345 return TRUE; 1346 } 1347 1348 #define __G_OUTPUT_STREAM_C__ 1349 #include "gioaliasdef.c" 1350