diff options
author | Brett Cannon <brett@python.org> | 2012-03-06 15:33:24 -0500 |
---|---|---|
committer | Brett Cannon <brett@python.org> | 2012-03-06 15:33:24 -0500 |
commit | f67e494ca8dfc72c0f812ed46c6a08ad3b9ddc24 (patch) | |
tree | ceed84488164142e5884411566de19f66702c3e7 /Modules/_testbuffer.c | |
parent | 0d4d410b2d6891520b1772a85f5ebdf926a0c77e (diff) | |
parent | 0119e4753eec50f671ee716af202b4a1ca28deef (diff) | |
download | cpython-git-f67e494ca8dfc72c0f812ed46c6a08ad3b9ddc24.tar.gz |
merge
Diffstat (limited to 'Modules/_testbuffer.c')
-rw-r--r-- | Modules/_testbuffer.c | 174 |
1 files changed, 152 insertions, 22 deletions
diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 39a7bcc9f0..cc4aea86fb 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -44,23 +44,21 @@ static PyTypeObject NDArray_Type; #define ADJUST_PTR(ptr, suboffsets) \ (HAVE_PTR(suboffsets) ? *((char**)ptr) + suboffsets[0] : ptr) +/* Default: NumPy style (strides), read-only, no var-export, C-style layout */ +#define ND_DEFAULT 0x000 /* User configurable flags for the ndarray */ -#define ND_VAREXPORT 0x001 /* change layout while buffers are exported */ - +#define ND_VAREXPORT 0x001 /* change layout while buffers are exported */ /* User configurable flags for each base buffer */ -#define ND_WRITABLE 0x002 /* mark base buffer as writable */ -#define ND_FORTRAN 0x004 /* Fortran contiguous layout */ -#define ND_SCALAR 0x008 /* scalar: ndim = 0 */ -#define ND_PIL 0x010 /* convert to PIL-style array (suboffsets) */ -#define ND_GETBUF_FAIL 0x020 /* test issue 7385 */ - -/* Default: NumPy style (strides), read-only, no var-export, C-style layout */ -#define ND_DEFAULT 0x0 - +#define ND_WRITABLE 0x002 /* mark base buffer as writable */ +#define ND_FORTRAN 0x004 /* Fortran contiguous layout */ +#define ND_SCALAR 0x008 /* scalar: ndim = 0 */ +#define ND_PIL 0x010 /* convert to PIL-style array (suboffsets) */ +#define ND_REDIRECT 0x020 /* redirect buffer requests */ +#define ND_GETBUF_FAIL 0x040 /* trigger getbuffer failure */ +#define ND_GETBUF_UNDEFINED 0x080 /* undefined view.obj */ /* Internal flags for the base buffer */ -#define ND_C 0x040 /* C contiguous layout (default) */ -#define ND_OWN_ARRAYS 0x080 /* consumer owns arrays */ -#define ND_UNUSED 0x100 /* initializer */ +#define ND_C 0x100 /* C contiguous layout (default) */ +#define ND_OWN_ARRAYS 0x200 /* consumer owns arrays */ /* ndarray properties */ #define ND_IS_CONSUMER(nd) \ @@ -1290,7 +1288,7 @@ ndarray_init(PyObject *self, PyObject *args, PyObject *kwds) PyObject *strides = NULL; /* number of bytes to the next elt in each dim */ Py_ssize_t offset = 0; /* buffer offset */ PyObject *format = simple_format; /* struct module specifier: "B" */ - int flags = ND_UNUSED; /* base buffer and ndarray flags */ + int flags = ND_DEFAULT; /* base buffer and ndarray flags */ int getbuf = PyBUF_UNUSED; /* re-exporter: getbuffer request flags */ @@ -1302,10 +1300,10 @@ ndarray_init(PyObject *self, PyObject *args, PyObject *kwds) /* NDArrayObject is re-exporter */ if (PyObject_CheckBuffer(v) && shape == NULL) { if (strides || offset || format != simple_format || - flags != ND_UNUSED) { + !(flags == ND_DEFAULT || flags == ND_REDIRECT)) { PyErr_SetString(PyExc_TypeError, - "construction from exporter object only takes a single " - "additional getbuf argument"); + "construction from exporter object only takes 'obj', 'getbuf' " + "and 'flags' arguments"); return -1; } @@ -1315,6 +1313,7 @@ ndarray_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; init_flags(nd->head); + nd->head->flags |= flags; return 0; } @@ -1333,8 +1332,6 @@ ndarray_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; } - if (flags == ND_UNUSED) - flags = ND_DEFAULT; if (flags & ND_VAREXPORT) { nd->flags |= ND_VAREXPORT; flags &= ~ND_VAREXPORT; @@ -1357,7 +1354,7 @@ ndarray_push(PyObject *self, PyObject *args, PyObject *kwds) PyObject *strides = NULL; /* number of bytes to the next elt in each dim */ PyObject *format = simple_format; /* struct module specifier: "B" */ Py_ssize_t offset = 0; /* buffer offset */ - int flags = ND_UNUSED; /* base buffer flags */ + int flags = ND_DEFAULT; /* base buffer flags */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|OnOi", kwlist, &items, &shape, &strides, &offset, &format, &flags)) @@ -1423,6 +1420,11 @@ ndarray_getbuf(NDArrayObject *self, Py_buffer *view, int flags) Py_buffer *base = &ndbuf->base; int baseflags = ndbuf->flags; + /* redirect mode */ + if (base->obj != NULL && (baseflags&ND_REDIRECT)) { + return PyObject_GetBuffer(base->obj, view, flags); + } + /* start with complete information */ *view = *base; view->obj = NULL; @@ -1445,6 +1447,8 @@ ndarray_getbuf(NDArrayObject *self, Py_buffer *view, int flags) if (baseflags & ND_GETBUF_FAIL) { PyErr_SetString(PyExc_BufferError, "ND_GETBUF_FAIL: forced test exception"); + if (baseflags & ND_GETBUF_UNDEFINED) + view->obj = (PyObject *)0x1; /* wrong but permitted in <= 3.2 */ return -1; } @@ -2598,6 +2602,126 @@ static PyTypeObject NDArray_Type = { ndarray_new, /* tp_new */ }; +/**************************************************************************/ +/* StaticArray Object */ +/**************************************************************************/ + +static PyTypeObject StaticArray_Type; + +typedef struct { + PyObject_HEAD + int legacy_mode; /* if true, use the view.obj==NULL hack */ +} StaticArrayObject; + +static char static_mem[12] = {0,1,2,3,4,5,6,7,8,9,10,11}; +static Py_ssize_t static_shape[1] = {12}; +static Py_ssize_t static_strides[1] = {1}; +static Py_buffer static_buffer = { + static_mem, /* buf */ + NULL, /* obj */ + 12, /* len */ + 1, /* itemsize */ + 1, /* readonly */ + 1, /* ndim */ + "B", /* format */ + static_shape, /* shape */ + static_strides, /* strides */ + NULL, /* suboffsets */ + NULL /* internal */ +}; + +static PyObject * +staticarray_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + return (PyObject *)PyObject_New(StaticArrayObject, &StaticArray_Type); +} + +static int +staticarray_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + StaticArrayObject *a = (StaticArrayObject *)self; + static char *kwlist[] = { + "legacy_mode", NULL + }; + PyObject *legacy_mode = Py_False; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &legacy_mode)) + return -1; + + a->legacy_mode = (legacy_mode != Py_False); + return 0; +} + +static void +staticarray_dealloc(StaticArrayObject *self) +{ + PyObject_Del(self); +} + +/* Return a buffer for a PyBUF_FULL_RO request. Flags are not checked, + which makes this object a non-compliant exporter! */ +static int +staticarray_getbuf(StaticArrayObject *self, Py_buffer *view, int flags) +{ + *view = static_buffer; + + if (self->legacy_mode) { + view->obj = NULL; /* Don't use this in new code. */ + } + else { + view->obj = (PyObject *)self; + Py_INCREF(view->obj); + } + + return 0; +} + +static PyBufferProcs staticarray_as_buffer = { + (getbufferproc)staticarray_getbuf, /* bf_getbuffer */ + NULL, /* bf_releasebuffer */ +}; + +static PyTypeObject StaticArray_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "staticarray", /* Name of this type */ + sizeof(StaticArrayObject), /* Basic object size */ + 0, /* Item size for varobject */ + (destructor)staticarray_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + &staticarray_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + staticarray_init, /* tp_init */ + 0, /* tp_alloc */ + staticarray_new, /* tp_new */ +}; + static struct PyMethodDef _testbuffer_functions[] = { {"slice_indices", slice_indices, METH_VARARGS, NULL}, @@ -2630,10 +2754,14 @@ PyInit__testbuffer(void) if (m == NULL) return NULL; - Py_TYPE(&NDArray_Type)=&PyType_Type; + Py_TYPE(&NDArray_Type) = &PyType_Type; Py_INCREF(&NDArray_Type); PyModule_AddObject(m, "ndarray", (PyObject *)&NDArray_Type); + Py_TYPE(&StaticArray_Type) = &PyType_Type; + Py_INCREF(&StaticArray_Type); + PyModule_AddObject(m, "staticarray", (PyObject *)&StaticArray_Type); + structmodule = PyImport_ImportModule("struct"); if (structmodule == NULL) return NULL; @@ -2654,6 +2782,8 @@ PyInit__testbuffer(void) PyModule_AddIntConstant(m, "ND_SCALAR", ND_SCALAR); PyModule_AddIntConstant(m, "ND_PIL", ND_PIL); PyModule_AddIntConstant(m, "ND_GETBUF_FAIL", ND_GETBUF_FAIL); + PyModule_AddIntConstant(m, "ND_GETBUF_UNDEFINED", ND_GETBUF_UNDEFINED); + PyModule_AddIntConstant(m, "ND_REDIRECT", ND_REDIRECT); PyModule_AddIntConstant(m, "PyBUF_SIMPLE", PyBUF_SIMPLE); PyModule_AddIntConstant(m, "PyBUF_WRITABLE", PyBUF_WRITABLE); |