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.
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 @@
 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 @@
 
        */
 
+     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 @@
 		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 @@
 		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 @@
 		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 @@
 	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 @@
 		PyErr_Clear();
 	return result;
 }
+