diff options
-rw-r--r-- | Doc/api/abstract.tex | 39 | ||||
-rw-r--r-- | Include/abstract.h | 9 | ||||
-rw-r--r-- | Objects/abstract.c | 64 |
3 files changed, 83 insertions, 29 deletions
diff --git a/Doc/api/abstract.tex b/Doc/api/abstract.tex index 3078e90..c6a19c2 100644 --- a/Doc/api/abstract.tex +++ b/Doc/api/abstract.tex @@ -867,4 +867,43 @@ if (PyErr_Occurred()) { else { /* continue doing useful work */ } + +\section{Buffer Protocol \label{buffer}} + +\begin{cfuncdesc}{int}{PyObject_AsCharBuffer}{PyObject *obj, + const char **buffer, + int *buffer_len} + Returns a pointer to a read-only memory location useable as character- + based input. The \var{obj} argument must support the single-segment + character buffer interface. On success, returns \code{1}, sets + \var{buffer} to the memory location and \var{buffer} to the buffer + length. Returns \code{0} and sets a \exception{TypeError} on error. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyObject_AsReadBuffer}{PyObject *obj, + const char **buffer, + int *buffer_len} + Returns a pointer to a read-only memory location containing + arbitrary data. The \var{obj} argument must support the + single-segment readable buffer interface. On success, returns + \code{1}, sets \var{buffer} to the memory location and \var{buffer} + to the buffer length. Returns \code{0} and sets a + \exception{TypeError} on error. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyObject_CheckReadBuffer}{PyObject *o} + Returns \code{1} if \var{o} supports the single-segment readable + buffer interface. Otherwise returns \code{0}. +\enc{cfuncdesc} + +\begin{cfuncdesc}{int}{PyObject_AsWriteBuffer}{PyObject *obj, + const char **buffer, + int *buffer_len} + Returns a pointer to a writeable memory location. The \var{obj} + argument must support the single-segment, character buffer + interface. On success, returns \code{1}, sets \var{buffer} to the + memory location and \var{buffer} to the buffer length. Returns + \code{0} and sets a \exception{TypeError} on error. +\end{cfuncdesc} + \end{verbatim} diff --git a/Include/abstract.h b/Include/abstract.h index 8ebc3cd..a710509 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -468,6 +468,15 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ */ + DL_IMPORT(int) PyObject_CheckReadBuffer(PyObject *obj); + + /* + Checks whether an arbitrary object supports the (character, + single segment) buffer interface. Returns 1 on success, 0 + on failure. + + */ + DL_IMPORT(int) PyObject_AsReadBuffer(PyObject *obj, const void **buffer, int *buffer_len); diff --git a/Objects/abstract.c b/Objects/abstract.c index 938c2e2..0856f19 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -182,27 +182,37 @@ int PyObject_AsCharBuffer(PyObject *obj, return -1; } pb = obj->ob_type->tp_as_buffer; - if ( pb == NULL || + if (pb == NULL || pb->bf_getcharbuffer == NULL || - pb->bf_getsegcount == NULL ) { + pb->bf_getsegcount == NULL) { PyErr_SetString(PyExc_TypeError, "expected a character buffer object"); - goto onError; + return -1; } - if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) { + if ((*pb->bf_getsegcount)(obj,NULL) != 1) { PyErr_SetString(PyExc_TypeError, "expected a single-segment buffer object"); - goto onError; + return -1; } - len = (*pb->bf_getcharbuffer)(obj,0,&pp); + len = (*pb->bf_getcharbuffer)(obj, 0, &pp); if (len < 0) - goto onError; + return -1; *buffer = pp; *buffer_len = len; return 0; +} - onError: - return -1; +int +PyObject_CheckReadBuffer(PyObject *obj) +{ + PyBufferProcs *pb = obj->ob_type->tp_as_buffer; + + if (pb == NULL || + pb->bf_getreadbuffer == NULL || + pb->bf_getsegcount == NULL || + (*pb->bf_getsegcount)(obj, NULL) != 1) + return 0; + return 1; } int PyObject_AsReadBuffer(PyObject *obj, @@ -218,27 +228,24 @@ int PyObject_AsReadBuffer(PyObject *obj, return -1; } pb = obj->ob_type->tp_as_buffer; - if ( pb == NULL || + if (pb == NULL || pb->bf_getreadbuffer == NULL || - pb->bf_getsegcount == NULL ) { + pb->bf_getsegcount == NULL) { PyErr_SetString(PyExc_TypeError, "expected a readable buffer object"); - goto onError; + return -1; } - if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) { + if ((*pb->bf_getsegcount)(obj, NULL) != 1) { PyErr_SetString(PyExc_TypeError, "expected a single-segment buffer object"); - goto onError; + return -1; } - len = (*pb->bf_getreadbuffer)(obj,0,&pp); + len = (*pb->bf_getreadbuffer)(obj, 0, &pp); if (len < 0) - goto onError; + return -1; *buffer = pp; *buffer_len = len; return 0; - - onError: - return -1; } int PyObject_AsWriteBuffer(PyObject *obj, @@ -254,27 +261,24 @@ int PyObject_AsWriteBuffer(PyObject *obj, return -1; } pb = obj->ob_type->tp_as_buffer; - if ( pb == NULL || + if (pb == NULL || pb->bf_getwritebuffer == NULL || - pb->bf_getsegcount == NULL ) { + pb->bf_getsegcount == NULL) { PyErr_SetString(PyExc_TypeError, "expected a writeable buffer object"); - goto onError; + return -1; } - if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) { + if ((*pb->bf_getsegcount)(obj, NULL) != 1) { PyErr_SetString(PyExc_TypeError, "expected a single-segment buffer object"); - goto onError; + return -1; } len = (*pb->bf_getwritebuffer)(obj,0,&pp); if (len < 0) - goto onError; + return -1; *buffer = pp; *buffer_len = len; return 0; - - onError: - return -1; } /* Operations on numbers */ @@ -1980,7 +1984,8 @@ PyObject_GetIter(PyObject *o) if (f == NULL) { if (PySequence_Check(o)) return PySeqIter_New(o); - PyErr_SetString(PyExc_TypeError, "iteration over non-sequence"); + PyErr_SetString(PyExc_TypeError, + "iteration over non-sequence"); return NULL; } else { @@ -2021,3 +2026,4 @@ PyIter_Next(PyObject *iter) PyErr_Clear(); return result; } + |