1/////////////// BufferStructDeclare.proto ///////////////
2
3/* structs for buffer access */
4
5typedef struct {
6  Py_ssize_t shape, strides, suboffsets;
7} __Pyx_Buf_DimInfo;
8
9typedef struct {
10  size_t refcount;
11  Py_buffer pybuffer;
12} __Pyx_Buffer;
13
14typedef struct {
15  __Pyx_Buffer *rcbuffer;
16  char *data;
17  __Pyx_Buf_DimInfo diminfo[{{max_dims}}];
18} __Pyx_LocalBuf_ND;
19
20/////////////// BufferIndexError.proto ///////////////
21static void __Pyx_RaiseBufferIndexError(int axis); /*proto*/
22
23/////////////// BufferIndexError ///////////////
24static 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
32static void __Pyx_RaiseBufferIndexErrorNogil(int axis); /*proto*/
33
34/////////////// BufferIndexErrorNogil ///////////////
35static 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 ///////////////
46static void __Pyx_RaiseBufferFallbackError(void); /*proto*/
47
48/////////////// BufferFallbackError ///////////////
49static 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
56#define IS_UNSIGNED(type) (((type) -1) > 0)
57
58/* Run-time type information about structs used with buffers */
59struct __Pyx_StructField_;
60
61#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
62
63typedef 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;
73
74typedef struct __Pyx_StructField_ {
75  __Pyx_TypeInfo* type;
76  const char* name;
77  size_t offset;
78} __Pyx_StructField;
79
80typedef struct {
81  __Pyx_StructField* field;
82  size_t parent_offset;
83} __Pyx_BufFmt_StackElem;
84
85typedef 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;
97
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
106
107/////////////// GetAndReleaseBuffer ///////////////
108#if PY_MAJOR_VERSION < 3
109static 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
113
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}}
119
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;
129
130            return func(obj, view, flags);
131        } else {
132            PyErr_Clear();
133        }
134    }
135  #endif
136
137    PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
138
139#if PY_VERSION_HEX < 0x02060000
140fail:
141#endif
142
143    return -1;
144}
145
146static void __Pyx_ReleaseBuffer(Py_buffer *view) {
147    PyObject *obj = view->obj;
148    if (!obj) return;
149
150  #if PY_VERSION_HEX >= 0x02060000
151    if (PyObject_CheckBuffer(obj)) {
152        PyBuffer_Release(view);
153        return;
154    }
155  #endif
156
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}}
162
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();
176        }
177    }
178  #endif
179
180    goto nofail;
181
182#if PY_VERSION_HEX < 0x02060000
183fail:
184#endif
185    PyErr_WriteUnraisable(obj);
186
187nofail:
188    Py_DECREF(obj);
189    view->obj = NULL;
190}
191
192#endif /*  PY_MAJOR_VERSION < 3 */
193
194/////////////// BufferFormatCheck.proto ///////////////
195{{#
196
197    Buffer format string checking
198
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:
203
204    http://docs.python.org/3/library/struct.html
205    http://legacy.python.org/dev/peps/pep-3118/#additions-to-the-struct-string-syntax
206
207    The alignment code is copied from _struct.c in Python.
208}}
209
210static CYTHON_INLINE int  __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
211    __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
212static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
213
214/////////////// BufferFormatCheck ///////////////
215static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
216  unsigned int n = 1;
217  return *(unsigned char*)(&n) != 0;
218}
219
220
221static 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;
246  }
247}
248
249static 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';
259        }
260    }
261    *ts = t;
262    return count;
263}
264
265static 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;
271}
272
273
274static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
275  PyErr_Format(PyExc_ValueError,
276               "Unexpected format string character: '%c'", ch);
277}
278
279static 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";
301  }
302}
303
304static 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;
315    }
316    case 'O': case 'P': return sizeof(void*);
317    default:
318      __Pyx_BufFmt_RaiseUnexpectedChar(ch);
319      return 0;
320    }
321}
322
323static 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;
339    }
340  }
341}
342
343typedef struct { char c; short x; } __Pyx_st_short;
344typedef struct { char c; int x; } __Pyx_st_int;
345typedef struct { char c; long x; } __Pyx_st_long;
346typedef struct { char c; float x; } __Pyx_st_float;
347typedef struct { char c; double x; } __Pyx_st_double;
348typedef struct { char c; long double x; } __Pyx_st_longdouble;
349typedef struct { char c; void *x; } __Pyx_st_void_p;
350#ifdef HAVE_LONG_LONG
351typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
352#endif
353
354static 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;
370    }
371}
372
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.
376 */
377typedef struct { short x; char c; } __Pyx_pad_short;
378typedef struct { int x; char c; } __Pyx_pad_int;
379typedef struct { long x; char c; } __Pyx_pad_long;
380typedef struct { float x; char c; } __Pyx_pad_float;
381typedef struct { double x; char c; } __Pyx_pad_double;
382typedef struct { long double x; char c; } __Pyx_pad_longdouble;
383typedef struct { void *x; char c; } __Pyx_pad_void_p;
384#ifdef HAVE_LONG_LONG
385typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
386#endif
387
388static 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;
404    }
405}
406
407static 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;
425    }
426  }
427}
428
429
430static 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 = "'";
440    }
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);
452  }
453}
454
455static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
456  char group;
457  size_t size, offset, arraysize = 1;
458
459  /* printf("processing... %s\n", ctx->head->field->type->name); */
460
461  if (ctx->enc_type == 0) return 0;
462
463  /* Validate array size */
464  if (ctx->head->field->type->arraysize[0]) {
465    int i, ndim = 0;
466
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;
476        }
477    }
478
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;
483    }
484    for (i = 0; i < ctx->head->field->type->ndim; i++) {
485      arraysize *= ctx->head->field->type->arraysize[i];
486    }
487    ctx->is_valid_array = 0;
488    ctx->enc_count = 1;
489  }
490
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;
495
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);
500    }
501
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;
508
509      if (ctx->struct_alignment == 0)
510          ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
511                                                                 ctx->is_complex);
512    }
513
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;
522      }
523
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;
529      }
530    }
531
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;
538    }
539
540    ctx->fmt_offset += size;
541    if (arraysize)
542      ctx->fmt_offset += (arraysize - 1) * size;
543
544    --ctx->enc_count; /* Consume from buffer string */
545
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;
553        }
554        break; /* breaks both loops as ctx->enc_count == 0 */
555      }
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;
571      }
572    }
573  } while (ctx->enc_count);
574  ctx->enc_type = 0;
575  ctx->is_complex = 0;
576  return 0;
577}
578
579/* Parse an array in the format string (e.g. (1,2,3)) */
580static CYTHON_INLINE PyObject *
581__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
582{
583    const char *ts = *tsp;
584    int i = 0, number;
585    int ndim = ctx->head->field->type->ndim;
586;
587    ++ts;
588    if (ctx->new_count != 1) {
589        PyErr_SetString(PyExc_ValueError,
590                        "Cannot handle repeated arrays in format string");
591        return NULL;
592    }
593
594    /* Process the previous element */
595    if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
596
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 */
603        }
604
605        number = __Pyx_BufFmt_ExpectNumber(&ts);
606        if (number == -1) return NULL;
607
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);
612
613        if (*ts != ',' && *ts != ')')
614            return PyErr_Format(PyExc_ValueError,
615                                "Expected a comma in format string, got '%c'", *ts);
616
617        if (*ts == ',') ts++;
618        i++;
619    }
620
621    if (i != ndim)
622        return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
623                            ctx->head->field->type->ndim, i);
624
625    if (!*ts) {
626        PyErr_SetString(PyExc_ValueError,
627                        "Unexpected end of format string, expected ')'");
628        return NULL;
629    }
630
631    ctx->is_valid_array = 1;
632    ctx->new_count = 1;
633    *tsp = ++ts;
634    return Py_None;
635}
636
637static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
638  int got_Z = 0;
639
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;
647        }
648        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
649        if (ctx->head != NULL) {
650          __Pyx_BufFmt_RaiseExpected(ctx);
651          return NULL;
652        }
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;
663        }
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;
672        }
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 */
682        {
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;
691          }
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;
701          }
702          ts = ts_after_sub;
703          if (struct_alignment) ctx->struct_alignment = struct_alignment;
704        }
705        break;
706      case '}': /* end of substruct; either repeat or move on */
707        {
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);
715          }
716        }
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;
733        }
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;
747        }
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:
769        {
770          int number = __Pyx_BufFmt_ExpectNumber(&ts);
771          if (number == -1) return NULL;
772          ctx->new_count = (size_t)number;
773        }
774    }
775  }
776}
777
778static 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;
784}
785
786static 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)
789{
790  if (obj == Py_None || obj == NULL) {
791    __Pyx_ZeroBuffer(buf);
792    return 0;
793  }
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;
801  }
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;
806  }
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;
813  }
814  if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
815  return 0;
816fail:;
817  __Pyx_ZeroBuffer(buf);
818  return -1;
819}
820
821static 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);
825}
826
827/////////////// TypeInfoCompare.proto ///////////////
828static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
829
830/////////////// TypeInfoCompare ///////////////
831/* See if two dtypes are equal */
832static int
833__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
834{
835    int i;
836
837    if (!a || !b)
838        return 0;
839
840    if (a == b)
841        return 1;
842
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;
850        }
851    }
852
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;
858    }
859
860    if (a->typegroup == 'S') {
861        /* Check for packed struct */
862        if (a->flags != b->flags)
863            return 0;
864
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;
870
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;
875
876                if (field_a->offset != field_b->offset ||
877                    !__pyx_typeinfo_cmp(field_a->type, field_b->type))
878                    return 0;
879            }
880
881            /* If all fields are processed, we have a match */
882            return !a->fields[i].type && !b->fields[i].type;
883        }
884    }
885
886    return 1;
887}
888
889
890
891/////////////// TypeInfoToFormat.proto ///////////////
892struct __pyx_typeinfo_string {
893    char string[3];
894};
895static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type);
896
897/////////////// TypeInfoToFormat ///////////////
898{{# See also MemoryView.pyx:BufferFormatFromTypeInfo }}
899
900static 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;
904
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';
919
920            if (type->is_unsigned)
921                *buf = toupper(*buf);
922            break;
923        case 'P':
924            *buf = 'P';
925            break;
926        case 'C':
927         {
928            __Pyx_TypeInfo complex_type = *type;
929            complex_type.typegroup = 'R';
930            complex_type.size /= 2;
931
932            *buf++ = 'Z';
933            *buf = __Pyx_TypeInfoToFormat(&complex_type).string[0];
934            break;
935         }
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;
944    }
945
946    return result;
947}
948