Commit 62d061fc authored by smutch's avatar smutch Committed by Stefan Behnel

Fix buffer parsing for memoryviews of arrays of structs (GH-3562)

See #1407.
parent a3d9bc71
...@@ -602,9 +602,8 @@ static PyObject * ...@@ -602,9 +602,8 @@ static PyObject *
__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) __pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
{ {
const char *ts = *tsp; const char *ts = *tsp;
int i = 0, number; int i = 0, number, ndim;
int ndim = ctx->head->field->type->ndim;
;
++ts; ++ts;
if (ctx->new_count != 1) { if (ctx->new_count != 1) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
...@@ -615,6 +614,9 @@ __pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) ...@@ -615,6 +614,9 @@ __pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
/* Process the previous element */ /* Process the previous element */
if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
// store ndim now, as field advanced by __Pyx_BufFmt_ProcessTypeChunk call
ndim = ctx->head->field->type->ndim;
/* Parse all numbers in the format string */ /* Parse all numbers in the format string */
while (*ts && *ts != ')') { while (*ts && *ts != ')') {
// ignore space characters (not using isspace() due to C/C++ problem on MacOS-X) // ignore space characters (not using isspace() due to C/C++ problem on MacOS-X)
...@@ -757,8 +759,8 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha ...@@ -757,8 +759,8 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha
case 'l': case 'L': case 'q': case 'Q': case 'l': case 'L': case 'q': case 'Q':
case 'f': case 'd': case 'g': case 'f': case 'd': case 'g':
case 'O': case 'p': case 'O': case 'p':
if (ctx->enc_type == *ts && got_Z == ctx->is_complex && if ((ctx->enc_type == *ts) && (got_Z == ctx->is_complex) &&
ctx->enc_packmode == ctx->new_packmode) { (ctx->enc_packmode == ctx->new_packmode) && (!ctx->is_valid_array)) {
/* Continue pooling same type */ /* Continue pooling same type */
ctx->enc_count += ctx->new_count; ctx->enc_count += ctx->new_count;
ctx->new_count = 1; ctx->new_count = 1;
......
...@@ -406,6 +406,59 @@ def packed_struct_with_strings(fmt): ...@@ -406,6 +406,59 @@ def packed_struct_with_strings(fmt):
fmt, sizeof(PackedStructWithCharArrays)) fmt, sizeof(PackedStructWithCharArrays))
ctypedef struct PackedStructWithArrays:
double a[16]
double b[16]
double c
ctypedef struct UnpackedStructWithArrays:
int a
float b[8]
float c
unsigned long d
int e[5]
int f
int g
double h[4]
int i
ctypedef struct PackedStructWithNDArrays:
double a
double b[2][2]
float c
float d
@testcase
def packed_struct_with_arrays(fmt):
"""
>>> packed_struct_with_arrays("T{(16)d:a:(16)d:b:d:c:}")
"""
cdef object[PackedStructWithArrays] buf = MockBuffer(
fmt, sizeof(PackedStructWithArrays))
@testcase
def unpacked_struct_with_arrays(fmt):
"""
>>> unpacked_struct_with_arrays("T{i:a:(8)f:b:f:c:L:d:(5)i:e:i:f:i:g:xxxx(4)d:h:i:i:}")
"""
cdef object[UnpackedStructWithArrays] buf = MockBuffer(
fmt, sizeof(UnpackedStructWithArrays))
@testcase
def packed_struct_with_ndarrays(fmt):
"""
>>> packed_struct_with_ndarrays("T{d:a:(2,2)d:b:f:c:f:d:}")
"""
cdef object[PackedStructWithNDArrays] buf = MockBuffer(
fmt, sizeof(PackedStructWithNDArrays))
# TODO: empty struct # TODO: empty struct
# TODO: Incomplete structs # TODO: Incomplete structs
# TODO: mixed structs # TODO: mixed structs
...@@ -718,3 +718,41 @@ def test_boundscheck_and_wraparound(double[:, :] x): ...@@ -718,3 +718,41 @@ def test_boundscheck_and_wraparound(double[:, :] x):
x[i] x[i]
x[i, ...] x[i, ...]
x[i, :] x[i, :]
ctypedef struct SameTypeAfterArraysStructSimple:
double a[16]
double b[16]
double c
@testcase
def same_type_after_arrays_simple():
"""
>>> same_type_after_arrays_simple()
"""
cdef SameTypeAfterArraysStructSimple element
arr = np.ones(2, np.asarray(<SameTypeAfterArraysStructSimple[:1]>&element).dtype)
cdef SameTypeAfterArraysStructSimple[:] memview = arr
ctypedef struct SameTypeAfterArraysStructComposite:
int a
float b[8]
float c
unsigned long d
int e[5]
int f
int g
double h[4]
int i
@testcase
def same_type_after_arrays_composite():
"""
>>> same_type_after_arrays_composite()
"""
cdef SameTypeAfterArraysStructComposite element
arr = np.ones(2, np.asarray(<SameTypeAfterArraysStructComposite[:1]>&element).dtype)
cdef SameTypeAfterArraysStructComposite[:] memview = arr
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment