~ubuntu-branches/debian/sid/glib2.0/sid

« back to all changes in this revision

Viewing changes to gio/gbufferedinputstream.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2013-05-08 06:25:57 UTC
  • mfrom: (1.27.14) (3.1.181 experimental)
  • Revision ID: package-import@ubuntu.com-20130508062557-i7gbku66mls70gi2
Tags: 2.36.1-2
Merge experimental branch, upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include "ginputstream.h"
27
27
#include "gcancellable.h"
28
28
#include "gasyncresult.h"
29
 
#include "gsimpleasyncresult.h"
 
29
#include "gtask.h"
 
30
#include "gseekable.h"
30
31
#include "gioerror.h"
31
32
#include <string.h>
32
33
#include "glibintl.h"
100
101
                                                        gsize                  count,
101
102
                                                        GCancellable          *cancellable,
102
103
                                                        GError               **error);
103
 
static void   g_buffered_input_stream_read_async       (GInputStream          *stream,
104
 
                                                        void                  *buffer,
105
 
                                                        gsize                  count,
106
 
                                                        int                    io_priority,
107
 
                                                        GCancellable          *cancellable,
108
 
                                                        GAsyncReadyCallback    callback,
109
 
                                                        gpointer               user_data);
110
 
static gssize g_buffered_input_stream_read_finish      (GInputStream          *stream,
111
 
                                                        GAsyncResult          *result,
112
 
                                                        GError               **error);
113
104
static gssize g_buffered_input_stream_real_fill        (GBufferedInputStream  *stream,
114
105
                                                        gssize                 count,
115
106
                                                        GCancellable          *cancellable,
124
115
                                                        GAsyncResult          *result,
125
116
                                                        GError               **error);
126
117
 
 
118
static void     g_buffered_input_stream_seekable_iface_init (GSeekableIface  *iface);
 
119
static goffset  g_buffered_input_stream_tell                (GSeekable       *seekable);
 
120
static gboolean g_buffered_input_stream_can_seek            (GSeekable       *seekable);
 
121
static gboolean g_buffered_input_stream_seek                (GSeekable       *seekable,
 
122
                                                             goffset          offset,
 
123
                                                             GSeekType        type,
 
124
                                                             GCancellable    *cancellable,
 
125
                                                             GError         **error);
 
126
static gboolean g_buffered_input_stream_can_truncate        (GSeekable       *seekable);
 
127
static gboolean g_buffered_input_stream_truncate            (GSeekable       *seekable,
 
128
                                                             goffset          offset,
 
129
                                                             GCancellable    *cancellable,
 
130
                                                             GError         **error);
 
131
 
 
132
static void     g_buffered_input_stream_finalize            (GObject         *object);
 
133
 
127
134
static void compact_buffer (GBufferedInputStream *stream);
128
135
 
129
 
G_DEFINE_TYPE (GBufferedInputStream,
130
 
               g_buffered_input_stream,
131
 
               G_TYPE_FILTER_INPUT_STREAM)
132
 
 
 
136
G_DEFINE_TYPE_WITH_CODE (GBufferedInputStream,
 
137
                         g_buffered_input_stream,
 
138
                         G_TYPE_FILTER_INPUT_STREAM,
 
139
                         G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE,
 
140
                                                g_buffered_input_stream_seekable_iface_init))
133
141
 
134
142
static void
135
143
g_buffered_input_stream_class_init (GBufferedInputStreamClass *klass)
150
158
  istream_class->skip_async  = g_buffered_input_stream_skip_async;
151
159
  istream_class->skip_finish = g_buffered_input_stream_skip_finish;
152
160
  istream_class->read_fn = g_buffered_input_stream_read;
153
 
  istream_class->read_async  = g_buffered_input_stream_read_async;
154
 
  istream_class->read_finish = g_buffered_input_stream_read_finish;
155
161
 
156
162
  bstream_class = G_BUFFERED_INPUT_STREAM_CLASS (klass);
157
163
  bstream_class->fill = g_buffered_input_stream_real_fill;
299
305
}
300
306
 
301
307
static void
 
308
g_buffered_input_stream_seekable_iface_init (GSeekableIface *iface)
 
309
{
 
310
  iface->tell         = g_buffered_input_stream_tell;
 
311
  iface->can_seek     = g_buffered_input_stream_can_seek;
 
312
  iface->seek         = g_buffered_input_stream_seek;
 
313
  iface->can_truncate = g_buffered_input_stream_can_truncate;
 
314
  iface->truncate_fn  = g_buffered_input_stream_truncate;
 
315
}
 
316
 
 
317
static void
302
318
g_buffered_input_stream_init (GBufferedInputStream *stream)
303
319
{
304
320
  stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
467
483
                                    gpointer              user_data)
468
484
{
469
485
  GBufferedInputStreamClass *class;
470
 
  GSimpleAsyncResult *simple;
471
486
  GError *error = NULL;
472
487
 
473
488
  g_return_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream));
474
489
 
475
490
  if (count == 0)
476
491
    {
477
 
      simple = g_simple_async_result_new (G_OBJECT (stream),
478
 
                                          callback,
479
 
                                          user_data,
480
 
                                          g_buffered_input_stream_fill_async);
481
 
      g_simple_async_result_complete_in_idle (simple);
482
 
      g_object_unref (simple);
 
492
      GTask *task;
 
493
 
 
494
      task = g_task_new (stream, cancellable, callback, user_data);
 
495
      g_task_set_source_tag (task, g_buffered_input_stream_fill_async);
 
496
      g_task_return_int (task, 0);
 
497
      g_object_unref (task);
483
498
      return;
484
499
    }
485
500
 
486
501
  if (count < -1)
487
502
    {
488
 
      g_simple_async_report_error_in_idle (G_OBJECT (stream),
489
 
                                           callback,
490
 
                                           user_data,
491
 
                                           G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
492
 
                                           _("Too large count value passed to %s"),
493
 
                                           G_STRFUNC);
 
503
      g_task_report_new_error (stream, callback, user_data,
 
504
                               g_buffered_input_stream_fill_async,
 
505
                               G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
 
506
                               _("Too large count value passed to %s"),
 
507
                               G_STRFUNC);
494
508
      return;
495
509
    }
496
510
 
497
511
  if (!g_input_stream_set_pending (G_INPUT_STREAM (stream), &error))
498
512
    {
499
 
      g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
500
 
                                            callback,
501
 
                                            user_data,
502
 
                                            error);
 
513
      g_task_report_error (stream, callback, user_data,
 
514
                           g_buffered_input_stream_fill_async,
 
515
                           error);
503
516
      return;
504
517
    }
505
518
 
526
539
                                     GAsyncResult          *result,
527
540
                                     GError               **error)
528
541
{
529
 
  GSimpleAsyncResult *simple;
530
542
  GBufferedInputStreamClass *class;
531
543
 
532
544
  g_return_val_if_fail (G_IS_BUFFERED_INPUT_STREAM (stream), -1);
533
545
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), -1);
534
546
 
535
 
  if (G_IS_SIMPLE_ASYNC_RESULT (result))
536
 
    {
537
 
      simple = G_SIMPLE_ASYNC_RESULT (result);
538
 
      if (g_simple_async_result_propagate_error (simple, error))
539
 
        return -1;
540
 
 
541
 
      /* Special case read of 0 bytes */
542
 
      if (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_fill_async)
543
 
        return 0;
544
 
    }
 
547
  if (g_async_result_legacy_propagate_error (result, error))
 
548
    return -1;
 
549
  else if (g_async_result_is_tagged (result, g_buffered_input_stream_fill_async))
 
550
    return g_task_propagate_int (G_TASK (result), error);
545
551
 
546
552
  class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
547
553
  return class->fill_finish (stream, result, error);
838
844
  return bytes_read;
839
845
}
840
846
 
 
847
static goffset
 
848
g_buffered_input_stream_tell (GSeekable *seekable)
 
849
{
 
850
  GBufferedInputStream        *bstream;
 
851
  GBufferedInputStreamPrivate *priv;
 
852
  GInputStream *base_stream;
 
853
  GSeekable    *base_stream_seekable;
 
854
  gsize available;
 
855
  goffset base_offset;
 
856
  
 
857
  bstream = G_BUFFERED_INPUT_STREAM (seekable);
 
858
  priv = bstream->priv;
 
859
 
 
860
  base_stream = G_FILTER_INPUT_STREAM (seekable)->base_stream;
 
861
  if (!G_IS_SEEKABLE (base_stream))
 
862
    return 0;
 
863
  base_stream_seekable = G_SEEKABLE (base_stream);
 
864
  
 
865
  available = priv->end - priv->pos;
 
866
  base_offset = g_seekable_tell (base_stream_seekable);
 
867
 
 
868
  return base_offset - available;
 
869
}
 
870
 
 
871
static gboolean
 
872
g_buffered_input_stream_can_seek (GSeekable *seekable)
 
873
{
 
874
  GInputStream *base_stream;
 
875
  
 
876
  base_stream = G_FILTER_INPUT_STREAM (seekable)->base_stream;
 
877
  return G_IS_SEEKABLE (base_stream) && g_seekable_can_seek (G_SEEKABLE (base_stream));
 
878
}
 
879
 
 
880
static gboolean
 
881
g_buffered_input_stream_seek (GSeekable     *seekable,
 
882
                              goffset        offset,
 
883
                              GSeekType      type,
 
884
                              GCancellable  *cancellable,
 
885
                              GError       **error)
 
886
{
 
887
  GBufferedInputStream        *bstream;
 
888
  GBufferedInputStreamPrivate *priv;
 
889
  GInputStream *base_stream;
 
890
  GSeekable *base_stream_seekable;
 
891
 
 
892
  bstream = G_BUFFERED_INPUT_STREAM (seekable);
 
893
  priv = bstream->priv;
 
894
 
 
895
  base_stream = G_FILTER_INPUT_STREAM (seekable)->base_stream;
 
896
  if (!G_IS_SEEKABLE (base_stream))
 
897
    {
 
898
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 
899
                           _("Seek not supported on base stream"));
 
900
      return FALSE;
 
901
    }
 
902
 
 
903
  base_stream_seekable = G_SEEKABLE (base_stream);
 
904
  
 
905
  if (type == G_SEEK_CUR)
 
906
    {
 
907
      if (offset <= priv->end - priv->pos && offset >= -priv->pos)
 
908
        {
 
909
          priv->pos += offset;
 
910
          return TRUE;
 
911
        }
 
912
      else
 
913
        {
 
914
          offset -= priv->end - priv->pos;
 
915
        }
 
916
    }
 
917
 
 
918
  if (g_seekable_seek (base_stream_seekable, offset, type, cancellable, error))
 
919
    {
 
920
      priv->pos = 0;
 
921
      priv->end = 0;
 
922
      return TRUE;
 
923
    }
 
924
  else
 
925
    {
 
926
      return FALSE;
 
927
    }
 
928
}
 
929
 
 
930
static gboolean
 
931
g_buffered_input_stream_can_truncate (GSeekable *seekable)
 
932
{
 
933
  return FALSE;
 
934
}
 
935
 
 
936
static gboolean
 
937
g_buffered_input_stream_truncate (GSeekable     *seekable,
 
938
                                  goffset        offset,
 
939
                                  GCancellable  *cancellable,
 
940
                                  GError       **error)
 
941
{
 
942
  g_set_error_literal (error,
 
943
                       G_IO_ERROR,
 
944
                       G_IO_ERROR_NOT_SUPPORTED,
 
945
                       _("Cannot truncate GBufferedInputStream"));
 
946
  return FALSE;
 
947
}
 
948
 
841
949
/**
842
950
 * g_buffered_input_stream_read_byte:
843
951
 * @stream: a #GBufferedInputStream
927
1035
{
928
1036
  GError *error;
929
1037
  gssize res;
930
 
  GSimpleAsyncResult *simple;
931
 
 
932
 
  simple = user_data;
 
1038
  GTask *task = user_data;
933
1039
 
934
1040
  error = NULL;
935
1041
  res = g_input_stream_read_finish (G_INPUT_STREAM (source_object),
936
1042
                                    result, &error);
937
 
 
938
 
  g_simple_async_result_set_op_res_gssize (simple, res);
939
1043
  if (res == -1)
940
 
    {
941
 
      g_simple_async_result_take_error (simple, error);
942
 
    }
 
1044
    g_task_return_error (task, error);
943
1045
  else
944
1046
    {
 
1047
      GBufferedInputStream *stream;
945
1048
      GBufferedInputStreamPrivate *priv;
946
 
      GObject *object;
947
1049
 
948
 
      object = g_async_result_get_source_object (G_ASYNC_RESULT (simple));
949
 
      priv = G_BUFFERED_INPUT_STREAM (object)->priv;
 
1050
      stream = g_task_get_source_object (task);
 
1051
      priv = G_BUFFERED_INPUT_STREAM (stream)->priv;
950
1052
 
951
1053
      g_assert_cmpint (priv->end + res, <=, priv->len);
952
1054
      priv->end += res;
953
1055
 
954
 
      g_object_unref (object);
 
1056
      g_task_return_int (task, res);
955
1057
    }
956
1058
 
957
 
  /* Complete immediately, not in idle, since we're already
958
 
   * in a mainloop callout
959
 
   */
960
 
  g_simple_async_result_complete (simple);
961
 
  g_object_unref (simple);
 
1059
  g_object_unref (task);
962
1060
}
963
1061
 
964
1062
static void
971
1069
{
972
1070
  GBufferedInputStreamPrivate *priv;
973
1071
  GInputStream *base_stream;
974
 
  GSimpleAsyncResult *simple;
 
1072
  GTask *task;
975
1073
  gsize in_buffer;
976
1074
 
977
1075
  priv = stream->priv;
988
1086
  if (priv->len - priv->end < count)
989
1087
    compact_buffer (stream);
990
1088
 
991
 
  simple = g_simple_async_result_new (G_OBJECT (stream),
992
 
                                      callback, user_data,
993
 
                                      g_buffered_input_stream_real_fill_async);
 
1089
  task = g_task_new (stream, cancellable, callback, user_data);
994
1090
 
995
1091
  base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
996
1092
  g_input_stream_read_async (base_stream,
999
1095
                             io_priority,
1000
1096
                             cancellable,
1001
1097
                             fill_async_callback,
1002
 
                             simple);
 
1098
                             task);
1003
1099
}
1004
1100
 
1005
1101
static gssize
1007
1103
                                          GAsyncResult         *result,
1008
1104
                                          GError              **error)
1009
1105
{
1010
 
  GSimpleAsyncResult *simple;
1011
 
  gssize nread;
1012
 
 
1013
 
  simple = G_SIMPLE_ASYNC_RESULT (result);
1014
 
  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_real_fill_async);
1015
 
 
1016
 
  nread = g_simple_async_result_get_op_res_gssize (simple);
1017
 
  return nread;
1018
 
}
1019
 
 
1020
 
typedef struct
1021
 
{
1022
 
  gssize bytes_read;
1023
 
  gssize count;
1024
 
  void *buffer;
1025
 
} ReadAsyncData;
1026
 
 
1027
 
static void
1028
 
free_read_async_data (gpointer _data)
1029
 
{
1030
 
  ReadAsyncData *data = _data;
1031
 
  g_slice_free (ReadAsyncData, data);
1032
 
}
1033
 
 
1034
 
static void
1035
 
large_read_callback (GObject *source_object,
1036
 
                     GAsyncResult *result,
1037
 
                     gpointer user_data)
1038
 
{
1039
 
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
1040
 
  ReadAsyncData *data;
1041
 
  GError *error;
1042
 
  gssize nread;
1043
 
 
1044
 
  data = g_simple_async_result_get_op_res_gpointer (simple);
1045
 
 
1046
 
  error = NULL;
1047
 
  nread = g_input_stream_read_finish (G_INPUT_STREAM (source_object),
1048
 
                                      result, &error);
1049
 
 
1050
 
  /* Only report the error if we've not already read some data */
1051
 
  if (nread < 0 && data->bytes_read == 0)
1052
 
    g_simple_async_result_take_error (simple, error);
1053
 
  else if (error)
1054
 
    g_error_free (error);
1055
 
 
1056
 
  if (nread > 0)
1057
 
    data->bytes_read += nread;
1058
 
 
1059
 
  /* Complete immediately, not in idle, since we're already
1060
 
   * in a mainloop callout
1061
 
   */
1062
 
  g_simple_async_result_complete (simple);
1063
 
  g_object_unref (simple);
1064
 
}
1065
 
 
1066
 
static void
1067
 
read_fill_buffer_callback (GObject      *source_object,
1068
 
                           GAsyncResult *result,
1069
 
                           gpointer      user_data)
1070
 
{
1071
 
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
1072
 
  GBufferedInputStream *bstream;
1073
 
  GBufferedInputStreamPrivate *priv;
1074
 
  ReadAsyncData *data;
1075
 
  GError *error;
1076
 
  gssize nread;
1077
 
  gsize available;
1078
 
 
1079
 
  bstream = G_BUFFERED_INPUT_STREAM (source_object);
1080
 
  priv = bstream->priv;
1081
 
 
1082
 
  data = g_simple_async_result_get_op_res_gpointer (simple);
1083
 
 
1084
 
  error = NULL;
1085
 
  nread = g_buffered_input_stream_fill_finish (bstream,
1086
 
                                               result, &error);
1087
 
 
1088
 
  if (nread < 0 && data->bytes_read == 0)
1089
 
    g_simple_async_result_take_error (simple, error);
1090
 
  else if (error)
1091
 
    g_error_free (error);
1092
 
 
1093
 
  if (nread > 0)
1094
 
    {
1095
 
      available = priv->end - priv->pos;
1096
 
      data->count = MIN (data->count, available);
1097
 
 
1098
 
      memcpy ((char *)data->buffer + data->bytes_read, (char *)priv->buffer + priv->pos, data->count);
1099
 
      data->bytes_read += data->count;
1100
 
      priv->pos += data->count;
1101
 
    }
1102
 
 
1103
 
  /* Complete immediately, not in idle, since we're already
1104
 
   * in a mainloop callout
1105
 
   */
1106
 
  g_simple_async_result_complete (simple);
1107
 
  g_object_unref (simple);
1108
 
}
1109
 
 
1110
 
static void
1111
 
g_buffered_input_stream_read_async (GInputStream        *stream,
1112
 
                                    void                *buffer,
1113
 
                                    gsize                count,
1114
 
                                    int                  io_priority,
1115
 
                                    GCancellable        *cancellable,
1116
 
                                    GAsyncReadyCallback  callback,
1117
 
                                    gpointer             user_data)
1118
 
{
1119
 
  GBufferedInputStream *bstream;
1120
 
  GBufferedInputStreamPrivate *priv;
1121
 
  GBufferedInputStreamClass *class;
1122
 
  GInputStream *base_stream;
1123
 
  gsize available;
1124
 
  GSimpleAsyncResult *simple;
1125
 
  ReadAsyncData *data;
1126
 
 
1127
 
  bstream = G_BUFFERED_INPUT_STREAM (stream);
1128
 
  priv = bstream->priv;
1129
 
 
1130
 
  data = g_slice_new (ReadAsyncData);
1131
 
  data->buffer = buffer;
1132
 
  data->bytes_read = 0;
1133
 
  simple = g_simple_async_result_new (G_OBJECT (stream),
1134
 
                                      callback, user_data,
1135
 
                                      g_buffered_input_stream_read_async);
1136
 
  g_simple_async_result_set_op_res_gpointer (simple, data, free_read_async_data);
1137
 
 
1138
 
  available = priv->end - priv->pos;
1139
 
 
1140
 
  if (count <= available)
1141
 
    {
1142
 
      memcpy (buffer, priv->buffer + priv->pos, count);
1143
 
      priv->pos += count;
1144
 
      data->bytes_read = count;
1145
 
 
1146
 
      g_simple_async_result_complete_in_idle (simple);
1147
 
      g_object_unref (simple);
1148
 
      return;
1149
 
    }
1150
 
 
1151
 
 
1152
 
  /* Full request not available, read all currently available
1153
 
   * and request refill for more
1154
 
   */
1155
 
 
1156
 
  memcpy (buffer, priv->buffer + priv->pos, available);
1157
 
  priv->pos = 0;
1158
 
  priv->end = 0;
1159
 
 
1160
 
  count -= available;
1161
 
 
1162
 
  data->bytes_read = available;
1163
 
  data->count = count;
1164
 
 
1165
 
  if (count > priv->len)
1166
 
    {
1167
 
      /* Large request, shortcut buffer */
1168
 
 
1169
 
      base_stream = G_FILTER_INPUT_STREAM (stream)->base_stream;
1170
 
 
1171
 
      g_input_stream_read_async (base_stream,
1172
 
                                 (char *)buffer + data->bytes_read,
1173
 
                                 count,
1174
 
                                 io_priority, cancellable,
1175
 
                                 large_read_callback,
1176
 
                                 simple);
1177
 
    }
1178
 
  else
1179
 
    {
1180
 
      class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
1181
 
      class->fill_async (bstream, priv->len, io_priority, cancellable,
1182
 
                         read_fill_buffer_callback, simple);
1183
 
    }
1184
 
}
1185
 
 
1186
 
static gssize
1187
 
g_buffered_input_stream_read_finish (GInputStream   *stream,
1188
 
                                     GAsyncResult   *result,
1189
 
                                     GError        **error)
1190
 
{
1191
 
  GSimpleAsyncResult *simple;
1192
 
  ReadAsyncData *data;
1193
 
 
1194
 
  simple = G_SIMPLE_ASYNC_RESULT (result);
1195
 
 
1196
 
  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_read_async);
1197
 
 
1198
 
  data = g_simple_async_result_get_op_res_gpointer (simple);
1199
 
 
1200
 
  return data->bytes_read;
 
1106
  g_return_val_if_fail (g_task_is_valid (result, stream), -1);
 
1107
 
 
1108
  return g_task_propagate_int (G_TASK (result), error);
1201
1109
}
1202
1110
 
1203
1111
typedef struct
1218
1126
                     GAsyncResult *result,
1219
1127
                     gpointer      user_data)
1220
1128
{
1221
 
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
 
1129
  GTask *task = G_TASK (user_data);
1222
1130
  SkipAsyncData *data;
1223
1131
  GError *error;
1224
1132
  gssize nread;
1225
1133
 
1226
 
  data = g_simple_async_result_get_op_res_gpointer (simple);
 
1134
  data = g_task_get_task_data (task);
1227
1135
 
1228
1136
  error = NULL;
1229
1137
  nread = g_input_stream_skip_finish (G_INPUT_STREAM (source_object),
1231
1139
 
1232
1140
  /* Only report the error if we've not already read some data */
1233
1141
  if (nread < 0 && data->bytes_skipped == 0)
1234
 
    g_simple_async_result_take_error (simple, error);
1235
 
  else if (error)
1236
 
    g_error_free (error);
1237
 
 
1238
 
  if (nread > 0)
1239
 
    data->bytes_skipped += nread;
1240
 
 
1241
 
  /* Complete immediately, not in idle, since we're already
1242
 
   * in a mainloop callout
1243
 
   */
1244
 
  g_simple_async_result_complete (simple);
1245
 
  g_object_unref (simple);
 
1142
    g_task_return_error (task, error);
 
1143
  else
 
1144
    {
 
1145
      if (error)
 
1146
        g_error_free (error);
 
1147
 
 
1148
      if (nread > 0)
 
1149
        data->bytes_skipped += nread;
 
1150
 
 
1151
      g_task_return_int (task, data->bytes_skipped);
 
1152
    }
 
1153
 
 
1154
  g_object_unref (task);
1246
1155
}
1247
1156
 
1248
1157
static void
1250
1159
                           GAsyncResult *result,
1251
1160
                           gpointer      user_data)
1252
1161
{
1253
 
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
 
1162
  GTask *task = G_TASK (user_data);
1254
1163
  GBufferedInputStream *bstream;
1255
1164
  GBufferedInputStreamPrivate *priv;
1256
1165
  SkipAsyncData *data;
1261
1170
  bstream = G_BUFFERED_INPUT_STREAM (source_object);
1262
1171
  priv = bstream->priv;
1263
1172
 
1264
 
  data = g_simple_async_result_get_op_res_gpointer (simple);
 
1173
  data = g_task_get_task_data (task);
1265
1174
 
1266
1175
  error = NULL;
1267
1176
  nread = g_buffered_input_stream_fill_finish (bstream,
1268
1177
                                               result, &error);
1269
1178
 
1270
1179
  if (nread < 0 && data->bytes_skipped == 0)
1271
 
    g_simple_async_result_take_error (simple, error);
1272
 
  else if (error)
1273
 
    g_error_free (error);
1274
 
 
1275
 
  if (nread > 0)
 
1180
    g_task_return_error (task, error);
 
1181
  else
1276
1182
    {
1277
 
      available = priv->end - priv->pos;
1278
 
      data->count = MIN (data->count, available);
1279
 
 
1280
 
      data->bytes_skipped += data->count;
1281
 
      priv->pos += data->count;
 
1183
      if (error)
 
1184
        g_error_free (error);
 
1185
 
 
1186
      if (nread > 0)
 
1187
        {
 
1188
          available = priv->end - priv->pos;
 
1189
          data->count = MIN (data->count, available);
 
1190
 
 
1191
          data->bytes_skipped += data->count;
 
1192
          priv->pos += data->count;
 
1193
        }
 
1194
 
 
1195
      g_task_return_int (task, data->bytes_skipped);
1282
1196
    }
1283
1197
 
1284
 
  /* Complete immediately, not in idle, since we're already
1285
 
   * in a mainloop callout
1286
 
   */
1287
 
  g_simple_async_result_complete (simple);
1288
 
  g_object_unref (simple);
 
1198
  g_object_unref (task);
1289
1199
}
1290
1200
 
1291
1201
static void
1301
1211
  GBufferedInputStreamClass *class;
1302
1212
  GInputStream *base_stream;
1303
1213
  gsize available;
1304
 
  GSimpleAsyncResult *simple;
 
1214
  GTask *task;
1305
1215
  SkipAsyncData *data;
1306
1216
 
1307
1217
  bstream = G_BUFFERED_INPUT_STREAM (stream);
1309
1219
 
1310
1220
  data = g_slice_new (SkipAsyncData);
1311
1221
  data->bytes_skipped = 0;
1312
 
  simple = g_simple_async_result_new (G_OBJECT (stream),
1313
 
                                      callback, user_data,
1314
 
                                      g_buffered_input_stream_skip_async);
1315
 
  g_simple_async_result_set_op_res_gpointer (simple, data, free_skip_async_data);
 
1222
  task = g_task_new (stream, cancellable, callback, user_data);
 
1223
  g_task_set_task_data (task, data, free_skip_async_data);
1316
1224
 
1317
1225
  available = priv->end - priv->pos;
1318
1226
 
1319
1227
  if (count <= available)
1320
1228
    {
1321
1229
      priv->pos += count;
1322
 
      data->bytes_skipped = count;
1323
1230
 
1324
 
      g_simple_async_result_complete_in_idle (simple);
1325
 
      g_object_unref (simple);
 
1231
      g_task_return_int (task, count);
 
1232
      g_object_unref (task);
1326
1233
      return;
1327
1234
    }
1328
1235
 
1348
1255
                                 count,
1349
1256
                                 io_priority, cancellable,
1350
1257
                                 large_skip_callback,
1351
 
                                 simple);
 
1258
                                 task);
1352
1259
    }
1353
1260
  else
1354
1261
    {
1355
1262
      class = G_BUFFERED_INPUT_STREAM_GET_CLASS (stream);
1356
1263
      class->fill_async (bstream, priv->len, io_priority, cancellable,
1357
 
                         skip_fill_buffer_callback, simple);
 
1264
                         skip_fill_buffer_callback, task);
1358
1265
    }
1359
1266
}
1360
1267
 
1363
1270
                                     GAsyncResult   *result,
1364
1271
                                     GError        **error)
1365
1272
{
1366
 
  GSimpleAsyncResult *simple;
1367
 
  SkipAsyncData *data;
1368
 
 
1369
 
  simple = G_SIMPLE_ASYNC_RESULT (result);
1370
 
 
1371
 
  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_buffered_input_stream_skip_async);
1372
 
 
1373
 
  data = g_simple_async_result_get_op_res_gpointer (simple);
1374
 
 
1375
 
  return data->bytes_skipped;
 
1273
  g_return_val_if_fail (g_task_is_valid (result, stream), -1);
 
1274
 
 
1275
  return g_task_propagate_int (G_TASK (result), error);
1376
1276
}