Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 89c3a22

Browse files
committed
Add PyObject_CheckReadBuffer(), which returns true if its argument
supports the single-segment readable buffer interface. Add documentation for this and other PyObject_XXXBuffer() calls.
1 parent da4ffee commit 89c3a22

3 files changed

Lines changed: 83 additions & 29 deletions

File tree

Doc/api/abstract.tex

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,4 +867,43 @@ \section{Iterator Protocol \label{iterator}}
867867
else {
868868
/* continue doing useful work */
869869
}
870+
871+
\section{Buffer Protocol \label{buffer}}
872+
873+
\begin{cfuncdesc}{int}{PyObject_AsCharBuffer}{PyObject *obj,
874+
const char **buffer,
875+
int *buffer_len}
876+
Returns a pointer to a read-only memory location useable as character-
877+
based input. The \var{obj} argument must support the single-segment
878+
character buffer interface. On success, returns \code{1}, sets
879+
\var{buffer} to the memory location and \var{buffer} to the buffer
880+
length. Returns \code{0} and sets a \exception{TypeError} on error.
881+
\end{cfuncdesc}
882+
883+
\begin{cfuncdesc}{int}{PyObject_AsReadBuffer}{PyObject *obj,
884+
const char **buffer,
885+
int *buffer_len}
886+
Returns a pointer to a read-only memory location containing
887+
arbitrary data. The \var{obj} argument must support the
888+
single-segment readable buffer interface. On success, returns
889+
\code{1}, sets \var{buffer} to the memory location and \var{buffer}
890+
to the buffer length. Returns \code{0} and sets a
891+
\exception{TypeError} on error.
892+
\end{cfuncdesc}
893+
894+
\begin{cfuncdesc}{int}{PyObject_CheckReadBuffer}{PyObject *o}
895+
Returns \code{1} if \var{o} supports the single-segment readable
896+
buffer interface. Otherwise returns \code{0}.
897+
\enc{cfuncdesc}
898+
899+
\begin{cfuncdesc}{int}{PyObject_AsWriteBuffer}{PyObject *obj,
900+
const char **buffer,
901+
int *buffer_len}
902+
Returns a pointer to a writeable memory location. The \var{obj}
903+
argument must support the single-segment, character buffer
904+
interface. On success, returns \code{1}, sets \var{buffer} to the
905+
memory location and \var{buffer} to the buffer length. Returns
906+
\code{0} and sets a \exception{TypeError} on error.
907+
\end{cfuncdesc}
908+
870909
\end{verbatim}

Include/abstract.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,15 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
468468
469469
*/
470470

471+
DL_IMPORT(int) PyObject_CheckReadBuffer(PyObject *obj);
472+
473+
/*
474+
Checks whether an arbitrary object supports the (character,
475+
single segment) buffer interface. Returns 1 on success, 0
476+
on failure.
477+
478+
*/
479+
471480
DL_IMPORT(int) PyObject_AsReadBuffer(PyObject *obj,
472481
const void **buffer,
473482
int *buffer_len);

Objects/abstract.c

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -182,27 +182,37 @@ int PyObject_AsCharBuffer(PyObject *obj,
182182
return -1;
183183
}
184184
pb = obj->ob_type->tp_as_buffer;
185-
if ( pb == NULL ||
185+
if (pb == NULL ||
186186
pb->bf_getcharbuffer == NULL ||
187-
pb->bf_getsegcount == NULL ) {
187+
pb->bf_getsegcount == NULL) {
188188
PyErr_SetString(PyExc_TypeError,
189189
"expected a character buffer object");
190-
goto onError;
190+
return -1;
191191
}
192-
if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) {
192+
if ((*pb->bf_getsegcount)(obj,NULL) != 1) {
193193
PyErr_SetString(PyExc_TypeError,
194194
"expected a single-segment buffer object");
195-
goto onError;
195+
return -1;
196196
}
197-
len = (*pb->bf_getcharbuffer)(obj,0,&pp);
197+
len = (*pb->bf_getcharbuffer)(obj, 0, &pp);
198198
if (len < 0)
199-
goto onError;
199+
return -1;
200200
*buffer = pp;
201201
*buffer_len = len;
202202
return 0;
203+
}
203204

204-
onError:
205-
return -1;
205+
int
206+
PyObject_CheckReadBuffer(PyObject *obj)
207+
{
208+
PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
209+
210+
if (pb == NULL ||
211+
pb->bf_getreadbuffer == NULL ||
212+
pb->bf_getsegcount == NULL ||
213+
(*pb->bf_getsegcount)(obj, NULL) != 1)
214+
return 0;
215+
return 1;
206216
}
207217

208218
int PyObject_AsReadBuffer(PyObject *obj,
@@ -218,27 +228,24 @@ int PyObject_AsReadBuffer(PyObject *obj,
218228
return -1;
219229
}
220230
pb = obj->ob_type->tp_as_buffer;
221-
if ( pb == NULL ||
231+
if (pb == NULL ||
222232
pb->bf_getreadbuffer == NULL ||
223-
pb->bf_getsegcount == NULL ) {
233+
pb->bf_getsegcount == NULL) {
224234
PyErr_SetString(PyExc_TypeError,
225235
"expected a readable buffer object");
226-
goto onError;
236+
return -1;
227237
}
228-
if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) {
238+
if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
229239
PyErr_SetString(PyExc_TypeError,
230240
"expected a single-segment buffer object");
231-
goto onError;
241+
return -1;
232242
}
233-
len = (*pb->bf_getreadbuffer)(obj,0,&pp);
243+
len = (*pb->bf_getreadbuffer)(obj, 0, &pp);
234244
if (len < 0)
235-
goto onError;
245+
return -1;
236246
*buffer = pp;
237247
*buffer_len = len;
238248
return 0;
239-
240-
onError:
241-
return -1;
242249
}
243250

244251
int PyObject_AsWriteBuffer(PyObject *obj,
@@ -254,27 +261,24 @@ int PyObject_AsWriteBuffer(PyObject *obj,
254261
return -1;
255262
}
256263
pb = obj->ob_type->tp_as_buffer;
257-
if ( pb == NULL ||
264+
if (pb == NULL ||
258265
pb->bf_getwritebuffer == NULL ||
259-
pb->bf_getsegcount == NULL ) {
266+
pb->bf_getsegcount == NULL) {
260267
PyErr_SetString(PyExc_TypeError,
261268
"expected a writeable buffer object");
262-
goto onError;
269+
return -1;
263270
}
264-
if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) {
271+
if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
265272
PyErr_SetString(PyExc_TypeError,
266273
"expected a single-segment buffer object");
267-
goto onError;
274+
return -1;
268275
}
269276
len = (*pb->bf_getwritebuffer)(obj,0,&pp);
270277
if (len < 0)
271-
goto onError;
278+
return -1;
272279
*buffer = pp;
273280
*buffer_len = len;
274281
return 0;
275-
276-
onError:
277-
return -1;
278282
}
279283

280284
/* Operations on numbers */
@@ -1980,7 +1984,8 @@ PyObject_GetIter(PyObject *o)
19801984
if (f == NULL) {
19811985
if (PySequence_Check(o))
19821986
return PySeqIter_New(o);
1983-
PyErr_SetString(PyExc_TypeError, "iteration over non-sequence");
1987+
PyErr_SetString(PyExc_TypeError,
1988+
"iteration over non-sequence");
19841989
return NULL;
19851990
}
19861991
else {
@@ -2021,3 +2026,4 @@ PyIter_Next(PyObject *iter)
20212026
PyErr_Clear();
20222027
return result;
20232028
}
2029+

0 commit comments

Comments
 (0)