[Numpy-svn] r8136 - in trunk/numpy/core: . src/multiarray
numpy-svn at scipy.org
numpy-svn at scipy.org
Sat Feb 20 13:05:03 EST 2010
Author: ptvirtan
Date: 2010-02-20 12:05:03 -0600 (Sat, 20 Feb 2010)
New Revision: 8136
Modified:
trunk/numpy/core/_internal.py
trunk/numpy/core/src/multiarray/buffer.c
trunk/numpy/core/src/multiarray/buffer.h
trunk/numpy/core/src/multiarray/numpyos.c
trunk/numpy/core/src/multiarray/numpyos.h
Log:
ENH: core: add some support routines needed for consuming PEP 3118 buffers
Modified: trunk/numpy/core/_internal.py
===================================================================
--- trunk/numpy/core/_internal.py 2010-02-20 18:04:43 UTC (rev 8135)
+++ trunk/numpy/core/_internal.py 2010-02-20 18:05:03 UTC (rev 8136)
@@ -347,3 +347,125 @@
return newarray
+# Given a string containing a PEP 3118 format specifier,
+# construct a Numpy dtype
+
+_pep3118_map = {
+ 'b': 'b',
+ 'B': 'B',
+ 'h': 'h',
+ 'H': 'H',
+ 'i': 'i',
+ 'I': 'I',
+ 'l': 'l',
+ 'L': 'L',
+ 'q': 'q',
+ 'Q': 'Q',
+ 'f': 'f',
+ 'd': 'd',
+ 'g': 'g',
+ 'Q': 'Q',
+ 'Zf': 'F',
+ 'Zd': 'D',
+ 'Zg': 'G',
+ 's': 'S',
+ 'w': 'U',
+ 'O': 'O',
+ 'x': 'V', # padding
+}
+
+def _dtype_from_pep3118(spec, byteorder='=', is_subdtype=False):
+ from numpy.core.multiarray import dtype
+
+ fields = {}
+ offset = 0
+ findex = 0
+ explicit_name = False
+
+ while spec:
+ value = None
+
+ # End of structure, bail out to upper level
+ if spec[0] == '}':
+ spec = spec[1:]
+ break
+
+ # Sub-arrays (1)
+ shape = None
+ if spec[0] == '(':
+ j = spec.index(')')
+ shape = tuple(map(int, spec[1:j].split(',')))
+ spec = spec[j+1:]
+
+ # Byte order
+ if spec[0] in ('=', '<', '>'):
+ byteorder = spec[0]
+ spec = spec[1:]
+
+ # Item sizes
+ itemsize = 1
+ if spec[0].isdigit():
+ j = 1
+ for j in xrange(1, len(spec)):
+ if not spec[j].isdigit():
+ break
+ itemsize = int(spec[:j])
+ spec = spec[j:]
+
+ # Data types
+ is_padding = False
+
+ if spec[:2] == 'T{':
+ value, spec = _dtype_from_pep3118(spec[2:], byteorder=byteorder,
+ is_subdtype=True)
+ if itemsize != 1:
+ # Not supported
+ raise ValueError("Non item-size 1 structures not supported")
+ elif spec[0].isalpha():
+ j = 1
+ for j in xrange(1, len(spec)):
+ if not spec[j].isalpha():
+ break
+ typechar = spec[:j]
+ spec = spec[j:]
+ is_padding = (typechar == 'x')
+ dtypechar = _pep3118_map[typechar]
+ if dtypechar in 'USV':
+ dtypechar += '%d' % itemsize
+ itemsize = 1
+ value = dtype(byteorder + dtypechar)
+ else:
+ raise ValueError("Unknown PEP 3118 data type specifier %r" % spec)
+
+ # Convert itemsize to sub-array
+ if itemsize != 1:
+ value = dtype((value, (itemsize,)))
+
+ # Sub-arrays (2)
+ if shape is not None:
+ value = dtype((value, shape))
+
+ # Field name
+ if spec and spec.startswith(':'):
+ i = spec[1:].index(':') + 1
+ name = spec[1:i]
+ spec = spec[i+1:]
+ explicit_name = True
+ else:
+ name = 'f%d' % findex
+ findex += 1
+
+ if not is_padding:
+ fields[name] = (value, offset)
+ offset += value.itemsize
+
+
+ if len(fields.keys()) == 1 and not explicit_name and fields['f0'][1] == 0:
+ ret = fields['f0'][0]
+ else:
+ ret = dtype(fields)
+
+ if is_subdtype:
+ return ret, spec
+ else:
+ return ret
Modified: trunk/numpy/core/src/multiarray/buffer.c
===================================================================
--- trunk/numpy/core/src/multiarray/buffer.c 2010-02-20 18:04:43 UTC (rev 8135)
+++ trunk/numpy/core/src/multiarray/buffer.c 2010-02-20 18:05:03 UTC (rev 8136)
@@ -594,3 +594,67 @@
(releasebufferproc)0,
#endif
};
+
+
+/*************************************************************************
+ * Convert PEP 3118 format string to PyArray_Descr
+ */
+#if PY_VERSION_HEX >= 0x02060000
+
+NPY_NO_EXPORT PyArray_Descr*
+_descriptor_from_pep3118_format(char *s)
+{
+ char *buf, *p;
+ int in_name = 0;
+ PyArray_Descr *descr;
+ PyObject *str;
+ PyObject *_numpy_internal;
+
+ if (s == NULL) {
+ return PyArray_DescrNewFromType(PyArray_BYTE);
+ }
+
+ /* Strip whitespace, except from field names */
+ buf = (char*)malloc(strlen(s) + 1);
+ p = buf;
+ while (*s != '\0') {
+ if (*s == ':') {
+ in_name = !in_name;
+ *p = *s;
+ }
+ else if (in_name || !NumPyOS_ascii_isspace(*s)) {
+ *p = *s;
+ }
+ ++p;
+ ++s;
+ }
+ *p = '\0';
+
+ /* Convert */
+ _numpy_internal = PyImport_ImportModule("numpy.core._internal");
+ if (_numpy_internal == NULL) {
+ return NULL;
+ }
+ str = PyUString_FromStringAndSize(buf, strlen(buf));
+ descr = PyObject_CallMethod(_numpy_internal, "_dtype_from_pep3118",
+ "O", str);
+ Py_DECREF(str);
+ if (descr == NULL) {
+ PyErr_Format(PyExc_ValueError,
+ "'%s' is not a valid PEP 3118 buffer format string", buf);
+ }
+ free(buf);
+ return descr;
+}
+
+#else
+
+NPY_NO_EXPORT PyArray_Descr*
+_descriptor_from_pep3118_format(char *s)
+{
+ PyErr_SetString(PyExc_RuntimeError,
+ "PEP 3118 is not supported on Python versions < 2.6");
+ return NULL;
+}
+
+#endif
Modified: trunk/numpy/core/src/multiarray/buffer.h
===================================================================
--- trunk/numpy/core/src/multiarray/buffer.h 2010-02-20 18:04:43 UTC (rev 8135)
+++ trunk/numpy/core/src/multiarray/buffer.h 2010-02-20 18:05:03 UTC (rev 8136)
@@ -10,4 +10,7 @@
NPY_NO_EXPORT void
_array_dealloc_buffer_info(PyArrayObject *self);
+NPY_NO_EXPORT PyArray_Descr*
+_descriptor_from_pep3118_format(char *s);
+
#endif
Modified: trunk/numpy/core/src/multiarray/numpyos.c
===================================================================
--- trunk/numpy/core/src/multiarray/numpyos.c 2010-02-20 18:04:43 UTC (rev 8135)
+++ trunk/numpy/core/src/multiarray/numpyos.c 2010-02-20 18:05:03 UTC (rev 8136)
@@ -336,7 +336,7 @@
*
* Same as isspace under C locale
*/
-static int
+NPY_NO_EXPORT int
NumPyOS_ascii_isspace(char c)
{
return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t'
Modified: trunk/numpy/core/src/multiarray/numpyos.h
===================================================================
--- trunk/numpy/core/src/multiarray/numpyos.h 2010-02-20 18:04:43 UTC (rev 8135)
+++ trunk/numpy/core/src/multiarray/numpyos.h 2010-02-20 18:05:03 UTC (rev 8136)
@@ -22,4 +22,7 @@
NPY_NO_EXPORT int
NumPyOS_ascii_ftolf(FILE *fp, double *value);
+NPY_NO_EXPORT int
+NumPyOS_ascii_isspace(char c);
+
#endif
More information about the Numpy-svn
mailing list