Author: Andrew Leech <and...@alelec.net> Branch: calculate_variable_array_length Changeset: r2791:3a9e42446693 Date: 2016-09-14 16:56 +1000 http://bitbucket.org/cffi/cffi/changeset/3a9e42446693/
Log: Detect and mark the final variable array in a varsized struct with BS_VARSIZESTRUCT_ARRAY Use this when returning this field/arrtibute of said struct diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -185,14 +185,15 @@ PyObject_HEAD CTypeDescrObject *cf_type; Py_ssize_t cf_offset; - short cf_bitshift; /* >= 0: bitshift; or BS_REGULAR or BS_EMPTY_ARRAY */ + short cf_bitshift; /* >= 0: bitshift; or BS_REGULAR or BS_EMPTY_ARRAY or BS_VARSIZESTRUCT_ARRAY */ short cf_bitsize; unsigned char cf_flags; /* BF_... */ struct cfieldobject_s *cf_next; } CFieldObject; -#define BS_REGULAR (-1) /* a regular field, not with bitshift */ -#define BS_EMPTY_ARRAY (-2) /* a field which is an array 'type[0]' */ -#define BF_IGNORE_IN_CTOR 0x01 /* union field not in the first place */ +#define BS_REGULAR (-1) /* a regular field, not with bitshift */ +#define BS_EMPTY_ARRAY (-2) /* a field which is an array 'type[0]' */ +#define BS_VARSIZESTRUCT_ARRAY (-3) /* a variable sized struct variable field 'type[]' */ +#define BF_IGNORE_IN_CTOR 0x01 /* union field not in the first place */ static PyTypeObject CTypeDescr_Type; static PyTypeObject CField_Type; @@ -2406,8 +2407,7 @@ char *data = cd->c_data + cf->cf_offset; if ((cd->c_type->ct_flags & CT_IS_PTR_TO_OWNED) && // Is owned struct (or union) - (cf->cf_type->ct_flags & CT_ARRAY) && // field is an array - (cf->cf_type->ct_size == -1)) { // unknown length array + (cf->cf_bitshift == BS_VARSIZESTRUCT_ARRAY)) { // variable length array /* if reading variable length array from variable length struct, calculate array type from allocated length*/ Py_ssize_t array_len = (((CDataObject_own_structptr *)cd)->length - ct->ct_size) / cf->cf_type->ct_itemdescr->ct_size; return new_sized_cdata(data, cf->cf_type, array_len); @@ -3227,6 +3227,7 @@ } /* store the only reference to cds into cd */ ((CDataObject_own_structptr *)cd)->structobj = (PyObject *)cds; + /* store information about the allocated size of the struct */ ((CDataObject_own_structptr *)cd)->length = datasize; assert(explicitlength < 0); @@ -4299,7 +4300,9 @@ /* not a bitfield: common case */ int bs_flag; - if (ftype->ct_flags & CT_ARRAY && ftype->ct_length == 0) + if (ftype->ct_flags & CT_ARRAY && ftype->ct_length == -1 && i == nb_fields - 1) + bs_flag = BS_VARSIZESTRUCT_ARRAY; + else if (ftype->ct_flags & CT_ARRAY && ftype->ct_length == 0) bs_flag = BS_EMPTY_ARRAY; else bs_flag = BS_REGULAR; diff --git a/c/test_c.py b/c/test_c.py --- a/c/test_c.py +++ b/c/test_c.py @@ -3172,7 +3172,7 @@ assert d[1][0] == 'y' assert d[1][1].type is BArray assert d[1][1].offset == size_of_int() - assert d[1][1].bitshift == -1 + assert d[1][1].bitshift == -3 assert d[1][1].bitsize == -1 # p = newp(new_pointer_type(BStruct)) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit