Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / third_party / cython / src / Cython / Utility / Buffer.c
blob9e43d5d7dd6a6ccaa97ce6bdf961b4bc0cdc3ded
1 /////////////// BufferStructDeclare.proto ///////////////
3 /* structs for buffer access */
5 typedef struct {
6 Py_ssize_t shape, strides, suboffsets;
7 } __Pyx_Buf_DimInfo;
9 typedef struct {
10 size_t refcount;
11 Py_buffer pybuffer;
12 } __Pyx_Buffer;
14 typedef struct {
15 __Pyx_Buffer *rcbuffer;
16 char *data;
17 __Pyx_Buf_DimInfo diminfo[{{max_dims}}];
18 } __Pyx_LocalBuf_ND;
20 /////////////// BufferIndexError.proto ///////////////
21 static void __Pyx_RaiseBufferIndexError(int axis); /*proto*/
23 /////////////// BufferIndexError ///////////////
24 static void __Pyx_RaiseBufferIndexError(int axis) {
25 PyErr_Format(PyExc_IndexError,
26 "Out of bounds on buffer access (axis %d)", axis);
29 /////////////// BufferIndexErrorNogil.proto ///////////////
30 //@requires: BufferIndexError
32 static void __Pyx_RaiseBufferIndexErrorNogil(int axis); /*proto*/
34 /////////////// BufferIndexErrorNogil ///////////////
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
45 /////////////// BufferFallbackError.proto ///////////////
46 static void __Pyx_RaiseBufferFallbackError(void); /*proto*/
48 /////////////// BufferFallbackError ///////////////
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!");
54 /////////////// BufferFormatStructs.proto ///////////////
56 #define IS_UNSIGNED(type) (((type) -1) > 0)
58 /* Run-time type information about structs used with buffers */
59 struct __Pyx_StructField_;
61 #define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
63 typedef struct {
64 const char* name; /* for error messages only */
65 struct __Pyx_StructField_* fields;
66 size_t size; /* sizeof(type) */
67 size_t arraysize[8]; /* length of array in each dimension */
68 int ndim;
69 char typegroup; /* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject, c_H_ar */
70 char is_unsigned;
71 int flags;
72 } __Pyx_TypeInfo;
74 typedef struct __Pyx_StructField_ {
75 __Pyx_TypeInfo* type;
76 const char* name;
77 size_t offset;
78 } __Pyx_StructField;
80 typedef struct {
81 __Pyx_StructField* field;
82 size_t parent_offset;
83 } __Pyx_BufFmt_StackElem;
85 typedef struct {
86 __Pyx_StructField root;
87 __Pyx_BufFmt_StackElem* head;
88 size_t fmt_offset;
89 size_t new_count, enc_count;
90 size_t struct_alignment;
91 int is_complex;
92 char enc_type;
93 char new_packmode;
94 char enc_packmode;
95 char is_valid_array;
96 } __Pyx_BufFmt_Context;
98 /////////////// GetAndReleaseBuffer.proto ///////////////
99 #if PY_MAJOR_VERSION < 3
100 static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
101 static void __Pyx_ReleaseBuffer(Py_buffer *view);
102 #else
103 #define __Pyx_GetBuffer PyObject_GetBuffer
104 #define __Pyx_ReleaseBuffer PyBuffer_Release
105 #endif
107 /////////////// GetAndReleaseBuffer ///////////////
108 #if PY_MAJOR_VERSION < 3
109 static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
110 #if PY_VERSION_HEX >= 0x02060000
111 if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
112 #endif
114 {{for type_ptr, getbuffer, releasebuffer in types}}
115 {{if getbuffer}}
116 if (PyObject_TypeCheck(obj, {{type_ptr}})) return {{getbuffer}}(obj, view, flags);
117 {{endif}}
118 {{endfor}}
120 #if PY_VERSION_HEX < 0x02060000
121 if (obj->ob_type->tp_dict) {
122 PyObject *getbuffer_cobj = PyObject_GetItem(
123 obj->ob_type->tp_dict, PYIDENT("__pyx_getbuffer"));
124 if (getbuffer_cobj) {
125 getbufferproc func = (getbufferproc) PyCObject_AsVoidPtr(getbuffer_cobj);
126 Py_DECREF(getbuffer_cobj);
127 if (!func)
128 goto fail;
130 return func(obj, view, flags);
131 } else {
132 PyErr_Clear();
135 #endif
137 PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
139 #if PY_VERSION_HEX < 0x02060000
140 fail:
141 #endif
143 return -1;
146 static void __Pyx_ReleaseBuffer(Py_buffer *view) {
147 PyObject *obj = view->obj;
148 if (!obj) return;
150 #if PY_VERSION_HEX >= 0x02060000
151 if (PyObject_CheckBuffer(obj)) {
152 PyBuffer_Release(view);
153 return;
155 #endif
157 {{for type_ptr, getbuffer, releasebuffer in types}}
158 {{if releasebuffer}}
159 if (PyObject_TypeCheck(obj, {{type_ptr}})) { {{releasebuffer}}(obj, view); return; }
160 {{endif}}
161 {{endfor}}
163 #if PY_VERSION_HEX < 0x02060000
164 if (obj->ob_type->tp_dict) {
165 PyObject *releasebuffer_cobj = PyObject_GetItem(
166 obj->ob_type->tp_dict, PYIDENT("__pyx_releasebuffer"));
167 if (releasebuffer_cobj) {
168 releasebufferproc func = (releasebufferproc) PyCObject_AsVoidPtr(releasebuffer_cobj);
169 Py_DECREF(releasebuffer_cobj);
170 if (!func)
171 goto fail;
172 func(obj, view);
173 return;
174 } else {
175 PyErr_Clear();
178 #endif
180 goto nofail;
182 #if PY_VERSION_HEX < 0x02060000
183 fail:
184 #endif
185 PyErr_WriteUnraisable(obj);
187 nofail:
188 Py_DECREF(obj);
189 view->obj = NULL;
192 #endif /* PY_MAJOR_VERSION < 3 */
194 /////////////// BufferFormatCheck.proto ///////////////
197 Buffer format string checking
199 Buffer type checking. Utility code for checking that acquired
200 buffers match our assumptions. We only need to check ndim and
201 the format string; the access mode/flags is checked by the
202 exporter. See:
204 http://docs.python.org/3/library/struct.html
205 http://legacy.python.org/dev/peps/pep-3118/#additions-to-the-struct-string-syntax
207 The alignment code is copied from _struct.c in Python.
210 static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
211 __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
212 static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
214 /////////////// BufferFormatCheck ///////////////
215 static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
216 unsigned int n = 1;
217 return *(unsigned char*)(&n) != 0;
221 static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
222 __Pyx_BufFmt_StackElem* stack,
223 __Pyx_TypeInfo* type) {
224 stack[0].field = &ctx->root;
225 stack[0].parent_offset = 0;
226 ctx->root.type = type;
227 ctx->root.name = "buffer dtype";
228 ctx->root.offset = 0;
229 ctx->head = stack;
230 ctx->head->field = &ctx->root;
231 ctx->fmt_offset = 0;
232 ctx->head->parent_offset = 0;
233 ctx->new_packmode = '@';
234 ctx->enc_packmode = '@';
235 ctx->new_count = 1;
236 ctx->enc_count = 0;
237 ctx->enc_type = 0;
238 ctx->is_complex = 0;
239 ctx->is_valid_array = 0;
240 ctx->struct_alignment = 0;
241 while (type->typegroup == 'S') {
242 ++ctx->head;
243 ctx->head->field = type->fields;
244 ctx->head->parent_offset = 0;
245 type = type->fields->type;
249 static int __Pyx_BufFmt_ParseNumber(const char** ts) {
250 int count;
251 const char* t = *ts;
252 if (*t < '0' || *t > '9') {
253 return -1;
254 } else {
255 count = *t++ - '0';
256 while (*t >= '0' && *t < '9') {
257 count *= 10;
258 count += *t++ - '0';
261 *ts = t;
262 return count;
265 static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
266 int number = __Pyx_BufFmt_ParseNumber(ts);
267 if (number == -1) /* First char was not a digit */
268 PyErr_Format(PyExc_ValueError,\
269 "Does not understand character buffer dtype format string ('%c')", **ts);
270 return number;
274 static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
275 PyErr_Format(PyExc_ValueError,
276 "Unexpected format string character: '%c'", ch);
279 static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
280 switch (ch) {
281 case 'c': return "'char'";
282 case 'b': return "'signed char'";
283 case 'B': return "'unsigned char'";
284 case 'h': return "'short'";
285 case 'H': return "'unsigned short'";
286 case 'i': return "'int'";
287 case 'I': return "'unsigned int'";
288 case 'l': return "'long'";
289 case 'L': return "'unsigned long'";
290 case 'q': return "'long long'";
291 case 'Q': return "'unsigned long long'";
292 case 'f': return (is_complex ? "'complex float'" : "'float'");
293 case 'd': return (is_complex ? "'complex double'" : "'double'");
294 case 'g': return (is_complex ? "'complex long double'" : "'long double'");
295 case 'T': return "a struct";
296 case 'O': return "Python object";
297 case 'P': return "a pointer";
298 case 's': case 'p': return "a string";
299 case 0: return "end";
300 default: return "unparseable format string";
304 static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
305 switch (ch) {
306 case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
307 case 'h': case 'H': return 2;
308 case 'i': case 'I': case 'l': case 'L': return 4;
309 case 'q': case 'Q': return 8;
310 case 'f': return (is_complex ? 8 : 4);
311 case 'd': return (is_complex ? 16 : 8);
312 case 'g': {
313 PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
314 return 0;
316 case 'O': case 'P': return sizeof(void*);
317 default:
318 __Pyx_BufFmt_RaiseUnexpectedChar(ch);
319 return 0;
323 static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
324 switch (ch) {
325 case 'c': case 'b': case 'B': case 's': case 'p': return 1;
326 case 'h': case 'H': return sizeof(short);
327 case 'i': case 'I': return sizeof(int);
328 case 'l': case 'L': return sizeof(long);
329 #ifdef HAVE_LONG_LONG
330 case 'q': case 'Q': return sizeof(PY_LONG_LONG);
331 #endif
332 case 'f': return sizeof(float) * (is_complex ? 2 : 1);
333 case 'd': return sizeof(double) * (is_complex ? 2 : 1);
334 case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
335 case 'O': case 'P': return sizeof(void*);
336 default: {
337 __Pyx_BufFmt_RaiseUnexpectedChar(ch);
338 return 0;
343 typedef struct { char c; short x; } __Pyx_st_short;
344 typedef struct { char c; int x; } __Pyx_st_int;
345 typedef struct { char c; long x; } __Pyx_st_long;
346 typedef struct { char c; float x; } __Pyx_st_float;
347 typedef struct { char c; double x; } __Pyx_st_double;
348 typedef struct { char c; long double x; } __Pyx_st_longdouble;
349 typedef struct { char c; void *x; } __Pyx_st_void_p;
350 #ifdef HAVE_LONG_LONG
351 typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
352 #endif
354 static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
355 switch (ch) {
356 case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
357 case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
358 case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
359 case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
360 #ifdef HAVE_LONG_LONG
361 case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
362 #endif
363 case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
364 case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
365 case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
366 case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
367 default:
368 __Pyx_BufFmt_RaiseUnexpectedChar(ch);
369 return 0;
373 /* These are for computing the padding at the end of the struct to align
374 on the first member of the struct. This will probably the same as above,
375 but we don't have any guarantees.
377 typedef struct { short x; char c; } __Pyx_pad_short;
378 typedef struct { int x; char c; } __Pyx_pad_int;
379 typedef struct { long x; char c; } __Pyx_pad_long;
380 typedef struct { float x; char c; } __Pyx_pad_float;
381 typedef struct { double x; char c; } __Pyx_pad_double;
382 typedef struct { long double x; char c; } __Pyx_pad_longdouble;
383 typedef struct { void *x; char c; } __Pyx_pad_void_p;
384 #ifdef HAVE_LONG_LONG
385 typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
386 #endif
388 static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
389 switch (ch) {
390 case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
391 case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
392 case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
393 case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
394 #ifdef HAVE_LONG_LONG
395 case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
396 #endif
397 case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
398 case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
399 case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
400 case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
401 default:
402 __Pyx_BufFmt_RaiseUnexpectedChar(ch);
403 return 0;
407 static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
408 switch (ch) {
409 case 'c':
410 return 'H';
411 case 'b': case 'h': case 'i':
412 case 'l': case 'q': case 's': case 'p':
413 return 'I';
414 case 'B': case 'H': case 'I': case 'L': case 'Q':
415 return 'U';
416 case 'f': case 'd': case 'g':
417 return (is_complex ? 'C' : 'R');
418 case 'O':
419 return 'O';
420 case 'P':
421 return 'P';
422 default: {
423 __Pyx_BufFmt_RaiseUnexpectedChar(ch);
424 return 0;
430 static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
431 if (ctx->head == NULL || ctx->head->field == &ctx->root) {
432 const char* expected;
433 const char* quote;
434 if (ctx->head == NULL) {
435 expected = "end";
436 quote = "";
437 } else {
438 expected = ctx->head->field->type->name;
439 quote = "'";
441 PyErr_Format(PyExc_ValueError,
442 "Buffer dtype mismatch, expected %s%s%s but got %s",
443 quote, expected, quote,
444 __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
445 } else {
446 __Pyx_StructField* field = ctx->head->field;
447 __Pyx_StructField* parent = (ctx->head - 1)->field;
448 PyErr_Format(PyExc_ValueError,
449 "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
450 field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
451 parent->type->name, field->name);
455 static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
456 char group;
457 size_t size, offset, arraysize = 1;
459 /* printf("processing... %s\n", ctx->head->field->type->name); */
461 if (ctx->enc_type == 0) return 0;
463 /* Validate array size */
464 if (ctx->head->field->type->arraysize[0]) {
465 int i, ndim = 0;
467 /* handle strings ('s' and 'p') */
468 if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
469 ctx->is_valid_array = ctx->head->field->type->ndim == 1;
470 ndim = 1;
471 if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
472 PyErr_Format(PyExc_ValueError,
473 "Expected a dimension of size %zu, got %zu",
474 ctx->head->field->type->arraysize[0], ctx->enc_count);
475 return -1;
479 if (!ctx->is_valid_array) {
480 PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
481 ctx->head->field->type->ndim, ndim);
482 return -1;
484 for (i = 0; i < ctx->head->field->type->ndim; i++) {
485 arraysize *= ctx->head->field->type->arraysize[i];
487 ctx->is_valid_array = 0;
488 ctx->enc_count = 1;
491 group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
492 do {
493 __Pyx_StructField* field = ctx->head->field;
494 __Pyx_TypeInfo* type = field->type;
496 if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
497 size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
498 } else {
499 size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
502 if (ctx->enc_packmode == '@') {
503 size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
504 size_t align_mod_offset;
505 if (align_at == 0) return -1;
506 align_mod_offset = ctx->fmt_offset % align_at;
507 if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
509 if (ctx->struct_alignment == 0)
510 ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
511 ctx->is_complex);
514 if (type->size != size || type->typegroup != group) {
515 if (type->typegroup == 'C' && type->fields != NULL) {
516 /* special case -- treat as struct rather than complex number */
517 size_t parent_offset = ctx->head->parent_offset + field->offset;
518 ++ctx->head;
519 ctx->head->field = type->fields;
520 ctx->head->parent_offset = parent_offset;
521 continue;
524 if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
525 /* special case -- chars don't care about sign */
526 } else {
527 __Pyx_BufFmt_RaiseExpected(ctx);
528 return -1;
532 offset = ctx->head->parent_offset + field->offset;
533 if (ctx->fmt_offset != offset) {
534 PyErr_Format(PyExc_ValueError,
535 "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
536 (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
537 return -1;
540 ctx->fmt_offset += size;
541 if (arraysize)
542 ctx->fmt_offset += (arraysize - 1) * size;
544 --ctx->enc_count; /* Consume from buffer string */
546 /* Done checking, move to next field, pushing or popping struct stack if needed */
547 while (1) {
548 if (field == &ctx->root) {
549 ctx->head = NULL;
550 if (ctx->enc_count != 0) {
551 __Pyx_BufFmt_RaiseExpected(ctx);
552 return -1;
554 break; /* breaks both loops as ctx->enc_count == 0 */
556 ctx->head->field = ++field;
557 if (field->type == NULL) {
558 --ctx->head;
559 field = ctx->head->field;
560 continue;
561 } else if (field->type->typegroup == 'S') {
562 size_t parent_offset = ctx->head->parent_offset + field->offset;
563 if (field->type->fields->type == NULL) continue; /* empty struct */
564 field = field->type->fields;
565 ++ctx->head;
566 ctx->head->field = field;
567 ctx->head->parent_offset = parent_offset;
568 break;
569 } else {
570 break;
573 } while (ctx->enc_count);
574 ctx->enc_type = 0;
575 ctx->is_complex = 0;
576 return 0;
579 /* Parse an array in the format string (e.g. (1,2,3)) */
580 static CYTHON_INLINE PyObject *
581 __pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
583 const char *ts = *tsp;
584 int i = 0, number;
585 int ndim = ctx->head->field->type->ndim;
587 ++ts;
588 if (ctx->new_count != 1) {
589 PyErr_SetString(PyExc_ValueError,
590 "Cannot handle repeated arrays in format string");
591 return NULL;
594 /* Process the previous element */
595 if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
597 /* Parse all numbers in the format string */
598 while (*ts && *ts != ')') {
599 // ignore space characters (not using isspace() due to C/C++ problem on MacOS-X)
600 switch (*ts) {
601 case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue;
602 default: break; /* not a 'break' in the loop */
605 number = __Pyx_BufFmt_ExpectNumber(&ts);
606 if (number == -1) return NULL;
608 if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
609 return PyErr_Format(PyExc_ValueError,
610 "Expected a dimension of size %zu, got %d",
611 ctx->head->field->type->arraysize[i], number);
613 if (*ts != ',' && *ts != ')')
614 return PyErr_Format(PyExc_ValueError,
615 "Expected a comma in format string, got '%c'", *ts);
617 if (*ts == ',') ts++;
618 i++;
621 if (i != ndim)
622 return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
623 ctx->head->field->type->ndim, i);
625 if (!*ts) {
626 PyErr_SetString(PyExc_ValueError,
627 "Unexpected end of format string, expected ')'");
628 return NULL;
631 ctx->is_valid_array = 1;
632 ctx->new_count = 1;
633 *tsp = ++ts;
634 return Py_None;
637 static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
638 int got_Z = 0;
640 while (1) {
641 /* puts(ts); */
642 switch(*ts) {
643 case 0:
644 if (ctx->enc_type != 0 && ctx->head == NULL) {
645 __Pyx_BufFmt_RaiseExpected(ctx);
646 return NULL;
648 if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
649 if (ctx->head != NULL) {
650 __Pyx_BufFmt_RaiseExpected(ctx);
651 return NULL;
653 return ts;
654 case ' ':
655 case '\r':
656 case '\n':
657 ++ts;
658 break;
659 case '<':
660 if (!__Pyx_IsLittleEndian()) {
661 PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
662 return NULL;
664 ctx->new_packmode = '=';
665 ++ts;
666 break;
667 case '>':
668 case '!':
669 if (__Pyx_IsLittleEndian()) {
670 PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
671 return NULL;
673 ctx->new_packmode = '=';
674 ++ts;
675 break;
676 case '=':
677 case '@':
678 case '^':
679 ctx->new_packmode = *ts++;
680 break;
681 case 'T': /* substruct */
683 const char* ts_after_sub;
684 size_t i, struct_count = ctx->new_count;
685 size_t struct_alignment = ctx->struct_alignment;
686 ctx->new_count = 1;
687 ++ts;
688 if (*ts != '{') {
689 PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
690 return NULL;
692 if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
693 ctx->enc_type = 0; /* Erase processed last struct element */
694 ctx->enc_count = 0;
695 ctx->struct_alignment = 0;
696 ++ts;
697 ts_after_sub = ts;
698 for (i = 0; i != struct_count; ++i) {
699 ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
700 if (!ts_after_sub) return NULL;
702 ts = ts_after_sub;
703 if (struct_alignment) ctx->struct_alignment = struct_alignment;
705 break;
706 case '}': /* end of substruct; either repeat or move on */
708 size_t alignment = ctx->struct_alignment;
709 ++ts;
710 if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
711 ctx->enc_type = 0; /* Erase processed last struct element */
712 if (alignment && ctx->fmt_offset % alignment) {
713 /* Pad struct on size of the first member */
714 ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
717 return ts;
718 case 'x':
719 if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
720 ctx->fmt_offset += ctx->new_count;
721 ctx->new_count = 1;
722 ctx->enc_count = 0;
723 ctx->enc_type = 0;
724 ctx->enc_packmode = ctx->new_packmode;
725 ++ts;
726 break;
727 case 'Z':
728 got_Z = 1;
729 ++ts;
730 if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
731 __Pyx_BufFmt_RaiseUnexpectedChar('Z');
732 return NULL;
734 /* fall through */
735 case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
736 case 'l': case 'L': case 'q': case 'Q':
737 case 'f': case 'd': case 'g':
738 case 'O': case 'p':
739 if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
740 ctx->enc_packmode == ctx->new_packmode) {
741 /* Continue pooling same type */
742 ctx->enc_count += ctx->new_count;
743 ctx->new_count = 1;
744 got_Z = 0;
745 ++ts;
746 break;
748 /* fall through */
749 case 's':
750 /* 's' or new type (cannot be added to current pool) */
751 if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
752 ctx->enc_count = ctx->new_count;
753 ctx->enc_packmode = ctx->new_packmode;
754 ctx->enc_type = *ts;
755 ctx->is_complex = got_Z;
756 ++ts;
757 ctx->new_count = 1;
758 got_Z = 0;
759 break;
760 case ':':
761 ++ts;
762 while(*ts != ':') ++ts;
763 ++ts;
764 break;
765 case '(':
766 if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
767 break;
768 default:
770 int number = __Pyx_BufFmt_ExpectNumber(&ts);
771 if (number == -1) return NULL;
772 ctx->new_count = (size_t)number;
778 static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
779 buf->buf = NULL;
780 buf->obj = NULL;
781 buf->strides = __Pyx_zeros;
782 buf->shape = __Pyx_zeros;
783 buf->suboffsets = __Pyx_minusones;
786 static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
787 Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
788 int nd, int cast, __Pyx_BufFmt_StackElem* stack)
790 if (obj == Py_None || obj == NULL) {
791 __Pyx_ZeroBuffer(buf);
792 return 0;
794 buf->buf = NULL;
795 if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
796 if (buf->ndim != nd) {
797 PyErr_Format(PyExc_ValueError,
798 "Buffer has wrong number of dimensions (expected %d, got %d)",
799 nd, buf->ndim);
800 goto fail;
802 if (!cast) {
803 __Pyx_BufFmt_Context ctx;
804 __Pyx_BufFmt_Init(&ctx, stack, dtype);
805 if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
807 if ((unsigned)buf->itemsize != dtype->size) {
808 PyErr_Format(PyExc_ValueError,
809 "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
810 buf->itemsize, (buf->itemsize > 1) ? "s" : "",
811 dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
812 goto fail;
814 if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
815 return 0;
816 fail:;
817 __Pyx_ZeroBuffer(buf);
818 return -1;
821 static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
822 if (info->buf == NULL) return;
823 if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
824 __Pyx_ReleaseBuffer(info);
827 /////////////// TypeInfoCompare.proto ///////////////
828 static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
830 /////////////// TypeInfoCompare ///////////////
831 /* See if two dtypes are equal */
832 static int
833 __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
835 int i;
837 if (!a || !b)
838 return 0;
840 if (a == b)
841 return 1;
843 if (a->size != b->size || a->typegroup != b->typegroup ||
844 a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
845 if (a->typegroup == 'H' || b->typegroup == 'H') {
846 /* Special case for chars */
847 return a->size == b->size;
848 } else {
849 return 0;
853 if (a->ndim) {
854 /* Verify multidimensional C arrays */
855 for (i = 0; i < a->ndim; i++)
856 if (a->arraysize[i] != b->arraysize[i])
857 return 0;
860 if (a->typegroup == 'S') {
861 /* Check for packed struct */
862 if (a->flags != b->flags)
863 return 0;
865 /* compare all struct fields */
866 if (a->fields || b->fields) {
867 /* Check if both have fields */
868 if (!(a->fields && b->fields))
869 return 0;
871 /* compare */
872 for (i = 0; a->fields[i].type && b->fields[i].type; i++) {
873 __Pyx_StructField *field_a = a->fields + i;
874 __Pyx_StructField *field_b = b->fields + i;
876 if (field_a->offset != field_b->offset ||
877 !__pyx_typeinfo_cmp(field_a->type, field_b->type))
878 return 0;
881 /* If all fields are processed, we have a match */
882 return !a->fields[i].type && !b->fields[i].type;
886 return 1;
891 /////////////// TypeInfoToFormat.proto ///////////////
892 struct __pyx_typeinfo_string {
893 char string[3];
895 static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type);
897 /////////////// TypeInfoToFormat ///////////////
898 {{# See also MemoryView.pyx:BufferFormatFromTypeInfo }}
900 static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type) {
901 struct __pyx_typeinfo_string result = { {0} };
902 char *buf = (char *) result.string;
903 size_t size = type->size;
905 switch (type->typegroup) {
906 case 'H':
907 *buf = 'c';
908 break;
909 case 'I':
910 case 'U':
911 if (size == 1)
912 *buf = 'b';
913 else if (size == 2)
914 *buf = 'h';
915 else if (size == 4)
916 *buf = 'i';
917 else if (size == 8)
918 *buf = 'q';
920 if (type->is_unsigned)
921 *buf = toupper(*buf);
922 break;
923 case 'P':
924 *buf = 'P';
925 break;
926 case 'C':
928 __Pyx_TypeInfo complex_type = *type;
929 complex_type.typegroup = 'R';
930 complex_type.size /= 2;
932 *buf++ = 'Z';
933 *buf = __Pyx_TypeInfoToFormat(&complex_type).string[0];
934 break;
936 case 'R':
937 if (size == 4)
938 *buf = 'f';
939 else if (size == 8)
940 *buf = 'd';
941 else
942 *buf = 'g';
943 break;
946 return result;