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; |
+} |