[pygobject] Wrap gio.DataInputStream.read_line_async and read_until_async



commit 833d4da202bcfcb01a414f8aec4b751ec8e1ccb2
Author: Paul Pogonyshev <pogonyshev gmx net>
Date:   Sat May 30 16:57:49 2009 +0300

    Wrap gio.DataInputStream.read_line_async and read_until_async
    
    Wrap the functions and their corresponding *_finish() functions.
    Create 'gdatainputstream.override' for these and move two existing
    functions there.  Add unit tests.  Re-enable synchronous read_line
    unit test and adjust it for new official GIO behavior.  Bug #584285.
---
 gio/Makefile.am               |    1 +
 gio/gdatainputstream.override |  250 +++++++++++++++++++++++++++++++++++++++++
 gio/ginputstream.override     |   65 -----------
 gio/gio.defs                  |    4 +-
 gio/gio.override              |    1 +
 tests/test_gio.py             |   51 ++++++++-
 6 files changed, 300 insertions(+), 72 deletions(-)

diff --git a/gio/Makefile.am b/gio/Makefile.am
index b430b8e..7a2fe58 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -38,6 +38,7 @@ GIO_OVERRIDES = 			\
 	gio.override			\
 	gappinfo.override		\
 	gapplaunchcontext.override 	\
+	gdatainputstream.override	\
         gdrive.override			\
 	gfile.override			\
 	gfileattribute.override		\
diff --git a/gio/gdatainputstream.override b/gio/gdatainputstream.override
new file mode 100644
index 0000000..92b0f99
--- /dev/null
+++ b/gio/gdatainputstream.override
@@ -0,0 +1,250 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pygobject - Python bindings for GObject
+ * Copyright (C) 2008  Johan Dahlin
+ * Copyright (C) 2009  Paul Pogonyshev
+ *
+ *   gdatainputstream.override: module overrides for GDataInputStream
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+%%
+override g_data_input_stream_read_line kwargs
+static PyObject *
+_wrap_g_data_input_stream_read_line(PyGObject *self,
+				    PyObject *args,
+				    PyObject *kwargs)
+{
+    static char *kwlist[] = { "cancellable", NULL };
+    PyGObject *pycancellable = NULL;
+    GCancellable *cancellable;
+    char *line;
+    gsize length;
+    PyObject *py_line;
+    GError *error = NULL;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+				     "|O:gio.DataInputStream.read_line",
+                                     kwlist, &pycancellable))
+        return NULL;
+
+    if (!pygio_check_cancellable(pycancellable, &cancellable))
+	return NULL;
+
+    line = g_data_input_stream_read_line(G_DATA_INPUT_STREAM(self->obj),
+					 &length, cancellable, &error);
+    if (pyg_error_check(&error))
+        return NULL;
+
+    py_line = PyString_FromStringAndSize(line, length);
+    g_free(line);
+    return py_line;
+}
+
+%%
+override g_data_input_stream_read_line_async kwargs
+static PyObject *
+_wrap_g_data_input_stream_read_line_async(PyGObject *self,
+				          PyObject *args,
+				          PyObject *kwargs)
+{
+    static char *kwlist[] = { "callback", "io_priority",
+                              "cancellable", "user_data", NULL };
+    int io_priority = G_PRIORITY_DEFAULT;
+    PyGObject *pycancellable = NULL;
+    GCancellable *cancellable;
+    PyGIONotify *notify;
+
+    notify = pygio_notify_new();
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                     "O|iOO:gio.DataInputStream.read_line_async",
+                                     kwlist,
+                                     &notify->callback,
+                                     &io_priority,
+                                     &pycancellable,
+                                     &notify->data))
+        goto error;
+
+    if (!pygio_notify_callback_is_valid(notify))
+        goto error;
+
+    if (!pygio_check_cancellable(pycancellable, &cancellable))
+        goto error;
+
+    pygio_notify_reference_callback(notify);
+
+    g_data_input_stream_read_line_async(G_DATA_INPUT_STREAM(self->obj),
+                                        io_priority,
+                                        cancellable,
+                                        (GAsyncReadyCallback) async_result_callback_marshal,
+                                        notify);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+
+ error:
+    pygio_notify_free(notify);
+    return NULL;
+}
+
+%%
+override g_data_input_stream_read_line_finish kwargs
+static PyObject *
+_wrap_g_data_input_stream_read_line_finish(PyGObject *self,
+                                           PyObject *args,
+                                           PyObject *kwargs)
+{
+    static char *kwlist[] = { "result", NULL };
+    PyGObject *result;
+    GError *error = NULL;
+    gchar *line;
+    gsize length;
+    PyObject *py_line;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                     "O!:gio.DataInputStream.read_line_finish",
+                                     kwlist, &PyGAsyncResult_Type, &result))
+        return NULL;
+
+    line = g_data_input_stream_read_line_finish(G_DATA_INPUT_STREAM(self->obj),
+                                                G_ASYNC_RESULT(result->obj),
+                                                &length,
+                                                &error);
+
+    if (pyg_error_check(&error))
+        return NULL;
+
+    py_line = PyString_FromStringAndSize(line, length);
+    g_free(line);
+    return py_line;
+}
+
+%%
+override g_data_input_stream_read_until kwargs
+static PyObject *
+_wrap_g_data_input_stream_read_until(PyGObject *self,
+				     PyObject *args,
+				     PyObject *kwargs)
+{
+    static char *kwlist[] = { "stop_chars", "cancellable", NULL };
+    const char *stop_chars;
+    PyGObject *pycancellable = NULL;
+    GCancellable *cancellable;
+    char *line;
+    gsize length;
+    PyObject *py_line;
+    GError *error = NULL;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+				     "s|O:gio.DataInputStream.read_line",
+                                     kwlist, &stop_chars, &pycancellable))
+        return NULL;
+
+    if (!pygio_check_cancellable(pycancellable, &cancellable))
+	return NULL;
+
+    line = g_data_input_stream_read_until(G_DATA_INPUT_STREAM(self->obj),
+					  stop_chars, &length, cancellable, &error);
+    if (pyg_error_check(&error))
+        return NULL;
+
+    py_line = PyString_FromStringAndSize(line, length);
+    g_free(line);
+    return py_line;
+}
+
+%%
+override g_data_input_stream_read_until_async kwargs
+static PyObject *
+_wrap_g_data_input_stream_read_until_async(PyGObject *self,
+                                           PyObject *args,
+                                           PyObject *kwargs)
+{
+    static char *kwlist[] = { "stop_chars", "callback", "io_priority",
+                              "cancellable", "user_data", NULL };
+    const char *stop_chars;
+    int io_priority = G_PRIORITY_DEFAULT;
+    PyGObject *pycancellable = NULL;
+    GCancellable *cancellable;
+    PyGIONotify *notify;
+
+    notify = pygio_notify_new();
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                     "sO|iOO:gio.DataInputStream.read_until_async",
+                                     kwlist,
+                                     &stop_chars,
+                                     &notify->callback,
+                                     &io_priority,
+                                     &pycancellable,
+                                     &notify->data))
+        goto error;
+
+    if (!pygio_notify_callback_is_valid(notify))
+        goto error;
+
+    if (!pygio_check_cancellable(pycancellable, &cancellable))
+        goto error;
+
+    pygio_notify_reference_callback(notify);
+
+    g_data_input_stream_read_until_async(G_DATA_INPUT_STREAM(self->obj),
+                                         stop_chars,
+                                         io_priority,
+                                         cancellable,
+                                         (GAsyncReadyCallback) async_result_callback_marshal,
+                                         notify);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+
+ error:
+    pygio_notify_free(notify);
+    return NULL;
+}
+
+%%
+override g_data_input_stream_read_until_finish kwargs
+static PyObject *
+_wrap_g_data_input_stream_read_until_finish(PyGObject *self,
+                                           PyObject *args,
+                                           PyObject *kwargs)
+{
+    static char *kwlist[] = { "result", NULL };
+    PyGObject *result;
+    GError *error = NULL;
+    gchar *line;
+    gsize length;
+    PyObject *py_line;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                     "O!:gio.DataInputStream.read_until_finish",
+                                     kwlist, &PyGAsyncResult_Type, &result))
+        return NULL;
+
+    line = g_data_input_stream_read_until_finish(G_DATA_INPUT_STREAM(self->obj),
+                                                 G_ASYNC_RESULT(result->obj),
+                                                 &length,
+                                                 &error);
+
+    if (pyg_error_check(&error))
+        return NULL;
+
+    py_line = PyString_FromStringAndSize(line, length);
+    g_free(line);
+    return py_line;
+}
diff --git a/gio/ginputstream.override b/gio/ginputstream.override
index 7518b3f..075a20c 100644
--- a/gio/ginputstream.override
+++ b/gio/ginputstream.override
@@ -293,71 +293,6 @@ _wrap_g_input_stream_close_async(PyGObject *self,
     return NULL;
 }
 %%
-override g_data_input_stream_read_line kwargs
-static PyObject *
-_wrap_g_data_input_stream_read_line(PyGObject *self,
-				    PyObject *args,
-				    PyObject *kwargs)
-{
-    static char *kwlist[] = { "cancellable", NULL };
-    PyGObject *pycancellable = NULL;
-    GCancellable *cancellable;
-    char *line;
-    gsize length;
-    PyObject *py_line;
-    GError *error = NULL;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-				     "|O:gio.DataInputStream.read_line",
-                                     kwlist, &pycancellable))
-        return NULL;
-
-    if (!pygio_check_cancellable(pycancellable, &cancellable))
-	return NULL;
-
-    line = g_data_input_stream_read_line(G_DATA_INPUT_STREAM(self->obj),
-					 &length, cancellable, &error);
-    if (pyg_error_check(&error))
-        return NULL;
-
-    py_line = PyString_FromStringAndSize(line, length);
-    g_free(line);
-    return py_line;
-}
-%%
-override g_data_input_stream_read_until kwargs
-static PyObject *
-_wrap_g_data_input_stream_read_until(PyGObject *self,
-				     PyObject *args,
-				     PyObject *kwargs)
-{
-    static char *kwlist[] = { "stop_chars", "cancellable", NULL };
-    const char *stop_chars;
-    PyGObject *pycancellable = NULL;
-    GCancellable *cancellable;
-    char *line;
-    gsize length;
-    PyObject *py_line;
-    GError *error = NULL;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-				     "s|O:gio.DataInputStream.read_line",
-                                     kwlist, &stop_chars, &pycancellable))
-        return NULL;
-
-    if (!pygio_check_cancellable(pycancellable, &cancellable))
-	return NULL;
-
-    line = g_data_input_stream_read_until(G_DATA_INPUT_STREAM(self->obj),
-					  stop_chars, &length, cancellable, &error);
-    if (pyg_error_check(&error))
-        return NULL;
-
-    py_line = PyString_FromStringAndSize(line, length);
-    g_free(line);
-    return py_line;
-}
-%%
 override g_memory_input_stream_add_data kwargs
 static PyObject *
 _wrap_g_memory_input_stream_add_data(PyGObject *self,
diff --git a/gio/gio.defs b/gio/gio.defs
index ed22d88..715e392 100644
--- a/gio/gio.defs
+++ b/gio/gio.defs
@@ -790,7 +790,7 @@
 )
 
 ;;
-;; wrapped in ginputstream.override
+;; wrapped in gdatainputstream.override
 ;;
 (define-method read_line
   (of-object "GDataInputStream")
@@ -808,7 +808,7 @@
 )
 
 ;;
-;; wrapped in ginputstream.override
+;; wrapped in gdatainputstream.override
 ;;
 (define-method read_until
   (of-object "GDataInputStream")
diff --git a/gio/gio.override b/gio/gio.override
index ea4c4ec..e68f725 100644
--- a/gio/gio.override
+++ b/gio/gio.override
@@ -230,6 +230,7 @@ async_result_callback_marshal(GObject *source_object,
 include
   gappinfo.override
   gapplaunchcontext.override
+  gdatainputstream.override
   gdrive.override
   gfile.override
   gfileattribute.override
diff --git a/tests/test_gio.py b/tests/test_gio.py
index 05b82b3..2d33e8f 100644
--- a/tests/test_gio.py
+++ b/tests/test_gio.py
@@ -691,20 +691,61 @@ class TestDataInputStream(unittest.TestCase):
         self.data_stream = gio.DataInputStream(self.base_stream)
 
     def test_read_line(self):
-        # Currently fails because GIO itself is buggy.  See bug 547481.
-        return
         self.base_stream.add_data('foo\nbar\n\nbaz')
-        self.assertEquals('foo\n', self.data_stream.read_line())
-        self.assertEquals('bar\n', self.data_stream.read_line())
-        self.assertEquals('\n', self.data_stream.read_line())
+        self.assertEquals('foo', self.data_stream.read_line())
+        self.assertEquals('bar', self.data_stream.read_line())
+        self.assertEquals('', self.data_stream.read_line())
         self.assertEquals('baz', self.data_stream.read_line())
 
+    def test_read_line_async(self):
+        def do_read_line_async():
+            loop = glib.MainLoop()
+            line = []
+
+            def callback(stream, result):
+                try:
+                    line.append(stream.read_line_finish(result))
+                finally:
+                    loop.quit()
+
+            self.data_stream.read_line_async(callback)
+            loop.run()
+            return line[0]
+
+        self.base_stream.add_data('foo\nbar\n\nbaz')
+        self.assertEquals('foo', do_read_line_async())
+        self.assertEquals('bar', do_read_line_async())
+        self.assertEquals('', do_read_line_async())
+        self.assertEquals('baz', do_read_line_async())
+
     def test_read_until(self):
         self.base_stream.add_data('sentence.end of line\nthe rest')
         self.assertEquals('sentence', self.data_stream.read_until('.!?'))
         self.assertEquals('end of line', self.data_stream.read_until('\n\r'))
         self.assertEquals('the rest', self.data_stream.read_until('#$%^&'))
 
+    def test_read_until_async(self):
+        def do_read_until_async(stop_chars):
+            loop = glib.MainLoop()
+            data = []
+
+            def callback(stream, result):
+                try:
+                    data.append(stream.read_until_finish(result))
+                finally:
+                    loop.quit()
+
+            self.data_stream.read_until_async(stop_chars, callback)
+            loop.run()
+            return data[0]
+
+        # Note the weird difference between synchronous and
+        # asynchronous version.  See bug #584284.
+        self.base_stream.add_data('sentence.end of line\nthe rest')
+        self.assertEquals('sentence', do_read_until_async('.!?'))
+        self.assertEquals('.end of line', do_read_until_async('\n\r'))
+        self.assertEquals('\nthe rest', do_read_until_async('#$%^&'))
+
 
 class TestMemoryInputStream(unittest.TestCase):
     def setUp(self):



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