aboutsummaryrefslogtreecommitdiffstats
path: root/tests/samplebinding
diff options
context:
space:
mode:
Diffstat (limited to 'tests/samplebinding')
-rw-r--r--tests/samplebinding/CMakeLists.txt1
-rw-r--r--tests/samplebinding/bytearray_bufferprotocol.cpp27
-rw-r--r--tests/samplebinding/bytearray_conversions.h28
-rw-r--r--tests/samplebinding/bytearray_test.py145
-rw-r--r--tests/samplebinding/global.h1
-rw-r--r--tests/samplebinding/typesystem_sample.xml104
6 files changed, 306 insertions, 0 deletions
diff --git a/tests/samplebinding/CMakeLists.txt b/tests/samplebinding/CMakeLists.txt
index 23a3c456c..f63ecf981 100644
--- a/tests/samplebinding/CMakeLists.txt
+++ b/tests/samplebinding/CMakeLists.txt
@@ -14,6 +14,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/base4_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/base5_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/base6_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/blackbox_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/bytearray_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/bucket_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/collector_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/color_wrapper.cpp
diff --git a/tests/samplebinding/bytearray_bufferprotocol.cpp b/tests/samplebinding/bytearray_bufferprotocol.cpp
new file mode 100644
index 000000000..b3a6a83f4
--- /dev/null
+++ b/tests/samplebinding/bytearray_bufferprotocol.cpp
@@ -0,0 +1,27 @@
+#if PY_VERSION_HEX < 0x03000000
+// ByteArray buffer protocol functions
+// See: http://www.python.org/dev/peps/pep-3118/
+extern "C" {
+static Py_ssize_t SbkByteArray_segcountproc(PyObject* self, Py_ssize_t* lenp)
+{
+ if (lenp)
+ *lenp = self->ob_type->tp_as_sequence->sq_length(self);
+ return 1;
+}
+static Py_ssize_t SbkByteArray_readbufferproc(PyObject* self, Py_ssize_t segment, void** ptrptr)
+{
+ if (segment || !Shiboken::Object::isValid(self))
+ return -1;
+
+ ByteArray* cppSelf = Shiboken::Converter<ByteArray*>::toCpp(self);
+ *ptrptr = reinterpret_cast<void*>(const_cast<char*>(cppSelf->data()));
+ return cppSelf->size();
+}
+PyBufferProcs SbkByteArrayBufferProc = {
+ /*bf_getreadbuffer*/ &SbkByteArray_readbufferproc,
+ /*bf_getwritebuffer*/ (writebufferproc)&SbkByteArray_readbufferproc,
+ /*bf_getsegcount*/ &SbkByteArray_segcountproc,
+ /*bf_getcharbuffer*/ (charbufferproc)&SbkByteArray_readbufferproc
+};
+}
+#endif
diff --git a/tests/samplebinding/bytearray_conversions.h b/tests/samplebinding/bytearray_conversions.h
new file mode 100644
index 000000000..79a070d7b
--- /dev/null
+++ b/tests/samplebinding/bytearray_conversions.h
@@ -0,0 +1,28 @@
+namespace Shiboken {
+inline bool Converter<ByteArray>::checkType(PyObject* pyObj)
+{
+ return ValueTypeConverter<ByteArray>::checkType(pyObj);
+}
+inline bool Converter<ByteArray>::isConvertible(PyObject* pyObj)
+{
+ if (ValueTypeConverter<ByteArray>::isConvertible(pyObj))
+ return true;
+ SbkObjectType* shiboType = reinterpret_cast<SbkObjectType*>(SbkType<ByteArray>());
+ return Shiboken::Converter<const char*>::checkType(pyObj)
+ || (ObjectType::isExternalConvertible(shiboType, pyObj));
+}
+inline ByteArray Converter<ByteArray>::toCpp(PyObject* pyObj)
+{
+ if (pyObj == Py_None)
+ return ByteArray();
+ else if (PyObject_TypeCheck(pyObj, SbkType<ByteArray>()))
+ return *Converter<ByteArray*>::toCpp(pyObj);
+ else if (PyString_Check(pyObj))
+ return ByteArray(PyString_AS_STRING(pyObj), PyString_GET_SIZE(pyObj));
+ return ValueTypeConverter<ByteArray>::toCpp(pyObj);
+}
+inline PyObject* Converter<ByteArray>::toPython(const ByteArray& cppObj)
+{
+ return ValueTypeConverter<ByteArray>::toPython(cppObj);
+}
+}
diff --git a/tests/samplebinding/bytearray_test.py b/tests/samplebinding/bytearray_test.py
new file mode 100644
index 000000000..2eb99601f
--- /dev/null
+++ b/tests/samplebinding/bytearray_test.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# 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 program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# version 2.1 as published by the Free Software Foundation. Please
+# review the following information to ensure the GNU Lesser General
+# Public License version 2.1 requirements will be met:
+# http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+# #
+# This program 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 program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+import unittest
+from os.path import isdir
+from sample import ByteArray
+
+
+class ByteArrayBufferProtocolTest(unittest.TestCase):
+ '''Tests ByteArray implementation of Python buffer protocol.'''
+
+ def testByteArrayBufferProtocol(self):
+ # Tests ByteArray implementation of Python buffer protocol using the os.path.isdir
+ # function which an unicode object or other object implementing the Python buffer protocol.
+ isdir(ByteArray('/tmp'))
+
+
+class ByteArrayConcatenationOperatorTest(unittest.TestCase):
+ '''Test cases for ByteArray concatenation with '+' operator.'''
+
+ def testConcatByteArrayAndPythonString(self):
+ # Test concatenation of a ByteArray with a Python string, in this order.
+ ba = ByteArray('foo')
+ result = ba + '\x00bar'
+ self.assertEqual(type(result), ByteArray)
+ self.assertEqual(result, 'foo\x00bar')
+
+ def testConcatPythonStringAndByteArray(self):
+ # Test concatenation of a Python string with a ByteArray, in this order.
+ concat_python_string_add_qbytearray_worked = True
+ ba = ByteArray('foo')
+ result = 'bar\x00' + ba
+ self.assertEqual(type(result), ByteArray)
+ self.assertEqual(result, 'bar\x00foo')
+
+
+class ByteArrayOperatorEqual(unittest.TestCase):
+ '''TestCase for operator ByteArray == ByteArray.'''
+
+ def testDefault(self):
+ # ByteArray() == ByteArray()
+ obj1 = ByteArray()
+ obj2 = ByteArray()
+ self.assertEqual(obj1, obj2)
+
+ def testSimple(self):
+ # ByteArray(some_string) == ByteArray(some_string)
+ string = 'egg snakes'
+ self.assertEqual(ByteArray(string), ByteArray(string))
+
+ def testPyString(self):
+ # ByteArray(string) == string
+ string = 'my test string'
+ self.assertEqual(ByteArray(string), string)
+
+ def testQString(self):
+ # ByteArray(string) == string
+ string = 'another test string'
+ self.assertEqual(ByteArray(string), string)
+
+
+class ByteArrayOperatorAt(unittest.TestCase):
+ '''TestCase for operator ByteArray[]'''
+
+ def testInRange(self):
+ # ByteArray[x] where x is a valid index.
+ string = 'abcdefgh'
+ obj = ByteArray(string)
+ for i in range(len(string)):
+ self.assertEqual(obj[i], string[i])
+
+ def testInRangeReverse(self):
+ # ByteArray[x] where x is a valid index (reverse order).
+ string = 'abcdefgh'
+ obj = ByteArray(string)
+ for i in range(len(string)-1, 0, -1):
+ self.assertEqual(obj[i], string[i])
+
+ def testOutOfRange(self):
+ # ByteArray[x] where x is out of index.
+ string = '1234567'
+ obj = ByteArray(string)
+ self.assertRaises(IndexError, lambda :obj[len(string)])
+
+ def testNullStrings(self):
+ ba = ByteArray('\x00')
+ self.assertEqual(ba.at(0), '\x00')
+ self.assertEqual(ba[0], '\x00')
+
+
+class ByteArrayOperatorLen(unittest.TestCase):
+ '''Test case for __len__ operator of ByteArray'''
+
+ def testBasic(self):
+ '''ByteArray __len__'''
+ self.assertEqual(len(ByteArray()), 0)
+ self.assertEqual(len(ByteArray('')), 0)
+ self.assertEqual(len(ByteArray(' ')), 1)
+ self.assertEqual(len(ByteArray('yabadaba')), 8)
+
+
+class ByteArrayAndPythonStr(unittest.TestCase):
+ '''Test case for __str__ operator of ByteArray'''
+
+ def testStrOperator(self):
+ '''ByteArray __str__'''
+ self.assertEqual(ByteArray().__str__(), '')
+ self.assertEqual(ByteArray('').__str__(), '')
+ self.assertEqual(ByteArray('aaa').__str__(), 'aaa')
+
+ def testPythonStrAndNull(self):
+ s1 = "123\000321"
+ ba = ByteArray(s1)
+ s2 = ba.data()
+ self.assertEqual(s1, s2)
+ self.assertEqual(type(s1), type(s2))
+ self.assertEqual(s1, ba)
+ self.assertNotEqual(type(s1), type(ba))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/samplebinding/global.h b/tests/samplebinding/global.h
index 08f45b1df..164e992a9 100644
--- a/tests/samplebinding/global.h
+++ b/tests/samplebinding/global.h
@@ -1,5 +1,6 @@
#include "abstract.h"
#include "blackbox.h"
+#include "bytearray.h"
#include "bucket.h"
#include "collector.h"
#include "complex.h"
diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml
index 9624ba27a..547710a52 100644
--- a/tests/samplebinding/typesystem_sample.xml
+++ b/tests/samplebinding/typesystem_sample.xml
@@ -1422,6 +1422,110 @@
</modify-function>
</value-type>
+ <value-type name="ByteArray" hash-function="ByteArray::hash">
+ <conversion-rule file="bytearray_conversions.h"/>
+ <modify-function signature="ByteArray(const char*,int)" remove="all" />
+ <modify-function signature="ByteArray(const char*)">
+ <!-- Keep \x00 bytes passed in Python strings. -->
+ <modify-argument index="1">
+ <replace-type modified-type="PyString"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ %0 = new %TYPE(PyString_AS_STRING(%PYARG_1), PyString_GET_SIZE(%PYARG_1));
+ </inject-code>
+ </modify-function>
+
+ <!-- buffer protocol -->
+ <inject-code class="native" position="beginning" file="bytearray_bufferprotocol.cpp" />
+ <inject-code class="target" position="end">
+ #if PY_VERSION_HEX &lt; 0x03000000
+ Shiboken::SbkType&lt;ByteArray&gt;()->tp_as_buffer = &amp;SbkByteArrayBufferProc;
+ Shiboken::SbkType&lt;ByteArray&gt;()->tp_flags |= Py_TPFLAGS_HAVE_GETCHARBUFFER;
+ #endif
+ </inject-code>
+
+ <modify-function signature="data() const">
+ <inject-code class="target" position="beginning">
+ %PYARG_0 = PyString_FromStringAndSize(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.size());
+ </inject-code>
+ </modify-function>
+
+ <modify-function signature="hash(const ByteArray&amp;)" remove="all" />
+ <modify-function signature="append(const char*)" remove="all" />
+ <modify-function signature="append(const char*,int)" remove="all" />
+ <modify-function signature="operator==(const char*,ByteArray)" remove="all" />
+ <modify-function signature="operator==(ByteArray,const char*)" remove="all" />
+ <modify-function signature="operator!=(const char*,ByteArray)" remove="all" />
+ <modify-function signature="operator!=(ByteArray,const char*)" remove="all" />
+ <modify-function signature="operator+(ByteArray,const char*)" remove="all" />
+ <modify-function signature="operator+(const char*,ByteArray)" remove="all" />
+ <modify-function signature="operator+=(const char*)" remove="all" />
+ <modify-function signature="operator[](int)const" remove="all"/>
+
+ <add-function signature="operator+(PyUnicode)">
+ <inject-code>
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ if (!data.isNull()) {
+ ByteArray ba(*%CPPSELF);
+ ba.append(PyString_AS_STRING(data.object()), PyString_GET_SIZE(data.object()));
+ %PYARG_0 = %CONVERTTOPYTHON[ByteArray](ba);
+ }
+ </inject-code>
+ </add-function>
+ <add-function signature="operator+(PyUnicode,ByteArray)">
+ <inject-code>
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ if (!data.isNull()) {
+ ByteArray ba(PyString_AS_STRING(data.object()), PyString_GET_SIZE(data.object()));
+ ba.append(*%CPPSELF);
+ %PYARG_0 = %CONVERTTOPYTHON[ByteArray](ba);
+ }
+ </inject-code>
+ </add-function>
+ <add-function signature="operator+(PyString,ByteArray)">
+ <inject-code>
+ ByteArray ba(PyString_AS_STRING(%PYARG_1), PyString_GET_SIZE(%PYARG_1));
+ %PYARG_0 = %CONVERTTOPYTHON[ByteArray](ba + *%CPPSELF);
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__repr__" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ ByteArray ba(((PyObject*)%PYSELF)->ob_type->tp_name);
+ ba += '(';
+ Shiboken::AutoDecRef contents(PyObject_Repr(PyString_FromStringAndSize(%CPPSELF.data(), %CPPSELF.size())));
+ ba += PyString_AS_STRING(contents.object());
+ ba += ")";
+ %PYARG_0 = PyString_FromStringAndSize(ba.data(), ba.size());
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__str__" return-type="PyString">
+ <inject-code class="target" position="beginning">
+ %PYARG_0 = PyString_FromStringAndSize(%CPPSELF.data(), %CPPSELF.size());
+ </inject-code>
+ </add-function>
+
+ <add-function signature="__len__">
+ <inject-code class="target" position="beginning">
+ return %CPPSELF.size();
+ </inject-code>
+ </add-function>
+ <add-function signature="__getitem__">
+ <inject-code class="target" position="beginning">
+ if (_i &lt; 0 || _i >= %CPPSELF.size()) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return 0;
+ } else {
+ char res[2];
+ res[0] = %CPPSELF.at(_i);
+ res[1] = 0;
+ return PyString_FromStringAndSize(res, 1);
+ }
+ </inject-code>
+ </add-function>
+ </value-type>
+
<value-type name="StrList">
<add-function signature="__len__" >
<inject-code class="target" position="end">