/3rd-party/glib-2.16.6/gio/goutputstream.c

https://bitbucket.org/super119/plu2youku · C · 1340 lines · 820 code · 182 blank · 338 comment · 92 complexity · 4da38cbb323355e5786dd59667ee4b86 MD5 · raw file

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