[glib] GMemoryInputStream: fix skip_async()



commit f42347d82e3724958d36922a6171c2eb262336cb
Author: Dan Winship <danw gnome org>
Date:   Sat Jan 5 13:26:23 2013 -0500

    GMemoryInputStream: fix skip_async()
    
    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        |    8 +++++-
 gio/tests/memory-input-stream.c |   43 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 3 deletions(-)
---
diff --git a/gio/gmemoryinputstream.c b/gio/gmemoryinputstream.c
index f058d9d..777dc84 100644
--- a/gio/gmemoryinputstream.c
+++ b/gio/gmemoryinputstream.c
@@ -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);
 }
 
diff --git a/gio/tests/memory-input-stream.c b/gio/tests/memory-input-stream.c
index 98bb2f1..48fa3c7 100644
--- a/gio/tests/memory-input-stream.c
+++ b/gio/tests/memory-input-stream.c
@@ -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);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]