diff options
author | Johan Dahlin <johan@gnome.org> | 2008-07-28 22:06:26 +0000 |
---|---|---|
committer | Johan Dahlin <johan@src.gnome.org> | 2008-07-28 22:06:26 +0000 |
commit | 05461cad1d58f4c0de73a63a69f260a01286e08e (patch) | |
tree | 159dd7ab7b5f46d648e42a346eedbba471c247fd | |
parent | 6151bbd9f69c6131be611267c887eb130607e569 (diff) | |
download | gobject-introspection-05461cad1d58f4c0de73a63a69f260a01286e08e.tar.gz |
Add a new example
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.
svn path=/trunk/; revision=892
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | examples/gio/downloader.py | 61 | ||||
-rw-r--r-- | gio/ginputstream.override | 21 |
3 files changed, 83 insertions, 9 deletions
@@ -1,3 +1,13 @@ +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. + 2008-07-28 Johan Dahlin <johan@gnome.org> * glib/pyglib-python-compat.h: diff --git a/examples/gio/downloader.py b/examples/gio/downloader.py new file mode 100644 index 00000000..36c803bb --- /dev/null +++ b/examples/gio/downloader.py @@ -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)) diff --git a/gio/ginputstream.override b/gio/ginputstream.override index 878f7e7d..267ae019 100644 --- a/gio/ginputstream.override +++ b/gio/ginputstream.override @@ -26,7 +26,7 @@ headers typedef struct { PyObject *callback; PyObject *data; - PyObject *buffer; + guchar *buffer; } PyGIONotifyRead; static void @@ -44,7 +44,6 @@ async_result_callback_marshal_read(GObject *source_object, 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 @@ _wrap_g_input_stream_read_async(PyGObject *self, 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 @@ _wrap_g_input_stream_read_finish(PyGObject *self, 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 @@ _wrap_g_input_stream_read_finish(PyGObject *self, 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 |