pygobject r892 - in trunk: . examples/gio gio



Author: johan
Date: Mon Jul 28 22:06:26 2008
New Revision: 892
URL: http://svn.gnome.org/viewvc/pygobject?rev=892&view=rev

Log:
2008-07-29  Johan Dahlin  <johan gnome org>

    * examples/gio/downloader.py:
    Add a new example

    * gio/ginputstream.override:
    Use a string internally instead of a PyStringObject when
    in read_async. Create a new python string in finish and
    honor the number of bytes read.



Added:
   trunk/examples/gio/downloader.py
Modified:
   trunk/ChangeLog
   trunk/gio/ginputstream.override

Added: trunk/examples/gio/downloader.py
==============================================================================
--- (empty file)
+++ trunk/examples/gio/downloader.py	Mon Jul 28 22:06:26 2008
@@ -0,0 +1,61 @@
+# Example GIO based Asynchronous downloader
+
+import sys
+
+import glib
+import glib.option
+import gio
+
+
+class Downloader(object):
+    def __init__(self, uri):
+        self.total = 0
+        self.gfile = gio.File(uri)
+        self.loop = glib.MainLoop()
+
+        output = self.get_output_filename()
+        self.fd = open(output, 'w')
+        print 'Downloading %s -> %s' % (uri, output)
+
+        self.gfile.read_async(self.read_callback)
+
+    def get_output_filename(self):
+        basename = self.gfile.get_basename()
+        if basename == '/':
+            basename = 'index.html'
+        return basename
+
+    def stream_read_callback(self, stream, result):
+        data = stream.read_finish(result)
+        if not data:
+            self.data_finished()
+            return
+        self.data_read(data)
+        stream.read_async(4096, self.stream_read_callback)
+
+
+    def read_callback(self, gfile, result):
+        stream = gfile.read_finish(result)
+        stream.read_async(4096, self.stream_read_callback)
+
+    def data_read(self, data):
+        self.fd.write(data)
+        self.total += len(data)
+
+    def data_finished(self):
+        print '%d bytes read' % (self.total,)
+        self.loop.quit()
+
+    def run(self):
+        self.loop.run()
+
+def main(args):
+    if len(args) < 2:
+        print 'Needs a URI'
+        return 1
+
+    d = Downloader(args[1])
+    d.run()
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))

Modified: trunk/gio/ginputstream.override
==============================================================================
--- trunk/gio/ginputstream.override	(original)
+++ trunk/gio/ginputstream.override	Mon Jul 28 22:06:26 2008
@@ -26,7 +26,7 @@
 typedef struct {
     PyObject *callback;
     PyObject *data;
-    PyObject *buffer;
+    guchar *buffer;
 } PyGIONotifyRead;
 
 static void
@@ -44,7 +44,6 @@
     if (notify->buffer) {
 	if (!quark)
 	    quark = g_quark_from_string("pygio::buffer");
-	Py_XINCREF(notify->buffer);
 	g_object_set_qdata_full(G_OBJECT(result), quark,
 				notify->buffer, py_decref_callback);
     }
@@ -186,12 +185,12 @@
   if (!pygio_check_cancellable(pycancellable, &cancellable))
     return NULL;
   
-  notify->buffer = PyString_FromStringAndSize((char *)NULL, count);
+  notify->buffer = g_malloc(count);
   if (notify->buffer == NULL)
     return NULL;
   
   g_input_stream_read_async(G_INPUT_STREAM(self->obj),
-			    PyString_AS_STRING((PyStringObject *)notify->buffer),
+			    notify->buffer,
 			    count,
 			    io_priority,
 			    cancellable,
@@ -212,7 +211,8 @@
     PyGObject *result;
     GError *error = NULL;
     static GQuark quark = 0;
-    PyObject *buffer;
+    gchar *buffer;
+    Py_ssize_t bytesread;
     
     if (!quark)
 	quark = g_quark_from_string("pygio::buffer");
@@ -223,15 +223,18 @@
         return NULL;
     
 
-    g_input_stream_read_finish(G_INPUT_STREAM(self->obj),
-			       G_ASYNC_RESULT(result->obj), &error);
+    bytesread = g_input_stream_read_finish(G_INPUT_STREAM(self->obj),
+					   G_ASYNC_RESULT(result->obj), &error);
     
     if (pyg_error_check(&error))
         return NULL;
 
+    if (bytesread == 0) {
+	return PyString_FromString("");
+    }
+
     buffer = g_object_get_qdata(G_OBJECT(result->obj), quark);
-    /* FIXME: Should we refcount the buffer here? */
-    return buffer;
+    return PyString_FromStringAndSize(buffer, bytesread);
 }
 %%
 override g_input_stream_close_async kwargs



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