From 111f3d42c2c07050fde23d4e58115a2b29e4cf95 Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Thu, 4 Sep 2008 13:47:08 +0200 Subject: [PATCH] Buffers: Format string parsing change (ticket 66) --- Cython/Compiler/Buffer.py | 37 +++++++++---------------------------- tests/run/bufaccess.pyx | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/Cython/Compiler/Buffer.py b/Cython/Compiler/Buffer.py index 41b5ee11..985351ed 100644 --- a/Cython/Compiler/Buffer.py +++ b/Cython/Compiler/Buffer.py @@ -534,12 +534,11 @@ def get_getbuffer_code(dtype, code): } ts = buf->format; ts = __Pyx_ConsumeWhitespace(ts); - ts = __Pyx_BufferTypestringCheckEndian(ts); if (!ts) goto fail; - ts = __Pyx_ConsumeWhitespace(ts); ts = %(itemchecker)s(ts); if (!ts) goto fail; ts = __Pyx_ConsumeWhitespace(ts); + if (!ts) goto fail; if (*ts != 0) { PyErr_Format(PyExc_ValueError, "Expected non-struct buffer data type (expected end, got '%%s')", ts); @@ -667,7 +666,6 @@ acquire_utility_code = ["""\ static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf); /*proto*/ static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts); /*proto*/ -static INLINE const char* __Pyx_BufferTypestringCheckEndian(const char* ts); /*proto*/ static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim); /*proto*/ """, """ static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { @@ -687,41 +685,24 @@ static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) { static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts) { while (1) { switch (*ts) { + case '@': case 10: case 13: case ' ': ++ts; + break; + case '=': + case '<': + case '>': + case '!': + PyErr_SetString(PyExc_ValueError, "Buffer acquisition error: Only native byte order, size and alignment supported."); + return NULL; default: return ts; } } } -static INLINE const char* __Pyx_BufferTypestringCheckEndian(const char* ts) { - int num = 1; - int little_endian = ((char*)&num)[0]; - int ok = 1; - switch (*ts) { - case '@': - case '=': - ++ts; break; - case '<': - if (little_endian) ++ts; - else ok = 0; - break; - case '>': - case '!': - if (!little_endian) ++ts; - else ok = 0; - break; - } - if (!ok) { - PyErr_Format(PyExc_ValueError, "Buffer has wrong endianness (rejecting on '%s')", ts); - return NULL; - } - return ts; -} - static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim) { PyErr_Format(PyExc_ValueError, "Buffer has wrong number of dimensions (expected %d, got %d)", diff --git a/tests/run/bufaccess.pyx b/tests/run/bufaccess.pyx index dff49290..3a571297 100644 --- a/tests/run/bufaccess.pyx +++ b/tests/run/bufaccess.pyx @@ -329,6 +329,35 @@ def explicitly_release_buffer(): x = None print "After release" +# +# Format strings +# +@testcase +def alignment_string(object[int] buf): + """ + >>> alignment_string(IntMockBuffer(None, [1,2], format="@i")) + 2 + >>> alignment_string(IntMockBuffer(None, [1,2], format="@i@@")) + 2 + >>> alignment_string(IntMockBuffer(None, [1,2], format=">i")) + Traceback (most recent call last): + ... + ValueError: Buffer acquisition error: Only native byte order, size and alignment supported. + >>> alignment_string(IntMockBuffer(None, [1,2], format=">> alignment_string(IntMockBuffer(None, [1,2], format="=i")) + Traceback (most recent call last): + ... + ValueError: Buffer acquisition error: Only native byte order, size and alignment supported. + >>> alignment_string(IntMockBuffer(None, [1,2], format="!i")) + Traceback (most recent call last): + ... + ValueError: Buffer acquisition error: Only native byte order, size and alignment supported. + """ + print buf[1] + # # Getting items and index bounds checking # @@ -997,7 +1026,7 @@ cdef class IntMockBuffer(MockBuffer): (buf)[0] = value return 0 cdef get_itemsize(self): return sizeof(int) - cdef get_default_format(self): return b"=i" + cdef get_default_format(self): return b"@i" cdef class ShortMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: @@ -1011,7 +1040,7 @@ cdef class UnsignedShortMockBuffer(MockBuffer): (buf)[0] = value return 0 cdef get_itemsize(self): return sizeof(unsigned short) - cdef get_default_format(self): return b"=1H" # Try with repeat count + cdef get_default_format(self): return b"@1H" # Try with repeat count cdef class FloatMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: @@ -1037,7 +1066,7 @@ cdef class ObjectMockBuffer(MockBuffer): return 0 cdef get_itemsize(self): return sizeof(void*) - cdef get_default_format(self): return b"=O" + cdef get_default_format(self): return b"@O" cdef class IntStridedMockBuffer(IntMockBuffer): -- 2.26.2