/* This file contains code for conversion between various (often nested) mapped types which are not wrapped by PyQt: - QVector< QVector > - QVector< QVector< QVector > > - QList< QList > - QList - QSet - QSet - QSet - QMap > - QMap - QMap - QMap - QMap - QMultiMap - QMultiMap - QMap - QList< QPair< QString, QList > > - QVector - QMap - NULL QVariant which is missing in PyQt5 with sip.enableautoconversion */ template %MappedType QVector< QVector > { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the list. PyObject *l; if ((l = PyList_New(sipCpp->size())) == NULL) return NULL; const sipTypeDef *qvector_type = sipFindType("QVector"); // Set the list elements. for (int i = 0; i < sipCpp->size(); ++i) { QVector *t = new QVector(sipCpp->at(i)); PyObject *tobj; if ((tobj = sipConvertFromNewType(t, qvector_type, NULL)) == NULL) { Py_DECREF(l); delete t; return NULL; } PyList_SET_ITEM(l, i, tobj); } return l; %End %ConvertToTypeCode const sipTypeDef *qvector_type = sipFindType("QVector"); // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyList_Check(sipPy)) return 0; for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i), qvector_type, SIP_NOT_NONE)) return 0; return 1; } QVector< QVector > *ql = new QVector< QVector >; for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) { int state; //TYPE *t = reinterpret_cast(sipConvertToType(PyList_GET_ITEM(sipPy, i), sipType_TYPE, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); QVector *t = reinterpret_cast< QVector * >(sipConvertToType(PyList_GET_ITEM(sipPy, i), qvector_type, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); if (*sipIsErr) { sipReleaseType(t, qvector_type, state); delete ql; return 0; } ql->append(*t); sipReleaseType(t, qvector_type, state); } *sipCppPtr = ql; return sipGetState(sipTransferObj); %End }; template %MappedType QVector< QVector< QVector > > { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the list. PyObject *l; if ((l = PyList_New(sipCpp->size())) == NULL) return NULL; const sipTypeDef *qvector_type = sipFindType("QVector >"); // Set the list elements. for (int i = 0; i < sipCpp->size(); ++i) { QVector > *t = new QVector >(sipCpp->at(i)); PyObject *tobj; if ((tobj = sipConvertFromNewType(t, qvector_type, NULL)) == NULL) { Py_DECREF(l); delete t; return NULL; } PyList_SET_ITEM(l, i, tobj); } return l; %End %ConvertToTypeCode const sipTypeDef *qvector_type = sipFindType("QVector >"); // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyList_Check(sipPy)) return 0; for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i), qvector_type, SIP_NOT_NONE)) return 0; return 1; } QVector< QVector< QVector > > *ql = new QVector< QVector< QVector > >; for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) { int state; //TYPE *t = reinterpret_cast(sipConvertToType(PyList_GET_ITEM(sipPy, i), sipType_TYPE, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); QVector > *t = reinterpret_cast< QVector< QVector > * >(sipConvertToType(PyList_GET_ITEM(sipPy, i), qvector_type, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); if (*sipIsErr) { sipReleaseType(t, qvector_type, state); delete ql; return 0; } ql->append(*t); sipReleaseType(t, qvector_type, state); } *sipCppPtr = ql; return sipGetState(sipTransferObj); %End }; template %MappedType QList< QList > { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the list. PyObject *l; if ((l = PyList_New(sipCpp->size())) == NULL) return NULL; const sipTypeDef *qlist_type = sipFindType("QList"); // Set the list elements. for (int i = 0; i < sipCpp->size(); ++i) { QList *t = new QList(sipCpp->at(i)); PyObject *tobj; if ((tobj = sipConvertFromNewType(t, qlist_type, NULL)) == NULL) { Py_DECREF(l); delete t; return NULL; } PyList_SET_ITEM(l, i, tobj); } return l; %End %ConvertToTypeCode const sipTypeDef *qlist_type = sipFindType("QList"); // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyList_Check(sipPy)) return 0; for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i), qlist_type, SIP_NOT_NONE)) return 0; return 1; } QList< QList > *ql = new QList< QList >; for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) { int state; //TYPE *t = reinterpret_cast(sipConvertToType(PyList_GET_ITEM(sipPy, i), sipType_TYPE, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); QList *t = reinterpret_cast< QList * >(sipConvertToType(PyList_GET_ITEM(sipPy, i), qlist_type, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); if (*sipIsErr) { sipReleaseType(t, qlist_type, state); delete ql; return 0; } ql->append(*t); sipReleaseType(t, qlist_type, state); } *sipCppPtr = ql; return sipGetState(sipTransferObj); %End }; %MappedType QSet { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the list. PyObject *l; if ((l = PyList_New(sipCpp->size())) == NULL) return NULL; // Set the list elements. QSet::iterator it = sipCpp->begin(); for (int i = 0; it != sipCpp->end(); ++it, ++i) { PyObject *tobj; if ((tobj = PyLong_FromLong(*it)) == NULL) { Py_DECREF(l); return NULL; } PyList_SET_ITEM(l, i, tobj); } return l; %End %ConvertToTypeCode // Check the type if that is all that is required. if (sipIsErr == NULL) return PyList_Check(sipPy); QSet *qset = new QSet; for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) { qset->insert(PyLong_AsLong(PyList_GET_ITEM(sipPy, i))); } *sipCppPtr = qset; return sipGetState(sipTransferObj); %End }; %MappedType QList { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the list. PyObject *l; if ((l = PyList_New(sipCpp->size())) == NULL) return NULL; // Set the list elements. QList::iterator it = sipCpp->begin(); for (int i = 0; it != sipCpp->end(); ++it, ++i) { PyObject *tobj; if ((tobj = PyLong_FromLong(*it)) == NULL) { Py_DECREF(l); return NULL; } PyList_SET_ITEM(l, i, tobj); } return l; %End %ConvertToTypeCode // Check the type if that is all that is required. if (sipIsErr == NULL) return PyList_Check(sipPy); QList *qlist = new QList; for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) { *qlist << PyLong_AsLong(PyList_GET_ITEM(sipPy, i)); } *sipCppPtr = qlist; return sipGetState(sipTransferObj); %End }; %MappedType QList { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the list. PyObject *l; if ((l = PyList_New(sipCpp->size())) == NULL) return NULL; // Set the list elements. QList::iterator it = sipCpp->begin(); for (int i = 0; it != sipCpp->end(); ++it, ++i) { PyObject *tobj; if ((tobj = PyLong_FromLongLong(*it)) == NULL) { Py_DECREF(l); return NULL; } PyList_SET_ITEM(l, i, tobj); } return l; %End %ConvertToTypeCode // Check the type if that is all that is required. if (sipIsErr == NULL) return PyList_Check(sipPy); QList *qlist = new QList; for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) { *qlist << PyLong_AsLongLong(PyList_GET_ITEM(sipPy, i)); } *sipCppPtr = qlist; return sipGetState(sipTransferObj); %End }; %MappedType QSet { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the list. PyObject *l; if ((l = PyList_New(sipCpp->size())) == NULL) return NULL; // Set the list elements. QSet::iterator it = sipCpp->begin(); for (int i = 0; it != sipCpp->end(); ++it, ++i) { PyObject *tobj; if ((tobj = PyLong_FromLongLong(*it)) == NULL) { Py_DECREF(l); return NULL; } PyList_SET_ITEM(l, i, tobj); } return l; %End %ConvertToTypeCode // Check the type if that is all that is required. if (sipIsErr == NULL) return PyList_Check(sipPy); QSet *qset = new QSet; for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) { qset->insert(PyLong_AsLongLong(PyList_GET_ITEM(sipPy, i))); } *sipCppPtr = qset; return sipGetState(sipTransferObj); %End }; template %MappedType QMap > { %TypeHeaderCode #include #include %End %ConvertFromTypeCode // Create the list. PyObject *d; if ((d = PyDict_New()) == NULL) return NULL; const sipTypeDef *qmap2 = sipFindType("QMap"); // Set the list elements. for (QMap >::iterator it = sipCpp->begin(); it != sipCpp->end(); ++it) { QMap *t = new QMap(*it); PyObject *kobj = PyLong_FromLongLong(it.key()); PyObject *tobj = sipConvertFromNewType(t, qmap2, sipTransferObj); if (kobj == NULL || tobj == NULL || PyDict_SetItem(d, kobj, tobj) < 0) { Py_DECREF(d); if (kobj) { Py_DECREF(kobj); } if (tobj) { Py_DECREF(tobj); } else { delete t; } return NULL; } Py_DECREF(kobj); Py_DECREF(tobj); } return d; %End %ConvertToTypeCode PyObject *kobj, *tobj, *kobj2, *tobj2; Py_ssize_t i = 0; // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyDict_Check(sipPy)) return 0; while (PyDict_Next(sipPy, &i, &kobj, &tobj)) { if (!PyDict_Check(tobj)) return 0; Py_ssize_t j = 0; while (PyDict_Next(tobj, &j, &kobj2, &tobj2)) { if (!sipCanConvertToType(tobj2, sipType_TYPE, SIP_NOT_NONE)) return 0; } } return 1; } QMap > *qm = new QMap >; while (PyDict_Next(sipPy, &i, &kobj, &tobj)) { qint64 k = PyLong_AsLongLong(kobj); // using sipConvertToType to convert directly to QMap doesn't work // and ends with a segfault QMap qm2; Py_ssize_t j = 0; while (PyDict_Next(tobj, &j, &kobj2, &tobj2)) { int k2 = PyLong_AsLong(kobj2); int state; TYPE *t2 = reinterpret_cast(sipConvertToType(tobj2, sipType_TYPE, sipTransferObj,SIP_NOT_NONE,&state,sipIsErr)); if (*sipIsErr) { sipReleaseType(t2, sipType_TYPE, state); delete qm; return 0; } qm2.insert(k2, *t2); sipReleaseType(t2, sipType_TYPE, state); } qm->insert(k, qm2); } *sipCppPtr = qm; return sipGetState(sipTransferObj); %End }; // // copied from PyQt4 QMap and adapted to qint64 // // QMap is implemented as a Python dictionary. template %MappedType QMap { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the dictionary. PyObject *d = PyDict_New(); if (!d) return NULL; // Set the dictionary elements. QMap::const_iterator i = sipCpp->constBegin(); while (i != sipCpp->constEnd()) { TYPE *t = new TYPE(i.value()); PyObject *kobj = PyLong_FromLongLong(i.key()); //PyObject *kobj = SIPLong_FromLong(i.key()); PyObject *tobj = sipConvertFromNewType(t, sipType_TYPE, sipTransferObj); if (kobj == NULL || tobj == NULL || PyDict_SetItem(d, kobj, tobj) < 0) { Py_DECREF(d); if (kobj) { Py_DECREF(kobj); } if (tobj) { Py_DECREF(tobj); } else { delete t; } return NULL; } Py_DECREF(kobj); Py_DECREF(tobj); ++i; } return d; %End %ConvertToTypeCode PyObject *kobj, *tobj; SIP_SSIZE_T i = 0; // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyDict_Check(sipPy)) return 0; while (PyDict_Next(sipPy, &i, &kobj, &tobj)) if (!sipCanConvertToType(tobj, sipType_TYPE, SIP_NOT_NONE)) return 0; return 1; } QMap *qm = new QMap; while (PyDict_Next(sipPy, &i, &kobj, &tobj)) { int state; //, k = SIPLong_AsLong(kobj); qint64 k = PyLong_AsLongLong(kobj); TYPE *t = reinterpret_cast(sipConvertToType(tobj, sipType_TYPE, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); if (*sipIsErr) { sipReleaseType(t, sipType_TYPE, state); delete qm; return 0; } qm->insert(k, *t); sipReleaseType(t, sipType_TYPE, state); } *sipCppPtr = qm; return sipGetState(sipTransferObj); %End }; %MappedType QMap { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the dictionary. PyObject *d = PyDict_New(); if (!d) return NULL; // Set the dictionary elements. QMap::const_iterator i = sipCpp->constBegin(); while (i != sipCpp->constEnd()) { QString *t1 = new QString(i.key()); PyObject *t1obj = sipConvertFromNewType(t1, sipType_QString, sipTransferObj); PyObject *t2obj = PyLong_FromLong( (long) i.value() ); if (t1obj == NULL || t2obj == NULL || PyDict_SetItem(d, t1obj, t2obj) < 0) { Py_DECREF(d); if (t1obj) { Py_DECREF(t1obj); } else { delete t1; } if (t2obj) { Py_DECREF(t2obj); } return NULL; } Py_DECREF(t1obj); Py_DECREF(t2obj); ++i; } return d; %End %ConvertToTypeCode PyObject *t1obj, *t2obj; Py_ssize_t i = 0; // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyDict_Check(sipPy)) return 0; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { if (!sipCanConvertToType(t1obj, sipType_QString, SIP_NOT_NONE)) return 0; } return 1; } QMap *qm = new QMap; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { int state; QString *t1 = reinterpret_cast(sipConvertToType(t1obj, sipType_QString, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); int t2 = PyLong_AsLong(t1obj); if (*sipIsErr) { sipReleaseType(t1, sipType_QString, state); delete qm; return 0; } qm->insert(*t1, t2); sipReleaseType(t1, sipType_QString, state); } *sipCppPtr = qm; return sipGetState(sipTransferObj); %End }; template %MappedType QMap { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the dictionary. PyObject *d = PyDict_New(); if (!d) return NULL; // Set the dictionary elements. QMap::const_iterator i = sipCpp->constBegin(); while (i != sipCpp->constEnd()) { TYPE1 *t1 = new TYPE1(i.key()); TYPE2 *t2 = i.value(); PyObject *t1obj = sipConvertFromNewType(t1, sipType_TYPE1, sipTransferObj); PyObject *t2obj = sipConvertFromType(t2, sipType_TYPE2, sipTransferObj); if (t1obj == NULL || t2obj == NULL || PyDict_SetItem(d, t1obj, t2obj) < 0) { Py_DECREF(d); if (t1obj) Py_DECREF(t1obj); else delete t1; if (t2obj) Py_DECREF(t2obj); else delete t2; return NULL; } Py_DECREF(t1obj); Py_DECREF(t2obj); ++i; } return d; %End %ConvertToTypeCode PyObject *t1obj, *t2obj; Py_ssize_t i = 0; // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyDict_Check(sipPy)) return 0; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { if (!sipCanConvertToType(t1obj, sipType_TYPE1, SIP_NOT_NONE)) return 0; if (!sipCanConvertToType(t2obj, sipType_TYPE2, SIP_NOT_NONE)) return 0; } return 1; } QMap *qm = new QMap; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { int state1, state2; TYPE1 *t1 = reinterpret_cast(sipConvertToType(t1obj, sipType_TYPE1, sipTransferObj, SIP_NOT_NONE, &state1, sipIsErr)); TYPE2 *t2 = reinterpret_cast(sipConvertToType(t2obj, sipType_TYPE2, sipTransferObj, SIP_NOT_NONE, &state2, sipIsErr)); if (*sipIsErr) { sipReleaseType(t1, sipType_TYPE1, state1); sipReleaseType(t2, sipType_TYPE2, state2); delete qm; return 0; } qm->insert(*t1, t2); sipReleaseType(t1, sipType_TYPE1, state1); sipReleaseType(t2, sipType_TYPE2, state2); } *sipCppPtr = qm; return sipGetState(sipTransferObj); %End }; template %MappedType QMap { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the dictionary. PyObject *d = PyDict_New(); if (!d) return NULL; // Set the dictionary elements. QMap::iterator i; for (i = sipCpp->begin(); i != sipCpp->end(); ++i) { PyObject *t1obj = PyFloat_FromDouble(i.key()); TYPE *t2 = &i.value(); PyObject *t2obj = sipConvertFromType(t2, sipType_TYPE, sipTransferObj); if (t1obj == NULL || t2obj == NULL || PyDict_SetItem(d, t1obj, t2obj) < 0) { Py_DECREF(d); if (t1obj) Py_DECREF(t1obj); if (t2obj) Py_DECREF(t2obj); return NULL; } Py_DECREF(t1obj); Py_DECREF(t2obj); } return d; %End %ConvertToTypeCode PyObject *t1obj, *t2obj; Py_ssize_t i = 0; // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyDict_Check(sipPy)) return 0; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { if (!PyFloat_Check(t1obj)) return 0; if (!sipCanConvertToType(t2obj, sipType_TYPE, SIP_NOT_NONE)) return 0; } return 1; } QMap *qm = new QMap; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { int state; double k = PyFloat_AsDouble(t1obj); TYPE *t2 = reinterpret_cast(sipConvertToType(t2obj, sipType_TYPE, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); if (*sipIsErr) { sipReleaseType(t2, sipType_TYPE, state); delete qm; return 0; } qm->insert(k, *t2); sipReleaseType(t2, sipType_TYPE, state); } *sipCppPtr = qm; return sipGetState(sipTransferObj); %End }; template %MappedType QMap > { %TypeHeaderCode #include #include %End %ConvertFromTypeCode // Create the dictionary. PyObject *d = PyDict_New(); if (!d) return NULL; // Set the dictionary elements. QMap >::const_iterator i; for (i = sipCpp->constBegin(); i != sipCpp->constEnd(); ++i) { QString *t1 = new QString(i.key()); PyObject *t1obj = sipConvertFromNewType(t1, sipType_QString, sipTransferObj); // build list for dictionary value QList< TYPE2 > sourceList = i.value(); PyObject *t2list = PyList_New( sourceList.size() ); if ( t2list ) { for ( int j = 0; j < sourceList.size(); j++ ) { TYPE2 *t = new TYPE2(sourceList.at(j)); PyObject *lobj = sipConvertFromNewType(t, sipType_TYPE2, sipTransferObj); PyList_SetItem( t2list, j, lobj ); } } if (t1obj == NULL || t2list == NULL || PyDict_SetItem(d, t1obj, t2list) < 0) { Py_DECREF(d); if (t1obj) Py_DECREF(t1obj); if (t2list) Py_DECREF(t2list); return NULL; } Py_DECREF(t1obj); Py_DECREF(t2list); } return d; %End %ConvertToTypeCode PyObject *t1obj, *t2obj; Py_ssize_t i = 0; const sipTypeDef *qlist_type = sipFindType("QList"); // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyDict_Check(sipPy)) return 0; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { if (!sipCanConvertToType(t1obj, sipType_QString, SIP_NOT_NONE)) return 0; } return 1; } QMap > *qm = new QMap >; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { int state; QString *t1 = reinterpret_cast(sipConvertToType(t1obj, sipType_QString, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); QList *t2 = reinterpret_cast< QList * >(sipConvertToType(t2obj, qlist_type, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); if (*sipIsErr) { sipReleaseType(t2, sipType_TYPE2, state); delete qm; return 0; } if ( t2 ) qm->insert(*t1, *t2); else qm->insert(*t1, QList() ); sipReleaseType(t1, sipType_QString, state); sipReleaseType(t2, sipType_TYPE2, state); } *sipCppPtr = qm; return sipGetState(sipTransferObj); %End }; template %MappedType QMultiMap { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the dictionary. PyObject *d = PyDict_New(); if (!d) return NULL; // Set the dictionary elements. QMultiMap::iterator i = sipCpp->begin(); while (i != sipCpp->end()) { const double t1 = i.key(); TYPE2 *t2 = &i.value(); PyObject *t1obj = PyFloat_FromDouble(t1); PyObject *t2obj = sipConvertFromType(t2, sipType_TYPE2, sipTransferObj); if (PyDict_GetItem(d, t1obj) == NULL) { PyObject *lst = PyList_New(0); PyDict_SetItem(d, t1obj, lst); if (lst) { Py_DECREF(lst); } } if (t1obj == NULL || t2obj == NULL || PyList_Append(PyDict_GetItem(d, t1obj), t2obj) < 0) { Py_DECREF(d); if (t1obj) { Py_DECREF(t1obj); } if (t2obj) { Py_DECREF(t2obj); } return NULL; } Py_DECREF(t1obj); Py_DECREF(t2obj); ++i; } return d; %End %ConvertToTypeCode PyObject *t1obj, *t2obj; Py_ssize_t i = 0; // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyDict_Check(sipPy)) return 0; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { for (int i = 0; i < PyList_GET_SIZE(t2obj); ++i) { if (!sipCanConvertToType(PyList_GET_ITEM(t2obj, i), sipType_TYPE2, SIP_NOT_NONE)) return 0; } } return 1; } QMultiMap *qm = new QMultiMap; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { int state2; double k = PyFloat_AsDouble(t1obj); for (int i = 0; i < PyList_GET_SIZE(t2obj); ++i) { TYPE2 *t2 = reinterpret_cast(sipConvertToType(PyList_GET_ITEM(t2obj, i), sipType_TYPE2, sipTransferObj, SIP_NOT_NONE, &state2, sipIsErr)); if (*sipIsErr) { sipReleaseType(t2, sipType_TYPE2, state2); delete qm; return 0; } qm->insert(k, *t2); sipReleaseType(t2, sipType_TYPE2, state2); } } *sipCppPtr = qm; return sipGetState(sipTransferObj); %End }; template %MappedType QMultiMap { %TypeHeaderCode #include %End %ConvertFromTypeCode // Convert to Python: create the dictionary. PyObject *d = PyDict_New(); if (!d) { return NULL; } // Set the dictionary elements. QMultiMap::iterator i = sipCpp->begin(); while (i != sipCpp->end()) { const int t1 = i.key(); TYPE2 *t2 = i.value(); PyObject *t1obj = PyLong_FromSize_t(t1); PyObject *t2obj = sipConvertFromType(t2, sipType_TYPE2, sipTransferObj); if (PyDict_GetItem(d, t1obj) == NULL) { PyObject *lst = PyList_New(0); PyDict_SetItem(d, t1obj, lst); if (lst) { Py_DECREF(lst); } } if (t1obj == NULL || t2obj == NULL || PyList_Append(PyDict_GetItem(d, t1obj), t2obj) < 0) { Py_DECREF(d); if (t1obj) { Py_DECREF(t1obj); } if (t2obj) { Py_DECREF(t2obj); } return NULL; } Py_DECREF(t1obj); Py_DECREF(t2obj); ++i; } return d; %End %ConvertToTypeCode // Convert from Python: PyObject *t1obj, *t2obj; Py_ssize_t i = 0; // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyDict_Check(sipPy)) return 0; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { for (int i = 0; i < PyList_GET_SIZE(t2obj); ++i) { if (!sipCanConvertToType(PyList_GET_ITEM(t2obj, i), sipType_TYPE2, SIP_NOT_NONE)) return 0; } } return 1; } QMultiMap *qm = new QMultiMap; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { int state2; int k = (int) PyLong_AsLong(t1obj); for (int i = 0; i < PyList_GET_SIZE(t2obj); ++i) { TYPE2 *t2 = reinterpret_cast(sipConvertToType(PyList_GET_ITEM(t2obj, i), sipType_TYPE2, sipTransferObj, SIP_NOT_NONE, &state2, sipIsErr)); if (*sipIsErr) { sipReleaseType(t2, sipType_TYPE2, state2); delete qm; return 0; } qm->insert(k, t2); sipReleaseType(t2, sipType_TYPE2, state2); } } *sipCppPtr = qm; return sipGetState(sipTransferObj); %End }; template %MappedType QMap< QPair< QString, QString>, TYPE > { %TypeHeaderCode #include #include %End %ConvertFromTypeCode //convert map to a python dictionary PyObject *d; if ( ( d = PyDict_New() ) == NULL ) return NULL; for ( auto it = sipCpp->constBegin(); it != sipCpp->constEnd(); ++ it ) { PyObject *keyobj; if ( ( keyobj = PyTuple_New( 2 ) ) == NULL ) { Py_DECREF( d ); return NULL; } TYPE *t = new TYPE(it.value()); PyObject *tobj = sipConvertFromNewType(t, sipType_TYPE, sipTransferObj); if ( tobj == NULL ) { Py_DECREF(d); delete t; return NULL; } // build key PyObject *k1obj = sipConvertFromNewType( new QString( it.key().first ), sipType_QString, sipTransferObj ); PyTuple_SetItem( keyobj, 0, k1obj ); PyObject *k2obj = sipConvertFromNewType( new QString( it.key().second ), sipType_QString, sipTransferObj ); PyTuple_SetItem( keyobj, 1, k2obj ); if(keyobj == NULL || tobj == NULL || PyDict_SetItem(d, keyobj, tobj) < 0) { Py_DECREF(d); if (keyobj) { Py_DECREF(keyobj); } if (tobj) { Py_DECREF(tobj); } return NULL; } Py_DECREF(keyobj); Py_DECREF(tobj); } return d; %End %ConvertToTypeCode Py_ssize_t i = 0; PyObject *kobj, *tobj; // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyDict_Check(sipPy)) return 0; while (PyDict_Next(sipPy, &i, &kobj, &tobj)) if (!sipCanConvertToType(tobj, sipType_TYPE, SIP_NOT_NONE)) return 0; return 1; } PyObject *t1obj, *t2obj; QMap< QPair< QString, QString>, TYPE > *qm = new QMap< QPair< QString, QString>, TYPE >; int state; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { PyObject *sipKeyFirst = PyTuple_GetItem( t1obj, 0 ); PyObject *sipKeySecond = PyTuple_GetItem( t1obj, 1 ); QString *k1 = reinterpret_cast(sipConvertToType(sipKeyFirst, sipType_QString, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); if (*sipIsErr) { sipReleaseType(k1, sipType_QString, state); delete qm; return 0; } QString *k2 = reinterpret_cast(sipConvertToType(sipKeySecond, sipType_QString, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); if (*sipIsErr) { sipReleaseType(k1, sipType_QString, state); sipReleaseType(k2, sipType_QString, state); delete qm; return 0; } TYPE *t = reinterpret_cast(sipConvertToType(t2obj, sipType_TYPE, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); if (*sipIsErr) { sipReleaseType(t, sipType_TYPE, state); delete qm; return 0; } qm->insert( qMakePair( *k1,*k2 ), *t ); sipReleaseType(k1, sipType_QString, state); sipReleaseType(k2, sipType_QString, state); sipReleaseType(t, sipType_TYPE, state); } *sipCppPtr = qm; return sipGetState( sipTransferObj ); %End }; %If (VECTOR_MAPPED_TYPE) template %MappedType QVector< TYPE* > { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the list PyObject *l = PyList_New(sipCpp->size()); if (!l) return NULL; // Set the dictionary elements. for( int i = 0; i < sipCpp->size(); i++ ) { TYPE *t = sipCpp->at(i); PyObject *tobj = sipConvertFromType(t, sipType_TYPE, sipTransferObj); if (tobj == NULL || PyList_SetItem(l, i, tobj) < 0) { Py_DECREF(tobj); Py_DECREF(l); return NULL; } } return l; %End %ConvertToTypeCode // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyList_Check(sipPy)) return 0; for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) { if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i), sipType_TYPE, SIP_NOT_NONE)) return 0; } return 1; } QVector *v = new QVector( PyList_GET_SIZE(sipPy) ); for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i) { int state; TYPE *t = reinterpret_cast(sipConvertToType(PyList_GET_ITEM(sipPy, i), sipType_TYPE, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); if (*sipIsErr) { sipReleaseType(t, sipType_TYPE, state); delete v; return 0; } v->replace( i, t ); sipReleaseType(t, sipType_TYPE, state); } *sipCppPtr = v; return sipGetState(sipTransferObj); %End }; %End %MappedType QMap { %TypeHeaderCode #include %End %ConvertFromTypeCode //convert map to a python dictionary PyObject *d; if ((d = PyDict_New()) == NULL) return NULL; for (QMap::iterator it = sipCpp->begin(); it != sipCpp->end(); ++it) { QgsFeature *oobj = new QgsFeature(*it.value()); PyObject *keyobj = PyLong_FromLong(it.key()); PyObject *pyOobj = sipConvertFromType(oobj, sipType_QgsFeature, sipTransferObj); if(pyOobj == NULL || keyobj == NULL || PyDict_SetItem(d, keyobj, pyOobj) < 0) { Py_DECREF(d); if (pyOobj) { Py_DECREF(pyOobj); } else { delete oobj; } if (keyobj) { Py_DECREF(keyobj); } return NULL; } Py_DECREF(pyOobj); Py_DECREF(keyobj); } return d; %End %ConvertToTypeCode PyObject *t1obj, *t2obj; Py_ssize_t i = 0; QMap *qm = new QMap; while (PyDict_Next(sipPy, &i, &t1obj, &t2obj)) { int state; qint64 t1 = PyLong_AsLongLong(t1obj); QgsFeature *t2 = reinterpret_cast(sipConvertToType(t2obj, sipType_QgsFeature, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); if (*sipIsErr) { sipReleaseType(t2, sipType_QgsFeature, state); delete qm; return 0; } qm->insert(t1, t2); sipReleaseType(t2, sipType_QgsFeature, state); } *sipCppPtr = qm; return sipGetState(sipTransferObj); %End }; // QList is implemented as a Python list of QgsField. %MappedType QList { %TypeHeaderCode #include %End %ConvertFromTypeCode PyObject *l = PyList_New(sipCpp->size()); if (!l) return 0; for (int i = 0; i < sipCpp->size(); ++i) { QgsField *t = new QgsField(sipCpp->at(i)); PyObject *tobj = sipConvertFromNewType(t, sipType_QgsField, sipTransferObj); if (!tobj) { delete t; Py_DECREF(l); return 0; } PyList_SET_ITEM(l, i, tobj); } return l; %End %ConvertToTypeCode PyObject *iter = PyObject_GetIter(sipPy); if (!sipIsErr) { Py_XDECREF(iter); return (iter #if PY_MAJOR_VERSION < 3 && !PyString_Check(sipPy) #endif && !PyUnicode_Check(sipPy)); } if (!iter) { *sipIsErr = 1; return 0; } QList *ql = new QList; for (SIP_SSIZE_T i = 0; ; ++i) { PyErr_Clear(); PyObject *itm = PyIter_Next(iter); if (!itm) { if (PyErr_Occurred()) { delete ql; Py_DECREF(iter); *sipIsErr = 1; return 0; } break; } int state; QgsField *t = reinterpret_cast( sipForceConvertToType(itm, sipType_QgsField, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr)); if (*sipIsErr) { PyErr_Format(PyExc_TypeError, "index %ld has type '%s' but 'QgsField' is expected", (long) i, Py_TYPE(itm)->tp_name); Py_DECREF(itm); delete ql; Py_DECREF(iter); return 0; } ql->append(*t); sipReleaseType(t, sipType_QgsField, state); Py_DECREF(itm); } Py_DECREF(iter); *sipCppPtr = ql; return sipGetState(sipTransferObj); %End }; %ModuleCode bool null_from_qvariant_converter( const QVariant *varp, PyObject **objp ) { static bool sWatchDog = false; if ( sWatchDog ) return false; // If we deal with a NULL QVariant (and it's not a QByteArray which properly // maps NULL values) // If there are more cases like QByteArray, we should consider using a allowlist // instead of a blocklist. if ( varp->isNull() && varp->type() != QVariant::ByteArray ) { sWatchDog = true; PyObject *vartype = sipConvertFromEnum( varp->type(), sipType_QVariant_Type ); PyObject *args = PyTuple_Pack( 1, vartype ); PyTypeObject *typeObj = sipTypeAsPyTypeObject( sipType_QVariant ); *objp = PyObject_Call(( PyObject * )typeObj, args, nullptr ); Py_DECREF(args); Py_DECREF(vartype); sWatchDog = false; return true; } else { return false; } } %End // Mapped type for QList. %MappedType QList { %TypeHeaderCode #include %End %ConvertFromTypeCode // Create the list. PyObject *l; if ((l = PyList_New(sipCpp->size())) == NULL) return NULL; // Set the list elements. for (int i = 0; i < sipCpp->size(); ++i) { QgsWkbTypes::GeometryType e = sipCpp->at(i); PyObject *eobj; if ((eobj = sipConvertFromEnum(e, sipType_QgsWkbTypes_GeometryType)) == NULL) { Py_DECREF(l); return NULL; } PyList_SET_ITEM(l, i, eobj); } return l; %End %ConvertToTypeCode // Check the type if that is all that is required. if (sipIsErr == NULL) { if (!PyList_Check(sipPy)) return 0; for (SIP_SSIZE_T i = 0; i < PyList_GET_SIZE(sipPy); ++i) if (PyObject_TypeCheck(PyList_GET_ITEM(sipPy, i), sipTypeAsPyTypeObject(sipType_QgsWkbTypes_GeometryType))) return 0; return 1; } QList *ql = new QList; for (SIP_SSIZE_T i = 0; i < PyList_GET_SIZE(sipPy); ++i) { long l = SIPLong_AsLong(PyList_GET_ITEM(sipPy, i)); ql->append(static_cast(l)); } *sipCppPtr = ql; return sipGetState(sipTransferObj); %End }; %PostInitialisationCode //#spellok // Import the Chimera helper registration functions. typedef bool ( *FromQVariantConverterFn )( const QVariant *, PyObject ** ); void (*register_from_qvariant_converter)(FromQVariantConverterFn); register_from_qvariant_converter = (void (*)(FromQVariantConverterFn))sipImportSymbol("pyqt5_register_from_qvariant_convertor"); //#spellok register_from_qvariant_converter(null_from_qvariant_converter); %End