Buffers: Format string parsing change (ticket 66)
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Thu, 4 Sep 2008 11:47:08 +0000 (13:47 +0200)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Thu, 4 Sep 2008 11:47:08 +0000 (13:47 +0200)
Cython/Compiler/Buffer.py
tests/run/bufaccess.pyx

index 41b5ee11948947d20cb936a4b02142d3f2dbc5de..985351ed8047ada944b6a87d318e5649aa5caef0 100644 (file)
@@ -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)",
index dff492909ed8e7e61eb27747d33423f73b9d8153..3a571297b97843bad2b692337179b65a6de5641e 100644 (file)
@@ -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="<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.
+    >>> 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):
         (<int*>buf)[0] = <int>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):
         (<unsigned short*>buf)[0] = <unsigned short>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):