aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/libshiboken
diff options
context:
space:
mode:
authorCristian Maureira-Fredes <cristian.maureira-fredes@qt.io>2019-02-27 16:54:31 +0100
committerCristian Maureira-Fredes <cristian.maureira-fredes@qt.io>2019-03-15 16:47:46 +0000
commit45e3c96a8075d210b70eabdb2ef9c3f7f1ca17af (patch)
tree640e32355745259489fabcf7834c599cf717178d /sources/shiboken2/libshiboken
parent264f7fccaffa79d947b872a8179993ef547e069c (diff)
Add toBytes() and BufferProtocol
VoidPtr: Add toBytes() method that return a char* representation of the void* pointer. QByteArray: The current implementation only provided the Buffer Protocol for Python2, this patch includes the getbuffer implementation for Python3. Having a BufferProtocol implementation for Python3 allows the initialization of VoidPtr to get access to the internal content, so one can go back and forward with the representation of it: ba = QByteArray(b"Hello World") vp = VoidPtr(ba, ba.size()) vp.toBytes() # b"Hello World" The BufferProtocol was also changed for Python2 including the new buffer protocol (Py_TPFLAGS_HAVE_NEWBUFFER) function `bf_getbuffer`. A test case was included. Fixes: PYSIDE-934 Change-Id: I8936966da91b2dcc879c582cfc35e6a35f7a60b6 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'sources/shiboken2/libshiboken')
-rw-r--r--sources/shiboken2/libshiboken/voidptr.cpp65
1 files changed, 46 insertions, 19 deletions
diff --git a/sources/shiboken2/libshiboken/voidptr.cpp b/sources/shiboken2/libshiboken/voidptr.cpp
index a306f7a9d..e55ccfab5 100644
--- a/sources/shiboken2/libshiboken/voidptr.cpp
+++ b/sources/shiboken2/libshiboken/voidptr.cpp
@@ -95,13 +95,6 @@ int SbkVoidPtrObject_init(PyObject *self, PyObject *args, PyObject *kwds)
sbkSelf->size = sbkOther->size;
sbkSelf->isWritable = sbkOther->isWritable;
}
- // Shiboken::Object wrapper.
- else if (Shiboken::Object::checkType(addressObject)) {
- SbkObject *sbkOther = reinterpret_cast<SbkObject *>(addressObject);
- sbkSelf->cptr = sbkOther->d->cptr[0];
- sbkSelf->size = size;
- sbkSelf->isWritable = isWritable > 0 ? true : false;
- }
// Python buffer interface.
else if (PyObject_CheckBuffer(addressObject)) {
Py_buffer bufferView;
@@ -111,26 +104,41 @@ int SbkVoidPtrObject_init(PyObject *self, PyObject *args, PyObject *kwds)
return 0;
sbkSelf->cptr = bufferView.buf;
- sbkSelf->size = bufferView.len;
+ sbkSelf->size = bufferView.len > 0 ? bufferView.len : size;
sbkSelf->isWritable = bufferView.readonly > 0 ? false : true;
// Release the buffer.
PyBuffer_Release(&bufferView);
}
+ // Shiboken::Object wrapper.
+ else if (Shiboken::Object::checkType(addressObject)) {
+ SbkObject *sbkOther = reinterpret_cast<SbkObject *>(addressObject);
+ sbkSelf->cptr = sbkOther->d->cptr[0];
+ sbkSelf->size = size;
+ sbkSelf->isWritable = isWritable > 0 ? true : false;
+ }
// An integer representing an address.
else {
- void *cptr = PyLong_AsVoidPtr(addressObject);
- if (PyErr_Occurred()) {
- PyErr_SetString(PyExc_TypeError,
- "Creating a VoidPtr object requires an address of a C++ object, "
- "a wrapped Shiboken Object type, "
- "an object implementing the Python Buffer interface, "
- "or another VoidPtr object.");
- return -1;
+ if (addressObject == Py_None) {
+ sbkSelf->cptr = nullptr;
+ sbkSelf->size = 0;
+ sbkSelf->isWritable = false;
+ }
+
+ else {
+ void *cptr = PyLong_AsVoidPtr(addressObject);
+ if (PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "Creating a VoidPtr object requires an address of a C++ object, "
+ "a wrapped Shiboken Object type, "
+ "an object implementing the Python Buffer interface, "
+ "or another VoidPtr object.");
+ return -1;
+ }
+ sbkSelf->cptr = cptr;
+ sbkSelf->size = size;
+ sbkSelf->isWritable = isWritable > 0 ? true : false;
}
- sbkSelf->cptr = cptr;
- sbkSelf->size = size;
- sbkSelf->isWritable = isWritable > 0 ? true : false;
}
return 0;
@@ -174,6 +182,24 @@ PyObject *SbkVoidPtrObject_int(PyObject *v)
return PyLong_FromVoidPtr(sbkObject->cptr);
}
+PyObject *toBytes(PyObject *self, PyObject *args)
+{
+ SbkVoidPtrObject *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(self);
+ if (sbkObject->size < 0) {
+ PyErr_SetString(PyExc_IndexError, "VoidPtr does not have a size set.");
+ return nullptr;
+ }
+ PyObject *bytes = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(sbkObject->cptr),
+ sbkObject->size);
+ Py_XINCREF(bytes);
+ return bytes;
+}
+
+static struct PyMethodDef SbkVoidPtrObject_methods[] = {
+ {"toBytes", toBytes, METH_NOARGS},
+ {0}
+};
+
static Py_ssize_t SbkVoidPtrObject_length(PyObject *v)
{
SbkVoidPtrObject *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(v);
@@ -233,6 +259,7 @@ static PyType_Slot SbkVoidPtrType_slots[] = {
{Py_tp_init, (void *)SbkVoidPtrObject_init},
{Py_tp_new, (void *)SbkVoidPtrObject_new},
{Py_tp_dealloc, (void *)object_dealloc},
+ {Py_tp_methods, (void *)SbkVoidPtrObject_methods},
{0, 0}
};
static PyType_Spec SbkVoidPtrType_spec = {