Buffer.c 29 KB

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