]> xenbits.xensource.com Git - libvirt.git/commitdiff
python: Implement virStreamSend/Recv
authorCole Robinson <crobinso@redhat.com>
Tue, 14 Jun 2011 20:07:43 +0000 (16:07 -0400)
committerCole Robinson <crobinso@redhat.com>
Tue, 21 Jun 2011 14:08:47 +0000 (10:08 -0400)
The return values for the python version are different that the C version
of virStreamSend: on success we return a string, an error raises an exception,
and if the stream would block we return int(-2). We need to do this
since strings aren't passed by reference in python.

python/generator.py
python/libvirt-override-virStream.py
python/libvirt-override.c
python/typewrappers.c
python/typewrappers.h

index cb4d8a4bcba543df6c011ce7e0c726be999edcb2..315d3d4beb375513c6df4f37f418b0eb9c2e93d5 100755 (executable)
@@ -348,8 +348,6 @@ skip_impl = (
     'virNWFilterGetUUID',
     'virNWFilterGetUUIDString',
     'virNWFilterLookupByUUID',
-    'virStreamRecv',
-    'virStreamSend',
     'virStoragePoolGetUUID',
     'virStoragePoolGetUUIDString',
     'virStoragePoolLookupByUUID',
@@ -393,9 +391,12 @@ skip_function = (
     'virConnectDomainEventDeregisterAny', # overridden in virConnect.py
     'virSaveLastError', # We have our own python error wrapper
     'virFreeError', # Only needed if we use virSaveLastError
+
     'virStreamFree', # Overridden in libvirt-override-virStream.py
-    'virStreamRecvAll',
-    'virStreamSendAll',
+    'virStreamRecvAll', # XXX: Can be written in pure python?
+    'virStreamSendAll', # XXX: Can be written in pure python?
+    'virStreamRecv', # overridden in libvirt-override-virStream.py
+    'virStreamSend', # overridden in libvirt-override-virStream.py
 
     # 'Ref' functions have no use for bindings users.
     "virConnectRef",
index 56f1df5416eecdf44f0b4e57b40217ab75347b00..f8a1d0b584c5a8f7e863339428bb9bc0fa6417a8 100644 (file)
         cbData = {"stream": self, "cb" : cb, "opaque" : opaque}
         ret = libvirtmod.virStreamEventAddCallback(self._o, events, cbData)
         if ret == -1: raise libvirtError ('virStreamEventAddCallback() failed')
+
+    def recv(self, nbytes):
+        """Write a series of bytes to the stream. This method may
+        block the calling application for an arbitrary amount
+        of time.
+
+        Errors are not guaranteed to be reported synchronously
+        with the call, but may instead be delayed until a
+        subsequent call.
+
+        On success, the received data is returned. On failure, an
+        exception is raised. If the stream is a NONBLOCK stream and
+        the request would block, integer -2 is returned.
+        """
+        ret = libvirtmod.virStreamRecv(self._o, nbytes)
+        if ret == None: raise libvirtError ('virStreamRecv() failed')
+        return ret
+
+    def send(self, data):
+        """Write a series of bytes to the stream. This method may
+        block the calling application for an arbitrary amount
+        of time. Once an application has finished sending data
+        it should call virStreamFinish to wait for successful
+        confirmation from the driver, or detect any error
+
+        This method may not be used if a stream source has been
+        registered
+
+        Errors are not guaranteed to be reported synchronously
+        with the call, but may instead be delayed until a
+        subsequent call.
+        """
+        ret = libvirtmod.virStreamSend(self._o, data, len(data))
+        if ret == -1: raise libvirtError ('virStreamSend() failed')
+        return ret
index 55cb61ced2831e939c3c638809ec0e3e8ec9669c..63157b4f920fbb1fb2271e78c2dcf9a051701064 100644 (file)
@@ -3697,6 +3697,66 @@ libvirt_virStreamEventAddCallback(PyObject *self ATTRIBUTE_UNUSED,
     return py_retval;
 }
 
+static PyObject *
+libvirt_virStreamRecv(PyObject *self ATTRIBUTE_UNUSED,
+                      PyObject *args)
+{
+    PyObject *pyobj_stream;
+    virStreamPtr stream;
+    char *buf = NULL;
+    int ret;
+    int nbytes;
+
+    if (!PyArg_ParseTuple(args, (char *) "Oi:virStreamRecv",
+                          &pyobj_stream, &nbytes)) {
+        DEBUG("%s failed to parse tuple\n", __FUNCTION__);
+        return VIR_PY_NONE;
+    }
+    stream = PyvirStream_Get(pyobj_stream);
+
+    if ((buf = malloc(nbytes+1 > 0 ? nbytes+1 : 1)) == NULL)
+        return VIR_PY_NONE;
+
+    LIBVIRT_BEGIN_ALLOW_THREADS;
+    ret = virStreamRecv(stream, buf, nbytes);
+    LIBVIRT_END_ALLOW_THREADS;
+
+    buf[ret > -1 ? ret : 0] = '\0';
+    DEBUG("StreamRecv ret=%d strlen=%d\n", ret, (int) strlen(buf));
+
+    if (ret < 0)
+        return libvirt_intWrap(ret);
+    return libvirt_charPtrSizeWrap((char *) buf, (Py_ssize_t) ret);
+}
+
+static PyObject *
+libvirt_virStreamSend(PyObject *self ATTRIBUTE_UNUSED,
+                      PyObject *args)
+{
+    PyObject *py_retval;
+    PyObject *pyobj_stream;
+    virStreamPtr stream;
+    char *data;
+    int ret;
+    int nbytes;
+
+    if (!PyArg_ParseTuple(args, (char *) "Ozi:virStreamRecv",
+                          &pyobj_stream, &data, &nbytes)) {
+        DEBUG("%s failed to parse tuple\n", __FUNCTION__);
+        return VIR_PY_INT_FAIL;
+    }
+    stream = PyvirStream_Get(pyobj_stream);
+
+    LIBVIRT_BEGIN_ALLOW_THREADS;
+    ret = virStreamSend(stream, data, nbytes);
+    LIBVIRT_END_ALLOW_THREADS;
+
+    DEBUG("StreamSend ret=%d\n", ret);
+
+    py_retval = libvirt_intWrap(ret);
+    return py_retval;
+}
+
 /************************************************************************
  *                                                                     *
  *                     The registration stuff                          *
@@ -3715,6 +3775,8 @@ static PyMethodDef libvirtMethods[] = {
     {(char *) "virConnectDomainEventRegisterAny", libvirt_virConnectDomainEventRegisterAny, METH_VARARGS, NULL},
     {(char *) "virConnectDomainEventDeregisterAny", libvirt_virConnectDomainEventDeregisterAny, METH_VARARGS, NULL},
     {(char *) "virStreamEventAddCallback", libvirt_virStreamEventAddCallback, METH_VARARGS, NULL},
+    {(char *) "virStreamRecv", libvirt_virStreamRecv, METH_VARARGS, NULL},
+    {(char *) "virStreamSend", libvirt_virStreamSend, METH_VARARGS, NULL},
     {(char *) "virDomainGetInfo", libvirt_virDomainGetInfo, METH_VARARGS, NULL},
     {(char *) "virDomainGetState", libvirt_virDomainGetState, METH_VARARGS, NULL},
     {(char *) "virDomainGetControlInfo", libvirt_virDomainGetControlInfo, METH_VARARGS, NULL},
index e39d3cd99edb20050cfaaf217d5558bf6a395695..b5758b4687cf77b514d52558c04bc42514be3ec3 100644 (file)
@@ -76,6 +76,20 @@ libvirt_ulonglongWrap(unsigned long long val)
     return (ret);
 }
 
+PyObject *
+libvirt_charPtrSizeWrap(char *str, Py_ssize_t size)
+{
+    PyObject *ret;
+
+    if (str == NULL) {
+        Py_INCREF(Py_None);
+        return (Py_None);
+    }
+    ret = PyString_FromStringAndSize(str, size);
+    free(str);
+    return (ret);
+}
+
 PyObject *
 libvirt_charPtrWrap(char *str)
 {
index cc981101a201aab34c554fe9dbe45a7343008ef8..305d594401e23a55b1cd4ef8ab183847fb44089d 100644 (file)
@@ -156,6 +156,7 @@ PyObject * libvirt_ulongWrap(unsigned long val);
 PyObject * libvirt_longlongWrap(long long val);
 PyObject * libvirt_ulonglongWrap(unsigned long long val);
 PyObject * libvirt_charPtrWrap(char *str);
+PyObject * libvirt_charPtrSizeWrap(char *str, Py_ssize_t size);
 PyObject * libvirt_constcharPtrWrap(const char *str);
 PyObject * libvirt_charPtrConstWrap(const char *str);
 PyObject * libvirt_virConnectPtrWrap(virConnectPtr node);