PyObject * CCNObject_New(enum _pyccn_capsules type, void *pointer) { PyObject *capsule; int r; assert(pointer); capsule = PyCapsule_New(pointer, type2name(type), pyccn_Capsule_Destructor); if (!capsule) return NULL; switch (type) { case CONTENT_OBJECT: { struct content_object_data *context; context = calloc(1, sizeof(*context)); JUMP_IF_NULL_MEM(context, error); r = PyCapsule_SetContext(capsule, context); if (r < 0) { free(context); goto error; } break; } case INTEREST: { struct interest_data *context; context = calloc(1, sizeof(*context)); JUMP_IF_NULL_MEM(context, error); r = PyCapsule_SetContext(capsule, context); if (r < 0) { free(context); goto error; } break; } default: break; } return capsule; error: Py_XDECREF(capsule); return NULL; }
static int addcleanup_convert(void *ptr, PyObject **freelist, int (*destr)(PyObject*,void*)) { PyObject *cobj; if (!*freelist) { *freelist = PyList_New(0); if (!*freelist) { destr(NULL, ptr); return -1; } } cobj = PyCapsule_New(ptr, GETARGS_CAPSULE_NAME_CLEANUP_CONVERT, cleanup_convert); if (!cobj) { destr(NULL, ptr); return -1; } if (PyCapsule_SetContext(cobj, destr) == -1) { /* This really should not happen. */ Py_FatalError("capsule refused setting of context."); } if (PyList_Append(*freelist, cobj)) { Py_DECREF(cobj); /* This will also call destr. */ return -1; } Py_DECREF(cobj); return 0; }
// Parse a Python object as a sequence of either QVector[234]D or // QMatrix[234]x[234] instances, or a sequence of sequence of floats and return // an array that can be passed to QOpenGLShaderProgram::setUniformValueArray(). // The array is destroyed only when the shader is garbage collected or when // replaced by another array. const void *qpyopengl_uniform_value_array(PyObject *values, PyObject *shader, PyObject *key, const sipTypeDef **array_type, int *array_len, int *tsize, sipErrorState *estate) { // Check the key was created correctly. if (!key) { *estate = sipErrorFail; return 0; } // Get the dict that holds the converted arrays. PyObject *dict = ((sipSimpleWrapper *)shader)->user; if (!dict) { dict = PyDict_New(); if (!dict) { Py_DECREF(key); *estate = sipErrorFail; return 0; } ((sipSimpleWrapper *)shader)->user = dict; } // Check that values is a non-empty sequence. values = PySequence_Fast(values, "a uniform value array must be a sequence"); if (!values) { Py_DECREF(key); *estate = sipErrorContinue; return 0; } SIP_SSIZE_T nr_items = PySequence_Fast_GET_SIZE(values); if (nr_items < 1) { PyErr_SetString(PyExc_TypeError, "a uniform value array must have at least one element"); Py_DECREF(key); Py_DECREF(values); *estate = sipErrorFail; return 0; } // The first element determines the type expected. PyObject *itm = PySequence_Fast_GET_ITEM(values, 0); const sipTypeDef *td; SIP_SSIZE_T nr_dim = 0; void *array; if (sipCanConvertToType(itm, sipType_QVector2D, SIP_NOT_NONE)) { td = sipType_QVector2D; array = new QVector2D[nr_items]; } else if (sipCanConvertToType(itm, sipType_QVector3D, SIP_NOT_NONE)) { td = sipType_QVector3D; array = new QVector3D[nr_items]; } else if (sipCanConvertToType(itm, sipType_QVector4D, SIP_NOT_NONE)) { td = sipType_QVector4D; array = new QVector4D[nr_items]; } else if (sipCanConvertToType(itm, sipType_QMatrix2x2, SIP_NOT_NONE)) { td = sipType_QMatrix2x2; array = new QMatrix2x2[nr_items]; } else if (sipCanConvertToType(itm, sipType_QMatrix2x3, SIP_NOT_NONE)) { td = sipType_QMatrix2x3; array = new QMatrix2x3[nr_items]; } else if (sipCanConvertToType(itm, sipType_QMatrix2x4, SIP_NOT_NONE)) { td = sipType_QMatrix2x4; array = new QMatrix2x4[nr_items]; } else if (sipCanConvertToType(itm, sipType_QMatrix3x2, SIP_NOT_NONE)) { td = sipType_QMatrix3x2; array = new QMatrix3x2[nr_items]; } else if (sipCanConvertToType(itm, sipType_QMatrix3x3, SIP_NOT_NONE)) { td = sipType_QMatrix3x3; array = new QMatrix3x3[nr_items]; } else if (sipCanConvertToType(itm, sipType_QMatrix3x4, SIP_NOT_NONE)) { td = sipType_QMatrix3x4; array = new QMatrix3x4[nr_items]; } else if (sipCanConvertToType(itm, sipType_QMatrix4x2, SIP_NOT_NONE)) { td = sipType_QMatrix4x2; array = new QMatrix4x2[nr_items]; } else if (sipCanConvertToType(itm, sipType_QMatrix4x3, SIP_NOT_NONE)) { td = sipType_QMatrix4x3; array = new QMatrix4x3[nr_items]; } else if (sipCanConvertToType(itm, sipType_QMatrix4x4, SIP_NOT_NONE)) { td = sipType_QMatrix4x4; array = new QMatrix4x4[nr_items]; } else if (PySequence_Check(itm) && (nr_dim = PySequence_Size(itm)) >= 1) { td = 0; array = new GLfloat[nr_items * nr_dim]; } else { PyErr_SetString(PyExc_TypeError, "a uniform value array must be a sequence of QVector2D, " "QVector3D, QVector4D, QMatrix2x2, QMatrix2x3, QMatrix2x4, " "QMatrix3x2, QMatrix3x3, QMatrix3x4, QMatrix4x2, QMatrix4x3, " "QMatrix4x4, or a sequence of sequences of floats"); Py_DECREF(key); Py_DECREF(values); *estate = sipErrorFail; return 0; } // Convert the values. for (SIP_SSIZE_T i = 0; i < nr_items; ++i) { int iserr = 0; itm = PySequence_Fast_GET_ITEM(values, i); if (td) { void *cpp; cpp = sipForceConvertToType(itm, td, 0, SIP_NOT_NONE | SIP_NO_CONVERTORS, 0, &iserr); if (iserr) { PyErr_Format(PyExc_TypeError, "uniform value array elements should all be '%s', not " "'%s'", sipTypeAsPyTypeObject(td)->tp_name, Py_TYPE(itm)->tp_name); } else if (td == sipType_QVector2D) { QVector2D *a = reinterpret_cast<QVector2D *>(array); a[i] = *reinterpret_cast<QVector2D *>(cpp); } else if (td == sipType_QVector3D) { QVector3D *a = reinterpret_cast<QVector3D *>(array); a[i] = *reinterpret_cast<QVector3D *>(cpp); } else if (td == sipType_QVector4D) { QVector4D *a = reinterpret_cast<QVector4D *>(array); a[i] = *reinterpret_cast<QVector4D *>(cpp); } else if (td == sipType_QMatrix2x2) { QMatrix2x2 *a = reinterpret_cast<QMatrix2x2 *>(array); a[i] = *reinterpret_cast<QMatrix2x2 *>(cpp); } else if (td == sipType_QMatrix2x3) { QMatrix2x3 *a = reinterpret_cast<QMatrix2x3 *>(array); a[i] = *reinterpret_cast<QMatrix2x3 *>(cpp); } else if (td == sipType_QMatrix2x4) { QMatrix2x4 *a = reinterpret_cast<QMatrix2x4 *>(array); a[i] = *reinterpret_cast<QMatrix2x4 *>(cpp); } else if (td == sipType_QMatrix3x2) { QMatrix3x2 *a = reinterpret_cast<QMatrix3x2 *>(array); a[i] = *reinterpret_cast<QMatrix3x2 *>(cpp); } else if (td == sipType_QMatrix3x3) { QMatrix3x3 *a = reinterpret_cast<QMatrix3x3 *>(array); a[i] = *reinterpret_cast<QMatrix3x3 *>(cpp); } else if (td == sipType_QMatrix3x4) { QMatrix3x4 *a = reinterpret_cast<QMatrix3x4 *>(array); a[i] = *reinterpret_cast<QMatrix3x4 *>(cpp); } else if (td == sipType_QMatrix4x2) { QMatrix4x2 *a = reinterpret_cast<QMatrix4x2 *>(array); a[i] = *reinterpret_cast<QMatrix4x2 *>(cpp); } else if (td == sipType_QMatrix4x3) { QMatrix4x3 *a = reinterpret_cast<QMatrix4x3 *>(array); a[i] = *reinterpret_cast<QMatrix4x3 *>(cpp); } else if (td == sipType_QMatrix4x4) { QMatrix4x4 *a = reinterpret_cast<QMatrix4x4 *>(array); a[i] = *reinterpret_cast<QMatrix4x4 *>(cpp); } } else { itm = PySequence_Fast(itm, "uniform value array elements should all be sequences"); if (itm) { if (PySequence_Fast_GET_SIZE(itm) != nr_dim) { PyErr_Format(PyExc_TypeError, "uniform value array elements should all be " "sequences of length " #if PY_VERSION_HEX >= 0x02050000 "%zd", #else "%d", #endif nr_dim); Py_DECREF(itm); iserr = 1; } else { GLfloat *ap = reinterpret_cast<GLfloat *>(array); PyErr_Clear(); for (SIP_SSIZE_T j = 0; j < nr_dim; ++j) *ap++ = PyFloat_AsDouble( PySequence_Fast_GET_ITEM(itm, j)); if (PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "uniform value array elements should all be " "sequences of floats"); Py_DECREF(itm); iserr = 1; } } } else { iserr = 1; } } if (iserr) { Py_DECREF(key); Py_DECREF(values); delete_array(array, td); *estate = sipErrorFail; return 0; } } Py_DECREF(values); // Wrap the array in a Python object so that it won't leak. #if defined(SIP_USE_PYCAPSULE) PyObject *array_obj = PyCapsule_New(array, 0, array_dtor); if (array_obj && PyCapsule_SetContext(array_obj, const_cast<sipTypeDef *>(td)) != 0) { Py_DECREF(array_obj); array_obj = 0; } #else PyObject *array_obj = PyCObject_FromVoidPtrAndDesc(array, const_cast<sipTypeDef *>(td), array_dtor); #endif if (!array_obj) { Py_DECREF(key); delete_array(array, td); *estate = sipErrorFail; return 0; } int rc = PyDict_SetItem(dict, key, array_obj); Py_DECREF(key); Py_DECREF(array_obj); if (rc < 0) { *estate = sipErrorFail; return 0; } *array_type = td; *array_len = nr_items; *tsize = nr_dim; return array; }