Coverage Report

Created: 2026-07-11 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/irssi/subprojects/glib-2.74.7/gio/ginputstream.c
Line
Count
Source
1
/* GIO - GLib Input, Output and Streaming Library
2
 * 
3
 * Copyright (C) 2006-2007 Red Hat, Inc.
4
 *
5
 * SPDX-License-Identifier: LGPL-2.1-or-later
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.1 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, see <http://www.gnu.org/licenses/>.
19
 *
20
 * Author: Alexander Larsson <alexl@redhat.com>
21
 */
22
23
#include "config.h"
24
#include <glib.h>
25
#include "glibintl.h"
26
27
#include "ginputstream.h"
28
#include "gioprivate.h"
29
#include "gseekable.h"
30
#include "gcancellable.h"
31
#include "gasyncresult.h"
32
#include "gioerror.h"
33
#include "gpollableinputstream.h"
34
35
/**
36
 * SECTION:ginputstream
37
 * @short_description: Base class for implementing streaming input
38
 * @include: gio/gio.h
39
 *
40
 * #GInputStream has functions to read from a stream (g_input_stream_read()),
41
 * to close a stream (g_input_stream_close()) and to skip some content
42
 * (g_input_stream_skip()). 
43
 *
44
 * To copy the content of an input stream to an output stream without 
45
 * manually handling the reads and writes, use g_output_stream_splice().
46
 *
47
 * See the documentation for #GIOStream for details of thread safety of
48
 * streaming APIs.
49
 *
50
 * All of these functions have async variants too.
51
 **/
52
53
struct _GInputStreamPrivate {
54
  guint closed : 1;
55
  guint pending : 1;
56
  GAsyncReadyCallback outstanding_callback;
57
};
58
59
0
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GInputStream, g_input_stream, G_TYPE_OBJECT)
60
0
61
0
static gssize   g_input_stream_real_skip         (GInputStream         *stream,
62
0
              gsize                 count,
63
0
              GCancellable         *cancellable,
64
0
              GError              **error);
65
0
static void     g_input_stream_real_read_async   (GInputStream         *stream,
66
0
              void                 *buffer,
67
0
              gsize                 count,
68
0
              int                   io_priority,
69
0
              GCancellable         *cancellable,
70
0
              GAsyncReadyCallback   callback,
71
0
              gpointer              user_data);
72
0
static gssize   g_input_stream_real_read_finish  (GInputStream         *stream,
73
0
              GAsyncResult         *result,
74
0
              GError              **error);
75
0
static void     g_input_stream_real_skip_async   (GInputStream         *stream,
76
0
              gsize                 count,
77
0
              int                   io_priority,
78
0
              GCancellable         *cancellable,
79
0
              GAsyncReadyCallback   callback,
80
0
              gpointer              data);
81
0
static gssize   g_input_stream_real_skip_finish  (GInputStream         *stream,
82
0
              GAsyncResult         *result,
83
0
              GError              **error);
84
0
static void     g_input_stream_real_close_async  (GInputStream         *stream,
85
0
              int                   io_priority,
86
0
              GCancellable         *cancellable,
87
0
              GAsyncReadyCallback   callback,
88
0
              gpointer              data);
89
0
static gboolean g_input_stream_real_close_finish (GInputStream         *stream,
90
0
              GAsyncResult         *result,
91
0
              GError              **error);
92
0
93
0
static void
94
0
g_input_stream_dispose (GObject *object)
95
0
{
96
0
  GInputStream *stream;
97
98
0
  stream = G_INPUT_STREAM (object);
99
  
100
0
  if (!stream->priv->closed)
101
0
    g_input_stream_close (stream, NULL, NULL);
102
103
0
  G_OBJECT_CLASS (g_input_stream_parent_class)->dispose (object);
104
0
}
105
106
107
static void
108
g_input_stream_class_init (GInputStreamClass *klass)
109
0
{
110
0
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
111
  
112
0
  gobject_class->dispose = g_input_stream_dispose;
113
  
114
0
  klass->skip = g_input_stream_real_skip;
115
0
  klass->read_async = g_input_stream_real_read_async;
116
0
  klass->read_finish = g_input_stream_real_read_finish;
117
0
  klass->skip_async = g_input_stream_real_skip_async;
118
0
  klass->skip_finish = g_input_stream_real_skip_finish;
119
0
  klass->close_async = g_input_stream_real_close_async;
120
0
  klass->close_finish = g_input_stream_real_close_finish;
121
0
}
122
123
static void
124
g_input_stream_init (GInputStream *stream)
125
0
{
126
0
  stream->priv = g_input_stream_get_instance_private (stream);
127
0
}
128
129
/**
130
 * g_input_stream_read:
131
 * @stream: a #GInputStream.
132
 * @buffer: (array length=count) (element-type guint8) (out caller-allocates):
133
 *     a buffer to read data into (which should be at least count bytes long).
134
 * @count: (in): the number of bytes that will be read from the stream
135
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
136
 * @error: location to store the error occurring, or %NULL to ignore
137
 *
138
 * Tries to read @count bytes from the stream into the buffer starting at
139
 * @buffer. Will block during this read.
140
 * 
141
 * If count is zero returns zero and does nothing. A value of @count
142
 * larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
143
 *
144
 * On success, the number of bytes read into the buffer is returned.
145
 * It is not an error if this is not the same as the requested size, as it
146
 * can happen e.g. near the end of a file. Zero is returned on end of file
147
 * (or if @count is zero),  but never otherwise.
148
 *
149
 * The returned @buffer is not a nul-terminated string, it can contain nul bytes
150
 * at any position, and this function doesn't nul-terminate the @buffer.
151
 *
152
 * If @cancellable is not %NULL, then the operation can be cancelled by
153
 * triggering the cancellable object from another thread. If the operation
154
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
155
 * operation was partially finished when the operation was cancelled the
156
 * partial result will be returned, without an error.
157
 *
158
 * On error -1 is returned and @error is set accordingly.
159
 * 
160
 * Returns: Number of bytes read, or -1 on error, or 0 on end of file.
161
 **/
162
gssize
163
g_input_stream_read  (GInputStream  *stream,
164
          void          *buffer,
165
          gsize          count,
166
          GCancellable  *cancellable,
167
          GError       **error)
168
0
{
169
0
  GInputStreamClass *class;
170
0
  gssize res;
171
172
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1);
173
0
  g_return_val_if_fail (buffer != NULL, 0);
174
175
0
  if (count == 0)
176
0
    return 0;
177
  
178
0
  if (((gssize) count) < 0)
179
0
    {
180
0
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
181
0
       _("Too large count value passed to %s"), G_STRFUNC);
182
0
      return -1;
183
0
    }
184
185
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
186
187
0
  if (class->read_fn == NULL) 
188
0
    {
189
0
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
190
0
                           _("Input stream doesn’t implement read"));
191
0
      return -1;
192
0
    }
193
194
0
  if (!g_input_stream_set_pending (stream, error))
195
0
    return -1;
196
197
0
  if (cancellable)
198
0
    g_cancellable_push_current (cancellable);
199
  
200
0
  res = class->read_fn (stream, buffer, count, cancellable, error);
201
202
0
  if (cancellable)
203
0
    g_cancellable_pop_current (cancellable);
204
  
205
0
  g_input_stream_clear_pending (stream);
206
207
0
  return res;
208
0
}
209
210
/**
211
 * g_input_stream_read_all:
212
 * @stream: a #GInputStream.
213
 * @buffer: (array length=count) (element-type guint8) (out caller-allocates):
214
 *     a buffer to read data into (which should be at least count bytes long).
215
 * @count: (in): the number of bytes that will be read from the stream
216
 * @bytes_read: (out): location to store the number of bytes that was read from the stream
217
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
218
 * @error: location to store the error occurring, or %NULL to ignore
219
 *
220
 * Tries to read @count bytes from the stream into the buffer starting at
221
 * @buffer. Will block during this read.
222
 *
223
 * This function is similar to g_input_stream_read(), except it tries to
224
 * read as many bytes as requested, only stopping on an error or end of stream.
225
 *
226
 * On a successful read of @count bytes, or if we reached the end of the
227
 * stream,  %TRUE is returned, and @bytes_read is set to the number of bytes
228
 * read into @buffer.
229
 * 
230
 * If there is an error during the operation %FALSE is returned and @error
231
 * is set to indicate the error status.
232
 *
233
 * As a special exception to the normal conventions for functions that
234
 * use #GError, if this function returns %FALSE (and sets @error) then
235
 * @bytes_read will be set to the number of bytes that were successfully
236
 * read before the error was encountered.  This functionality is only
237
 * available from C.  If you need it from another language then you must
238
 * write your own loop around g_input_stream_read().
239
 *
240
 * Returns: %TRUE on success, %FALSE if there was an error
241
 **/
242
gboolean
243
g_input_stream_read_all (GInputStream  *stream,
244
       void          *buffer,
245
       gsize          count,
246
       gsize         *bytes_read,
247
       GCancellable  *cancellable,
248
       GError       **error)
249
0
{
250
0
  gsize _bytes_read;
251
0
  gssize res;
252
253
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
254
0
  g_return_val_if_fail (buffer != NULL, FALSE);
255
256
0
  _bytes_read = 0;
257
0
  while (_bytes_read < count)
258
0
    {
259
0
      res = g_input_stream_read (stream, (char *)buffer + _bytes_read, count - _bytes_read,
260
0
         cancellable, error);
261
0
      if (res == -1)
262
0
  {
263
0
    if (bytes_read)
264
0
      *bytes_read = _bytes_read;
265
0
    return FALSE;
266
0
  }
267
      
268
0
      if (res == 0)
269
0
  break;
270
271
0
      _bytes_read += res;
272
0
    }
273
274
0
  if (bytes_read)
275
0
    *bytes_read = _bytes_read;
276
0
  return TRUE;
277
0
}
278
279
/**
280
 * g_input_stream_read_bytes:
281
 * @stream: a #GInputStream.
282
 * @count: maximum number of bytes that will be read from the stream. Common
283
 * values include 4096 and 8192.
284
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
285
 * @error: location to store the error occurring, or %NULL to ignore
286
 *
287
 * Like g_input_stream_read(), this tries to read @count bytes from
288
 * the stream in a blocking fashion. However, rather than reading into
289
 * a user-supplied buffer, this will create a new #GBytes containing
290
 * the data that was read. This may be easier to use from language
291
 * bindings.
292
 *
293
 * If count is zero, returns a zero-length #GBytes and does nothing. A
294
 * value of @count larger than %G_MAXSSIZE will cause a
295
 * %G_IO_ERROR_INVALID_ARGUMENT error.
296
 *
297
 * On success, a new #GBytes is returned. It is not an error if the
298
 * size of this object is not the same as the requested size, as it
299
 * can happen e.g. near the end of a file. A zero-length #GBytes is
300
 * returned on end of file (or if @count is zero), but never
301
 * otherwise.
302
 *
303
 * If @cancellable is not %NULL, then the operation can be cancelled by
304
 * triggering the cancellable object from another thread. If the operation
305
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
306
 * operation was partially finished when the operation was cancelled the
307
 * partial result will be returned, without an error.
308
 *
309
 * On error %NULL is returned and @error is set accordingly.
310
 *
311
 * Returns: (transfer full): a new #GBytes, or %NULL on error
312
 *
313
 * Since: 2.34
314
 **/
315
GBytes *
316
g_input_stream_read_bytes (GInputStream  *stream,
317
         gsize          count,
318
         GCancellable  *cancellable,
319
         GError       **error)
320
0
{
321
0
  guchar *buf;
322
0
  gssize nread;
323
324
0
  buf = g_malloc (count);
325
0
  nread = g_input_stream_read (stream, buf, count, cancellable, error);
326
0
  if (nread == -1)
327
0
    {
328
0
      g_free (buf);
329
0
      return NULL;
330
0
    }
331
0
  else if (nread == 0)
332
0
    {
333
0
      g_free (buf);
334
0
      return g_bytes_new_static ("", 0);
335
0
    }
336
0
  else
337
0
    return g_bytes_new_take (buf, nread);
338
0
}
339
340
/**
341
 * g_input_stream_skip:
342
 * @stream: a #GInputStream.
343
 * @count: the number of bytes that will be skipped from the stream
344
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. 
345
 * @error: location to store the error occurring, or %NULL to ignore
346
 *
347
 * Tries to skip @count bytes from the stream. Will block during the operation.
348
 *
349
 * This is identical to g_input_stream_read(), from a behaviour standpoint,
350
 * but the bytes that are skipped are not returned to the user. Some
351
 * streams have an implementation that is more efficient than reading the data.
352
 *
353
 * This function is optional for inherited classes, as the default implementation
354
 * emulates it using read.
355
 *
356
 * If @cancellable is not %NULL, then the operation can be cancelled by
357
 * triggering the cancellable object from another thread. If the operation
358
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. If an
359
 * operation was partially finished when the operation was cancelled the
360
 * partial result will be returned, without an error.
361
 *
362
 * Returns: Number of bytes skipped, or -1 on error
363
 **/
364
gssize
365
g_input_stream_skip (GInputStream  *stream,
366
         gsize          count,
367
         GCancellable  *cancellable,
368
         GError       **error)
369
0
{
370
0
  GInputStreamClass *class;
371
0
  gssize res;
372
373
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1);
374
375
0
  if (count == 0)
376
0
    return 0;
377
378
0
  if (((gssize) count) < 0)
379
0
    {
380
0
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
381
0
       _("Too large count value passed to %s"), G_STRFUNC);
382
0
      return -1;
383
0
    }
384
  
385
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
386
387
0
  if (!g_input_stream_set_pending (stream, error))
388
0
    return -1;
389
390
0
  if (cancellable)
391
0
    g_cancellable_push_current (cancellable);
392
  
393
0
  res = class->skip (stream, count, cancellable, error);
394
395
0
  if (cancellable)
396
0
    g_cancellable_pop_current (cancellable);
397
  
398
0
  g_input_stream_clear_pending (stream);
399
400
0
  return res;
401
0
}
402
403
static gssize
404
g_input_stream_real_skip (GInputStream  *stream,
405
        gsize          count,
406
        GCancellable  *cancellable,
407
        GError       **error)
408
0
{
409
0
  GInputStreamClass *class;
410
0
  gssize ret, read_bytes;
411
0
  char buffer[8192];
412
0
  GError *my_error;
413
414
0
  if (G_IS_SEEKABLE (stream) && g_seekable_can_seek (G_SEEKABLE (stream)))
415
0
    {
416
0
      GSeekable *seekable = G_SEEKABLE (stream);
417
0
      goffset start, end;
418
0
      gboolean success;
419
420
      /* g_seekable_seek() may try to set pending itself */
421
0
      stream->priv->pending = FALSE;
422
423
0
      start = g_seekable_tell (seekable);
424
425
0
      if (g_seekable_seek (G_SEEKABLE (stream),
426
0
                           0,
427
0
                           G_SEEK_END,
428
0
                           cancellable,
429
0
                           NULL))
430
0
        {
431
0
          end = g_seekable_tell (seekable);
432
0
          g_assert (start >= 0);
433
0
          g_assert (end >= start);
434
0
          if (start > (goffset) (G_MAXOFFSET - count) ||
435
0
              (goffset) (start + count) > end)
436
0
            {
437
0
              stream->priv->pending = TRUE;
438
0
              return end - start;
439
0
            }
440
441
0
          success = g_seekable_seek (G_SEEKABLE (stream),
442
0
                                     start + count,
443
0
                                     G_SEEK_SET,
444
0
                                     cancellable,
445
0
                                     error);
446
0
          stream->priv->pending = TRUE;
447
448
0
          if (success)
449
0
            return count;
450
0
          else
451
0
            return -1;
452
0
        }
453
0
    }
454
455
  /* If not seekable, or seek failed, fall back to reading data: */
456
457
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
458
459
0
  read_bytes = 0;
460
0
  while (1)
461
0
    {
462
0
      my_error = NULL;
463
464
0
      ret = class->read_fn (stream, buffer, MIN (sizeof (buffer), count),
465
0
                            cancellable, &my_error);
466
0
      if (ret == -1)
467
0
  {
468
0
    if (read_bytes > 0 &&
469
0
        my_error->domain == G_IO_ERROR &&
470
0
        my_error->code == G_IO_ERROR_CANCELLED)
471
0
      {
472
0
        g_error_free (my_error);
473
0
        return read_bytes;
474
0
      }
475
476
0
    g_propagate_error (error, my_error);
477
0
    return -1;
478
0
  }
479
480
0
      count -= ret;
481
0
      read_bytes += ret;
482
483
0
      if (ret == 0 || count == 0)
484
0
        return read_bytes;
485
0
    }
486
0
}
487
488
/**
489
 * g_input_stream_close:
490
 * @stream: A #GInputStream.
491
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
492
 * @error: location to store the error occurring, or %NULL to ignore
493
 *
494
 * Closes the stream, releasing resources related to it.
495
 *
496
 * Once the stream is closed, all other operations will return %G_IO_ERROR_CLOSED.
497
 * Closing a stream multiple times will not return an error.
498
 *
499
 * Streams will be automatically closed when the last reference
500
 * is dropped, but you might want to call this function to make sure 
501
 * resources are released as early as possible.
502
 *
503
 * Some streams might keep the backing store of the stream (e.g. a file descriptor)
504
 * open after the stream is closed. See the documentation for the individual
505
 * stream for details.
506
 *
507
 * On failure the first error that happened will be reported, but the close
508
 * operation will finish as much as possible. A stream that failed to
509
 * close will still return %G_IO_ERROR_CLOSED for all operations. Still, it
510
 * is important to check and report the error to the user.
511
 *
512
 * If @cancellable is not %NULL, then the operation can be cancelled by
513
 * triggering the cancellable object from another thread. If the operation
514
 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
515
 * Cancelling a close will still leave the stream closed, but some streams
516
 * can use a faster close that doesn't block to e.g. check errors. 
517
 *
518
 * Returns: %TRUE on success, %FALSE on failure
519
 **/
520
gboolean
521
g_input_stream_close (GInputStream  *stream,
522
          GCancellable  *cancellable,
523
          GError       **error)
524
0
{
525
0
  GInputStreamClass *class;
526
0
  gboolean res;
527
528
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
529
530
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
531
532
0
  if (stream->priv->closed)
533
0
    return TRUE;
534
535
0
  res = TRUE;
536
537
0
  if (!g_input_stream_set_pending (stream, error))
538
0
    return FALSE;
539
540
0
  if (cancellable)
541
0
    g_cancellable_push_current (cancellable);
542
543
0
  if (class->close_fn)
544
0
    res = class->close_fn (stream, cancellable, error);
545
546
0
  if (cancellable)
547
0
    g_cancellable_pop_current (cancellable);
548
549
0
  g_input_stream_clear_pending (stream);
550
  
551
0
  stream->priv->closed = TRUE;
552
  
553
0
  return res;
554
0
}
555
556
static void
557
async_ready_callback_wrapper (GObject      *source_object,
558
            GAsyncResult *res,
559
            gpointer      user_data)
560
0
{
561
0
  GInputStream *stream = G_INPUT_STREAM (source_object);
562
563
0
  g_input_stream_clear_pending (stream);
564
0
  if (stream->priv->outstanding_callback)
565
0
    (*stream->priv->outstanding_callback) (source_object, res, user_data);
566
0
  g_object_unref (stream);
567
0
}
568
569
static void
570
async_ready_close_callback_wrapper (GObject      *source_object,
571
            GAsyncResult *res,
572
            gpointer      user_data)
573
0
{
574
0
  GInputStream *stream = G_INPUT_STREAM (source_object);
575
576
0
  g_input_stream_clear_pending (stream);
577
0
  stream->priv->closed = TRUE;
578
0
  if (stream->priv->outstanding_callback)
579
0
    (*stream->priv->outstanding_callback) (source_object, res, user_data);
580
0
  g_object_unref (stream);
581
0
}
582
583
/**
584
 * g_input_stream_read_async:
585
 * @stream: A #GInputStream.
586
 * @buffer: (array length=count) (element-type guint8) (out caller-allocates):
587
 *     a buffer to read data into (which should be at least count bytes long).
588
 * @count: (in): the number of bytes that will be read from the stream
589
 * @io_priority: the [I/O priority][io-priority]
590
 * of the request. 
591
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
592
 * @callback: (scope async): callback to call when the request is satisfied
593
 * @user_data: (closure): the data to pass to callback function
594
 *
595
 * Request an asynchronous read of @count bytes from the stream into the buffer
596
 * starting at @buffer. When the operation is finished @callback will be called. 
597
 * You can then call g_input_stream_read_finish() to get the result of the 
598
 * operation.
599
 *
600
 * During an async request no other sync and async calls are allowed on @stream, and will
601
 * result in %G_IO_ERROR_PENDING errors. 
602
 *
603
 * A value of @count larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
604
 *
605
 * On success, the number of bytes read into the buffer will be passed to the
606
 * callback. It is not an error if this is not the same as the requested size, as it
607
 * can happen e.g. near the end of a file, but generally we try to read
608
 * as many bytes as requested. Zero is returned on end of file
609
 * (or if @count is zero),  but never otherwise.
610
 *
611
 * Any outstanding i/o request with higher priority (lower numerical value) will
612
 * be executed before an outstanding request with lower priority. Default
613
 * priority is %G_PRIORITY_DEFAULT.
614
 *
615
 * The asynchronous methods have a default fallback that uses threads to implement
616
 * asynchronicity, so they are optional for inheriting classes. However, if you
617
 * override one you must override all.
618
 **/
619
void
620
g_input_stream_read_async (GInputStream        *stream,
621
         void                *buffer,
622
         gsize                count,
623
         int                  io_priority,
624
         GCancellable        *cancellable,
625
         GAsyncReadyCallback  callback,
626
         gpointer             user_data)
627
0
{
628
0
  GInputStreamClass *class;
629
0
  GError *error = NULL;
630
631
0
  g_return_if_fail (G_IS_INPUT_STREAM (stream));
632
0
  g_return_if_fail (buffer != NULL);
633
634
0
  if (count == 0)
635
0
    {
636
0
      GTask *task;
637
638
0
      task = g_task_new (stream, cancellable, callback, user_data);
639
0
      g_task_set_source_tag (task, g_input_stream_read_async);
640
0
      g_task_return_int (task, 0);
641
0
      g_object_unref (task);
642
0
      return;
643
0
    }
644
  
645
0
  if (((gssize) count) < 0)
646
0
    {
647
0
      g_task_report_new_error (stream, callback, user_data,
648
0
                               g_input_stream_read_async,
649
0
                               G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
650
0
                               _("Too large count value passed to %s"),
651
0
                               G_STRFUNC);
652
0
      return;
653
0
    }
654
655
0
  if (!g_input_stream_set_pending (stream, &error))
656
0
    {
657
0
      g_task_report_error (stream, callback, user_data,
658
0
                           g_input_stream_read_async,
659
0
                           error);
660
0
      return;
661
0
    }
662
663
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
664
0
  stream->priv->outstanding_callback = callback;
665
0
  g_object_ref (stream);
666
0
  class->read_async (stream, buffer, count, io_priority, cancellable,
667
0
         async_ready_callback_wrapper, user_data);
668
0
}
669
670
/**
671
 * g_input_stream_read_finish:
672
 * @stream: a #GInputStream.
673
 * @result: a #GAsyncResult.
674
 * @error: a #GError location to store the error occurring, or %NULL to 
675
 * ignore.
676
 * 
677
 * Finishes an asynchronous stream read operation. 
678
 * 
679
 * Returns: number of bytes read in, or -1 on error, or 0 on end of file.
680
 **/
681
gssize
682
g_input_stream_read_finish (GInputStream  *stream,
683
          GAsyncResult  *result,
684
          GError       **error)
685
0
{
686
0
  GInputStreamClass *class;
687
  
688
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1);
689
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
690
691
0
  if (g_async_result_legacy_propagate_error (result, error))
692
0
    return -1;
693
0
  else if (g_async_result_is_tagged (result, g_input_stream_read_async))
694
0
    return g_task_propagate_int (G_TASK (result), error);
695
696
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
697
0
  return class->read_finish (stream, result, error);
698
0
}
699
700
typedef struct
701
{
702
  gchar *buffer;
703
  gsize to_read;
704
  gsize bytes_read;
705
} AsyncReadAll;
706
707
static void
708
free_async_read_all (gpointer data)
709
0
{
710
0
  g_slice_free (AsyncReadAll, data);
711
0
}
712
713
static void
714
read_all_callback (GObject      *stream,
715
                   GAsyncResult *result,
716
                   gpointer      user_data)
717
0
{
718
0
  GTask *task = user_data;
719
0
  AsyncReadAll *data = g_task_get_task_data (task);
720
0
  gboolean got_eof = FALSE;
721
722
0
  if (result)
723
0
    {
724
0
      GError *error = NULL;
725
0
      gssize nread;
726
727
0
      nread = g_input_stream_read_finish (G_INPUT_STREAM (stream), result, &error);
728
729
0
      if (nread == -1)
730
0
        {
731
0
          g_task_return_error (task, error);
732
0
          g_object_unref (task);
733
0
          return;
734
0
        }
735
736
0
      g_assert_cmpint (nread, <=, data->to_read);
737
0
      data->to_read -= nread;
738
0
      data->bytes_read += nread;
739
0
      got_eof = (nread == 0);
740
0
    }
741
742
0
  if (got_eof || data->to_read == 0)
743
0
    {
744
0
      g_task_return_boolean (task, TRUE);
745
0
      g_object_unref (task);
746
0
    }
747
748
0
  else
749
0
    g_input_stream_read_async (G_INPUT_STREAM (stream),
750
0
                               data->buffer + data->bytes_read,
751
0
                               data->to_read,
752
0
                               g_task_get_priority (task),
753
0
                               g_task_get_cancellable (task),
754
0
                               read_all_callback, task);
755
0
}
756
757
758
static void
759
read_all_async_thread (GTask        *task,
760
                       gpointer      source_object,
761
                       gpointer      task_data,
762
                       GCancellable *cancellable)
763
0
{
764
0
  GInputStream *stream = source_object;
765
0
  AsyncReadAll *data = task_data;
766
0
  GError *error = NULL;
767
768
0
  if (g_input_stream_read_all (stream, data->buffer, data->to_read, &data->bytes_read,
769
0
                               g_task_get_cancellable (task), &error))
770
0
    g_task_return_boolean (task, TRUE);
771
0
  else
772
0
    g_task_return_error (task, error);
773
0
}
774
775
/**
776
 * g_input_stream_read_all_async:
777
 * @stream: A #GInputStream
778
 * @buffer: (array length=count) (element-type guint8) (out caller-allocates):
779
 *     a buffer to read data into (which should be at least count bytes long)
780
 * @count: (in): the number of bytes that will be read from the stream
781
 * @io_priority: the [I/O priority][io-priority] of the request
782
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore
783
 * @callback: (scope async): callback to call when the request is satisfied
784
 * @user_data: (closure): the data to pass to callback function
785
 *
786
 * Request an asynchronous read of @count bytes from the stream into the
787
 * buffer starting at @buffer.
788
 *
789
 * This is the asynchronous equivalent of g_input_stream_read_all().
790
 *
791
 * Call g_input_stream_read_all_finish() to collect the result.
792
 *
793
 * Any outstanding I/O request with higher priority (lower numerical
794
 * value) will be executed before an outstanding request with lower
795
 * priority. Default priority is %G_PRIORITY_DEFAULT.
796
 *
797
 * Since: 2.44
798
 **/
799
void
800
g_input_stream_read_all_async (GInputStream        *stream,
801
                               void                *buffer,
802
                               gsize                count,
803
                               int                  io_priority,
804
                               GCancellable        *cancellable,
805
                               GAsyncReadyCallback  callback,
806
                               gpointer             user_data)
807
0
{
808
0
  AsyncReadAll *data;
809
0
  GTask *task;
810
811
0
  g_return_if_fail (G_IS_INPUT_STREAM (stream));
812
0
  g_return_if_fail (buffer != NULL || count == 0);
813
814
0
  task = g_task_new (stream, cancellable, callback, user_data);
815
0
  data = g_slice_new0 (AsyncReadAll);
816
0
  data->buffer = buffer;
817
0
  data->to_read = count;
818
819
0
  g_task_set_source_tag (task, g_input_stream_read_all_async);
820
0
  g_task_set_task_data (task, data, free_async_read_all);
821
0
  g_task_set_priority (task, io_priority);
822
823
  /* If async reads are going to be handled via the threadpool anyway
824
   * then we may as well do it with a single dispatch instead of
825
   * bouncing in and out.
826
   */
827
0
  if (g_input_stream_async_read_is_via_threads (stream))
828
0
    {
829
0
      g_task_run_in_thread (task, read_all_async_thread);
830
0
      g_object_unref (task);
831
0
    }
832
0
  else
833
0
    read_all_callback (G_OBJECT (stream), NULL, task);
834
0
}
835
836
/**
837
 * g_input_stream_read_all_finish:
838
 * @stream: a #GInputStream
839
 * @result: a #GAsyncResult
840
 * @bytes_read: (out): location to store the number of bytes that was read from the stream
841
 * @error: a #GError location to store the error occurring, or %NULL to ignore
842
 *
843
 * Finishes an asynchronous stream read operation started with
844
 * g_input_stream_read_all_async().
845
 *
846
 * As a special exception to the normal conventions for functions that
847
 * use #GError, if this function returns %FALSE (and sets @error) then
848
 * @bytes_read will be set to the number of bytes that were successfully
849
 * read before the error was encountered.  This functionality is only
850
 * available from C.  If you need it from another language then you must
851
 * write your own loop around g_input_stream_read_async().
852
 *
853
 * Returns: %TRUE on success, %FALSE if there was an error
854
 *
855
 * Since: 2.44
856
 **/
857
gboolean
858
g_input_stream_read_all_finish (GInputStream  *stream,
859
                                GAsyncResult  *result,
860
                                gsize         *bytes_read,
861
                                GError       **error)
862
0
{
863
0
  GTask *task;
864
865
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
866
0
  g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
867
868
0
  task = G_TASK (result);
869
870
0
  if (bytes_read)
871
0
    {
872
0
      AsyncReadAll *data = g_task_get_task_data (task);
873
874
0
      *bytes_read = data->bytes_read;
875
0
    }
876
877
0
  return g_task_propagate_boolean (task, error);
878
0
}
879
880
static void
881
read_bytes_callback (GObject      *stream,
882
         GAsyncResult *result,
883
         gpointer      user_data)
884
0
{
885
0
  GTask *task = user_data;
886
0
  guchar *buf = g_task_get_task_data (task);
887
0
  GError *error = NULL;
888
0
  gssize nread;
889
0
  GBytes *bytes = NULL;
890
891
0
  nread = g_input_stream_read_finish (G_INPUT_STREAM (stream),
892
0
              result, &error);
893
0
  if (nread == -1)
894
0
    {
895
0
      g_free (buf);
896
0
      g_task_return_error (task, error);
897
0
    }
898
0
  else if (nread == 0)
899
0
    {
900
0
      g_free (buf);
901
0
      bytes = g_bytes_new_static ("", 0);
902
0
    }
903
0
  else
904
0
    bytes = g_bytes_new_take (buf, nread);
905
906
0
  if (bytes)
907
0
    g_task_return_pointer (task, bytes, (GDestroyNotify)g_bytes_unref);
908
909
0
  g_object_unref (task);
910
0
}
911
912
/**
913
 * g_input_stream_read_bytes_async:
914
 * @stream: A #GInputStream.
915
 * @count: the number of bytes that will be read from the stream
916
 * @io_priority: the [I/O priority][io-priority] of the request
917
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
918
 * @callback: (scope async): callback to call when the request is satisfied
919
 * @user_data: (closure): the data to pass to callback function
920
 *
921
 * Request an asynchronous read of @count bytes from the stream into a
922
 * new #GBytes. When the operation is finished @callback will be
923
 * called. You can then call g_input_stream_read_bytes_finish() to get the
924
 * result of the operation.
925
 *
926
 * During an async request no other sync and async calls are allowed
927
 * on @stream, and will result in %G_IO_ERROR_PENDING errors.
928
 *
929
 * A value of @count larger than %G_MAXSSIZE will cause a
930
 * %G_IO_ERROR_INVALID_ARGUMENT error.
931
 *
932
 * On success, the new #GBytes will be passed to the callback. It is
933
 * not an error if this is smaller than the requested size, as it can
934
 * happen e.g. near the end of a file, but generally we try to read as
935
 * many bytes as requested. Zero is returned on end of file (or if
936
 * @count is zero), but never otherwise.
937
 *
938
 * Any outstanding I/O request with higher priority (lower numerical
939
 * value) will be executed before an outstanding request with lower
940
 * priority. Default priority is %G_PRIORITY_DEFAULT.
941
 *
942
 * Since: 2.34
943
 **/
944
void
945
g_input_stream_read_bytes_async (GInputStream          *stream,
946
         gsize                  count,
947
         int                    io_priority,
948
         GCancellable          *cancellable,
949
         GAsyncReadyCallback    callback,
950
         gpointer               user_data)
951
0
{
952
0
  GTask *task;
953
0
  guchar *buf;
954
955
0
  task = g_task_new (stream, cancellable, callback, user_data);
956
0
  g_task_set_source_tag (task, g_input_stream_read_bytes_async);
957
958
0
  buf = g_malloc (count);
959
0
  g_task_set_task_data (task, buf, NULL);
960
961
0
  g_input_stream_read_async (stream, buf, count,
962
0
                             io_priority, cancellable,
963
0
                             read_bytes_callback, task);
964
0
}
965
966
/**
967
 * g_input_stream_read_bytes_finish:
968
 * @stream: a #GInputStream.
969
 * @result: a #GAsyncResult.
970
 * @error: a #GError location to store the error occurring, or %NULL to
971
 *   ignore.
972
 *
973
 * Finishes an asynchronous stream read-into-#GBytes operation.
974
 *
975
 * Returns: (transfer full): the newly-allocated #GBytes, or %NULL on error
976
 *
977
 * Since: 2.34
978
 **/
979
GBytes *
980
g_input_stream_read_bytes_finish (GInputStream  *stream,
981
          GAsyncResult  *result,
982
          GError       **error)
983
0
{
984
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL);
985
0
  g_return_val_if_fail (g_task_is_valid (result, stream), NULL);
986
987
0
  return g_task_propagate_pointer (G_TASK (result), error);
988
0
}
989
990
/**
991
 * g_input_stream_skip_async:
992
 * @stream: A #GInputStream.
993
 * @count: the number of bytes that will be skipped from the stream
994
 * @io_priority: the [I/O priority][io-priority] of the request
995
 * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore.
996
 * @callback: (scope async): callback to call when the request is satisfied
997
 * @user_data: (closure): the data to pass to callback function
998
 *
999
 * Request an asynchronous skip of @count bytes from the stream.
1000
 * When the operation is finished @callback will be called.
1001
 * You can then call g_input_stream_skip_finish() to get the result
1002
 * of the operation.
1003
 *
1004
 * During an async request no other sync and async calls are allowed,
1005
 * and will result in %G_IO_ERROR_PENDING errors.
1006
 *
1007
 * A value of @count larger than %G_MAXSSIZE will cause a %G_IO_ERROR_INVALID_ARGUMENT error.
1008
 *
1009
 * On success, the number of bytes skipped will be passed to the callback.
1010
 * It is not an error if this is not the same as the requested size, as it
1011
 * can happen e.g. near the end of a file, but generally we try to skip
1012
 * as many bytes as requested. Zero is returned on end of file
1013
 * (or if @count is zero), but never otherwise.
1014
 *
1015
 * Any outstanding i/o request with higher priority (lower numerical value)
1016
 * will be executed before an outstanding request with lower priority.
1017
 * Default priority is %G_PRIORITY_DEFAULT.
1018
 *
1019
 * The asynchronous methods have a default fallback that uses threads to
1020
 * implement asynchronicity, so they are optional for inheriting classes.
1021
 * However, if you override one, you must override all.
1022
 **/
1023
void
1024
g_input_stream_skip_async (GInputStream        *stream,
1025
         gsize                count,
1026
         int                  io_priority,
1027
         GCancellable        *cancellable,
1028
         GAsyncReadyCallback  callback,
1029
         gpointer             user_data)
1030
0
{
1031
0
  GInputStreamClass *class;
1032
0
  GError *error = NULL;
1033
1034
0
  g_return_if_fail (G_IS_INPUT_STREAM (stream));
1035
1036
0
  if (count == 0)
1037
0
    {
1038
0
      GTask *task;
1039
1040
0
      task = g_task_new (stream, cancellable, callback, user_data);
1041
0
      g_task_set_source_tag (task, g_input_stream_skip_async);
1042
0
      g_task_return_int (task, 0);
1043
0
      g_object_unref (task);
1044
0
      return;
1045
0
    }
1046
  
1047
0
  if (((gssize) count) < 0)
1048
0
    {
1049
0
      g_task_report_new_error (stream, callback, user_data,
1050
0
                               g_input_stream_skip_async,
1051
0
                               G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
1052
0
                               _("Too large count value passed to %s"),
1053
0
                               G_STRFUNC);
1054
0
      return;
1055
0
    }
1056
1057
0
  if (!g_input_stream_set_pending (stream, &error))
1058
0
    {
1059
0
      g_task_report_error (stream, callback, user_data,
1060
0
                           g_input_stream_skip_async,
1061
0
                           error);
1062
0
      return;
1063
0
    }
1064
1065
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
1066
0
  stream->priv->outstanding_callback = callback;
1067
0
  g_object_ref (stream);
1068
0
  class->skip_async (stream, count, io_priority, cancellable,
1069
0
         async_ready_callback_wrapper, user_data);
1070
0
}
1071
1072
/**
1073
 * g_input_stream_skip_finish:
1074
 * @stream: a #GInputStream.
1075
 * @result: a #GAsyncResult.
1076
 * @error: a #GError location to store the error occurring, or %NULL to 
1077
 * ignore.
1078
 * 
1079
 * Finishes a stream skip operation.
1080
 * 
1081
 * Returns: the size of the bytes skipped, or `-1` on error.
1082
 **/
1083
gssize
1084
g_input_stream_skip_finish (GInputStream  *stream,
1085
          GAsyncResult  *result,
1086
          GError       **error)
1087
0
{
1088
0
  GInputStreamClass *class;
1089
1090
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), -1);
1091
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
1092
1093
0
  if (g_async_result_legacy_propagate_error (result, error))
1094
0
    return -1;
1095
0
  else if (g_async_result_is_tagged (result, g_input_stream_skip_async))
1096
0
    return g_task_propagate_int (G_TASK (result), error);
1097
1098
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
1099
0
  return class->skip_finish (stream, result, error);
1100
0
}
1101
1102
/**
1103
 * g_input_stream_close_async:
1104
 * @stream: A #GInputStream.
1105
 * @io_priority: the [I/O priority][io-priority] of the request
1106
 * @cancellable: (nullable): optional cancellable object
1107
 * @callback: (scope async): callback to call when the request is satisfied
1108
 * @user_data: (closure): the data to pass to callback function
1109
 *
1110
 * Requests an asynchronous closes of the stream, releasing resources related to it.
1111
 * When the operation is finished @callback will be called. 
1112
 * You can then call g_input_stream_close_finish() to get the result of the 
1113
 * operation.
1114
 *
1115
 * For behaviour details see g_input_stream_close().
1116
 *
1117
 * The asynchronous methods have a default fallback that uses threads to implement
1118
 * asynchronicity, so they are optional for inheriting classes. However, if you
1119
 * override one you must override all.
1120
 **/
1121
void
1122
g_input_stream_close_async (GInputStream        *stream,
1123
          int                  io_priority,
1124
          GCancellable        *cancellable,
1125
          GAsyncReadyCallback  callback,
1126
          gpointer             user_data)
1127
0
{
1128
0
  GInputStreamClass *class;
1129
0
  GError *error = NULL;
1130
1131
0
  g_return_if_fail (G_IS_INPUT_STREAM (stream));
1132
1133
0
  if (stream->priv->closed)
1134
0
    {
1135
0
      GTask *task;
1136
1137
0
      task = g_task_new (stream, cancellable, callback, user_data);
1138
0
      g_task_set_source_tag (task, g_input_stream_close_async);
1139
0
      g_task_return_boolean (task, TRUE);
1140
0
      g_object_unref (task);
1141
0
      return;
1142
0
    }
1143
1144
0
  if (!g_input_stream_set_pending (stream, &error))
1145
0
    {
1146
0
      g_task_report_error (stream, callback, user_data,
1147
0
                           g_input_stream_close_async,
1148
0
                           error);
1149
0
      return;
1150
0
    }
1151
  
1152
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
1153
0
  stream->priv->outstanding_callback = callback;
1154
0
  g_object_ref (stream);
1155
0
  class->close_async (stream, io_priority, cancellable,
1156
0
          async_ready_close_callback_wrapper, user_data);
1157
0
}
1158
1159
/**
1160
 * g_input_stream_close_finish:
1161
 * @stream: a #GInputStream.
1162
 * @result: a #GAsyncResult.
1163
 * @error: a #GError location to store the error occurring, or %NULL to 
1164
 * ignore.
1165
 * 
1166
 * Finishes closing a stream asynchronously, started from g_input_stream_close_async().
1167
 * 
1168
 * Returns: %TRUE if the stream was closed successfully.
1169
 **/
1170
gboolean
1171
g_input_stream_close_finish (GInputStream  *stream,
1172
           GAsyncResult  *result,
1173
           GError       **error)
1174
0
{
1175
0
  GInputStreamClass *class;
1176
1177
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
1178
0
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
1179
1180
0
  if (g_async_result_legacy_propagate_error (result, error))
1181
0
    return FALSE;
1182
0
  else if (g_async_result_is_tagged (result, g_input_stream_close_async))
1183
0
    return g_task_propagate_boolean (G_TASK (result), error);
1184
1185
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
1186
0
  return class->close_finish (stream, result, error);
1187
0
}
1188
1189
/**
1190
 * g_input_stream_is_closed:
1191
 * @stream: input stream.
1192
 * 
1193
 * Checks if an input stream is closed.
1194
 * 
1195
 * Returns: %TRUE if the stream is closed.
1196
 **/
1197
gboolean
1198
g_input_stream_is_closed (GInputStream *stream)
1199
0
{
1200
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), TRUE);
1201
  
1202
0
  return stream->priv->closed;
1203
0
}
1204
 
1205
/**
1206
 * g_input_stream_has_pending:
1207
 * @stream: input stream.
1208
 * 
1209
 * Checks if an input stream has pending actions.
1210
 * 
1211
 * Returns: %TRUE if @stream has pending actions.
1212
 **/  
1213
gboolean
1214
g_input_stream_has_pending (GInputStream *stream)
1215
0
{
1216
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), TRUE);
1217
  
1218
0
  return stream->priv->pending;
1219
0
}
1220
1221
/**
1222
 * g_input_stream_set_pending:
1223
 * @stream: input stream
1224
 * @error: a #GError location to store the error occurring, or %NULL to 
1225
 * ignore.
1226
 * 
1227
 * Sets @stream to have actions pending. If the pending flag is
1228
 * already set or @stream is closed, it will return %FALSE and set
1229
 * @error.
1230
 *
1231
 * Returns: %TRUE if pending was previously unset and is now set.
1232
 **/
1233
gboolean
1234
g_input_stream_set_pending (GInputStream *stream, GError **error)
1235
0
{
1236
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
1237
  
1238
0
  if (stream->priv->closed)
1239
0
    {
1240
0
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
1241
0
                           _("Stream is already closed"));
1242
0
      return FALSE;
1243
0
    }
1244
  
1245
0
  if (stream->priv->pending)
1246
0
    {
1247
0
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
1248
    /* Translators: This is an error you get if there is already an
1249
     * operation running against this stream when you try to start
1250
     * one */
1251
0
     _("Stream has outstanding operation"));
1252
0
      return FALSE;
1253
0
    }
1254
  
1255
0
  stream->priv->pending = TRUE;
1256
0
  return TRUE;
1257
0
}
1258
1259
/**
1260
 * g_input_stream_clear_pending:
1261
 * @stream: input stream
1262
 * 
1263
 * Clears the pending flag on @stream.
1264
 **/
1265
void
1266
g_input_stream_clear_pending (GInputStream *stream)
1267
0
{
1268
0
  g_return_if_fail (G_IS_INPUT_STREAM (stream));
1269
  
1270
0
  stream->priv->pending = FALSE;
1271
0
}
1272
1273
/*< internal >
1274
 * g_input_stream_async_read_is_via_threads:
1275
 * @stream: input stream
1276
 *
1277
 * Checks if an input stream's read_async function uses threads.
1278
 *
1279
 * Returns: %TRUE if @stream's read_async function uses threads.
1280
 **/
1281
gboolean
1282
g_input_stream_async_read_is_via_threads (GInputStream *stream)
1283
0
{
1284
0
  GInputStreamClass *class;
1285
1286
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
1287
1288
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
1289
1290
0
  return (class->read_async == g_input_stream_real_read_async &&
1291
0
      !(G_IS_POLLABLE_INPUT_STREAM (stream) &&
1292
0
        g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (stream))));
1293
0
}
1294
1295
/*< internal >
1296
 * g_input_stream_async_close_is_via_threads:
1297
 * @stream: input stream
1298
 *
1299
 * Checks if an input stream's close_async function uses threads.
1300
 *
1301
 * Returns: %TRUE if @stream's close_async function uses threads.
1302
 **/
1303
gboolean
1304
g_input_stream_async_close_is_via_threads (GInputStream *stream)
1305
0
{
1306
0
  GInputStreamClass *class;
1307
1308
0
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
1309
1310
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
1311
1312
0
  return class->close_async == g_input_stream_real_close_async;
1313
0
}
1314
1315
/********************************************
1316
 *   Default implementation of async ops    *
1317
 ********************************************/
1318
1319
typedef struct {
1320
  void   *buffer;
1321
  gsize   count;
1322
} ReadData;
1323
1324
static void
1325
free_read_data (ReadData *op)
1326
0
{
1327
0
  g_slice_free (ReadData, op);
1328
0
}
1329
1330
static void
1331
read_async_thread (GTask        *task,
1332
                   gpointer      source_object,
1333
                   gpointer      task_data,
1334
                   GCancellable *cancellable)
1335
0
{
1336
0
  GInputStream *stream = source_object;
1337
0
  ReadData *op = task_data;
1338
0
  GInputStreamClass *class;
1339
0
  GError *error = NULL;
1340
0
  gssize nread;
1341
 
1342
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
1343
1344
0
  nread = class->read_fn (stream,
1345
0
                          op->buffer, op->count,
1346
0
                          g_task_get_cancellable (task),
1347
0
                          &error);
1348
0
  if (nread == -1)
1349
0
    g_task_return_error (task, error);
1350
0
  else
1351
0
    g_task_return_int (task, nread);
1352
0
}
1353
1354
static void read_async_pollable (GPollableInputStream *stream,
1355
                                 GTask                *task);
1356
1357
static gboolean
1358
read_async_pollable_ready (GPollableInputStream *stream,
1359
         gpointer              user_data)
1360
0
{
1361
0
  GTask *task = user_data;
1362
1363
0
  read_async_pollable (stream, task);
1364
0
  return FALSE;
1365
0
}
1366
1367
static void
1368
read_async_pollable (GPollableInputStream *stream,
1369
                     GTask                *task)
1370
0
{
1371
0
  ReadData *op = g_task_get_task_data (task);
1372
0
  GError *error = NULL;
1373
0
  gssize nread;
1374
1375
0
  if (g_task_return_error_if_cancelled (task))
1376
0
    return;
1377
1378
0
  nread = G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)->
1379
0
    read_nonblocking (stream, op->buffer, op->count, &error);
1380
1381
0
  if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
1382
0
    {
1383
0
      GSource *source;
1384
1385
0
      g_error_free (error);
1386
1387
0
      source = g_pollable_input_stream_create_source (stream,
1388
0
                                                      g_task_get_cancellable (task));
1389
0
      g_task_attach_source (task, source,
1390
0
                            (GSourceFunc) read_async_pollable_ready);
1391
0
      g_source_unref (source);
1392
0
      return;
1393
0
    }
1394
1395
0
  if (nread == -1)
1396
0
    g_task_return_error (task, error);
1397
0
  else
1398
0
    g_task_return_int (task, nread);
1399
  /* g_input_stream_real_read_async() unrefs task */
1400
0
}
1401
1402
1403
static void
1404
g_input_stream_real_read_async (GInputStream        *stream,
1405
        void                *buffer,
1406
        gsize                count,
1407
        int                  io_priority,
1408
        GCancellable        *cancellable,
1409
        GAsyncReadyCallback  callback,
1410
        gpointer             user_data)
1411
0
{
1412
0
  GTask *task;
1413
0
  ReadData *op;
1414
  
1415
0
  op = g_slice_new0 (ReadData);
1416
0
  task = g_task_new (stream, cancellable, callback, user_data);
1417
0
  g_task_set_source_tag (task, g_input_stream_real_read_async);
1418
0
  g_task_set_task_data (task, op, (GDestroyNotify) free_read_data);
1419
0
  g_task_set_priority (task, io_priority);
1420
0
  op->buffer = buffer;
1421
0
  op->count = count;
1422
1423
0
  if (!g_input_stream_async_read_is_via_threads (stream))
1424
0
    read_async_pollable (G_POLLABLE_INPUT_STREAM (stream), task);
1425
0
  else
1426
0
    g_task_run_in_thread (task, read_async_thread);
1427
0
  g_object_unref (task);
1428
0
}
1429
1430
static gssize
1431
g_input_stream_real_read_finish (GInputStream  *stream,
1432
         GAsyncResult  *result,
1433
         GError       **error)
1434
0
{
1435
0
  g_return_val_if_fail (g_task_is_valid (result, stream), -1);
1436
1437
0
  return g_task_propagate_int (G_TASK (result), error);
1438
0
}
1439
1440
1441
static void
1442
skip_async_thread (GTask        *task,
1443
                   gpointer      source_object,
1444
                   gpointer      task_data,
1445
                   GCancellable *cancellable)
1446
0
{
1447
0
  GInputStream *stream = source_object;
1448
0
  gsize count = GPOINTER_TO_SIZE (task_data);
1449
0
  GInputStreamClass *class;
1450
0
  GError *error = NULL;
1451
0
  gssize ret;
1452
1453
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
1454
0
  ret = class->skip (stream, count,
1455
0
                     g_task_get_cancellable (task),
1456
0
                     &error);
1457
0
  if (ret == -1)
1458
0
    g_task_return_error (task, error);
1459
0
  else
1460
0
    g_task_return_int (task, ret);
1461
0
}
1462
1463
typedef struct {
1464
  char buffer[8192];
1465
  gsize count;
1466
  gsize count_skipped;
1467
} SkipFallbackAsyncData;
1468
1469
static void
1470
skip_callback_wrapper (GObject      *source_object,
1471
           GAsyncResult *res,
1472
           gpointer      user_data)
1473
0
{
1474
0
  GInputStreamClass *class;
1475
0
  GTask *task = user_data;
1476
0
  SkipFallbackAsyncData *data = g_task_get_task_data (task);
1477
0
  GError *error = NULL;
1478
0
  gssize ret;
1479
1480
0
  ret = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error);
1481
1482
0
  if (ret > 0)
1483
0
    {
1484
0
      data->count -= ret;
1485
0
      data->count_skipped += ret;
1486
1487
0
      if (data->count > 0)
1488
0
  {
1489
0
    class = G_INPUT_STREAM_GET_CLASS (source_object);
1490
0
    class->read_async (G_INPUT_STREAM (source_object),
1491
0
                             data->buffer, MIN (8192, data->count),
1492
0
                             g_task_get_priority (task),
1493
0
                             g_task_get_cancellable (task),
1494
0
                             skip_callback_wrapper, task);
1495
0
    return;
1496
0
  }
1497
0
    }
1498
1499
0
  if (ret == -1 &&
1500
0
      g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
1501
0
      data->count_skipped)
1502
0
    {
1503
      /* No error, return partial read */
1504
0
      g_clear_error (&error);
1505
0
    }
1506
1507
0
  if (error)
1508
0
    g_task_return_error (task, error);
1509
0
  else
1510
0
    g_task_return_int (task, data->count_skipped);
1511
0
  g_object_unref (task);
1512
0
 }
1513
1514
static void
1515
g_input_stream_real_skip_async (GInputStream        *stream,
1516
        gsize                count,
1517
        int                  io_priority,
1518
        GCancellable        *cancellable,
1519
        GAsyncReadyCallback  callback,
1520
        gpointer             user_data)
1521
0
{
1522
0
  GInputStreamClass *class;
1523
0
  SkipFallbackAsyncData *data;
1524
0
  GTask *task;
1525
1526
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
1527
1528
0
  task = g_task_new (stream, cancellable, callback, user_data);
1529
0
  g_task_set_source_tag (task, g_input_stream_real_skip_async);
1530
0
  g_task_set_priority (task, io_priority);
1531
1532
0
  if (g_input_stream_async_read_is_via_threads (stream))
1533
0
    {
1534
      /* Read is thread-using async fallback.
1535
       * Make skip use threads too, so that we can use a possible sync skip
1536
       * implementation. */
1537
0
      g_task_set_task_data (task, GSIZE_TO_POINTER (count), NULL);
1538
1539
0
      g_task_run_in_thread (task, skip_async_thread);
1540
0
      g_object_unref (task);
1541
0
    }
1542
0
  else
1543
0
    {
1544
      /* TODO: Skip fallback uses too much memory, should do multiple read calls */
1545
      
1546
      /* There is a custom async read function, lets use that. */
1547
0
      data = g_new (SkipFallbackAsyncData, 1);
1548
0
      data->count = count;
1549
0
      data->count_skipped = 0;
1550
0
      g_task_set_task_data (task, data, g_free);
1551
0
      g_task_set_check_cancellable (task, FALSE);
1552
0
      class->read_async (stream, data->buffer, MIN (8192, count), io_priority, cancellable,
1553
0
       skip_callback_wrapper, task);
1554
0
    }
1555
1556
0
}
1557
1558
static gssize
1559
g_input_stream_real_skip_finish (GInputStream  *stream,
1560
         GAsyncResult  *result,
1561
         GError       **error)
1562
0
{
1563
0
  g_return_val_if_fail (g_task_is_valid (result, stream), -1);
1564
1565
0
  return g_task_propagate_int (G_TASK (result), error);
1566
0
}
1567
1568
static void
1569
close_async_thread (GTask        *task,
1570
                    gpointer      source_object,
1571
                    gpointer      task_data,
1572
                    GCancellable *cancellable)
1573
0
{
1574
0
  GInputStream *stream = source_object;
1575
0
  GInputStreamClass *class;
1576
0
  GError *error = NULL;
1577
0
  gboolean result;
1578
1579
0
  class = G_INPUT_STREAM_GET_CLASS (stream);
1580
0
  if (class->close_fn)
1581
0
    {
1582
0
      result = class->close_fn (stream,
1583
0
                                g_task_get_cancellable (task),
1584
0
                                &error);
1585
0
      if (!result)
1586
0
        {
1587
0
          g_task_return_error (task, error);
1588
0
          return;
1589
0
        }
1590
0
    }
1591
1592
0
  g_task_return_boolean (task, TRUE);
1593
0
}
1594
1595
static void
1596
g_input_stream_real_close_async (GInputStream        *stream,
1597
         int                  io_priority,
1598
         GCancellable        *cancellable,
1599
         GAsyncReadyCallback  callback,
1600
         gpointer             user_data)
1601
0
{
1602
0
  GTask *task;
1603
1604
0
  task = g_task_new (stream, cancellable, callback, user_data);
1605
0
  g_task_set_source_tag (task, g_input_stream_real_close_async);
1606
0
  g_task_set_check_cancellable (task, FALSE);
1607
0
  g_task_set_priority (task, io_priority);
1608
  
1609
0
  g_task_run_in_thread (task, close_async_thread);
1610
0
  g_object_unref (task);
1611
0
}
1612
1613
static gboolean
1614
g_input_stream_real_close_finish (GInputStream  *stream,
1615
          GAsyncResult  *result,
1616
          GError       **error)
1617
0
{
1618
0
  g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
1619
1620
0
  return g_task_propagate_boolean (G_TASK (result), error);
1621
0
}