Skip to content

Commit e132d96

Browse files
usiemsmrbean-bremen
authored andcommitted
Support QByteArrayView arguments + return values
1 parent c7a13c6 commit e132d96

File tree

5 files changed

+78
-12
lines changed

5 files changed

+78
-12
lines changed

generator/main.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,12 @@ int main(int argc, char *argv[])
203203
printf("Parsing typesystem file [%s]\n", qPrintable(typesystemFileName));
204204
fflush(stdout);
205205
ReportHandler::setContext("Typesystem");
206-
if (!TypeDatabase::instance()->parseFile(typesystemFileName, qtVersion))
206+
if (TypeDatabase::instance()->parseFile(typesystemFileName, qtVersion)) {
207+
TypeDatabase::instance()->finalSetup();
208+
}
209+
else {
207210
qFatal("Cannot parse file: '%s'", qPrintable(typesystemFileName));
211+
}
208212

209213
printf("PreProcessing - Generate [%s] using [%s] and include-paths [%s]\n",
210214
qPrintable(pp_file), qPrintable(fileName), qPrintable(args.value("include-paths")));

generator/typesystem.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,6 +1573,19 @@ TypeDatabase::TypeDatabase() : m_suppressWarnings(true)
15731573
addRemoveFunctionToTemplates(this);
15741574
}
15751575

1576+
void TypeDatabase::finalSetup()
1577+
{
1578+
TypeEntry* byteArrayType = findType("QByteArray");
1579+
if (byteArrayType) {
1580+
// Support QByteArrayView as alternative parameter type.
1581+
// Using StringTypeEntry for it, because no wrappers are generated for those types
1582+
StringTypeEntry* e = new StringTypeEntry("QByteArrayView");
1583+
e->setPreferredConversion(false);
1584+
e->setEquivalentType(byteArrayType);
1585+
addType(e);
1586+
}
1587+
}
1588+
15761589
bool TypeDatabase::parseFile(const QString &filename, unsigned int qtVersion, bool generate)
15771590
{
15781591
QFile file(filename);

generator/typesystem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,7 @@ class TypeDatabase
12341234
QString filename() const { return "typesystem.txt"; }
12351235

12361236
bool parseFile(const QString &filename, unsigned int qtVersion, bool generate = true);
1237+
void finalSetup();
12371238

12381239
private:
12391240
bool m_suppressWarnings;

src/PythonQtConversion.cpp

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ int PythonQtConv::stringRefTypeId = 0;
5757
#else
5858
#include <QStringView>
5959
#include <QAnyStringView>
60+
#include <QByteArrayView>
6061

6162
int PythonQtConv::stringViewTypeId = 0;
6263
int PythonQtConv::anyStringViewTypeId = 0;
64+
int PythonQtConv::byteArrayViewTypeId = 0;
6365
#endif
6466

6567
QHash<int, PythonQtConvertMetaTypeToPythonCB*> PythonQtConv::_metaTypeToPythonConverters;
@@ -399,6 +401,9 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
399401

400402
if (PyObject_TypeCheck(obj, &PythonQtInstanceWrapper_Type) &&
401403
info.typeId != PythonQtMethodInfo::Variant &&
404+
#if QT_VERSION >= 0x060000
405+
info.typeId != byteArrayViewTypeId && // this case is handled later on
406+
#endif
402407
!PythonQt::priv()->isPythonQtAnyObjectPtrMetaId(info.typeId)) {
403408
// if we have a Qt wrapper object and if we do not need a QVariant, we do the following:
404409
// (the Variant case is handled below in a switch)
@@ -597,13 +602,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
597602
break;
598603
case QMetaType::QByteArray:
599604
{
600-
QByteArray bytes = PyObjGetBytes(obj, strict, ok);
601-
if (!ok && !strict) {
602-
// since Qt uses QByteArray in many places for identifier strings,
603-
// we need to allow implicit conversion from unicode as well.
604-
// We allow that for both Python 2.x and 3.x to be compatible.
605-
bytes = PyObjGetString(obj, true, ok).toUtf8();
606-
}
605+
QByteArray bytes = PyObjGetBytesAllowString(obj, strict, ok);
607606
if (ok) {
608607
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,frame, QVariant(bytes), ptr);
609608
ptr = (void*)((QVariant*)ptr)->constData();
@@ -680,6 +679,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
680679
}
681680
#else
682681
if (info.typeId == stringViewTypeId) {
682+
// Handle QStringView, which needs a reference to a persistent QString
683683
QString str = PyObjGetString(obj, strict, ok);
684684
if (ok) {
685685
void* ptr2 = nullptr;
@@ -694,7 +694,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
694694
}
695695
}
696696
else if (info.typeId == anyStringViewTypeId) {
697-
// Handle QStringView et al, which need a reference to a persistent QString
697+
// Handle QAnyStringView, which needs a reference to a persistent QString
698698
QString str = PyObjGetString(obj, strict, ok);
699699
if (ok) {
700700
void* ptr2 = nullptr;
@@ -708,6 +708,21 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
708708
return nullptr;
709709
}
710710
}
711+
else if (info.typeId == byteArrayViewTypeId) {
712+
// Handle QByteArrayView, which needs a reference to a persistent QByteArray
713+
QByteArray ba = PyObjGetBytesAllowString(obj, strict, ok);
714+
if (ok) {
715+
void* ptr2 = nullptr;
716+
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(nullptr, frame, QVariant(ba), ptr2);
717+
PythonQtArgumentFrame_ADD_VARIANT_VALUE_IF_NEEDED(alreadyAllocatedCPPObject, frame,
718+
QVariant::fromValue(QByteArrayView(*((const QByteArray*)((QVariant*)ptr2)->constData()))), ptr);
719+
ptr = (void*)((QVariant*)ptr)->constData();
720+
return ptr;
721+
}
722+
else {
723+
return nullptr;
724+
}
725+
}
711726
#endif
712727

713728
if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) {
@@ -847,6 +862,15 @@ QByteArray PythonQtConv::PyObjGetBytes(PyObject* val, bool /*strict*/, bool& ok)
847862
// TODO: support buffer objects in general
848863
QByteArray r;
849864
ok = true;
865+
if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) {
866+
// check if we already have a QByteArray wrapper here
867+
PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)val;
868+
bool baOk;
869+
QByteArray* baPtr = (QByteArray*)castWrapperTo(wrapper, "QByteArray", baOk);
870+
if (baOk && baPtr) {
871+
return *baPtr;
872+
}
873+
}
850874
if (PyBytes_Check(val)) {
851875
r = QByteArray(PyBytes_AS_STRING(val), PyBytes_GET_SIZE(val));
852876
} else {
@@ -855,6 +879,18 @@ QByteArray PythonQtConv::PyObjGetBytes(PyObject* val, bool /*strict*/, bool& ok)
855879
return r;
856880
}
857881

882+
QByteArray PythonQtConv::PyObjGetBytesAllowString(PyObject* val, bool strict, bool& ok)
883+
{
884+
QByteArray bytes = PyObjGetBytes(val, strict, ok);
885+
if (!ok && !strict) {
886+
// since Qt uses QByteArray in many places for identifier strings,
887+
// we need to allow implicit conversion from unicode as well.
888+
// We allow that for both Python 2.x and 3.x to be compatible.
889+
bytes = PyObjGetString(val, true, ok).toUtf8();
890+
}
891+
return bytes;
892+
}
893+
858894
bool PythonQtConv::PyObjGetBool(PyObject* val, bool strict, bool &ok) {
859895
bool d = false;
860896
ok = false;
@@ -1560,17 +1596,23 @@ PyObject* PythonQtConv::createCopyFromMetaType( int type, const void* data )
15601596
#if QT_VERSION < 0x060000
15611597
PyObject* PythonQtConv::convertFromStringRef(const void* inObject, int /*metaTypeId*/)
15621598
{
1563-
return PythonQtConv::QStringToPyObject(((QStringRef*)inObject)->toString());
1599+
return QStringToPyObject(((QStringRef*)inObject)->toString());
15641600
}
15651601
#else
15661602
PyObject* PythonQtConv::convertFromStringView(const void* inObject, int /*metaTypeId*/)
15671603
{
1568-
return PythonQtConv::QStringToPyObject(((QStringView*)inObject)->toString());
1604+
return QStringToPyObject(((QStringView*)inObject)->toString());
15691605
}
15701606

15711607
PyObject* PythonQtConv::convertFromAnyStringView(const void* inObject, int /*metaTypeId*/)
15721608
{
1573-
return PythonQtConv::QStringToPyObject(((QAnyStringView*)inObject)->toString());
1609+
return QStringToPyObject(((QAnyStringView*)inObject)->toString());
1610+
}
1611+
1612+
PyObject* PythonQtConv::convertFromByteArrayView(const void* inObject, int)
1613+
{
1614+
QByteArray ba = ((QByteArrayView*)inObject)->toByteArray();
1615+
return createCopyFromMetaType(QMetaType::QByteArray, &ba);
15741616
}
15751617
#endif
15761618

@@ -1634,6 +1676,8 @@ void PythonQtConv::registerStringViewTypes()
16341676
PythonQtConv::registerMetaTypeToPythonConverter(stringViewTypeId, PythonQtConv::convertFromStringView);
16351677
anyStringViewTypeId = qRegisterMetaType<QAnyStringView>("QAnyStringView");
16361678
PythonQtConv::registerMetaTypeToPythonConverter(anyStringViewTypeId, PythonQtConv::convertFromAnyStringView);
1679+
byteArrayViewTypeId = qRegisterMetaType<QByteArrayView>("QByteArrayView");
1680+
PythonQtConv::registerMetaTypeToPythonConverter(byteArrayViewTypeId, PythonQtConv::convertFromByteArrayView);
16371681
#endif
16381682
}
16391683

src/PythonQtConversion.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ class PYTHONQT_EXPORT PythonQtConv {
132132
static QString PyObjGetString(PyObject* val, bool strict, bool &ok);
133133
//! get bytes from py object
134134
static QByteArray PyObjGetBytes(PyObject* val, bool strict, bool &ok);
135+
//! get bytes from py object, also allows Python string
136+
static QByteArray PyObjGetBytesAllowString(PyObject* val, bool strict, bool& ok);
135137
//! get int from py object
136138
static int PyObjGetInt(PyObject* val, bool strict, bool &ok);
137139
//! get int64 from py object
@@ -190,6 +192,7 @@ class PYTHONQT_EXPORT PythonQtConv {
190192
#else
191193
static PyObject* convertFromStringView(const void* inObject, int /*metaTypeId*/);
192194
static PyObject* convertFromAnyStringView(const void* inObject, int /*metaTypeId*/);
195+
static PyObject* convertFromByteArrayView(const void* inObject, int /*metaTypeId*/);
193196
#endif
194197

195198
//! Returns the name of the equivalent CPP type (for signals and slots)
@@ -226,6 +229,7 @@ class PYTHONQT_EXPORT PythonQtConv {
226229
#else
227230
static int stringViewTypeId;
228231
static int anyStringViewTypeId;
232+
static int byteArrayViewTypeId;
229233
#endif
230234
};
231235

0 commit comments

Comments
 (0)