| Index: third_party/cython/src/Cython/Utility/Buffer.c
|
| diff --git a/third_party/cython/src/Cython/Utility/Buffer.c b/third_party/cython/src/Cython/Utility/Buffer.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9e43d5d7dd6a6ccaa97ce6bdf961b4bc0cdc3ded
|
| --- /dev/null
|
| +++ b/third_party/cython/src/Cython/Utility/Buffer.c
|
| @@ -0,0 +1,947 @@
|
| +/////////////// 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) {
|
| + #ifdef WITH_THREAD
|
| + PyGILState_STATE gilstate = PyGILState_Ensure();
|
| + #endif
|
| + __Pyx_RaiseBufferIndexError(axis);
|
| + #ifdef WITH_THREAD
|
| + PyGILState_Release(gilstate);
|
| + #endif
|
| +}
|
| +
|
| +/////////////// 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 ///////////////
|
| +
|
| +#define IS_UNSIGNED(type) (((type) -1) > 0)
|
| +
|
| +/* Run-time type information about structs used with buffers */
|
| +struct __Pyx_StructField_;
|
| +
|
| +#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
|
| +
|
| +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 ///////////////
|
| +#if PY_MAJOR_VERSION < 3
|
| + static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
|
| + static void __Pyx_ReleaseBuffer(Py_buffer *view);
|
| +#else
|
| + #define __Pyx_GetBuffer PyObject_GetBuffer
|
| + #define __Pyx_ReleaseBuffer PyBuffer_Release
|
| +#endif
|
| +
|
| +/////////////// GetAndReleaseBuffer ///////////////
|
| +#if PY_MAJOR_VERSION < 3
|
| +static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
|
| + #if PY_VERSION_HEX >= 0x02060000
|
| + if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
|
| + #endif
|
| +
|
| + {{for type_ptr, getbuffer, releasebuffer in types}}
|
| + {{if getbuffer}}
|
| + if (PyObject_TypeCheck(obj, {{type_ptr}})) return {{getbuffer}}(obj, view, flags);
|
| + {{endif}}
|
| + {{endfor}}
|
| +
|
| + #if PY_VERSION_HEX < 0x02060000
|
| + if (obj->ob_type->tp_dict) {
|
| + PyObject *getbuffer_cobj = PyObject_GetItem(
|
| + obj->ob_type->tp_dict, PYIDENT("__pyx_getbuffer"));
|
| + if (getbuffer_cobj) {
|
| + getbufferproc func = (getbufferproc) PyCObject_AsVoidPtr(getbuffer_cobj);
|
| + Py_DECREF(getbuffer_cobj);
|
| + if (!func)
|
| + goto fail;
|
| +
|
| + return func(obj, view, flags);
|
| + } else {
|
| + PyErr_Clear();
|
| + }
|
| + }
|
| + #endif
|
| +
|
| + PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
|
| +
|
| +#if PY_VERSION_HEX < 0x02060000
|
| +fail:
|
| +#endif
|
| +
|
| + return -1;
|
| +}
|
| +
|
| +static void __Pyx_ReleaseBuffer(Py_buffer *view) {
|
| + PyObject *obj = view->obj;
|
| + if (!obj) return;
|
| +
|
| + #if PY_VERSION_HEX >= 0x02060000
|
| + if (PyObject_CheckBuffer(obj)) {
|
| + PyBuffer_Release(view);
|
| + return;
|
| + }
|
| + #endif
|
| +
|
| + {{for type_ptr, getbuffer, releasebuffer in types}}
|
| + {{if releasebuffer}}
|
| + if (PyObject_TypeCheck(obj, {{type_ptr}})) { {{releasebuffer}}(obj, view); return; }
|
| + {{endif}}
|
| + {{endfor}}
|
| +
|
| + #if PY_VERSION_HEX < 0x02060000
|
| + if (obj->ob_type->tp_dict) {
|
| + PyObject *releasebuffer_cobj = PyObject_GetItem(
|
| + obj->ob_type->tp_dict, PYIDENT("__pyx_releasebuffer"));
|
| + if (releasebuffer_cobj) {
|
| + releasebufferproc func = (releasebufferproc) PyCObject_AsVoidPtr(releasebuffer_cobj);
|
| + Py_DECREF(releasebuffer_cobj);
|
| + if (!func)
|
| + goto fail;
|
| + func(obj, view);
|
| + return;
|
| + } else {
|
| + PyErr_Clear();
|
| + }
|
| + }
|
| + #endif
|
| +
|
| + goto nofail;
|
| +
|
| +#if PY_VERSION_HEX < 0x02060000
|
| +fail:
|
| +#endif
|
| + PyErr_WriteUnraisable(obj);
|
| +
|
| +nofail:
|
| + Py_DECREF(obj);
|
| + view->obj = NULL;
|
| +}
|
| +
|
| +#endif /* PY_MAJOR_VERSION < 3 */
|
| +
|
| +/////////////// 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 CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
|
| + __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
|
| +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
|
| +
|
| +/////////////// BufferFormatCheck ///////////////
|
| +static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
|
| + unsigned int n = 1;
|
| + return *(unsigned char*)(&n) != 0;
|
| +}
|
| +
|
| +
|
| +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 '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 '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);
|
| + #ifdef HAVE_LONG_LONG
|
| + case 'q': case 'Q': return sizeof(PY_LONG_LONG);
|
| + #endif
|
| + 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;
|
| +#ifdef HAVE_LONG_LONG
|
| +typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
|
| +#endif
|
| +
|
| +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);
|
| +#ifdef HAVE_LONG_LONG
|
| + case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
|
| +#endif
|
| + 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;
|
| +#ifdef HAVE_LONG_LONG
|
| +typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
|
| +#endif
|
| +
|
| +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);
|
| +#ifdef HAVE_LONG_LONG
|
| + case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
|
| +#endif
|
| + 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 '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 CYTHON_INLINE PyObject *
|
| +__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
|
| +{
|
| + const char *ts = *tsp;
|
| + int i = 0, number;
|
| + int ndim = ctx->head->field->type->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;
|
| +
|
| + /* 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_IsLittleEndian()) {
|
| + PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
|
| + return NULL;
|
| + }
|
| + ctx->new_packmode = '=';
|
| + ++ts;
|
| + break;
|
| + case '>':
|
| + case '!':
|
| + if (__Pyx_IsLittleEndian()) {
|
| + 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;
|
| + }
|
| + /* fall through */
|
| + 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) {
|
| + /* Continue pooling same type */
|
| + ctx->enc_count += ctx->new_count;
|
| + ctx->new_count = 1;
|
| + got_Z = 0;
|
| + ++ts;
|
| + break;
|
| + }
|
| + /* fall through */
|
| + 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;
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +static CYTHON_INLINE 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 CYTHON_INLINE int __Pyx_GetBufferAndValidate(
|
| + Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
|
| + int nd, int cast, __Pyx_BufFmt_StackElem* stack)
|
| +{
|
| + if (obj == Py_None || obj == NULL) {
|
| + __Pyx_ZeroBuffer(buf);
|
| + return 0;
|
| + }
|
| + buf->buf = NULL;
|
| + if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
|
| + if (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 ((unsigned)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_ZeroBuffer(buf);
|
| + return -1;
|
| +}
|
| +
|
| +static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
|
| + if (info->buf == NULL) return;
|
| + if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
|
| + __Pyx_ReleaseBuffer(info);
|
| +}
|
| +
|
| +/////////////// TypeInfoCompare.proto ///////////////
|
| +static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
|
| +
|
| +/////////////// TypeInfoCompare ///////////////
|
| +/* 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 ///////////////
|
| +{{# 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 = 'b';
|
| + else if (size == 2)
|
| + *buf = 'h';
|
| + else if (size == 4)
|
| + *buf = 'i';
|
| + else if (size == 8)
|
| + *buf = 'q';
|
| +
|
| + if (type->is_unsigned)
|
| + *buf = toupper(*buf);
|
| + 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;
|
| +}
|
|
|