Spaces:
Running
Running
/////////////// BufferStructDeclare.proto /////////////// | |
/* structs for buffer access */ | |
typedef struct { | |
Py_ssize_t shape, strides, suboffsets; | |
} __Pyx_Buf_DimInfo; | |
typedef struct { | |
size_t refcount; | |
Py_buffer pybuffer; | |
} __Pyx_Buffer; | |
typedef struct { | |
__Pyx_Buffer *rcbuffer; | |
char *data; | |
__Pyx_Buf_DimInfo diminfo[{{max_dims}}]; | |
} __Pyx_LocalBuf_ND; | |
/////////////// BufferIndexError.proto /////////////// | |
static void __Pyx_RaiseBufferIndexError(int axis); /*proto*/ | |
/////////////// BufferIndexError /////////////// | |
static void __Pyx_RaiseBufferIndexError(int axis) { | |
PyErr_Format(PyExc_IndexError, | |
"Out of bounds on buffer access (axis %d)", axis); | |
} | |
/////////////// BufferIndexErrorNogil.proto /////////////// | |
//@requires: BufferIndexError | |
static void __Pyx_RaiseBufferIndexErrorNogil(int axis); /*proto*/ | |
/////////////// BufferIndexErrorNogil /////////////// | |
static void __Pyx_RaiseBufferIndexErrorNogil(int axis) { | |
PyGILState_STATE gilstate = PyGILState_Ensure(); | |
__Pyx_RaiseBufferIndexError(axis); | |
PyGILState_Release(gilstate); | |
} | |
/////////////// BufferFallbackError.proto /////////////// | |
static void __Pyx_RaiseBufferFallbackError(void); /*proto*/ | |
/////////////// BufferFallbackError /////////////// | |
static void __Pyx_RaiseBufferFallbackError(void) { | |
PyErr_SetString(PyExc_ValueError, | |
"Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!"); | |
} | |
/////////////// BufferFormatStructs.proto /////////////// | |
//@proto_block: utility_code_proto_before_types | |
/* Run-time type information about structs used with buffers */ | |
struct __Pyx_StructField_; | |
typedef struct { | |
const char* name; /* for error messages only */ | |
struct __Pyx_StructField_* fields; | |
size_t size; /* sizeof(type) */ | |
size_t arraysize[8]; /* length of array in each dimension */ | |
int ndim; | |
char typegroup; /* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject, c_H_ar */ | |
char is_unsigned; | |
int flags; | |
} __Pyx_TypeInfo; | |
typedef struct __Pyx_StructField_ { | |
__Pyx_TypeInfo* type; | |
const char* name; | |
size_t offset; | |
} __Pyx_StructField; | |
typedef struct { | |
__Pyx_StructField* field; | |
size_t parent_offset; | |
} __Pyx_BufFmt_StackElem; | |
typedef struct { | |
__Pyx_StructField root; | |
__Pyx_BufFmt_StackElem* head; | |
size_t fmt_offset; | |
size_t new_count, enc_count; | |
size_t struct_alignment; | |
int is_complex; | |
char enc_type; | |
char new_packmode; | |
char enc_packmode; | |
char is_valid_array; | |
} __Pyx_BufFmt_Context; | |
/////////////// GetAndReleaseBuffer.proto /////////////// | |
static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); | |
static void __Pyx_ReleaseBuffer(Py_buffer *view); | |
/////////////// GetAndReleaseBuffer /////////////// | |
static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { | |
if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); | |
{{for type_ptr, getbuffer, releasebuffer in types}} | |
{{if getbuffer}} | |
if (__Pyx_TypeCheck(obj, {{type_ptr}})) return {{getbuffer}}(obj, view, flags); | |
{{endif}} | |
{{endfor}} | |
PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name); | |
return -1; | |
} | |
static void __Pyx_ReleaseBuffer(Py_buffer *view) { | |
PyObject *obj = view->obj; | |
if (!obj) return; | |
if (PyObject_CheckBuffer(obj)) { | |
PyBuffer_Release(view); | |
return; | |
} | |
if ((0)) {} | |
{{for type_ptr, getbuffer, releasebuffer in types}} | |
{{if releasebuffer}} | |
else if (__Pyx_TypeCheck(obj, {{type_ptr}})) {{releasebuffer}}(obj, view); | |
{{endif}} | |
{{endfor}} | |
view->obj = NULL; | |
Py_DECREF(obj); | |
} | |
/////////////// BufferGetAndValidate.proto /////////////// | |
static int __Pyx__GetBufferAndValidate(Py_buffer* buf, PyObject* obj, | |
__Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); | |
static void __Pyx_ZeroBuffer(Py_buffer* buf); | |
static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);/*proto*/ | |
static Py_ssize_t __Pyx_minusones[] = { {{ ", ".join(["-1"] * max_dims) }} }; | |
static Py_ssize_t __Pyx_zeros[] = { {{ ", ".join(["0"] * max_dims) }} }; | |
/////////////// BufferGetAndValidate /////////////// | |
//@requires: BufferFormatCheck | |
static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { | |
if (unlikely(info->buf == NULL)) return; | |
if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; | |
__Pyx_ReleaseBuffer(info); | |
} | |
static void __Pyx_ZeroBuffer(Py_buffer* buf) { | |
buf->buf = NULL; | |
buf->obj = NULL; | |
buf->strides = __Pyx_zeros; | |
buf->shape = __Pyx_zeros; | |
buf->suboffsets = __Pyx_minusones; | |
} | |
static int __Pyx__GetBufferAndValidate( | |
Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, | |
int nd, int cast, __Pyx_BufFmt_StackElem* stack) | |
{ | |
buf->buf = NULL; | |
if (unlikely(__Pyx_GetBuffer(obj, buf, flags) == -1)) { | |
__Pyx_ZeroBuffer(buf); | |
return -1; | |
} | |
// From this point on, we have acquired the buffer and must release it on errors. | |
if (unlikely(buf->ndim != nd)) { | |
PyErr_Format(PyExc_ValueError, | |
"Buffer has wrong number of dimensions (expected %d, got %d)", | |
nd, buf->ndim); | |
goto fail; | |
} | |
if (!cast) { | |
__Pyx_BufFmt_Context ctx; | |
__Pyx_BufFmt_Init(&ctx, stack, dtype); | |
if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; | |
} | |
if (unlikely((size_t)buf->itemsize != dtype->size)) { | |
PyErr_Format(PyExc_ValueError, | |
"Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", | |
buf->itemsize, (buf->itemsize > 1) ? "s" : "", | |
dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); | |
goto fail; | |
} | |
if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; | |
return 0; | |
fail:; | |
__Pyx_SafeReleaseBuffer(buf); | |
return -1; | |
} | |
/////////////// BufferFormatCheck.proto /////////////// | |
// Buffer format string checking | |
// | |
// Buffer type checking. Utility code for checking that acquired | |
// buffers match our assumptions. We only need to check ndim and | |
// the format string; the access mode/flags is checked by the | |
// exporter. See: | |
// | |
// http://docs.python.org/3/library/struct.html | |
// http://legacy.python.org/dev/peps/pep-3118/#additions-to-the-struct-string-syntax | |
// | |
// The alignment code is copied from _struct.c in Python. | |
static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts); | |
static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, | |
__Pyx_BufFmt_StackElem* stack, | |
__Pyx_TypeInfo* type); /*proto*/ | |
/////////////// BufferFormatCheck /////////////// | |
//@requires: ModuleSetupCode.c::IsLittleEndian | |
//@requires: BufferFormatStructs | |
static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, | |
__Pyx_BufFmt_StackElem* stack, | |
__Pyx_TypeInfo* type) { | |
stack[0].field = &ctx->root; | |
stack[0].parent_offset = 0; | |
ctx->root.type = type; | |
ctx->root.name = "buffer dtype"; | |
ctx->root.offset = 0; | |
ctx->head = stack; | |
ctx->head->field = &ctx->root; | |
ctx->fmt_offset = 0; | |
ctx->head->parent_offset = 0; | |
ctx->new_packmode = '@'; | |
ctx->enc_packmode = '@'; | |
ctx->new_count = 1; | |
ctx->enc_count = 0; | |
ctx->enc_type = 0; | |
ctx->is_complex = 0; | |
ctx->is_valid_array = 0; | |
ctx->struct_alignment = 0; | |
while (type->typegroup == 'S') { | |
++ctx->head; | |
ctx->head->field = type->fields; | |
ctx->head->parent_offset = 0; | |
type = type->fields->type; | |
} | |
} | |
static int __Pyx_BufFmt_ParseNumber(const char** ts) { | |
int count; | |
const char* t = *ts; | |
if (*t < '0' || *t > '9') { | |
return -1; | |
} else { | |
count = *t++ - '0'; | |
while (*t >= '0' && *t <= '9') { | |
count *= 10; | |
count += *t++ - '0'; | |
} | |
} | |
*ts = t; | |
return count; | |
} | |
static int __Pyx_BufFmt_ExpectNumber(const char **ts) { | |
int number = __Pyx_BufFmt_ParseNumber(ts); | |
if (number == -1) /* First char was not a digit */ | |
PyErr_Format(PyExc_ValueError,\ | |
"Does not understand character buffer dtype format string ('%c')", **ts); | |
return number; | |
} | |
static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { | |
PyErr_Format(PyExc_ValueError, | |
"Unexpected format string character: '%c'", ch); | |
} | |
static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { | |
switch (ch) { | |
case '?': return "'bool'"; | |
case 'c': return "'char'"; | |
case 'b': return "'signed char'"; | |
case 'B': return "'unsigned char'"; | |
case 'h': return "'short'"; | |
case 'H': return "'unsigned short'"; | |
case 'i': return "'int'"; | |
case 'I': return "'unsigned int'"; | |
case 'l': return "'long'"; | |
case 'L': return "'unsigned long'"; | |
case 'q': return "'long long'"; | |
case 'Q': return "'unsigned long long'"; | |
case 'f': return (is_complex ? "'complex float'" : "'float'"); | |
case 'd': return (is_complex ? "'complex double'" : "'double'"); | |
case 'g': return (is_complex ? "'complex long double'" : "'long double'"); | |
case 'T': return "a struct"; | |
case 'O': return "Python object"; | |
case 'P': return "a pointer"; | |
case 's': case 'p': return "a string"; | |
case 0: return "end"; | |
default: return "unparseable format string"; | |
} | |
} | |
static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { | |
switch (ch) { | |
case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; | |
case 'h': case 'H': return 2; | |
case 'i': case 'I': case 'l': case 'L': return 4; | |
case 'q': case 'Q': return 8; | |
case 'f': return (is_complex ? 8 : 4); | |
case 'd': return (is_complex ? 16 : 8); | |
case 'g': { | |
PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); | |
return 0; | |
} | |
case 'O': case 'P': return sizeof(void*); | |
default: | |
__Pyx_BufFmt_RaiseUnexpectedChar(ch); | |
return 0; | |
} | |
} | |
static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { | |
switch (ch) { | |
case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; | |
case 'h': case 'H': return sizeof(short); | |
case 'i': case 'I': return sizeof(int); | |
case 'l': case 'L': return sizeof(long); | |
case 'q': case 'Q': return sizeof(PY_LONG_LONG); | |
case 'f': return sizeof(float) * (is_complex ? 2 : 1); | |
case 'd': return sizeof(double) * (is_complex ? 2 : 1); | |
case 'g': return sizeof(long double) * (is_complex ? 2 : 1); | |
case 'O': case 'P': return sizeof(void*); | |
default: { | |
__Pyx_BufFmt_RaiseUnexpectedChar(ch); | |
return 0; | |
} | |
} | |
} | |
typedef struct { char c; short x; } __Pyx_st_short; | |
typedef struct { char c; int x; } __Pyx_st_int; | |
typedef struct { char c; long x; } __Pyx_st_long; | |
typedef struct { char c; float x; } __Pyx_st_float; | |
typedef struct { char c; double x; } __Pyx_st_double; | |
typedef struct { char c; long double x; } __Pyx_st_longdouble; | |
typedef struct { char c; void *x; } __Pyx_st_void_p; | |
typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; | |
static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) { | |
switch (ch) { | |
case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; | |
case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); | |
case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); | |
case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); | |
case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); | |
case 'f': return sizeof(__Pyx_st_float) - sizeof(float); | |
case 'd': return sizeof(__Pyx_st_double) - sizeof(double); | |
case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); | |
case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); | |
default: | |
__Pyx_BufFmt_RaiseUnexpectedChar(ch); | |
return 0; | |
} | |
} | |
/* These are for computing the padding at the end of the struct to align | |
on the first member of the struct. This will probably the same as above, | |
but we don't have any guarantees. | |
*/ | |
typedef struct { short x; char c; } __Pyx_pad_short; | |
typedef struct { int x; char c; } __Pyx_pad_int; | |
typedef struct { long x; char c; } __Pyx_pad_long; | |
typedef struct { float x; char c; } __Pyx_pad_float; | |
typedef struct { double x; char c; } __Pyx_pad_double; | |
typedef struct { long double x; char c; } __Pyx_pad_longdouble; | |
typedef struct { void *x; char c; } __Pyx_pad_void_p; | |
typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; | |
static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) { | |
switch (ch) { | |
case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; | |
case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); | |
case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); | |
case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); | |
case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); | |
case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); | |
case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); | |
case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); | |
case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); | |
default: | |
__Pyx_BufFmt_RaiseUnexpectedChar(ch); | |
return 0; | |
} | |
} | |
static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { | |
switch (ch) { | |
case 'c': | |
return 'H'; | |
case 'b': case 'h': case 'i': | |
case 'l': case 'q': case 's': case 'p': | |
return 'I'; | |
case '?': case 'B': case 'H': case 'I': case 'L': case 'Q': | |
return 'U'; | |
case 'f': case 'd': case 'g': | |
return (is_complex ? 'C' : 'R'); | |
case 'O': | |
return 'O'; | |
case 'P': | |
return 'P'; | |
default: { | |
__Pyx_BufFmt_RaiseUnexpectedChar(ch); | |
return 0; | |
} | |
} | |
} | |
static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { | |
if (ctx->head == NULL || ctx->head->field == &ctx->root) { | |
const char* expected; | |
const char* quote; | |
if (ctx->head == NULL) { | |
expected = "end"; | |
quote = ""; | |
} else { | |
expected = ctx->head->field->type->name; | |
quote = "'"; | |
} | |
PyErr_Format(PyExc_ValueError, | |
"Buffer dtype mismatch, expected %s%s%s but got %s", | |
quote, expected, quote, | |
__Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); | |
} else { | |
__Pyx_StructField* field = ctx->head->field; | |
__Pyx_StructField* parent = (ctx->head - 1)->field; | |
PyErr_Format(PyExc_ValueError, | |
"Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", | |
field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), | |
parent->type->name, field->name); | |
} | |
} | |
static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { | |
char group; | |
size_t size, offset, arraysize = 1; | |
/* printf("processing... %s\n", ctx->head->field->type->name); */ | |
if (ctx->enc_type == 0) return 0; | |
/* Validate array size */ | |
if (ctx->head->field->type->arraysize[0]) { | |
int i, ndim = 0; | |
/* handle strings ('s' and 'p') */ | |
if (ctx->enc_type == 's' || ctx->enc_type == 'p') { | |
ctx->is_valid_array = ctx->head->field->type->ndim == 1; | |
ndim = 1; | |
if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { | |
PyErr_Format(PyExc_ValueError, | |
"Expected a dimension of size %zu, got %zu", | |
ctx->head->field->type->arraysize[0], ctx->enc_count); | |
return -1; | |
} | |
} | |
if (!ctx->is_valid_array) { | |
PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", | |
ctx->head->field->type->ndim, ndim); | |
return -1; | |
} | |
for (i = 0; i < ctx->head->field->type->ndim; i++) { | |
arraysize *= ctx->head->field->type->arraysize[i]; | |
} | |
ctx->is_valid_array = 0; | |
ctx->enc_count = 1; | |
} | |
group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); | |
do { | |
__Pyx_StructField* field = ctx->head->field; | |
__Pyx_TypeInfo* type = field->type; | |
if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { | |
size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); | |
} else { | |
size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); | |
} | |
if (ctx->enc_packmode == '@') { | |
size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); | |
size_t align_mod_offset; | |
if (align_at == 0) return -1; | |
align_mod_offset = ctx->fmt_offset % align_at; | |
if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; | |
if (ctx->struct_alignment == 0) | |
ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, | |
ctx->is_complex); | |
} | |
if (type->size != size || type->typegroup != group) { | |
if (type->typegroup == 'C' && type->fields != NULL) { | |
/* special case -- treat as struct rather than complex number */ | |
size_t parent_offset = ctx->head->parent_offset + field->offset; | |
++ctx->head; | |
ctx->head->field = type->fields; | |
ctx->head->parent_offset = parent_offset; | |
continue; | |
} | |
if ((type->typegroup == 'H' || group == 'H') && type->size == size) { | |
/* special case -- chars don't care about sign */ | |
} else { | |
__Pyx_BufFmt_RaiseExpected(ctx); | |
return -1; | |
} | |
} | |
offset = ctx->head->parent_offset + field->offset; | |
if (ctx->fmt_offset != offset) { | |
PyErr_Format(PyExc_ValueError, | |
"Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", | |
(Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); | |
return -1; | |
} | |
ctx->fmt_offset += size; | |
if (arraysize) | |
ctx->fmt_offset += (arraysize - 1) * size; | |
--ctx->enc_count; /* Consume from buffer string */ | |
/* Done checking, move to next field, pushing or popping struct stack if needed */ | |
while (1) { | |
if (field == &ctx->root) { | |
ctx->head = NULL; | |
if (ctx->enc_count != 0) { | |
__Pyx_BufFmt_RaiseExpected(ctx); | |
return -1; | |
} | |
break; /* breaks both loops as ctx->enc_count == 0 */ | |
} | |
ctx->head->field = ++field; | |
if (field->type == NULL) { | |
--ctx->head; | |
field = ctx->head->field; | |
continue; | |
} else if (field->type->typegroup == 'S') { | |
size_t parent_offset = ctx->head->parent_offset + field->offset; | |
if (field->type->fields->type == NULL) continue; /* empty struct */ | |
field = field->type->fields; | |
++ctx->head; | |
ctx->head->field = field; | |
ctx->head->parent_offset = parent_offset; | |
break; | |
} else { | |
break; | |
} | |
} | |
} while (ctx->enc_count); | |
ctx->enc_type = 0; | |
ctx->is_complex = 0; | |
return 0; | |
} | |
/* Parse an array in the format string (e.g. (1,2,3)) */ | |
static PyObject * | |
__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) | |
{ | |
const char *ts = *tsp; | |
int i = 0, number, ndim; | |
++ts; | |
if (ctx->new_count != 1) { | |
PyErr_SetString(PyExc_ValueError, | |
"Cannot handle repeated arrays in format string"); | |
return NULL; | |
} | |
/* Process the previous element */ | |
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 */ | |
while (*ts && *ts != ')') { | |
// ignore space characters (not using isspace() due to C/C++ problem on MacOS-X) | |
switch (*ts) { | |
case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; | |
default: break; /* not a 'break' in the loop */ | |
} | |
number = __Pyx_BufFmt_ExpectNumber(&ts); | |
if (number == -1) return NULL; | |
if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) | |
return PyErr_Format(PyExc_ValueError, | |
"Expected a dimension of size %zu, got %d", | |
ctx->head->field->type->arraysize[i], number); | |
if (*ts != ',' && *ts != ')') | |
return PyErr_Format(PyExc_ValueError, | |
"Expected a comma in format string, got '%c'", *ts); | |
if (*ts == ',') ts++; | |
i++; | |
} | |
if (i != ndim) | |
return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", | |
ctx->head->field->type->ndim, i); | |
if (!*ts) { | |
PyErr_SetString(PyExc_ValueError, | |
"Unexpected end of format string, expected ')'"); | |
return NULL; | |
} | |
ctx->is_valid_array = 1; | |
ctx->new_count = 1; | |
*tsp = ++ts; | |
return Py_None; | |
} | |
static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { | |
int got_Z = 0; | |
while (1) { | |
/* puts(ts); */ | |
switch(*ts) { | |
case 0: | |
if (ctx->enc_type != 0 && ctx->head == NULL) { | |
__Pyx_BufFmt_RaiseExpected(ctx); | |
return NULL; | |
} | |
if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; | |
if (ctx->head != NULL) { | |
__Pyx_BufFmt_RaiseExpected(ctx); | |
return NULL; | |
} | |
return ts; | |
case ' ': | |
case '\r': | |
case '\n': | |
++ts; | |
break; | |
case '<': | |
if (!__Pyx_Is_Little_Endian()) { | |
PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); | |
return NULL; | |
} | |
ctx->new_packmode = '='; | |
++ts; | |
break; | |
case '>': | |
case '!': | |
if (__Pyx_Is_Little_Endian()) { | |
PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); | |
return NULL; | |
} | |
ctx->new_packmode = '='; | |
++ts; | |
break; | |
case '=': | |
case '@': | |
case '^': | |
ctx->new_packmode = *ts++; | |
break; | |
case 'T': /* substruct */ | |
{ | |
const char* ts_after_sub; | |
size_t i, struct_count = ctx->new_count; | |
size_t struct_alignment = ctx->struct_alignment; | |
ctx->new_count = 1; | |
++ts; | |
if (*ts != '{') { | |
PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); | |
return NULL; | |
} | |
if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; | |
ctx->enc_type = 0; /* Erase processed last struct element */ | |
ctx->enc_count = 0; | |
ctx->struct_alignment = 0; | |
++ts; | |
ts_after_sub = ts; | |
for (i = 0; i != struct_count; ++i) { | |
ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); | |
if (!ts_after_sub) return NULL; | |
} | |
ts = ts_after_sub; | |
if (struct_alignment) ctx->struct_alignment = struct_alignment; | |
} | |
break; | |
case '}': /* end of substruct; either repeat or move on */ | |
{ | |
size_t alignment = ctx->struct_alignment; | |
++ts; | |
if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; | |
ctx->enc_type = 0; /* Erase processed last struct element */ | |
if (alignment && ctx->fmt_offset % alignment) { | |
/* Pad struct on size of the first member */ | |
ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); | |
} | |
} | |
return ts; | |
case 'x': | |
if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; | |
ctx->fmt_offset += ctx->new_count; | |
ctx->new_count = 1; | |
ctx->enc_count = 0; | |
ctx->enc_type = 0; | |
ctx->enc_packmode = ctx->new_packmode; | |
++ts; | |
break; | |
case 'Z': | |
got_Z = 1; | |
++ts; | |
if (*ts != 'f' && *ts != 'd' && *ts != 'g') { | |
__Pyx_BufFmt_RaiseUnexpectedChar('Z'); | |
return NULL; | |
} | |
CYTHON_FALLTHROUGH; | |
case '?': case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': | |
case 'l': case 'L': case 'q': case 'Q': | |
case 'f': case 'd': case 'g': | |
case 'O': case 'p': | |
if ((ctx->enc_type == *ts) && (got_Z == ctx->is_complex) && | |
(ctx->enc_packmode == ctx->new_packmode) && (!ctx->is_valid_array)) { | |
/* Continue pooling same type */ | |
ctx->enc_count += ctx->new_count; | |
ctx->new_count = 1; | |
got_Z = 0; | |
++ts; | |
break; | |
} | |
CYTHON_FALLTHROUGH; | |
case 's': | |
/* 's' or new type (cannot be added to current pool) */ | |
if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; | |
ctx->enc_count = ctx->new_count; | |
ctx->enc_packmode = ctx->new_packmode; | |
ctx->enc_type = *ts; | |
ctx->is_complex = got_Z; | |
++ts; | |
ctx->new_count = 1; | |
got_Z = 0; | |
break; | |
case ':': | |
++ts; | |
while(*ts != ':') ++ts; | |
++ts; | |
break; | |
case '(': | |
if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL; | |
break; | |
default: | |
{ | |
int number = __Pyx_BufFmt_ExpectNumber(&ts); | |
if (number == -1) return NULL; | |
ctx->new_count = (size_t)number; | |
} | |
} | |
} | |
} | |
/////////////// TypeInfoCompare.proto /////////////// | |
static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b); | |
/////////////// TypeInfoCompare /////////////// | |
//@requires: BufferFormatStructs | |
// See if two dtypes are equal | |
static int | |
__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b) | |
{ | |
int i; | |
if (!a || !b) | |
return 0; | |
if (a == b) | |
return 1; | |
if (a->size != b->size || a->typegroup != b->typegroup || | |
a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) { | |
if (a->typegroup == 'H' || b->typegroup == 'H') { | |
/* Special case for chars */ | |
return a->size == b->size; | |
} else { | |
return 0; | |
} | |
} | |
if (a->ndim) { | |
/* Verify multidimensional C arrays */ | |
for (i = 0; i < a->ndim; i++) | |
if (a->arraysize[i] != b->arraysize[i]) | |
return 0; | |
} | |
if (a->typegroup == 'S') { | |
/* Check for packed struct */ | |
if (a->flags != b->flags) | |
return 0; | |
/* compare all struct fields */ | |
if (a->fields || b->fields) { | |
/* Check if both have fields */ | |
if (!(a->fields && b->fields)) | |
return 0; | |
/* compare */ | |
for (i = 0; a->fields[i].type && b->fields[i].type; i++) { | |
__Pyx_StructField *field_a = a->fields + i; | |
__Pyx_StructField *field_b = b->fields + i; | |
if (field_a->offset != field_b->offset || | |
!__pyx_typeinfo_cmp(field_a->type, field_b->type)) | |
return 0; | |
} | |
/* If all fields are processed, we have a match */ | |
return !a->fields[i].type && !b->fields[i].type; | |
} | |
} | |
return 1; | |
} | |
/////////////// TypeInfoToFormat.proto /////////////// | |
struct __pyx_typeinfo_string { | |
char string[3]; | |
}; | |
static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type); | |
/////////////// TypeInfoToFormat /////////////// | |
//@requires: BufferFormatStructs | |
// See also MemoryView.pyx:BufferFormatFromTypeInfo | |
static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type) { | |
struct __pyx_typeinfo_string result = { {0} }; | |
char *buf = (char *) result.string; | |
size_t size = type->size; | |
switch (type->typegroup) { | |
case 'H': | |
*buf = 'c'; | |
break; | |
case 'I': | |
case 'U': | |
if (size == 1) | |
*buf = (type->is_unsigned) ? 'B' : 'b'; | |
else if (size == 2) | |
*buf = (type->is_unsigned) ? 'H' : 'h'; | |
else if (size == 4) | |
*buf = (type->is_unsigned) ? 'I' : 'i'; | |
else if (size == 8) | |
*buf = (type->is_unsigned) ? 'Q' : 'q'; | |
break; | |
case 'P': | |
*buf = 'P'; | |
break; | |
case 'C': | |
{ | |
__Pyx_TypeInfo complex_type = *type; | |
complex_type.typegroup = 'R'; | |
complex_type.size /= 2; | |
*buf++ = 'Z'; | |
*buf = __Pyx_TypeInfoToFormat(&complex_type).string[0]; | |
break; | |
} | |
case 'R': | |
if (size == 4) | |
*buf = 'f'; | |
else if (size == 8) | |
*buf = 'd'; | |
else | |
*buf = 'g'; | |
break; | |
} | |
return result; | |
} | |