static PyObject *idprop_py_from_idp_idparray(ID *id, IDProperty *prop) { PyObject *seq = PyList_New(prop->len); IDProperty *array = IDP_IDPArray(prop); int i; if (!seq) { PyErr_Format(PyExc_RuntimeError, "%s: IDP_IDPARRAY: PyList_New(%d) failed", __func__, prop->len); return NULL; } for (i = 0; i < prop->len; i++) { PyObject *wrap = BPy_IDGroup_WrapData(id, array++, prop); /* BPy_IDGroup_MapDataToPy sets the error */ if (UNLIKELY(wrap == NULL)) { Py_DECREF(seq); return NULL; } PyList_SET_ITEM(seq, i, wrap); } return seq; }
PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop ) { switch ( prop->type ) { case IDP_STRING: #ifdef USE_STRING_COERCE return PyC_UnicodeFromByte(prop->data.pointer); #else return PyUnicode_FromString(prop->data.pointer); #endif case IDP_INT: return PyLong_FromLong( (long)prop->data.val ); case IDP_FLOAT: return PyFloat_FromDouble( (double)(*(float*)(&prop->data.val)) ); case IDP_DOUBLE: return PyFloat_FromDouble( (*(double*)(&prop->data.val)) ); case IDP_GROUP: /*blegh*/ { BPy_IDProperty *group = PyObject_New(BPy_IDProperty, &IDGroup_Type); group->id = id; group->prop = prop; return (PyObject*) group; } case IDP_ARRAY: { BPy_IDProperty *array = PyObject_New(BPy_IDProperty, &IDArray_Type); array->id = id; array->prop = prop; return (PyObject*) array; } case IDP_IDPARRAY: /* this could be better a internal type */ { PyObject *seq = PyList_New(prop->len), *wrap; IDProperty *array= IDP_IDPArray(prop); int i; if (!seq) { PyErr_Format(PyExc_RuntimeError, "BPy_IDGroup_MapDataToPy, IDP_IDPARRAY: PyList_New(%d) failed", prop->len); return NULL; } for (i=0; i<prop->len; i++) { wrap= BPy_IDGroup_WrapData(id, array++); if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ return NULL; PyList_SET_ITEM(seq, i, wrap); } return seq; } /* case IDP_IDPARRAY: TODO */ } Py_RETURN_NONE; }
/* for simple, non nested types this is the same as BPy_IDGroup_WrapData */ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) { switch (prop->type) { case IDP_STRING: return idprop_py_from_idp_string(prop); case IDP_INT: return idprop_py_from_idp_int(prop); case IDP_FLOAT: return idprop_py_from_idp_float(prop); case IDP_DOUBLE: return idprop_py_from_idp_double(prop); case IDP_ARRAY: { PyObject *seq = PyList_New(prop->len); int i; if (!seq) { PyErr_Format(PyExc_RuntimeError, "%s: IDP_ARRAY: PyList_New(%d) failed", __func__, prop->len); return NULL; } switch (prop->subtype) { case IDP_FLOAT: { float *array = (float *)IDP_Array(prop); for (i = 0; i < prop->len; i++) { PyList_SET_ITEM(seq, i, PyFloat_FromDouble(array[i])); } break; } case IDP_DOUBLE: { double *array = (double *)IDP_Array(prop); for (i = 0; i < prop->len; i++) { PyList_SET_ITEM(seq, i, PyFloat_FromDouble(array[i])); } break; } case IDP_INT: { int *array = (int *)IDP_Array(prop); for (i = 0; i < prop->len; i++) { PyList_SET_ITEM(seq, i, PyLong_FromLong(array[i])); } break; } default: PyErr_Format(PyExc_RuntimeError, "%s: invalid/corrupt array type '%d'!", __func__, prop->subtype); Py_DECREF(seq); return NULL; } return seq; } case IDP_IDPARRAY: { PyObject *seq = PyList_New(prop->len), *wrap; IDProperty *array = IDP_IDPArray(prop); int i; if (!seq) { PyErr_Format(PyExc_RuntimeError, "%s: IDP_IDPARRAY: PyList_New(%d) failed", __func__, prop->len); return NULL; } for (i = 0; i < prop->len; i++) { wrap = BPy_IDGroup_MapDataToPy(array++); if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ return NULL; PyList_SET_ITEM(seq, i, wrap); } return seq; } case IDP_GROUP: { PyObject *dict = PyDict_New(), *wrap; IDProperty *loop; for (loop = prop->data.group.first; loop; loop = loop->next) { wrap = BPy_IDGroup_MapDataToPy(loop); if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ return NULL; PyDict_SetItemString(dict, loop->name, wrap); Py_DECREF(wrap); } return dict; } } PyErr_Format(PyExc_RuntimeError, "%s ERROR: '%s' property exists with a bad type code '%d'!", __func__, prop->name, prop->type); return NULL; }
static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) { switch (prop->type) { case IDP_STRING: #ifdef USE_STRING_COERCE return PyC_UnicodeFromByte(prop->data.pointer); #else return PyUnicode_FromString(prop->data.pointer); #endif break; case IDP_FLOAT: return PyFloat_FromDouble(*((float*)&prop->data.val)); break; case IDP_DOUBLE: return PyFloat_FromDouble(*((double*)&prop->data.val)); break; case IDP_INT: return PyLong_FromSsize_t( prop->data.val ); break; case IDP_ARRAY: { PyObject *seq = PyList_New(prop->len); int i; if (!seq) { PyErr_Format(PyExc_RuntimeError, "BPy_IDGroup_MapDataToPy, IDP_ARRAY: PyList_New(%d) failed", prop->len); return NULL; } for (i=0; i<prop->len; i++) { if (prop->subtype == IDP_FLOAT) { PyList_SET_ITEM(seq, i, PyFloat_FromDouble(((float*)prop->data.pointer)[i])); } else if (prop->subtype == IDP_DOUBLE) { PyList_SET_ITEM(seq, i, PyFloat_FromDouble(((double*)prop->data.pointer)[i])); } else { PyList_SET_ITEM(seq, i, PyLong_FromLong(((int*)prop->data.pointer)[i])); } } return seq; } case IDP_IDPARRAY: { PyObject *seq = PyList_New(prop->len), *wrap; IDProperty *array= IDP_IDPArray(prop); int i; if (!seq) { PyErr_Format(PyExc_RuntimeError, "BPy_IDGroup_MapDataToPy, IDP_IDPARRAY: PyList_New(%d) failed", prop->len); return NULL; } for (i=0; i<prop->len; i++) { wrap= BPy_IDGroup_MapDataToPy(array++); if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ return NULL; PyList_SET_ITEM(seq, i, wrap); } return seq; } case IDP_GROUP: { PyObject *dict = PyDict_New(), *wrap; IDProperty *loop; for (loop=prop->data.group.first; loop; loop=loop->next) { wrap = BPy_IDGroup_MapDataToPy(loop); if (!wrap) /* BPy_IDGroup_MapDataToPy sets the error */ return NULL; PyDict_SetItemString(dict, loop->name, wrap); } return dict; } } PyErr_Format(PyExc_RuntimeError, "eek!! '%s' property exists with a bad type code '%d' !!!", prop->name, prop->type); return NULL; }
static void rna_IDPArray_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { IDProperty *prop = (IDProperty *)ptr->data; rna_iterator_array_begin(iter, IDP_IDPArray(prop), sizeof(IDProperty), prop->len, 0, NULL); }