summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/api/abstract.tex39
-rw-r--r--Include/abstract.h9
-rw-r--r--Objects/abstract.c64
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;
}
+