aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/pyside2/tests/support/voidptr_test.py7
-rw-r--r--sources/shiboken2/libshiboken/voidptr.cpp87
2 files changed, 91 insertions, 3 deletions
diff --git a/sources/pyside2/tests/support/voidptr_test.py b/sources/pyside2/tests/support/voidptr_test.py
index c04022489..f68217244 100644
--- a/sources/pyside2/tests/support/voidptr_test.py
+++ b/sources/pyside2/tests/support/voidptr_test.py
@@ -54,6 +54,11 @@ class PySide2Support(unittest.TestCase):
# Convert original and new to str
self.assertTrue(str(b), str(nba))
+ # Modify nba through a memoryview of vp
+ mv = memoryview(vp)
+ self.assertFalse(mv.readonly)
+ mv[6:11] = b'void*'
+ self.assertEqual(str(ba), str(b"Hello void*"))
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken2/libshiboken/voidptr.cpp b/sources/shiboken2/libshiboken/voidptr.cpp
index e55ccfab5..5b0cb84ea 100644
--- a/sources/shiboken2/libshiboken/voidptr.cpp
+++ b/sources/shiboken2/libshiboken/voidptr.cpp
@@ -249,6 +249,83 @@ PyObject *SbkVoidPtrObject_str(PyObject *v)
}
+static int SbkVoidPtrObject_getbuffer(PyObject *obj, Py_buffer *view, int flags)
+{
+ if (view == NULL)
+ return -1;
+
+ SbkVoidPtrObject *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(obj);
+ if (sbkObject->size < 0)
+ return -1;
+
+ int readonly = sbkObject->isWritable ? 0 : 1;
+ if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) &&
+ (readonly == 1)) {
+ PyErr_SetString(PyExc_BufferError,
+ "Object is not writable.");
+ return -1;
+ }
+
+ view->obj = obj;
+ if (obj)
+ Py_XINCREF(obj);
+ view->buf = sbkObject->cptr;
+ view->len = sbkObject->size;
+ view->readonly = readonly;
+ view->itemsize = 1;
+ view->format = NULL;
+ if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
+ view->format = "B";
+ view->ndim = 1;
+ view->shape = NULL;
+ if ((flags & PyBUF_ND) == PyBUF_ND)
+ view->shape = &(view->len);
+ view->strides = NULL;
+ if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES)
+ view->strides = &(view->itemsize);
+ view->suboffsets = NULL;
+ view->internal = NULL;
+ return 0;
+}
+
+#if PY_VERSION_HEX < 0x03000000
+
+static Py_ssize_t SbkVoidPtrObject_readbufferproc(PyObject* self, Py_ssize_t segment, void** ptrptr)
+{
+ if (segment || !Shiboken::Object::isValid(self))
+ return -1;
+
+ SbkVoidPtrObject *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(self);
+ *ptrptr = reinterpret_cast<void*>(sbkObject->cptr);
+ return sbkObject->size;
+}
+
+static Py_ssize_t SbkVoidPtrObject_segcountproc(PyObject* self, Py_ssize_t* lenp)
+{
+ if (lenp) {
+ SbkVoidPtrObject *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(self);
+ *lenp = sbkObject->size;
+ }
+ return 1;
+}
+
+PyBufferProcs SbkVoidPtrObjectBufferProc = {
+ &SbkVoidPtrObject_readbufferproc, // bf_getreadbuffer
+ (writebufferproc)&SbkVoidPtrObject_readbufferproc, // bf_getwritebuffer
+ &SbkVoidPtrObject_segcountproc, // bf_getsegcount
+ (charbufferproc)&SbkVoidPtrObject_readbufferproc, // bf_getcharbuffer
+ (getbufferproc)SbkVoidPtrObject_getbuffer, // bf_getbuffer
+};
+
+#else
+
+static PyBufferProcs SbkVoidPtrObjectBufferProc = {
+ (getbufferproc)SbkVoidPtrObject_getbuffer, // bf_getbuffer
+ (releasebufferproc)0 // bf_releasebuffer
+};
+
+#endif
+
// Void pointer type definition.
static PyType_Slot SbkVoidPtrType_slots[] = {
{Py_tp_repr, (void *)SbkVoidPtrObject_repr},
@@ -278,6 +355,14 @@ PyTypeObject *SbkVoidPtrTypeF(void)
static PyTypeObject *type = nullptr;
if (!type)
type = (PyTypeObject *)PyType_FromSpec(&SbkVoidPtrType_spec);
+
+#if PY_VERSION_HEX < 0x03000000
+ type->tp_as_buffer = &SbkVoidPtrObjectBufferProc;
+ type->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
+#else
+ PepType_AS_BUFFER(type) = &SbkVoidPtrObjectBufferProc;
+#endif
+
return type;
}
@@ -394,5 +479,3 @@ SbkConverter *createConverter()
}
} // namespace VoidPtr
-
-