|
Blender
V2.59
|
00001 /* 00002 * $Id: bpy_rna_array.c 39233 2011-08-09 20:00:53Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * Contributor(s): Arystanbek Dyussenov 00021 * 00022 * ***** END GPL LICENSE BLOCK ***** 00023 */ 00024 00029 #include <Python.h> 00030 00031 #include "RNA_types.h" 00032 00033 #include "bpy_rna.h" 00034 #include "BKE_global.h" 00035 #include "MEM_guardedalloc.h" 00036 00037 #include "RNA_access.h" 00038 00039 #define MAX_ARRAY_DIMENSION 10 00040 00041 typedef void (*ItemConvertFunc)(PyObject *, char *); 00042 typedef int (*ItemTypeCheckFunc)(PyObject *); 00043 typedef void (*RNA_SetArrayFunc)(PointerRNA *, PropertyRNA *, const char *); 00044 typedef void (*RNA_SetIndexFunc)(PointerRNA *, PropertyRNA *, int index, void *); 00045 00046 /* 00047 arr[3][4][5] 00048 0 1 2 <- dimension index 00049 */ 00050 00051 /* 00052 arr[2]= x 00053 00054 py_to_array_index(arraydim=0, arrayoffset=0, index=2) 00055 validate_array(lvalue_dim=0) 00056 ... make real index ... 00057 */ 00058 00059 /* arr[3]=x, self->arraydim is 0, lvalue_dim is 1 */ 00060 /* Ensures that a python sequence has expected number of items/sub-items and items are of desired type. */ 00061 static int validate_array_type(PyObject *seq, int dim, int totdim, int dimsize[], 00062 ItemTypeCheckFunc check_item_type, const char *item_type_str, const char *error_prefix) 00063 { 00064 int i; 00065 00066 /* not the last dimension */ 00067 if (dim + 1 < totdim) { 00068 /* check that a sequence contains dimsize[dim] items */ 00069 const int seq_size= PySequence_Size(seq); 00070 if(seq_size == -1) { 00071 PyErr_Format(PyExc_ValueError, "%s sequence expected at dimension %d, not '%s'", 00072 error_prefix, (int)dim + 1, Py_TYPE(seq)->tp_name); 00073 return -1; 00074 } 00075 for (i= 0; i < seq_size; i++) { 00076 PyObject *item; 00077 int ok= 1; 00078 item= PySequence_GetItem(seq, i); 00079 00080 if(item == NULL) { 00081 PyErr_Format(PyExc_TypeError, "%s sequence type '%s' failed to retrieve index %d", 00082 error_prefix, Py_TYPE(seq)->tp_name, i); 00083 ok= 0; 00084 } 00085 else if (!PySequence_Check(item)) { 00086 /* BLI_snprintf(error_str, error_str_size, "expected a sequence of %s", item_type_str); */ 00087 PyErr_Format(PyExc_TypeError, "%s expected a sequence of %s, not %s", 00088 error_prefix, item_type_str, Py_TYPE(item)->tp_name); 00089 ok= 0; 00090 } 00091 /* arr[3][4][5] 00092 dimsize[1]=4 00093 dimsize[2]=5 00094 00095 dim=0 */ 00096 else if (PySequence_Size(item) != dimsize[dim + 1]) { 00097 /* BLI_snprintf(error_str, error_str_size, "sequences of dimension %d should contain %d items", (int)dim + 1, (int)dimsize[dim + 1]); */ 00098 PyErr_Format(PyExc_ValueError, "%s sequences of dimension %d should contain %d items", 00099 error_prefix, (int)dim + 1, (int)dimsize[dim + 1]); 00100 ok= 0; 00101 } 00102 else if (validate_array_type(item, dim + 1, totdim, dimsize, check_item_type, item_type_str, error_prefix) == -1) { 00103 ok= 0; 00104 } 00105 00106 Py_XDECREF(item); 00107 00108 if (!ok) 00109 return -1; 00110 } 00111 } 00112 else { 00113 /* check that items are of correct type */ 00114 const int seq_size= PySequence_Size(seq); 00115 if(seq_size == -1) { 00116 PyErr_Format(PyExc_ValueError, "%s sequence expected at dimension %d, not '%s'", 00117 error_prefix, (int)dim + 1, Py_TYPE(seq)->tp_name); 00118 return -1; 00119 } 00120 for (i= 0; i < seq_size; i++) { 00121 PyObject *item= PySequence_GetItem(seq, i); 00122 00123 if(item == NULL) { 00124 PyErr_Format(PyExc_TypeError, "%s sequence type '%s' failed to retrieve index %d", 00125 error_prefix, Py_TYPE(seq)->tp_name, i); 00126 return -1; 00127 } 00128 else if (!check_item_type(item)) { 00129 Py_DECREF(item); 00130 00131 /* BLI_snprintf(error_str, error_str_size, "sequence items should be of type %s", item_type_str); */ 00132 PyErr_Format(PyExc_TypeError, "%s expected sequence items of type %s, not %s", 00133 error_prefix, item_type_str, Py_TYPE(item)->tp_name); 00134 return -1; 00135 } 00136 00137 Py_DECREF(item); 00138 } 00139 } 00140 00141 return 0; /* ok */ 00142 } 00143 00144 /* Returns the number of items in a single- or multi-dimensional sequence. */ 00145 static int count_items(PyObject *seq, int dim) 00146 { 00147 int totitem= 0; 00148 00149 if(dim > 1) { 00150 const int seq_size= PySequence_Size(seq); 00151 int i; 00152 for (i= 0; i < seq_size; i++) { 00153 PyObject *item= PySequence_GetItem(seq, i); 00154 if(item) { 00155 const int tot= count_items(item, dim - 1); 00156 Py_DECREF(item); 00157 if(tot != -1) { 00158 totitem += tot; 00159 } 00160 else { 00161 totitem= -1; 00162 break; 00163 } 00164 } 00165 else { 00166 totitem= -1; 00167 break; 00168 } 00169 } 00170 } 00171 else { 00172 totitem= PySequence_Size(seq); 00173 } 00174 00175 return totitem; 00176 } 00177 00178 /* Modifies property array length if needed and PROP_DYNAMIC flag is set. */ 00179 static int validate_array_length(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int *totitem, const char *error_prefix) 00180 { 00181 int dimsize[MAX_ARRAY_DIMENSION]; 00182 int tot, totdim, len; 00183 00184 totdim= RNA_property_array_dimension(ptr, prop, dimsize); 00185 tot= count_items(rvalue, totdim - lvalue_dim); 00186 00187 if(tot == -1) { 00188 PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, error validating the sequence length", 00189 error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop)); 00190 return -1; 00191 } 00192 else if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) { 00193 if (RNA_property_array_length(ptr, prop) != tot) { 00194 #if 0 00195 /* length is flexible */ 00196 if (!RNA_property_dynamic_array_set_length(ptr, prop, tot)) { 00197 /* BLI_snprintf(error_str, error_str_size, "%s.%s: array length cannot be changed to %d", RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); */ 00198 PyErr_Format(PyExc_ValueError, "%s %s.%s: array length cannot be changed to %d", 00199 error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), tot); 00200 return -1; 00201 } 00202 #else 00203 *totitem= tot; 00204 return 0; 00205 00206 #endif 00207 } 00208 00209 len= tot; 00210 } 00211 else { 00212 /* length is a constraint */ 00213 if (!lvalue_dim) { 00214 len= RNA_property_array_length(ptr, prop); 00215 } 00216 /* array item assignment */ 00217 else { 00218 int i; 00219 00220 len= 1; 00221 00222 /* arr[3][4][5] 00223 00224 arr[2]= x 00225 dimsize={4, 5} 00226 dimsize[1]= 4 00227 dimsize[2]= 5 00228 lvalue_dim=0, totdim=3 00229 00230 arr[2][3]= x 00231 lvalue_dim=1 00232 00233 arr[2][3][4]= x 00234 lvalue_dim=2 */ 00235 for (i= lvalue_dim; i < totdim; i++) 00236 len *= dimsize[i]; 00237 } 00238 00239 if (tot != len) { 00240 /* BLI_snprintf(error_str, error_str_size, "sequence must have length of %d", len); */ 00241 PyErr_Format(PyExc_ValueError, "%s %.200s.%.200s, sequence must have %d items total, not %d", 00242 error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), len, tot); 00243 return -1; 00244 } 00245 } 00246 00247 *totitem= len; 00248 00249 return 0; 00250 } 00251 00252 static int validate_array(PyObject *rvalue, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, ItemTypeCheckFunc check_item_type, const char *item_type_str, int *totitem, const char *error_prefix) 00253 { 00254 int dimsize[MAX_ARRAY_DIMENSION]; 00255 int totdim= RNA_property_array_dimension(ptr, prop, dimsize); 00256 00257 /* validate type first because length validation may modify property array length */ 00258 00259 if (validate_array_type(rvalue, lvalue_dim, totdim, dimsize, check_item_type, item_type_str, error_prefix) == -1) 00260 return -1; 00261 00262 return validate_array_length(rvalue, ptr, prop, lvalue_dim, totitem, error_prefix); 00263 } 00264 00265 static char *copy_value_single(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index) 00266 { 00267 if (!data) { 00268 char value[sizeof(int)]; 00269 00270 convert_item(item, value); 00271 rna_set_index(ptr, prop, *index, value); 00272 *index= *index + 1; 00273 } 00274 else { 00275 convert_item(item, data); 00276 data += item_size; 00277 } 00278 00279 return data; 00280 } 00281 00282 static char *copy_values(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, int dim, char *data, unsigned int item_size, int *index, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index) 00283 { 00284 unsigned int i; 00285 int totdim= RNA_property_array_dimension(ptr, prop, NULL); 00286 const int seq_size= PySequence_Size(seq); 00287 00288 /* Regarding PySequence_GetItem() failing. 00289 * 00290 * This should never be NULL since we validated it, _but_ some triky python 00291 * developer could write their own sequence type which succeeds on 00292 * validating but fails later somehow, so include checks for safety. 00293 */ 00294 00295 /* Note that 'data can be NULL' */ 00296 00297 if(seq_size == -1) { 00298 return NULL; 00299 } 00300 00301 for (i= 0; i < seq_size; i++) { 00302 PyObject *item= PySequence_GetItem(seq, i); 00303 if(item) { 00304 if (dim + 1 < totdim) { 00305 data= copy_values(item, ptr, prop, dim + 1, data, item_size, index, convert_item, rna_set_index); 00306 } 00307 else { 00308 data= copy_value_single(item, ptr, prop, data, item_size, index, convert_item, rna_set_index); 00309 } 00310 00311 Py_DECREF(item); 00312 00313 /* data may be NULL, but the for loop checks */ 00314 } 00315 else { 00316 return NULL; 00317 } 00318 } 00319 00320 return data; 00321 } 00322 00323 static int py_to_array(PyObject *seq, PointerRNA *ptr, PropertyRNA *prop, char *param_data, ItemTypeCheckFunc check_item_type, const char *item_type_str, int item_size, ItemConvertFunc convert_item, RNA_SetArrayFunc rna_set_array, const char *error_prefix) 00324 { 00325 /*int totdim, dim_size[MAX_ARRAY_DIMENSION];*/ 00326 int totitem; 00327 char *data= NULL; 00328 00329 /*totdim= RNA_property_array_dimension(ptr, prop, dim_size);*/ /*UNUSED*/ 00330 00331 if (validate_array(seq, ptr, prop, 0, check_item_type, item_type_str, &totitem, error_prefix) == -1) { 00332 return -1; 00333 } 00334 00335 if (totitem) { 00336 /* note: this code is confusing */ 00337 if(param_data && RNA_property_flag(prop) & PROP_DYNAMIC) { 00338 /* not freeing allocated mem, RNA_parameter_list_free() will do this */ 00339 ParameterDynAlloc *param_alloc= (ParameterDynAlloc *)param_data; 00340 param_alloc->array_tot= (int)totitem; 00341 param_alloc->array= MEM_callocN(item_size * totitem, "py_to_array dyn"); /* freeing param list will free */ 00342 00343 data= param_alloc->array; 00344 } 00345 else if (param_data) { 00346 data= param_data; 00347 } 00348 else { 00349 data= PyMem_MALLOC(item_size * totitem); 00350 } 00351 00352 /* will only fail in very rare cases since we already validated the 00353 * python data, the check here is mainly for completeness. */ 00354 if(copy_values(seq, ptr, prop, 0, data, item_size, NULL, convert_item, NULL) != NULL) { 00355 if (param_data==NULL) { 00356 /* NULL can only pass through in case RNA property arraylength is 0 (impossible?) */ 00357 rna_set_array(ptr, prop, data); 00358 PyMem_FREE(data); 00359 } 00360 } 00361 else { 00362 if (param_data==NULL) { 00363 PyMem_FREE(data); 00364 } 00365 00366 PyErr_Format(PyExc_TypeError, "%s internal error parsing sequence of type '%s' after successful validation", 00367 error_prefix, Py_TYPE(seq)->tp_name); 00368 return -1; 00369 } 00370 } 00371 00372 return 0; 00373 } 00374 00375 static int py_to_array_index(PyObject *py, PointerRNA *ptr, PropertyRNA *prop, int lvalue_dim, int arrayoffset, int index, ItemTypeCheckFunc check_item_type, const char *item_type_str, ItemConvertFunc convert_item, RNA_SetIndexFunc rna_set_index, const char *error_prefix) 00376 { 00377 int totdim, dimsize[MAX_ARRAY_DIMENSION]; 00378 int totitem, i; 00379 00380 totdim= RNA_property_array_dimension(ptr, prop, dimsize); 00381 00382 /* convert index */ 00383 00384 /* arr[3][4][5] 00385 00386 arr[2]= x 00387 lvalue_dim=0, index= 0 + 2 * 4 * 5 00388 00389 arr[2][3]= x 00390 lvalue_dim=1, index= 40 + 3 * 5 */ 00391 00392 lvalue_dim++; 00393 00394 for (i= lvalue_dim; i < totdim; i++) 00395 index *= dimsize[i]; 00396 00397 index += arrayoffset; 00398 00399 if(lvalue_dim == totdim) { /* single item, assign directly */ 00400 if(!check_item_type(py)) { 00401 PyErr_Format(PyExc_TypeError, "%s %.200s.%.200s, expected a %s type, not %s", 00402 error_prefix, RNA_struct_identifier(ptr->type), 00403 RNA_property_identifier(prop), item_type_str, 00404 Py_TYPE(py)->tp_name); 00405 return -1; 00406 } 00407 copy_value_single(py, ptr, prop, NULL, 0, &index, convert_item, rna_set_index); 00408 } 00409 else { 00410 if (validate_array(py, ptr, prop, lvalue_dim, check_item_type, item_type_str, &totitem, error_prefix) == -1) { 00411 return -1; 00412 } 00413 00414 if (totitem) { 00415 copy_values(py, ptr, prop, lvalue_dim, NULL, 0, &index, convert_item, rna_set_index); 00416 } 00417 } 00418 return 0; 00419 } 00420 00421 static void py_to_float(PyObject *py, char *data) 00422 { 00423 *(float*)data= (float)PyFloat_AsDouble(py); 00424 } 00425 00426 static void py_to_int(PyObject *py, char *data) 00427 { 00428 *(int*)data= (int)PyLong_AsSsize_t(py); 00429 } 00430 00431 static void py_to_bool(PyObject *py, char *data) 00432 { 00433 *(int*)data= (int)PyObject_IsTrue(py); 00434 } 00435 00436 static int py_float_check(PyObject *py) 00437 { 00438 /* accept both floats and integers */ 00439 return PyNumber_Check(py); 00440 } 00441 00442 static int py_int_check(PyObject *py) 00443 { 00444 /* accept only integers */ 00445 return PyLong_Check(py); 00446 } 00447 00448 static int py_bool_check(PyObject *py) 00449 { 00450 return PyBool_Check(py); 00451 } 00452 00453 static void float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value) 00454 { 00455 RNA_property_float_set_index(ptr, prop, index, *(float*)value); 00456 } 00457 00458 static void int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value) 00459 { 00460 RNA_property_int_set_index(ptr, prop, index, *(int*)value); 00461 } 00462 00463 static void bool_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, void *value) 00464 { 00465 RNA_property_boolean_set_index(ptr, prop, index, *(int*)value); 00466 } 00467 00468 int pyrna_py_to_array(PointerRNA *ptr, PropertyRNA *prop, char *param_data, PyObject *py, const char *error_prefix) 00469 { 00470 int ret; 00471 switch (RNA_property_type(prop)) { 00472 case PROP_FLOAT: 00473 ret= py_to_array(py, ptr, prop, param_data, py_float_check, "float", sizeof(float), py_to_float, (RNA_SetArrayFunc)RNA_property_float_set_array, error_prefix); 00474 break; 00475 case PROP_INT: 00476 ret= py_to_array(py, ptr, prop, param_data, py_int_check, "int", sizeof(int), py_to_int, (RNA_SetArrayFunc)RNA_property_int_set_array, error_prefix); 00477 break; 00478 case PROP_BOOLEAN: 00479 ret= py_to_array(py, ptr, prop, param_data, py_bool_check, "boolean", sizeof(int), py_to_bool, (RNA_SetArrayFunc)RNA_property_boolean_set_array, error_prefix); 00480 break; 00481 default: 00482 PyErr_SetString(PyExc_TypeError, "not an array type"); 00483 ret= -1; 00484 } 00485 00486 return ret; 00487 } 00488 00489 int pyrna_py_to_array_index(PointerRNA *ptr, PropertyRNA *prop, int arraydim, int arrayoffset, int index, PyObject *py, const char *error_prefix) 00490 { 00491 int ret; 00492 switch (RNA_property_type(prop)) { 00493 case PROP_FLOAT: 00494 ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_float_check, "float", py_to_float, float_set_index, error_prefix); 00495 break; 00496 case PROP_INT: 00497 ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_int_check, "int", py_to_int, int_set_index, error_prefix); 00498 break; 00499 case PROP_BOOLEAN: 00500 ret= py_to_array_index(py, ptr, prop, arraydim, arrayoffset, index, py_bool_check, "boolean", py_to_bool, bool_set_index, error_prefix); 00501 break; 00502 default: 00503 PyErr_SetString(PyExc_TypeError, "not an array type"); 00504 ret= -1; 00505 } 00506 00507 return ret; 00508 } 00509 00510 PyObject *pyrna_array_index(PointerRNA *ptr, PropertyRNA *prop, int index) 00511 { 00512 PyObject *item; 00513 00514 switch (RNA_property_type(prop)) { 00515 case PROP_FLOAT: 00516 item= PyFloat_FromDouble(RNA_property_float_get_index(ptr, prop, index)); 00517 break; 00518 case PROP_BOOLEAN: 00519 item= PyBool_FromLong(RNA_property_boolean_get_index(ptr, prop, index)); 00520 break; 00521 case PROP_INT: 00522 item= PyLong_FromSsize_t(RNA_property_int_get_index(ptr, prop, index)); 00523 break; 00524 default: 00525 PyErr_SetString(PyExc_TypeError, "not an array type"); 00526 item= NULL; 00527 } 00528 00529 return item; 00530 } 00531 00532 #if 0 00533 /* XXX this is not used (and never will?) */ 00534 /* Given an array property, creates an N-dimensional tuple of values. */ 00535 static PyObject *pyrna_py_from_array_internal(PointerRNA *ptr, PropertyRNA *prop, int dim, int *index) 00536 { 00537 PyObject *tuple; 00538 int i, len; 00539 int totdim= RNA_property_array_dimension(ptr, prop, NULL); 00540 00541 len= RNA_property_multi_array_length(ptr, prop, dim); 00542 00543 tuple= PyTuple_New(len); 00544 00545 for (i= 0; i < len; i++) { 00546 PyObject *item; 00547 00548 if (dim + 1 < totdim) 00549 item= pyrna_py_from_array_internal(ptr, prop, dim + 1, index); 00550 else { 00551 item= pyrna_array_index(ptr, prop, *index); 00552 *index= *index + 1; 00553 } 00554 00555 if (!item) { 00556 Py_DECREF(tuple); 00557 return NULL; 00558 } 00559 00560 PyTuple_SET_ITEM(tuple, i, item); 00561 } 00562 00563 return tuple; 00564 } 00565 #endif 00566 00567 PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PropertyRNA *prop, int index) 00568 { 00569 int totdim, arraydim, arrayoffset, dimsize[MAX_ARRAY_DIMENSION], i, len; 00570 BPy_PropertyArrayRNA *ret= NULL; 00571 00572 arraydim= self ? self->arraydim : 0; 00573 arrayoffset= self ? self->arrayoffset : 0; 00574 00575 /* just in case check */ 00576 len= RNA_property_multi_array_length(ptr, prop, arraydim); 00577 if (index >= len || index < 0) { 00578 /* this shouldn't happen because higher level funcs must check for invalid index */ 00579 if (G.f & G_DEBUG) printf("pyrna_py_from_array_index: invalid index %d for array with length=%d\n", index, len); 00580 00581 PyErr_SetString(PyExc_IndexError, "out of range"); 00582 return NULL; 00583 } 00584 00585 totdim= RNA_property_array_dimension(ptr, prop, dimsize); 00586 00587 if (arraydim + 1 < totdim) { 00588 ret= (BPy_PropertyArrayRNA*)pyrna_prop_CreatePyObject(ptr, prop); 00589 ret->arraydim= arraydim + 1; 00590 00591 /* arr[3][4][5] 00592 00593 x= arr[2] 00594 index= 0 + 2 * 4 * 5 00595 00596 x= arr[2][3] 00597 index= offset + 3 * 5 */ 00598 00599 for (i= arraydim + 1; i < totdim; i++) 00600 index *= dimsize[i]; 00601 00602 ret->arrayoffset= arrayoffset + index; 00603 } 00604 else { 00605 index= arrayoffset + index; 00606 ret= (BPy_PropertyArrayRNA *)pyrna_array_index(ptr, prop, index); 00607 } 00608 00609 return (PyObject*)ret; 00610 } 00611 00612 PyObject *pyrna_py_from_array(PointerRNA *ptr, PropertyRNA *prop) 00613 { 00614 PyObject *ret; 00615 00616 ret= pyrna_math_object_from_array(ptr, prop); 00617 00618 /* is this a maths object? */ 00619 if (ret) return ret; 00620 00621 return pyrna_prop_CreatePyObject(ptr, prop); 00622 } 00623 00624 /* TODO, multi-dimensional arrays */ 00625 int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value) 00626 { 00627 int len= RNA_property_array_length(ptr, prop); 00628 int type; 00629 int i; 00630 00631 if(len==0) /* possible with dynamic arrays */ 00632 return 0; 00633 00634 if (RNA_property_array_dimension(ptr, prop, NULL) > 1) { 00635 PyErr_SetString(PyExc_TypeError, "PropertyRNA - multi dimensional arrays not supported yet"); 00636 return -1; 00637 } 00638 00639 type= RNA_property_type(prop); 00640 00641 switch (type) { 00642 case PROP_FLOAT: 00643 { 00644 float value_f= PyFloat_AsDouble(value); 00645 if(value_f==-1 && PyErr_Occurred()) { 00646 PyErr_Clear(); 00647 return 0; 00648 } 00649 else { 00650 float tmp[32]; 00651 float *tmp_arr; 00652 00653 if(len * sizeof(float) > sizeof(tmp)) { 00654 tmp_arr= PyMem_MALLOC(len * sizeof(float)); 00655 } 00656 else { 00657 tmp_arr= tmp; 00658 } 00659 00660 RNA_property_float_get_array(ptr, prop, tmp_arr); 00661 00662 for(i=0; i<len; i++) 00663 if(tmp_arr[i] == value_f) 00664 break; 00665 00666 if(tmp_arr != tmp) 00667 PyMem_FREE(tmp_arr); 00668 00669 return i<len ? 1 : 0; 00670 } 00671 break; 00672 } 00673 case PROP_BOOLEAN: 00674 case PROP_INT: 00675 { 00676 int value_i= PyLong_AsSsize_t(value); 00677 if(value_i==-1 && PyErr_Occurred()) { 00678 PyErr_Clear(); 00679 return 0; 00680 } 00681 else { 00682 int tmp[32]; 00683 int *tmp_arr; 00684 00685 if(len * sizeof(int) > sizeof(tmp)) { 00686 tmp_arr= PyMem_MALLOC(len * sizeof(int)); 00687 } 00688 else { 00689 tmp_arr= tmp; 00690 } 00691 00692 if(type==PROP_BOOLEAN) 00693 RNA_property_boolean_get_array(ptr, prop, tmp_arr); 00694 else 00695 RNA_property_int_get_array(ptr, prop, tmp_arr); 00696 00697 for(i=0; i<len; i++) 00698 if(tmp_arr[i] == value_i) 00699 break; 00700 00701 if(tmp_arr != tmp) 00702 PyMem_FREE(tmp_arr); 00703 00704 return i<len ? 1 : 0; 00705 } 00706 break; 00707 } 00708 } 00709 00710 /* should never reach this */ 00711 PyErr_SetString(PyExc_TypeError, "PropertyRNA - type not in float/bool/int"); 00712 return -1; 00713 }