summaryrefslogtreecommitdiffstats
path: root/Include
diff options
context:
space:
mode:
authorTravis E. Oliphant <oliphant@enthought.com>2007-08-18 11:21:56 (GMT)
committerTravis E. Oliphant <oliphant@enthought.com>2007-08-18 11:21:56 (GMT)
commitb99f762f10edb2646a634c2290ecb064bd52e5c7 (patch)
treee0a354d42dccb18b7b2c99ed2733c135135a50af /Include
parent3de862df45480438dc6756103109ea9010d2825e (diff)
downloadcpython-b99f762f10edb2646a634c2290ecb064bd52e5c7.zip
cpython-b99f762f10edb2646a634c2290ecb064bd52e5c7.tar.gz
cpython-b99f762f10edb2646a634c2290ecb064bd52e5c7.tar.bz2
Merged in py3k-buffer branch to main line. All objects now use the buffer protocol in PEP 3118.
Diffstat (limited to 'Include')
-rw-r--r--Include/Python.h1
-rw-r--r--Include/abstract.h110
-rw-r--r--Include/bytesobject.h1
-rw-r--r--Include/memoryobject.h67
-rw-r--r--Include/object.h67
-rw-r--r--Include/pyerrors.h1
6 files changed, 237 insertions, 10 deletions
diff --git a/Include/Python.h b/Include/Python.h
index 43f16f7..32b2aa5 100644
--- a/Include/Python.h
+++ b/Include/Python.h
@@ -77,6 +77,7 @@
#include "rangeobject.h"
#include "stringobject.h"
#include "bufferobject.h"
+#include "memoryobject.h"
#include "tupleobject.h"
#include "listobject.h"
#include "dictobject.h"
diff --git a/Include/abstract.h b/Include/abstract.h
index 22b5d01..b8cc59c 100644
--- a/Include/abstract.h
+++ b/Include/abstract.h
@@ -475,6 +475,12 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
This is the equivalent of the Python statement: del o[key].
*/
+ /* old buffer API
+ FIXME: usage of these should all be replaced in Python itself
+ but for backwards compatibility we will implement them.
+ Their usage without a corresponding "unlock" mechansim
+ may create issues (but they would already be there). */
+
PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj,
const char **buffer,
Py_ssize_t *buffer_len);
@@ -527,6 +533,110 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
an exception set.
*/
+ /* new buffer API */
+
+#define PyObject_CheckBuffer(obj) \
+ (((obj)->ob_type->tp_as_buffer != NULL) && \
+ ((obj)->ob_type->tp_as_buffer->bf_getbuffer != NULL))
+
+ /* Return 1 if the getbuffer function is available, otherwise
+ return 0 */
+
+ PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, PyBuffer *view,
+ int flags);
+
+ /* This is a C-API version of the getbuffer function call. It checks
+ to make sure object has the required function pointer and issues the
+ call. Returns -1 and raises an error on failure and returns 0 on
+ success
+ */
+
+
+ PyAPI_FUNC(void) PyObject_ReleaseBuffer(PyObject *obj, PyBuffer *view);
+
+
+ /* C-API version of the releasebuffer function call. It
+ checks to make sure the object has the required function
+ pointer and issues the call. The obj must have the buffer
+ interface or this function will cause a segfault (i.e. it
+ is assumed to be called only after a corresponding
+ getbuffer which already verified the existence of the
+ tp_as_buffer pointer).
+
+ Returns 0 on success and -1 (with an error raised) on
+ failure. This function always succeeds (as a NO-OP) if
+ there is no releasebuffer function for the object so that
+ it can always be called when the consumer is done with the
+ buffer
+ */
+
+ PyAPI_FUNC(void *) PyBuffer_GetPointer(PyBuffer *view, Py_ssize_t *indices);
+
+ /* Get the memory area pointed to by the indices for the buffer given.
+ Note that view->ndim is the assumed size of indices
+ */
+
+ PyAPI_FUNC(int) PyBuffer_SizeFromFormat(const char *);
+
+ /* Return the implied itemsize of the data-format area from a
+ struct-style description */
+
+
+
+ PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, PyBuffer *view,
+ Py_ssize_t len, char fort);
+
+ PyAPI_FUNC(int) PyBuffer_FromContiguous(PyBuffer *view, void *buf,
+ Py_ssize_t len, char fort);
+
+
+ /* Copy len bytes of data from the contiguous chunk of memory
+ pointed to by buf into the buffer exported by obj. Return
+ 0 on success and return -1 and raise a PyBuffer_Error on
+ error (i.e. the object does not have a buffer interface or
+ it is not working).
+
+ If fortran is 'F', then if the object is multi-dimensional,
+ then the data will be copied into the array in
+ Fortran-style (first dimension varies the fastest). If
+ fortran is 'C', then the data will be copied into the array
+ in C-style (last dimension varies the fastest). If fortran
+ is 'A', then it does not matter and the copy will be made
+ in whatever way is more efficient.
+
+ */
+
+ PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src);
+
+ /* Copy the data from the src buffer to the buffer of destination
+ */
+
+ PyAPI_FUNC(int) PyBuffer_IsContiguous(PyBuffer *view, char fortran);
+
+
+ PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims,
+ Py_ssize_t *shape,
+ Py_ssize_t *strides,
+ int itemsize,
+ char fort);
+
+ /* Fill the strides array with byte-strides of a contiguous
+ (Fortran-style if fortran is 'F' or C-style otherwise)
+ array of the given shape with the given number of bytes
+ per element.
+ */
+
+ PyAPI_FUNC(int) PyBuffer_FillInfo(PyBuffer *view, void *buf,
+ Py_ssize_t len, int readonly,
+ int flags);
+
+ /* Fills in a buffer-info structure correctly for an exporter
+ that can only share a contiguous chunk of memory of
+ "unsigned bytes" of the given length. Returns 0 on success
+ and -1 (with raising an error) on error.
+ */
+
+
/* Iterators */
PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *);
diff --git a/Include/bytesobject.h b/Include/bytesobject.h
index f1e01d1..12ecf64 100644
--- a/Include/bytesobject.h
+++ b/Include/bytesobject.h
@@ -21,6 +21,7 @@ extern "C" {
/* Object layout */
typedef struct {
PyObject_VAR_HEAD
+ int ob_exports; /* how many buffer exports */
Py_ssize_t ob_alloc; /* How many bytes allocated */
char *ob_bytes;
} PyBytesObject;
diff --git a/Include/memoryobject.h b/Include/memoryobject.h
new file mode 100644
index 0000000..eb49c2e
--- /dev/null
+++ b/Include/memoryobject.h
@@ -0,0 +1,67 @@
+
+/* Memory object interface */
+
+#ifndef Py_MEMORYOBJECT_H
+#define Py_MEMORYOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *base;
+ PyBuffer view;
+} PyMemoryViewObject;
+
+
+PyAPI_DATA(PyTypeObject) PyMemoryView_Type;
+
+#define PyMemory_Check(op) (Py_Type(op) == &PyMemoryView_Type)
+#define PyMemoryView(op) (((PyMemoryViewObject *)(op))->view)
+
+#define Py_END_OF_MEMORY (-1)
+
+PyAPI_FUNC(PyObject *) PyMemoryView_GetContiguous(PyObject *base, int buffertype,
+ char fort);
+
+ /* Return a contiguous chunk of memory representing the buffer
+ from an object in a memory view object. If a copy is made then the
+ base object for the memory view will be a *new* bytes object.
+
+ Otherwise, the base-object will be the object itself and no
+ data-copying will be done.
+
+ The buffertype argument can be PyBUF_READ, PyBUF_WRITE,
+ PyBUF_UPDATEIFCOPY to determine whether the returned buffer
+ should be READONLY, WRITEABLE, or set to update the
+ original buffer if a copy must be made. If buffertype is
+ PyBUF_WRITE and the buffer is not contiguous an error will
+ be raised. In this circumstance, the user can use
+ PyBUF_UPDATEIFCOPY to ensure that a a writeable temporary
+ contiguous buffer is returned. The contents of this
+ contiguous buffer will be copied back into the original
+ object after the memoryview object is deleted as long as
+ the original object is writeable and allows setting its
+ memory to "readonly". If this is not allowed by the
+ original object, then a BufferError is raised.
+
+ If the object is multi-dimensional and if fortran is 'F',
+ the first dimension of the underlying array will vary the
+ fastest in the buffer. If fortran is 'C', then the last
+ dimension will vary the fastest (C-style contiguous). If
+ fortran is 'A', then it does not matter and you will get
+ whatever the object decides is more efficient.
+
+ A new reference is returned that must be DECREF'd when finished.
+ */
+
+PyAPI_FUNC(PyObject *) PyMemoryView_FromObject(PyObject *base);
+
+PyAPI_FUNC(PyObject *) PyMemoryView_FromMemory(PyBuffer *info);
+ /* create new if bufptr is NULL
+ will be a new bytesobject in base */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_MEMORYOBJECT_H */
diff --git a/Include/object.h b/Include/object.h
index 9470ed7..d936bca 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -140,11 +140,59 @@ typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *);
typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *);
-/* ssize_t-based buffer interface */
-typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **);
-typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **);
-typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *);
-typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **);
+
+/* buffer interface */
+typedef struct bufferinfo {
+ void *buf;
+ Py_ssize_t len;
+ Py_ssize_t itemsize;
+ int readonly;
+ int ndim;
+ char *format;
+ Py_ssize_t *shape;
+ Py_ssize_t *strides;
+ Py_ssize_t *suboffsets;
+ void *internal;
+} PyBuffer;
+
+typedef int (*getbufferproc)(PyObject *, PyBuffer *, int);
+typedef void (*releasebufferproc)(PyObject *, PyBuffer *);
+
+ /* Flags for getting buffers */
+#define PyBUF_SIMPLE 0
+#define PyBUF_CHARACTER 1
+#define PyBUF_WRITEABLE 0x0002
+#define PyBUF_LOCKDATA 0x0004
+#define PyBUF_FORMAT 0x0008
+#define PyBUF_ND 0x0010
+#define PyBUF_STRIDES (0x0020 | PyBUF_ND)
+#define PyBUF_C_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+#define PyBUF_F_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+#define PyBUF_ANY_CONTIGUOUS (0x0100 | PyBUF_STRIDES)
+#define PyBUF_INDIRECT (0x0200 | PyBUF_STRIDES)
+
+#define PyBUF_CONTIG (PyBUF_ND | PyBUF_WRITEABLE)
+#define PyBUF_CONTIG_RO (PyBUF_ND)
+#define PyBUF_CONTIG_LCK (PyBUF_ND | PyBUF_LOCKDATA)
+
+#define PyBUF_STRIDED (PyBUF_STRIDES | PyBUF_WRITEABLE)
+#define PyBUF_STRIDED_RO (PyBUF_STRIDES)
+#define PyBUF_STRIDED_LCK (PyBUF_STRIDES | PyBUF_LOCKDATA)
+
+#define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_WRITEABLE | PyBUF_FORMAT)
+#define PyBUF_RECORDS_RO (PyBUF_STRIDES | PyBUF_FORMAT)
+#define PyBUF_RECORDS_LCK (PyBUF_STRIDES | PyBUF_LOCKDATA | PyBUF_FORMAT)
+
+#define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_WRITEABLE | PyBUF_FORMAT)
+#define PyBUF_FULL_RO (PyBUF_INDIRECT | PyBUF_FORMAT)
+#define PyBUF_FULL_LCK (PyBUF_INDIRECT | PyBUF_LOCKDATA | PyBUF_FORMAT)
+
+
+#define PyBUF_READ 0x100
+#define PyBUF_WRITE 0x200
+#define PyBUF_SHADOW 0x400
+
+/* End buffer interface */
typedef int (*objobjproc)(PyObject *, PyObject *);
typedef int (*visitproc)(PyObject *, void *);
@@ -218,14 +266,13 @@ typedef struct {
objobjargproc mp_ass_subscript;
} PyMappingMethods;
+
typedef struct {
- readbufferproc bf_getreadbuffer;
- writebufferproc bf_getwritebuffer;
- segcountproc bf_getsegcount;
- charbufferproc bf_getcharbuffer;
+ getbufferproc bf_getbuffer;
+ releasebufferproc bf_releasebuffer;
+ inquiry bf_multisegment;
} PyBufferProcs;
-
typedef void (*freefunc)(void *);
typedef void (*destructor)(PyObject *);
typedef int (*printfunc)(PyObject *, FILE *, int);
diff --git a/Include/pyerrors.h b/Include/pyerrors.h
index b1cc429..c519cb6 100644
--- a/Include/pyerrors.h
+++ b/Include/pyerrors.h
@@ -138,6 +138,7 @@ PyAPI_DATA(PyObject *) PyExc_UnicodeDecodeError;
PyAPI_DATA(PyObject *) PyExc_UnicodeTranslateError;
PyAPI_DATA(PyObject *) PyExc_ValueError;
PyAPI_DATA(PyObject *) PyExc_ZeroDivisionError;
+PyAPI_DATA(PyObject *) PyExc_BufferError;
#ifdef MS_WINDOWS
PyAPI_DATA(PyObject *) PyExc_WindowsError;
#endif