diff options
-rw-r--r-- | generator/overloaddata.cpp | 11 | ||||
-rw-r--r-- | generator/shibokengenerator.cpp | 2 | ||||
-rw-r--r-- | libshiboken/CMakeLists.txt | 2 | ||||
-rw-r--r-- | libshiboken/shiboken.h | 1 | ||||
-rw-r--r-- | libshiboken/shibokenbuffer.cpp | 52 | ||||
-rw-r--r-- | libshiboken/shibokenbuffer.h | 68 | ||||
-rw-r--r-- | tests/samplebinding/typesystem_sample.xml | 12 |
7 files changed, 137 insertions, 11 deletions
diff --git a/generator/overloaddata.cpp b/generator/overloaddata.cpp index 6bb06fe57..7ec8cf07f 100644 --- a/generator/overloaddata.cpp +++ b/generator/overloaddata.cpp @@ -163,6 +163,8 @@ void OverloadData::sortNextOverloads() int qstringIndex = 0; bool checkQVariant = false; int qvariantIndex = 0; + bool checkPyBuffer = false; + int pyBufferIndex = 0; // Primitive types that are not int, long, short, // char and their respective unsigned counterparts. @@ -194,6 +196,9 @@ void OverloadData::sortNextOverloads() } else if (!checkPySequence && typeName == "PySequence") { checkPySequence = true; pySeqIndex = sortData.lastProcessedItemId(); + } else if (!checkPyBuffer && typeName == "PyBuffer") { + checkPyBuffer = true; + pyBufferIndex = sortData.lastProcessedItemId(); } else if (!checkQVariant && typeName == "QVariant") { checkQVariant = true; qvariantIndex = sortData.lastProcessedItemId(); @@ -315,12 +320,16 @@ void OverloadData::sortNextOverloads() } - if ((checkPySequence || checkPyObject) + if ((checkPySequence || checkPyObject || checkPyBuffer) && !targetTypeEntryName.contains("PyObject") + && !targetTypeEntryName.contains("PyBuffer") && !targetTypeEntryName.contains("PySequence")) { if (checkPySequence) { // PySequence will be checked after all more specific types, but before PyObject. graph.addEdge(targetTypeId, pySeqIndex); + } else if (checkPyBuffer) { + // PySequence will be checked after all more specific types, but before PyObject. + graph.addEdge(targetTypeId, pyBufferIndex); } else { // Add dependency on PyObject, so its check is the last one (too generic). graph.addEdge(targetTypeId, pyobjectIndex); diff --git a/generator/shibokengenerator.cpp b/generator/shibokengenerator.cpp index de96d03ac..8d98869d7 100644 --- a/generator/shibokengenerator.cpp +++ b/generator/shibokengenerator.cpp @@ -865,6 +865,8 @@ QString ShibokenGenerator::guessCPythonCheckFunction(const QString& type) metaType = 0; } else if (type == "PyTypeObject") { retval = "PyType_Check"; + } else if (type == "PyBuffer") { + retval = "Shiboken::Buffer::checkType"; } else { retval = QString("%1_Check").arg(type); } diff --git a/libshiboken/CMakeLists.txt b/libshiboken/CMakeLists.txt index 0cf3f3d21..38aa46bc7 100644 --- a/libshiboken/CMakeLists.txt +++ b/libshiboken/CMakeLists.txt @@ -29,6 +29,7 @@ sbkenum.cpp bindingmanager.cpp threadstatesaver.cpp typeresolver.cpp +shibokenbuffer.cpp ) include_directories(${CMAKE_CURRENT_SOURCE_DIR} @@ -55,6 +56,7 @@ install(FILES shibokenmacros.h threadstatesaver.h typeresolver.h + shibokenbuffer.h DESTINATION include/shiboken${shiboken_SUFFIX}) install(TARGETS libshiboken EXPORT shiboken LIBRARY DESTINATION "${LIB_INSTALL_DIR}" diff --git a/libshiboken/shiboken.h b/libshiboken/shiboken.h index 6a2df306c..f2087fe0e 100644 --- a/libshiboken/shiboken.h +++ b/libshiboken/shiboken.h @@ -34,6 +34,7 @@ #include "sbkenum.h" #include "shibokenmacros.h" #include "typeresolver.h" +#include "shibokenbuffer.h" #endif // SHIBOKEN_H diff --git a/libshiboken/shibokenbuffer.cpp b/libshiboken/shibokenbuffer.cpp new file mode 100644 index 000000000..67b3ba726 --- /dev/null +++ b/libshiboken/shibokenbuffer.cpp @@ -0,0 +1,52 @@ +/* +* This file is part of the Shiboken Python Bindings Generator project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "shibokenbuffer.h" +#include <cstdlib> +#include <cstring> + +bool Shiboken::Buffer::checkType(PyObject* pyObj) +{ + return PyObject_CheckReadBuffer(pyObj); +} + +void* Shiboken::Buffer::getPointer(PyObject* pyObj, Py_ssize_t* size) +{ + const void* buffer = 0; + Py_ssize_t bufferSize = 0; + + PyObject_AsReadBuffer(pyObj, &buffer, &bufferSize); + + if (size) + *size = bufferSize; + return const_cast<void*>(buffer); +} + +PyObject* Shiboken::Buffer::newObject(void* memory, Py_ssize_t size, Type type) +{ + return type == ReadOnly ? PyBuffer_FromMemory(memory, size) : PyBuffer_FromReadWriteMemory(memory, size); +} + +PyObject* Shiboken::Buffer::newObject(const void* memory, Py_ssize_t size) +{ + return newObject(const_cast<void*>(memory), size, ReadOnly); +} diff --git a/libshiboken/shibokenbuffer.h b/libshiboken/shibokenbuffer.h new file mode 100644 index 000000000..8f8e91dbe --- /dev/null +++ b/libshiboken/shibokenbuffer.h @@ -0,0 +1,68 @@ +/* +* This file is part of the Shiboken Python Bindings Generator project. +* +* Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +* +* Contact: PySide team <contact@pyside.org> +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef SHIBOKEN_BUFFER_H +#define SHIBOKEN_BUFFER_H + +#include <Python.h> +#include "shibokenmacros.h" + +namespace Shiboken +{ + +namespace Buffer +{ + enum Type { + ReadOnly, + WriteOnly, + ReadWrite + }; + + /** + * Creates a new Python buffer pointing to a contiguous memory block at + * \p memory of size \p size. + */ + LIBSHIBOKEN_API PyObject* newObject(void* memory, Py_ssize_t size, Type type); + + /** + * Creates a new <b>read only</b> Python buffer pointing to a contiguous memory block at + * \p memory of size \p size. + */ + LIBSHIBOKEN_API PyObject* newObject(const void* memory, Py_ssize_t size); + + /** + * Check if is ok to use \p pyObj as argument in all function under Shiboken::Buffer namespace. + */ + LIBSHIBOKEN_API bool checkType(PyObject* pyObj); + + /** + * Returns a pointer to the memory pointed by the buffer \p pyObj, \p size is filled with the buffer + * size if not null. + * + * If the \p pyObj is a non-contiguous buffer a Python error is set. + */ + LIBSHIBOKEN_API void* getPointer(PyObject* pyObj, Py_ssize_t* size = 0); + +} // namespace Buffer +} // namespace Shiboken + +#endif
\ No newline at end of file diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml index 338719372..87ee5512f 100644 --- a/tests/samplebinding/typesystem_sample.xml +++ b/tests/samplebinding/typesystem_sample.xml @@ -1231,20 +1231,12 @@ </modify-function> <template name="buffer_argument"> - unsigned char* %out; - if (PyObject_CheckReadBuffer(%PYARG_1)) { - PyBufferProcs* bufferProcs = %PYARG_1->ob_type->tp_as_buffer; - void* ptr; - bufferProcs->bf_getreadbuffer(%PYARG_1, 0, &ptr); - %out = (unsigned char*) ptr; - } else { - PyErr_SetString(PyExc_TypeError, "The object must support buffer protocol with just one segment."); - } + unsigned char* %out = (unsigned char*) Shiboken::Buffer::getPointer(%PYARG_1); </template> <modify-function signature="strBufferOverloads(unsigned char*,int)"> <modify-argument index="1"> - <replace-type modified-type="PyObject"/> + <replace-type modified-type="PyBuffer"/> <conversion-rule class="native"> <insert-template name="buffer_argument" /> </conversion-rule> |