On Wed, Jun 15, 2011 at 09:23:14PM -0400, Cole Robinson wrote: > Pure python implementation. The handler callbacks have been altered > a bit compared to the C API: RecvAll doesn't pass length of the data read > since that can be trivially obtained from python string objects, and SendAll > requires the handler to return the string data to send rather than > store the data in a string pointer. > > Signed-off-by: Cole Robinson <crobinso@xxxxxxxxxx> > --- > python/generator.py | 4 +- > python/libvirt-override-virStream.py | 64 ++++++++++++++++++++++++++++++++++ > 2 files changed, 66 insertions(+), 2 deletions(-) > > diff --git a/python/generator.py b/python/generator.py > index fdc2068..b73dc57 100755 > --- a/python/generator.py > +++ b/python/generator.py > @@ -391,8 +391,8 @@ skip_function = ( > 'virSaveLastError', # We have our own python error wrapper > 'virFreeError', # Only needed if we use virSaveLastError > > - 'virStreamRecvAll', # XXX: Can be written in pure python? > - 'virStreamSendAll', # XXX: Can be written in pure python? > + 'virStreamRecvAll', # Pure python libvirt-override-virStream.py > + 'virStreamSendAll', # Pure python libvirt-override-virStream.py > 'virStreamRecv', # overridden in libvirt-override-virStream.py > 'virStreamSend', # overridden in libvirt-override-virStream.py > > diff --git a/python/libvirt-override-virStream.py b/python/libvirt-override-virStream.py > index f8a1d0b..82e1648 100644 > --- a/python/libvirt-override-virStream.py > +++ b/python/libvirt-override-virStream.py > @@ -25,6 +25,70 @@ > ret = libvirtmod.virStreamEventAddCallback(self._o, events, cbData) > if ret == -1: raise libvirtError ('virStreamEventAddCallback() failed') > > + def recvAll(self, handler, opaque): > + """Receive the entire data stream, sending the data to the > + requested data sink. This is simply a convenient alternative > + to virStreamRecv, for apps that do blocking-I/o. > + > + A hypothetical handler function looks like: > + > + def handler(stream, # virStream instance > + buf, # string containing received data > + opaque): # extra data passed to recvAll as opaque > + fd = opaque > + return os.write(fd, buf) > + """ > + while True: > + got = self.recv(1024*64) > + if got == -2: > + raise libvirtError("cannot use recvAll with " > + "nonblocking stream") > + if len(got) == 0: > + break > + > + try: > + ret = handler(self, got, opaque) > + if type(ret) is int and ret < 0: > + raise RuntimeError("recvAll handler returned %d" % ret) > + except Exception, e: > + try: > + self.abort() > + except: > + pass > + raise e > + > + def sendAll(self, handler, opaque): > + """ > + Send the entire data stream, reading the data from the > + requested data source. This is simply a convenient alternative > + to virStreamSend, for apps that do blocking-I/o. > + > + A hypothetical handler function looks like: > + > + def handler(stream, # virStream instance > + nbytes, # int amt of data to read > + opaque): # extra data passed to recvAll as opaque > + fd = opaque > + return os.read(fd, nbytes) > + """ > + while True: > + try: > + got = handler(self, 1024*64, opaque) > + except: > + try: > + self.abort() > + except: > + pass > + raise e > + > + if got == "": > + break > + > + ret = self.send(got) > + if ret == -2: > + raise libvirtError("cannot use recvAll with " > + "nonblocking stream") > + > def recv(self, nbytes): > """Write a series of bytes to the stream. This method may > block the calling application for an arbitrary amount ACK -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list