static IDProperty *rna_EditBone_idprops(PointerRNA *ptr, bool create) { EditBone *ebone = ptr->data; if (create && !ebone->prop) { IDPropertyTemplate val = {0}; ebone->prop = IDP_New(IDP_GROUP, &val, "RNA_EditBone ID properties"); } return ebone->prop; }
static IDProperty *rna_ViewLayer_idprops(PointerRNA *ptr, bool create) { ViewLayer *view_layer = (ViewLayer *)ptr->data; if (create && !view_layer->id_properties) { IDPropertyTemplate val = {0}; view_layer->id_properties = IDP_New(IDP_GROUP, &val, "ViewLayer ID properties"); } return view_layer->id_properties; }
static IDProperty *rna_Bone_idprops(PointerRNA *ptr, int create) { Bone *bone= ptr->data; if(create && !bone->prop) { IDPropertyTemplate val = {0}; bone->prop= IDP_New(IDP_GROUP, &val, "RNA_Bone ID properties"); } return bone->prop; }
static IDProperty *idp_from_PySequence_Buffer(const char *name, Py_buffer *buffer) { IDProperty *prop; IDPropertyTemplate val = {0}; int format = idp_array_type_from_format_char(*buffer->format); if (format == -1) { /* should never happen as the type has been checked before */ return NULL; } else { val.array.type = format; val.array.len = buffer->len / buffer->itemsize; } prop = IDP_New(IDP_ARRAY, &val, name); memcpy(IDP_Array(prop), buffer->buf, buffer->len); return prop; }
/** * \note group can be a pointer array or a group. * assume we already checked key is a string. * * \return success. */ bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, PyObject *ob) { IDProperty *prop = NULL; IDPropertyTemplate val = {0}; const char *name; if (name_obj) { Py_ssize_t name_size; name = _PyUnicode_AsStringAndSize(name_obj, &name_size); if (name == NULL) { PyErr_Format(PyExc_KeyError, "invalid id-property key, expected a string, not a %.200s", Py_TYPE(name_obj)->tp_name); return false; } if (name_size > MAX_IDPROP_NAME) { PyErr_SetString(PyExc_KeyError, "the length of IDProperty names is limited to 63 characters"); return false; } } else { name = ""; } if (PyFloat_Check(ob)) { val.d = PyFloat_AsDouble(ob); prop = IDP_New(IDP_DOUBLE, &val, name); } else if (PyLong_Check(ob)) { val.i = _PyLong_AsInt(ob); if (val.i == -1 && PyErr_Occurred()) { return false; } prop = IDP_New(IDP_INT, &val, name); } else if (PyUnicode_Check(ob)) { #ifdef USE_STRING_COERCE PyObject *value_coerce = NULL; val.string.str = (char *)PyC_UnicodeAsByte(ob, &value_coerce); val.string.subtype = IDP_STRING_SUB_UTF8; prop = IDP_New(IDP_STRING, &val, name); Py_XDECREF(value_coerce); #else val.str = _PyUnicode_AsString(ob); prop = IDP_New(IDP_STRING, val, name); #endif } else if (PyBytes_Check(ob)) { val.string.str = PyBytes_AS_STRING(ob); val.string.len = PyBytes_GET_SIZE(ob); val.string.subtype = IDP_STRING_SUB_BYTE; prop = IDP_New(IDP_STRING, &val, name); //prop = IDP_NewString(PyBytes_AS_STRING(ob), name, PyBytes_GET_SIZE(ob)); //prop->subtype = IDP_STRING_SUB_BYTE; } else if (PySequence_Check(ob)) { PyObject *ob_seq_fast = PySequence_Fast(ob, "py -> idprop"); PyObject *item; int i; if (ob_seq_fast == NULL) { return false; } if ((val.array.type = idp_sequence_type(ob_seq_fast)) == -1) { Py_DECREF(ob_seq_fast); PyErr_SetString(PyExc_TypeError, "only floats, ints and dicts are allowed in ID property arrays"); return false; } /* validate sequence and derive type. * we assume IDP_INT unless we hit a float * number; then we assume it's */ val.array.len = PySequence_Fast_GET_SIZE(ob_seq_fast); switch (val.array.type) { case IDP_DOUBLE: { double *prop_data; prop = IDP_New(IDP_ARRAY, &val, name); prop_data = IDP_Array(prop); for (i = 0; i < val.array.len; i++) { item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); if (((prop_data[i] = PyFloat_AsDouble(item)) == -1.0) && PyErr_Occurred()) { Py_DECREF(ob_seq_fast); return false; } } break; } case IDP_INT: { int *prop_data; prop = IDP_New(IDP_ARRAY, &val, name); prop_data = IDP_Array(prop); for (i = 0; i < val.array.len; i++) { item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); if (((prop_data[i] = _PyLong_AsInt(item)) == -1) && PyErr_Occurred()) { Py_DECREF(ob_seq_fast); return false; } } break; } case IDP_IDPARRAY: { prop = IDP_NewIDPArray(name); for (i = 0; i < val.array.len; i++) { item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); if (BPy_IDProperty_Map_ValidateAndCreate(NULL, prop, item) == false) { Py_DECREF(ob_seq_fast); return false; } } break; } default: /* should never happen */ Py_DECREF(ob_seq_fast); PyErr_SetString(PyExc_RuntimeError, "internal error with idp array.type"); return false; } Py_DECREF(ob_seq_fast); } else if (PyMapping_Check(ob)) { PyObject *keys, *vals, *key, *pval; int i, len; /*yay! we get into recursive stuff now!*/ keys = PyMapping_Keys(ob); vals = PyMapping_Values(ob); /* we allocate the group first; if we hit any invalid data, * we can delete it easily enough.*/ prop = IDP_New(IDP_GROUP, &val, name); len = PyMapping_Length(ob); for (i = 0; i < len; i++) { key = PySequence_GetItem(keys, i); pval = PySequence_GetItem(vals, i); if (BPy_IDProperty_Map_ValidateAndCreate(key, prop, pval) == false) { IDP_FreeProperty(prop); MEM_freeN(prop); Py_XDECREF(keys); Py_XDECREF(vals); Py_XDECREF(key); Py_XDECREF(pval); /* error is already set */ return false; } Py_XDECREF(key); Py_XDECREF(pval); } Py_XDECREF(keys); Py_XDECREF(vals); } else { PyErr_Format(PyExc_TypeError, "invalid id-property type %.200s not supported", Py_TYPE(ob)->tp_name); return false; } if (group->type == IDP_IDPARRAY) { IDP_AppendArray(group, prop); // IDP_FreeProperty(item); /* IDP_AppendArray does a shallow copy (memcpy), only free memory */ MEM_freeN(prop); } else { IDP_ReplaceInGroup(group, prop); } return true; }
/* note: group can be a pointer array or a group */ const char *BPy_IDProperty_Map_ValidateAndCreate(const char *name, IDProperty *group, PyObject *ob) { IDProperty *prop = NULL; IDPropertyTemplate val = {0}; if(strlen(name) >= sizeof(group->name)) return "the length of IDProperty names is limited to 31 characters"; if (PyFloat_Check(ob)) { val.d = PyFloat_AsDouble(ob); prop = IDP_New(IDP_DOUBLE, val, name); } else if (PyLong_Check(ob)) { val.i = (int) PyLong_AsSsize_t(ob); prop = IDP_New(IDP_INT, val, name); } else if (PyUnicode_Check(ob)) { #ifdef USE_STRING_COERCE PyObject *value_coerce= NULL; val.str = (char *)PyC_UnicodeAsByte(ob, &value_coerce); prop = IDP_New(IDP_STRING, val, name); Py_XDECREF(value_coerce); #else val.str = _PyUnicode_AsString(ob); prop = IDP_New(IDP_STRING, val, name); #endif } else if (PySequence_Check(ob)) { PyObject *item; int i; if((val.array.type= idp_sequence_type(ob)) == -1) return "only floats, ints and dicts are allowed in ID property arrays"; /*validate sequence and derive type. we assume IDP_INT unless we hit a float number; then we assume it's */ val.array.len = PySequence_Size(ob); switch(val.array.type) { case IDP_DOUBLE: prop = IDP_New(IDP_ARRAY, val, name); for (i=0; i<val.array.len; i++) { item = PySequence_GetItem(ob, i); ((double*)prop->data.pointer)[i] = (float)PyFloat_AsDouble(item); Py_DECREF(item); } break; case IDP_INT: prop = IDP_New(IDP_ARRAY, val, name); for (i=0; i<val.array.len; i++) { item = PySequence_GetItem(ob, i); ((int*)prop->data.pointer)[i] = (int)PyLong_AsSsize_t(item); Py_DECREF(item); } break; case IDP_IDPARRAY: prop= IDP_NewIDPArray(name); for (i=0; i<val.array.len; i++) { const char *error; item = PySequence_GetItem(ob, i); error= BPy_IDProperty_Map_ValidateAndCreate("", prop, item); Py_DECREF(item); if(error) return error; } break; } } else if (PyMapping_Check(ob)) { PyObject *keys, *vals, *key, *pval; int i, len; /*yay! we get into recursive stuff now!*/ keys = PyMapping_Keys(ob); vals = PyMapping_Values(ob); /*we allocate the group first; if we hit any invalid data, we can delete it easily enough.*/ prop = IDP_New(IDP_GROUP, val, name); len = PyMapping_Length(ob); for (i=0; i<len; i++) { key = PySequence_GetItem(keys, i); pval = PySequence_GetItem(vals, i); if (!PyUnicode_Check(key)) { IDP_FreeProperty(prop); MEM_freeN(prop); Py_XDECREF(keys); Py_XDECREF(vals); Py_XDECREF(key); Py_XDECREF(pval); return "invalid element in subgroup dict template!"; } if (BPy_IDProperty_Map_ValidateAndCreate(_PyUnicode_AsString(key), prop, pval)) { IDP_FreeProperty(prop); MEM_freeN(prop); Py_XDECREF(keys); Py_XDECREF(vals); Py_XDECREF(key); Py_XDECREF(pval); return "invalid element in subgroup dict template!"; } Py_XDECREF(key); Py_XDECREF(pval); } Py_XDECREF(keys); Py_XDECREF(vals); } else return "invalid property value"; if(group->type==IDP_IDPARRAY) { IDP_AppendArray(group, prop); // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory MEM_freeN(prop); } else { IDP_ReplaceInGroup(group, prop); } return NULL; }
static IDProperty *idp_from_DatablockPointer(const char *name, PyObject *ob) { IDPropertyTemplate val = {0}; pyrna_id_FromPyObject(ob, &val.id); return IDP_New(IDP_ID, &val, name); }
static IDProperty *idp_from_PySequence_Fast(const char *name, PyObject *ob) { IDProperty *prop; IDPropertyTemplate val = {0}; PyObject **ob_seq_fast_items; PyObject *item; int i; ob_seq_fast_items = PySequence_Fast_ITEMS(ob); if ((val.array.type = idp_sequence_type(ob)) == (char)-1) { PyErr_SetString(PyExc_TypeError, "only floats, ints and dicts are allowed in ID property arrays"); return NULL; } /* validate sequence and derive type. * we assume IDP_INT unless we hit a float * number; then we assume it's */ val.array.len = PySequence_Fast_GET_SIZE(ob); switch (val.array.type) { case IDP_DOUBLE: { double *prop_data; prop = IDP_New(IDP_ARRAY, &val, name); prop_data = IDP_Array(prop); for (i = 0; i < val.array.len; i++) { item = ob_seq_fast_items[i]; if (((prop_data[i] = PyFloat_AsDouble(item)) == -1.0) && PyErr_Occurred()) { return NULL; } } break; } case IDP_INT: { int *prop_data; prop = IDP_New(IDP_ARRAY, &val, name); prop_data = IDP_Array(prop); for (i = 0; i < val.array.len; i++) { item = ob_seq_fast_items[i]; if (((prop_data[i] = PyC_Long_AsI32(item)) == -1) && PyErr_Occurred()) { return NULL; } } break; } case IDP_IDPARRAY: { prop = IDP_NewIDPArray(name); for (i = 0; i < val.array.len; i++) { item = ob_seq_fast_items[i]; if (BPy_IDProperty_Map_ValidateAndCreate(NULL, prop, item) == false) { return NULL; } } break; } default: /* should never happen */ PyErr_SetString(PyExc_RuntimeError, "internal error with idp array.type"); return NULL; } return prop; }
static IDProperty *idp_from_PyFloat(const char *name, PyObject *ob) { IDPropertyTemplate val = {0}; val.d = PyFloat_AsDouble(ob); return IDP_New(IDP_DOUBLE, &val, name); }
static IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, const AVOption *o, const AVOption *parent) { AVCodecContext c; IDProperty *group; IDProperty *prop; IDPropertyTemplate val; int idp_type; char name[256]; val.i = 0; avcodec_get_context_defaults3(&c, NULL); if (!rd->ffcodecdata.properties) { rd->ffcodecdata.properties = IDP_New(IDP_GROUP, &val, "ffmpeg"); } group = IDP_GetPropertyFromGroup(rd->ffcodecdata.properties, type); if (!group) { group = IDP_New(IDP_GROUP, &val, type); IDP_AddToGroup(rd->ffcodecdata.properties, group); } if (parent) { BLI_snprintf(name, sizeof(name), "%s:%s", parent->name, o->name); } else { BLI_strncpy(name, o->name, sizeof(name)); } PRINT("ffmpeg_property_add: %s %s\n", type, name); prop = IDP_GetPropertyFromGroup(group, name); if (prop) { return prop; } switch (o->type) { case AV_OPT_TYPE_INT: case AV_OPT_TYPE_INT64: val.i = FFMPEG_DEF_OPT_VAL_INT(o); idp_type = IDP_INT; break; case AV_OPT_TYPE_DOUBLE: case AV_OPT_TYPE_FLOAT: val.f = FFMPEG_DEF_OPT_VAL_DOUBLE(o); idp_type = IDP_FLOAT; break; case AV_OPT_TYPE_STRING: val.string.str = (char *)" "; val.string.len = 80; /* val.str = (char *)" ";*/ idp_type = IDP_STRING; break; case AV_OPT_TYPE_CONST: val.i = 1; idp_type = IDP_INT; break; default: return NULL; } prop = IDP_New(idp_type, &val, name); IDP_AddToGroup(group, prop); return prop; }
IDProperty *ffmpeg_property_add(RenderData *rd, char * type, int opt_index, int parent_index) { AVCodecContext c; const AVOption * o; const AVOption * parent; IDProperty * group; IDProperty * prop; IDPropertyTemplate val; int idp_type; char name[256]; val.i = 0; avcodec_get_context_defaults(&c); o = c.av_class->option + opt_index; parent = c.av_class->option + parent_index; if (!rd->ffcodecdata.properties) { rd->ffcodecdata.properties = IDP_New(IDP_GROUP, val, "ffmpeg"); } group = IDP_GetPropertyFromGroup( rd->ffcodecdata.properties, (char*) type); if (!group) { group = IDP_New(IDP_GROUP, val, (char*) type); IDP_AddToGroup(rd->ffcodecdata.properties, group); } if (parent_index) { sprintf(name, "%s:%s", parent->name, o->name); } else { strcpy(name, o->name); } fprintf(stderr, "ffmpeg_property_add: %s %d %d %s\n", type, parent_index, opt_index, name); prop = IDP_GetPropertyFromGroup(group, name); if (prop) { return prop; } switch (o->type) { case FF_OPT_TYPE_INT: case FF_OPT_TYPE_INT64: val.i = FFMPEG_DEF_OPT_VAL_INT(o); idp_type = IDP_INT; break; case FF_OPT_TYPE_DOUBLE: case FF_OPT_TYPE_FLOAT: val.f = FFMPEG_DEF_OPT_VAL_DOUBLE(o); idp_type = IDP_FLOAT; break; case FF_OPT_TYPE_STRING: val.str = " "; idp_type = IDP_STRING; break; case FF_OPT_TYPE_CONST: val.i = 1; idp_type = IDP_INT; break; default: return NULL; } prop = IDP_New(idp_type, val, name); IDP_AddToGroup(group, prop); return prop; }