1 /////////////// BufferStructDeclare.proto ///////////////
2
3 /* structs for buffer access */
4
5 typedef struct {
6 Py_ssize_t shape, strides, suboffsets;
7 } __Pyx_Buf_DimInfo;
8
9 typedef struct {
10 size_t refcount;
11 Py_buffer pybuffer;
12 } __Pyx_Buffer;
13
14 typedef struct {
15 __Pyx_Buffer *rcbuffer;
16 char *data;
17 __Pyx_Buf_DimInfo diminfo[{{max_dims}}];
18 } __Pyx_LocalBuf_ND;
19
20 /////////////// BufferIndexError.proto ///////////////
21 static void __Pyx_RaiseBufferIndexError(int axis); /*proto*/
22
23 /////////////// BufferIndexError ///////////////
__Pyx_RaiseBufferIndexError(int axis)24 static void __Pyx_RaiseBufferIndexError(int axis) {
25 PyErr_Format(PyExc_IndexError,
26 "Out of bounds on buffer access (axis %d)", axis);
27 }
28
29 /////////////// BufferIndexErrorNogil.proto ///////////////
30 //@requires: BufferIndexError
31
32 static void __Pyx_RaiseBufferIndexErrorNogil(int axis); /*proto*/
33
34 /////////////// BufferIndexErrorNogil ///////////////
__Pyx_RaiseBufferIndexErrorNogil(int axis)35 static void __Pyx_RaiseBufferIndexErrorNogil(int axis) {
36 #ifdef WITH_THREAD
37 PyGILState_STATE gilstate = PyGILState_Ensure();
38 #endif
39 __Pyx_RaiseBufferIndexError(axis);
40 #ifdef WITH_THREAD
41 PyGILState_Release(gilstate);
42 #endif
43 }
44
45 /////////////// BufferFallbackError.proto ///////////////
46 static void __Pyx_RaiseBufferFallbackError(void); /*proto*/
47
48 /////////////// BufferFallbackError ///////////////
__Pyx_RaiseBufferFallbackError(void)49 static void __Pyx_RaiseBufferFallbackError(void) {
50 PyErr_SetString(PyExc_ValueError,
51 "Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!");
52 }
53
54 /////////////// BufferFormatStructs.proto ///////////////
55 //@proto_block: utility_code_proto_before_types
56
57 #define IS_UNSIGNED(type) (((type) -1) > 0)
58
59 /* Run-time type information about structs used with buffers */
60 struct __Pyx_StructField_;
61
62 #define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
63
64 typedef struct {
65 const char* name; /* for error messages only */
66 struct __Pyx_StructField_* fields;
67 size_t size; /* sizeof(type) */
68 size_t arraysize[8]; /* length of array in each dimension */
69 int ndim;
70 char typegroup; /* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject, c_H_ar */
71 char is_unsigned;
72 int flags;
73 } __Pyx_TypeInfo;
74
75 typedef struct __Pyx_StructField_ {
76 __Pyx_TypeInfo* type;
77 const char* name;
78 size_t offset;
79 } __Pyx_StructField;
80
81 typedef struct {
82 __Pyx_StructField* field;
83 size_t parent_offset;
84 } __Pyx_BufFmt_StackElem;
85
86 typedef struct {
87 __Pyx_StructField root;
88 __Pyx_BufFmt_StackElem* head;
89 size_t fmt_offset;
90 size_t new_count, enc_count;
91 size_t struct_alignment;
92 int is_complex;
93 char enc_type;
94 char new_packmode;
95 char enc_packmode;
96 char is_valid_array;
97 } __Pyx_BufFmt_Context;
98
99
100 /////////////// GetAndReleaseBuffer.proto ///////////////
101
102 #if PY_MAJOR_VERSION < 3
103 static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
104 static void __Pyx_ReleaseBuffer(Py_buffer *view);
105 #else
106 #define __Pyx_GetBuffer PyObject_GetBuffer
107 #define __Pyx_ReleaseBuffer PyBuffer_Release
108 #endif
109
110 /////////////// GetAndReleaseBuffer ///////////////
111
112 #if PY_MAJOR_VERSION < 3
__Pyx_GetBuffer(PyObject * obj,Py_buffer * view,int flags)113 static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
114 if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
115
116 {{for type_ptr, getbuffer, releasebuffer in types}}
117 {{if getbuffer}}
118 if (__Pyx_TypeCheck(obj, {{type_ptr}})) return {{getbuffer}}(obj, view, flags);
119 {{endif}}
120 {{endfor}}
121
122 PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
123 return -1;
124 }
125
126 static void __Pyx_ReleaseBuffer(Py_buffer *view) {
127 PyObject *obj = view->obj;
128 if (!obj) return;
129
130 if (PyObject_CheckBuffer(obj)) {
131 PyBuffer_Release(view);
132 return;
133 }
134
135 if ((0)) {}
136 {{for type_ptr, getbuffer, releasebuffer in types}}
137 {{if releasebuffer}}
138 else if (__Pyx_TypeCheck(obj, {{type_ptr}})) {{releasebuffer}}(obj, view);
139 {{endif}}
140 {{endfor}}
141
142 view->obj = NULL;
143 Py_DECREF(obj);
144 }
145
146 #endif /* PY_MAJOR_VERSION < 3 */
147
148
149 /////////////// BufferGetAndValidate.proto ///////////////
150
151 #define __Pyx_GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack) \
152 ((obj == Py_None || obj == NULL) ? \
153 (__Pyx_ZeroBuffer(buf), 0) : \
154 __Pyx__GetBufferAndValidate(buf, obj, dtype, flags, nd, cast, stack))
155
156 static int __Pyx__GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
157 __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
158 static void __Pyx_ZeroBuffer(Py_buffer* buf);
159 static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);/*proto*/
160
161 static Py_ssize_t __Pyx_minusones[] = { {{ ", ".join(["-1"] * max_dims) }} };
162 static Py_ssize_t __Pyx_zeros[] = { {{ ", ".join(["0"] * max_dims) }} };
163
164
165 /////////////// BufferGetAndValidate ///////////////
166 //@requires: BufferFormatCheck
167
168 static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
169 if (unlikely(info->buf == NULL)) return;
170 if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
171 __Pyx_ReleaseBuffer(info);
172 }
173
174 static void __Pyx_ZeroBuffer(Py_buffer* buf) {
175 buf->buf = NULL;
176 buf->obj = NULL;
177 buf->strides = __Pyx_zeros;
178 buf->shape = __Pyx_zeros;
179 buf->suboffsets = __Pyx_minusones;
180 }
181
182 static int __Pyx__GetBufferAndValidate(
183 Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
184 int nd, int cast, __Pyx_BufFmt_StackElem* stack)
185 {
186 buf->buf = NULL;
187 if (unlikely(__Pyx_GetBuffer(obj, buf, flags) == -1)) {
188 __Pyx_ZeroBuffer(buf);
189 return -1;
190 }
191 // From this point on, we have acquired the buffer and must release it on errors.
192 if (unlikely(buf->ndim != nd)) {
193 PyErr_Format(PyExc_ValueError,
194 "Buffer has wrong number of dimensions (expected %d, got %d)",
195 nd, buf->ndim);
196 goto fail;
197 }
198 if (!cast) {
199 __Pyx_BufFmt_Context ctx;
200 __Pyx_BufFmt_Init(&ctx, stack, dtype);
201 if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
202 }
203 if (unlikely((size_t)buf->itemsize != dtype->size)) {
204 PyErr_Format(PyExc_ValueError,
205 "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
206 buf->itemsize, (buf->itemsize > 1) ? "s" : "",
207 dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
208 goto fail;
209 }
210 if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
211 return 0;
212 fail:;
213 __Pyx_SafeReleaseBuffer(buf);
214 return -1;
215 }
216
217
218 /////////////// BufferFormatCheck.proto ///////////////
219
220 // Buffer format string checking
221 //
222 // Buffer type checking. Utility code for checking that acquired
223 // buffers match our assumptions. We only need to check ndim and
224 // the format string; the access mode/flags is checked by the
225 // exporter. See:
226 //
227 // http://docs.python.org/3/library/struct.html
228 // http://legacy.python.org/dev/peps/pep-3118/#additions-to-the-struct-string-syntax
229 //
230 // The alignment code is copied from _struct.c in Python.
231
232 static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts);
233 static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
234 __Pyx_BufFmt_StackElem* stack,
235 __Pyx_TypeInfo* type); /*proto*/
236
237 /////////////// BufferFormatCheck ///////////////
238 //@requires: ModuleSetupCode.c::IsLittleEndian
239 //@requires: BufferFormatStructs
240
241 static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
242 __Pyx_BufFmt_StackElem* stack,
243 __Pyx_TypeInfo* type) {
244 stack[0].field = &ctx->root;
245 stack[0].parent_offset = 0;
246 ctx->root.type = type;
247 ctx->root.name = "buffer dtype";
248 ctx->root.offset = 0;
249 ctx->head = stack;
250 ctx->head->field = &ctx->root;
251 ctx->fmt_offset = 0;
252 ctx->head->parent_offset = 0;
253 ctx->new_packmode = '@';
254 ctx->enc_packmode = '@';
255 ctx->new_count = 1;
256 ctx->enc_count = 0;
257 ctx->enc_type = 0;
258 ctx->is_complex = 0;
259 ctx->is_valid_array = 0;
260 ctx->struct_alignment = 0;
261 while (type->typegroup == 'S') {
262 ++ctx->head;
263 ctx->head->field = type->fields;
264 ctx->head->parent_offset = 0;
265 type = type->fields->type;
266 }
267 }
268
269 static int __Pyx_BufFmt_ParseNumber(const char** ts) {
270 int count;
271 const char* t = *ts;
272 if (*t < '0' || *t > '9') {
273 return -1;
274 } else {
275 count = *t++ - '0';
276 while (*t >= '0' && *t <= '9') {
277 count *= 10;
278 count += *t++ - '0';
279 }
280 }
281 *ts = t;
282 return count;
283 }
284
285 static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
286 int number = __Pyx_BufFmt_ParseNumber(ts);
287 if (number == -1) /* First char was not a digit */
288 PyErr_Format(PyExc_ValueError,\
289 "Does not understand character buffer dtype format string ('%c')", **ts);
290 return number;
291 }
292
293
294 static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
295 PyErr_Format(PyExc_ValueError,
296 "Unexpected format string character: '%c'", ch);
297 }
298
299 static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
300 switch (ch) {
301 case '?': return "'bool'";
302 case 'c': return "'char'";
303 case 'b': return "'signed char'";
304 case 'B': return "'unsigned char'";
305 case 'h': return "'short'";
306 case 'H': return "'unsigned short'";
307 case 'i': return "'int'";
308 case 'I': return "'unsigned int'";
309 case 'l': return "'long'";
310 case 'L': return "'unsigned long'";
311 case 'q': return "'long long'";
312 case 'Q': return "'unsigned long long'";
313 case 'f': return (is_complex ? "'complex float'" : "'float'");
314 case 'd': return (is_complex ? "'complex double'" : "'double'");
315 case 'g': return (is_complex ? "'complex long double'" : "'long double'");
316 case 'T': return "a struct";
317 case 'O': return "Python object";
318 case 'P': return "a pointer";
319 case 's': case 'p': return "a string";
320 case 0: return "end";
321 default: return "unparseable format string";
322 }
323 }
324
325 static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
326 switch (ch) {
327 case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
328 case 'h': case 'H': return 2;
329 case 'i': case 'I': case 'l': case 'L': return 4;
330 case 'q': case 'Q': return 8;
331 case 'f': return (is_complex ? 8 : 4);
332 case 'd': return (is_complex ? 16 : 8);
333 case 'g': {
334 PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
335 return 0;
336 }
337 case 'O': case 'P': return sizeof(void*);
338 default:
339 __Pyx_BufFmt_RaiseUnexpectedChar(ch);
340 return 0;
341 }
342 }
343
344 static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
345 switch (ch) {
346 case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
347 case 'h': case 'H': return sizeof(short);
348 case 'i': case 'I': return sizeof(int);
349 case 'l': case 'L': return sizeof(long);
350 #ifdef HAVE_LONG_LONG
351 case 'q': case 'Q': return sizeof(PY_LONG_LONG);
352 #endif
353 case 'f': return sizeof(float) * (is_complex ? 2 : 1);
354 case 'd': return sizeof(double) * (is_complex ? 2 : 1);
355 case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
356 case 'O': case 'P': return sizeof(void*);
357 default: {
358 __Pyx_BufFmt_RaiseUnexpectedChar(ch);
359 return 0;
360 }
361 }
362 }
363
364 typedef struct { char c; short x; } __Pyx_st_short;
365 typedef struct { char c; int x; } __Pyx_st_int;
366 typedef struct { char c; long x; } __Pyx_st_long;
367 typedef struct { char c; float x; } __Pyx_st_float;
368 typedef struct { char c; double x; } __Pyx_st_double;
369 typedef struct { char c; long double x; } __Pyx_st_longdouble;
370 typedef struct { char c; void *x; } __Pyx_st_void_p;
371 #ifdef HAVE_LONG_LONG
372 typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
373 #endif
374
375 static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
376 switch (ch) {
377 case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
378 case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
379 case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
380 case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
381 #ifdef HAVE_LONG_LONG
382 case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
383 #endif
384 case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
385 case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
386 case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
387 case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
388 default:
389 __Pyx_BufFmt_RaiseUnexpectedChar(ch);
390 return 0;
391 }
392 }
393
394 /* These are for computing the padding at the end of the struct to align
395 on the first member of the struct. This will probably the same as above,
396 but we don't have any guarantees.
397 */
398 typedef struct { short x; char c; } __Pyx_pad_short;
399 typedef struct { int x; char c; } __Pyx_pad_int;
400 typedef struct { long x; char c; } __Pyx_pad_long;
401 typedef struct { float x; char c; } __Pyx_pad_float;
402 typedef struct { double x; char c; } __Pyx_pad_double;
403 typedef struct { long double x; char c; } __Pyx_pad_longdouble;
404 typedef struct { void *x; char c; } __Pyx_pad_void_p;
405 #ifdef HAVE_LONG_LONG
406 typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
407 #endif
408
409 static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
410 switch (ch) {
411 case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
412 case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
413 case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
414 case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
415 #ifdef HAVE_LONG_LONG
416 case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
417 #endif
418 case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
419 case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
420 case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
421 case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
422 default:
423 __Pyx_BufFmt_RaiseUnexpectedChar(ch);
424 return 0;
425 }
426 }
427
428 static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
429 switch (ch) {
430 case 'c':
431 return 'H';
432 case 'b': case 'h': case 'i':
433 case 'l': case 'q': case 's': case 'p':
434 return 'I';
435 case '?': case 'B': case 'H': case 'I': case 'L': case 'Q':
436 return 'U';
437 case 'f': case 'd': case 'g':
438 return (is_complex ? 'C' : 'R');
439 case 'O':
440 return 'O';
441 case 'P':
442 return 'P';
443 default: {
444 __Pyx_BufFmt_RaiseUnexpectedChar(ch);
445 return 0;
446 }
447 }
448 }
449
450
451 static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
452 if (ctx->head == NULL || ctx->head->field == &ctx->root) {
453 const char* expected;
454 const char* quote;
455 if (ctx->head == NULL) {
456 expected = "end";
457 quote = "";
458 } else {
459 expected = ctx->head->field->type->name;
460 quote = "'";
461 }
462 PyErr_Format(PyExc_ValueError,
463 "Buffer dtype mismatch, expected %s%s%s but got %s",
464 quote, expected, quote,
465 __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
466 } else {
467 __Pyx_StructField* field = ctx->head->field;
468 __Pyx_StructField* parent = (ctx->head - 1)->field;
469 PyErr_Format(PyExc_ValueError,
470 "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
471 field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
472 parent->type->name, field->name);
473 }
474 }
475
476 static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
477 char group;
478 size_t size, offset, arraysize = 1;
479
480 /* printf("processing... %s\n", ctx->head->field->type->name); */
481
482 if (ctx->enc_type == 0) return 0;
483
484 /* Validate array size */
485 if (ctx->head->field->type->arraysize[0]) {
486 int i, ndim = 0;
487
488 /* handle strings ('s' and 'p') */
489 if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
490 ctx->is_valid_array = ctx->head->field->type->ndim == 1;
491 ndim = 1;
492 if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
493 PyErr_Format(PyExc_ValueError,
494 "Expected a dimension of size %zu, got %zu",
495 ctx->head->field->type->arraysize[0], ctx->enc_count);
496 return -1;
497 }
498 }
499
500 if (!ctx->is_valid_array) {
501 PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
502 ctx->head->field->type->ndim, ndim);
503 return -1;
504 }
505 for (i = 0; i < ctx->head->field->type->ndim; i++) {
506 arraysize *= ctx->head->field->type->arraysize[i];
507 }
508 ctx->is_valid_array = 0;
509 ctx->enc_count = 1;
510 }
511
512 group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
513 do {
514 __Pyx_StructField* field = ctx->head->field;
515 __Pyx_TypeInfo* type = field->type;
516
517 if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
518 size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
519 } else {
520 size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
521 }
522
523 if (ctx->enc_packmode == '@') {
524 size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
525 size_t align_mod_offset;
526 if (align_at == 0) return -1;
527 align_mod_offset = ctx->fmt_offset % align_at;
528 if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
529
530 if (ctx->struct_alignment == 0)
531 ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
532 ctx->is_complex);
533 }
534
535 if (type->size != size || type->typegroup != group) {
536 if (type->typegroup == 'C' && type->fields != NULL) {
537 /* special case -- treat as struct rather than complex number */
538 size_t parent_offset = ctx->head->parent_offset + field->offset;
539 ++ctx->head;
540 ctx->head->field = type->fields;
541 ctx->head->parent_offset = parent_offset;
542 continue;
543 }
544
545 if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
546 /* special case -- chars don't care about sign */
547 } else {
548 __Pyx_BufFmt_RaiseExpected(ctx);
549 return -1;
550 }
551 }
552
553 offset = ctx->head->parent_offset + field->offset;
554 if (ctx->fmt_offset != offset) {
555 PyErr_Format(PyExc_ValueError,
556 "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
557 (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
558 return -1;
559 }
560
561 ctx->fmt_offset += size;
562 if (arraysize)
563 ctx->fmt_offset += (arraysize - 1) * size;
564
565 --ctx->enc_count; /* Consume from buffer string */
566
567 /* Done checking, move to next field, pushing or popping struct stack if needed */
568 while (1) {
569 if (field == &ctx->root) {
570 ctx->head = NULL;
571 if (ctx->enc_count != 0) {
572 __Pyx_BufFmt_RaiseExpected(ctx);
573 return -1;
574 }
575 break; /* breaks both loops as ctx->enc_count == 0 */
576 }
577 ctx->head->field = ++field;
578 if (field->type == NULL) {
579 --ctx->head;
580 field = ctx->head->field;
581 continue;
582 } else if (field->type->typegroup == 'S') {
583 size_t parent_offset = ctx->head->parent_offset + field->offset;
584 if (field->type->fields->type == NULL) continue; /* empty struct */
585 field = field->type->fields;
586 ++ctx->head;
587 ctx->head->field = field;
588 ctx->head->parent_offset = parent_offset;
589 break;
590 } else {
591 break;
592 }
593 }
594 } while (ctx->enc_count);
595 ctx->enc_type = 0;
596 ctx->is_complex = 0;
597 return 0;
598 }
599
600 /* Parse an array in the format string (e.g. (1,2,3)) */
601 static PyObject *
602 __pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
603 {
604 const char *ts = *tsp;
605 int i = 0, number, ndim;
606
607 ++ts;
608 if (ctx->new_count != 1) {
609 PyErr_SetString(PyExc_ValueError,
610 "Cannot handle repeated arrays in format string");
611 return NULL;
612 }
613
614 /* Process the previous element */
615 if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
616
617 // store ndim now, as field advanced by __Pyx_BufFmt_ProcessTypeChunk call
618 ndim = ctx->head->field->type->ndim;
619
620 /* Parse all numbers in the format string */
621 while (*ts && *ts != ')') {
622 // ignore space characters (not using isspace() due to C/C++ problem on MacOS-X)
623 switch (*ts) {
624 case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue;
625 default: break; /* not a 'break' in the loop */
626 }
627
628 number = __Pyx_BufFmt_ExpectNumber(&ts);
629 if (number == -1) return NULL;
630
631 if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
632 return PyErr_Format(PyExc_ValueError,
633 "Expected a dimension of size %zu, got %d",
634 ctx->head->field->type->arraysize[i], number);
635
636 if (*ts != ',' && *ts != ')')
637 return PyErr_Format(PyExc_ValueError,
638 "Expected a comma in format string, got '%c'", *ts);
639
640 if (*ts == ',') ts++;
641 i++;
642 }
643
644 if (i != ndim)
645 return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
646 ctx->head->field->type->ndim, i);
647
648 if (!*ts) {
649 PyErr_SetString(PyExc_ValueError,
650 "Unexpected end of format string, expected ')'");
651 return NULL;
652 }
653
654 ctx->is_valid_array = 1;
655 ctx->new_count = 1;
656 *tsp = ++ts;
657 return Py_None;
658 }
659
660 static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
661 int got_Z = 0;
662
663 while (1) {
664 /* puts(ts); */
665 switch(*ts) {
666 case 0:
667 if (ctx->enc_type != 0 && ctx->head == NULL) {
668 __Pyx_BufFmt_RaiseExpected(ctx);
669 return NULL;
670 }
671 if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
672 if (ctx->head != NULL) {
673 __Pyx_BufFmt_RaiseExpected(ctx);
674 return NULL;
675 }
676 return ts;
677 case ' ':
678 case '\r':
679 case '\n':
680 ++ts;
681 break;
682 case '<':
683 if (!__Pyx_Is_Little_Endian()) {
684 PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
685 return NULL;
686 }
687 ctx->new_packmode = '=';
688 ++ts;
689 break;
690 case '>':
691 case '!':
692 if (__Pyx_Is_Little_Endian()) {
693 PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
694 return NULL;
695 }
696 ctx->new_packmode = '=';
697 ++ts;
698 break;
699 case '=':
700 case '@':
701 case '^':
702 ctx->new_packmode = *ts++;
703 break;
704 case 'T': /* substruct */
705 {
706 const char* ts_after_sub;
707 size_t i, struct_count = ctx->new_count;
708 size_t struct_alignment = ctx->struct_alignment;
709 ctx->new_count = 1;
710 ++ts;
711 if (*ts != '{') {
712 PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
713 return NULL;
714 }
715 if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
716 ctx->enc_type = 0; /* Erase processed last struct element */
717 ctx->enc_count = 0;
718 ctx->struct_alignment = 0;
719 ++ts;
720 ts_after_sub = ts;
721 for (i = 0; i != struct_count; ++i) {
722 ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
723 if (!ts_after_sub) return NULL;
724 }
725 ts = ts_after_sub;
726 if (struct_alignment) ctx->struct_alignment = struct_alignment;
727 }
728 break;
729 case '}': /* end of substruct; either repeat or move on */
730 {
731 size_t alignment = ctx->struct_alignment;
732 ++ts;
733 if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
734 ctx->enc_type = 0; /* Erase processed last struct element */
735 if (alignment && ctx->fmt_offset % alignment) {
736 /* Pad struct on size of the first member */
737 ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
738 }
739 }
740 return ts;
741 case 'x':
742 if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
743 ctx->fmt_offset += ctx->new_count;
744 ctx->new_count = 1;
745 ctx->enc_count = 0;
746 ctx->enc_type = 0;
747 ctx->enc_packmode = ctx->new_packmode;
748 ++ts;
749 break;
750 case 'Z':
751 got_Z = 1;
752 ++ts;
753 if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
754 __Pyx_BufFmt_RaiseUnexpectedChar('Z');
755 return NULL;
756 }
757 CYTHON_FALLTHROUGH;
758 case '?': case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
759 case 'l': case 'L': case 'q': case 'Q':
760 case 'f': case 'd': case 'g':
761 case 'O': case 'p':
762 if ((ctx->enc_type == *ts) && (got_Z == ctx->is_complex) &&
763 (ctx->enc_packmode == ctx->new_packmode) && (!ctx->is_valid_array)) {
764 /* Continue pooling same type */
765 ctx->enc_count += ctx->new_count;
766 ctx->new_count = 1;
767 got_Z = 0;
768 ++ts;
769 break;
770 }
771 CYTHON_FALLTHROUGH;
772 case 's':
773 /* 's' or new type (cannot be added to current pool) */
774 if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
775 ctx->enc_count = ctx->new_count;
776 ctx->enc_packmode = ctx->new_packmode;
777 ctx->enc_type = *ts;
778 ctx->is_complex = got_Z;
779 ++ts;
780 ctx->new_count = 1;
781 got_Z = 0;
782 break;
783 case ':':
784 ++ts;
785 while(*ts != ':') ++ts;
786 ++ts;
787 break;
788 case '(':
789 if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
790 break;
791 default:
792 {
793 int number = __Pyx_BufFmt_ExpectNumber(&ts);
794 if (number == -1) return NULL;
795 ctx->new_count = (size_t)number;
796 }
797 }
798 }
799 }
800
801 /////////////// TypeInfoCompare.proto ///////////////
802 static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
803
804 /////////////// TypeInfoCompare ///////////////
805 //@requires: BufferFormatStructs
806
807 // See if two dtypes are equal
808 static int
809 __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
810 {
811 int i;
812
813 if (!a || !b)
814 return 0;
815
816 if (a == b)
817 return 1;
818
819 if (a->size != b->size || a->typegroup != b->typegroup ||
820 a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
821 if (a->typegroup == 'H' || b->typegroup == 'H') {
822 /* Special case for chars */
823 return a->size == b->size;
824 } else {
825 return 0;
826 }
827 }
828
829 if (a->ndim) {
830 /* Verify multidimensional C arrays */
831 for (i = 0; i < a->ndim; i++)
832 if (a->arraysize[i] != b->arraysize[i])
833 return 0;
834 }
835
836 if (a->typegroup == 'S') {
837 /* Check for packed struct */
838 if (a->flags != b->flags)
839 return 0;
840
841 /* compare all struct fields */
842 if (a->fields || b->fields) {
843 /* Check if both have fields */
844 if (!(a->fields && b->fields))
845 return 0;
846
847 /* compare */
848 for (i = 0; a->fields[i].type && b->fields[i].type; i++) {
849 __Pyx_StructField *field_a = a->fields + i;
850 __Pyx_StructField *field_b = b->fields + i;
851
852 if (field_a->offset != field_b->offset ||
853 !__pyx_typeinfo_cmp(field_a->type, field_b->type))
854 return 0;
855 }
856
857 /* If all fields are processed, we have a match */
858 return !a->fields[i].type && !b->fields[i].type;
859 }
860 }
861
862 return 1;
863 }
864
865
866 /////////////// TypeInfoToFormat.proto ///////////////
867 struct __pyx_typeinfo_string {
868 char string[3];
869 };
870 static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type);
871
872 /////////////// TypeInfoToFormat ///////////////
873 //@requires: BufferFormatStructs
874
875 // See also MemoryView.pyx:BufferFormatFromTypeInfo
876
877 static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type) {
878 struct __pyx_typeinfo_string result = { {0} };
879 char *buf = (char *) result.string;
880 size_t size = type->size;
881
882 switch (type->typegroup) {
883 case 'H':
884 *buf = 'c';
885 break;
886 case 'I':
887 case 'U':
888 if (size == 1)
889 *buf = (type->is_unsigned) ? 'B' : 'b';
890 else if (size == 2)
891 *buf = (type->is_unsigned) ? 'H' : 'h';
892 else if (size == 4)
893 *buf = (type->is_unsigned) ? 'I' : 'i';
894 else if (size == 8)
895 *buf = (type->is_unsigned) ? 'Q' : 'q';
896 break;
897 case 'P':
898 *buf = 'P';
899 break;
900 case 'C':
901 {
902 __Pyx_TypeInfo complex_type = *type;
903 complex_type.typegroup = 'R';
904 complex_type.size /= 2;
905
906 *buf++ = 'Z';
907 *buf = __Pyx_TypeInfoToFormat(&complex_type).string[0];
908 break;
909 }
910 case 'R':
911 if (size == 4)
912 *buf = 'f';
913 else if (size == 8)
914 *buf = 'd';
915 else
916 *buf = 'g';
917 break;
918 }
919
920 return result;
921 }
922