GMemoryInputStream: fix skip_async()
authorDan Winship <danw@gnome.org>
Sat, 5 Jan 2013 18:26:23 +0000 (13:26 -0500)
committerDan Winship <danw@gnome.org>
Sat, 5 Jan 2013 18:29:01 +0000 (13:29 -0500)
a5876e5f made GMemoryInputStream subclassable, but accidentally broke
read_async() and skip_async() in the process. The immediately
following e7983495 fixed read_async() (and added a test for it), but
skip_async() accidentally got... skipped.

Fix it now and add a test for it.

Also, GMemoryInputStream's skip_async() was assuming that skip() could
never fail, which is true of its own implementation, but might not be
true of a subclass's, so do proper GError handling too.

gio/gmemoryinputstream.c
gio/tests/memory-input-stream.c

index f058d9d..777dc84 100644 (file)
@@ -379,10 +379,14 @@ g_memory_input_stream_skip_async (GInputStream        *stream,
 {
   GTask *task;
   gssize nskipped;
+  GError *error = NULL;
 
-  nskipped = g_input_stream_skip (stream, count, cancellable, NULL);
+  nskipped = G_INPUT_STREAM_GET_CLASS (stream)->skip (stream, count, cancellable, &error);
   task = g_task_new (stream, cancellable, callback, user_data);
-  g_task_return_int (task, nskipped);
+  if (error)
+    g_task_return_error (task, error);
+  else
+    g_task_return_int (task, nskipped);
   g_object_unref (task);
 }
 
index 98bb2f1..48fa3c7 100644 (file)
@@ -85,13 +85,29 @@ async_read_chunk (GObject      *object,
 }
 
 static void
+async_skipped_chunk (GObject      *object,
+                     GAsyncResult *result,
+                     gpointer      user_data)
+{
+  gsize *bytes_skipped = user_data;
+  GError *error = NULL;
+
+  *bytes_skipped = g_input_stream_skip_finish (G_INPUT_STREAM (object),
+                                               result, &error);
+  g_assert_no_error (error);
+
+  g_main_loop_quit (loop);
+}
+
+static void
 test_async (void)
 {
   const char *data1 = "abcdefghijklmnopqrstuvwxyz";
   const char *data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
   const char *result = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
   char buffer[128];
-  gsize bytes_read, pos, len, chunk_size;
+  gsize bytes_read, bytes_skipped;
+  gsize pos, len, chunk_size;
   GError *error = NULL;
   GInputStream *stream;
   gboolean res;
@@ -126,6 +142,31 @@ test_async (void)
       res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error);
       g_assert_cmpint (res, ==, TRUE);
       g_assert_no_error (error);
+
+      pos = 0;
+      while (pos + chunk_size + 1 < len)
+        {
+          g_input_stream_skip_async (stream, chunk_size,
+                                    G_PRIORITY_DEFAULT, NULL,
+                                    async_skipped_chunk, &bytes_skipped);
+         g_main_loop_run (loop);
+
+          g_assert_cmpint (bytes_skipped, ==, MIN (chunk_size, len - pos));
+
+          pos += bytes_skipped;
+        }
+
+      g_input_stream_read_async (stream, buffer, len - pos,
+                                 G_PRIORITY_DEFAULT, NULL,
+                                 async_read_chunk, &bytes_read);
+      g_main_loop_run (loop);
+
+      g_assert_cmpint (bytes_read, ==, len - pos);
+      g_assert (strncmp (buffer, result + pos, bytes_read) == 0);
+
+      res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error);
+      g_assert_cmpint (res, ==, TRUE);
+      g_assert_no_error (error);
     }
 
   g_object_unref (stream);