aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside2
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/pyside2
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/pyside2')
-rw-r--r--sources/pyside2/PySide2/glue/qtcore.cpp46
-rw-r--r--sources/pyside2/tests/support/voidptr_test.py18
2 files changed, 54 insertions, 10 deletions
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp
index 629484458..6259724c3 100644
--- a/sources/pyside2/PySide2/glue/qtcore.cpp
+++ b/sources/pyside2/PySide2/glue/qtcore.cpp
@@ -965,13 +965,33 @@ if (PyIndex_Check(_key)) {
// @snippet qbytearray-msetitem
// @snippet qbytearray-bufferprotocol
-#if PY_VERSION_HEX < 0x03000000
-
+extern "C" {
// QByteArray buffer protocol functions
// see: http://www.python.org/dev/peps/pep-3118/
-extern "C" {
+static int SbkQByteArray_getbufferproc(PyObject* obj, Py_buffer *view, int flags)
+{
+ if (!view || !Shiboken::Object::isValid(obj))
+ return -1;
+
+ QByteArray* cppSelf = %CONVERTTOCPP[QByteArray*](obj);
+ view->obj = obj;
+ view->buf = reinterpret_cast<void*>(cppSelf->data());
+ view->len = cppSelf->size();
+ view->readonly = 0;
+ view->itemsize = 1;
+ view->format = const_cast<char*>("c");
+ view->ndim = 1;
+ view->shape = NULL;
+ view->strides = &view->itemsize;
+ view->suboffsets = NULL;
+ view->internal = NULL;
+
+ Py_XINCREF(obj);
+ return 0;
+}
+#if PY_VERSION_HEX < 0x03000000
static Py_ssize_t SbkQByteArray_segcountproc(PyObject* self, Py_ssize_t* lenp)
{
if (lenp)
@@ -993,12 +1013,18 @@ PyBufferProcs SbkQByteArrayBufferProc = {
/*bf_getreadbuffer*/ &SbkQByteArray_readbufferproc,
/*bf_getwritebuffer*/ (writebufferproc) &SbkQByteArray_readbufferproc,
/*bf_getsegcount*/ &SbkQByteArray_segcountproc,
- /*bf_getcharbuffer*/ (charbufferproc) &SbkQByteArray_readbufferproc
+ /*bf_getcharbuffer*/ (charbufferproc) &SbkQByteArray_readbufferproc,
+ /*bf_getbuffer*/ (getbufferproc)SbkQByteArray_getbufferproc,
};
+#else
-}
+static PyBufferProcs SbkQByteArrayBufferProc = {
+ /*bf_getbuffer*/ (getbufferproc)SbkQByteArray_getbufferproc,
+ /*bf_releasebuffer*/ (releasebufferproc)0,
+};
#endif
+}
// @snippet qbytearray-bufferprotocol
// @snippet qbytearray-operatorplus-1
@@ -1110,8 +1136,14 @@ if (PyBytes_Check(%PYARG_1)) {
// @snippet qbytearray-py3
#if PY_VERSION_HEX < 0x03000000
- Shiboken::SbkType<QByteArray>()->tp_as_buffer = &SbkQByteArrayBufferProc;
- Shiboken::SbkType<QByteArray>()->tp_flags |= Py_TPFLAGS_HAVE_GETCHARBUFFER;
+Shiboken::SbkType<QByteArray>()->tp_as_buffer = &SbkQByteArrayBufferProc;
+Shiboken::SbkType<QByteArray>()->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
+#else
+#ifdef Py_LIMITED_API
+PepType_AS_BUFFER(Shiboken::SbkType<QByteArray>()) = &SbkQByteArrayBufferProc;
+#else
+Shiboken::SbkType<QByteArray>()->tp_as_buffer = &SbkQByteArrayBufferProc;
+#endif
#endif
// @snippet qbytearray-py3
diff --git a/sources/pyside2/tests/support/voidptr_test.py b/sources/pyside2/tests/support/voidptr_test.py
index 330788c63..c04022489 100644
--- a/sources/pyside2/tests/support/voidptr_test.py
+++ b/sources/pyside2/tests/support/voidptr_test.py
@@ -38,9 +38,21 @@ class PySide2Support(unittest.TestCase):
# a C++ object, a wrapped Shiboken Object type,
# an object implementing the Python Buffer interface,
# or another VoidPtr object.
- ba = QByteArray(b"Hello world")
- voidptr = VoidPtr(ba)
- self.assertIsInstance(voidptr, shiboken.VoidPtr)
+
+ # Original content
+ b = b"Hello world"
+ ba = QByteArray(b)
+ vp = VoidPtr(ba, ba.size())
+ self.assertIsInstance(vp, shiboken.VoidPtr)
+
+ # Create QByteArray from voidptr byte interpretation
+ nba = QByteArray.fromRawData(vp.toBytes())
+ # Compare original bytes to toBytes()
+ self.assertTrue(b, vp.toBytes())
+ # Compare original with new QByteArray data
+ self.assertTrue(b, nba.data())
+ # Convert original and new to str
+ self.assertTrue(str(b), str(nba))
if __name__ == '__main__':
unittest.main()