[Python-3000-checkins] r56792 - in python/branches/py3k-buffer: Include/bytesobject.h Include/object.h Modules/arraymodule.c Objects/abstract.c Objects/bufferobject.c Objects/bytesobject.c Objects/stringobject.c Objects/unicodeobject.c

travis.oliphant python-3000-checkins at python.org
Tue Aug 7 07:43:49 CEST 2007


Author: travis.oliphant
Date: Tue Aug  7 07:43:49 2007
New Revision: 56792

Modified:
   python/branches/py3k-buffer/Include/bytesobject.h
   python/branches/py3k-buffer/Include/object.h
   python/branches/py3k-buffer/Modules/arraymodule.c
   python/branches/py3k-buffer/Objects/abstract.c
   python/branches/py3k-buffer/Objects/bufferobject.c
   python/branches/py3k-buffer/Objects/bytesobject.c
   python/branches/py3k-buffer/Objects/stringobject.c
   python/branches/py3k-buffer/Objects/unicodeobject.c
Log:
Update more objects to use new buffer interface.

Modified: python/branches/py3k-buffer/Include/bytesobject.h
==============================================================================
--- python/branches/py3k-buffer/Include/bytesobject.h	(original)
+++ python/branches/py3k-buffer/Include/bytesobject.h	Tue Aug  7 07:43:49 2007
@@ -21,6 +21,7 @@
 /* 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;

Modified: python/branches/py3k-buffer/Include/object.h
==============================================================================
--- python/branches/py3k-buffer/Include/object.h	(original)
+++ python/branches/py3k-buffer/Include/object.h	Tue Aug  7 07:43:49 2007
@@ -156,7 +156,7 @@
 } PyBuffer;
 
 typedef int (*getbufferproc)(PyObject *, PyBuffer *, int);
-typedef int (*releasebufferproc)(PyObject *, PyBuffer *);
+typedef void (*releasebufferproc)(PyObject *, PyBuffer *);
 
         /* Flags for getting buffers */
 #define PyBUF_SIMPLE 0
@@ -265,6 +265,7 @@
 typedef struct {
      getbufferproc bf_getbuffer;
      releasebufferproc bf_releasebuffer;
+     inquiry bf_multisegment;
 } PyBufferProcs;
 
 typedef void (*freefunc)(void *);

Modified: python/branches/py3k-buffer/Modules/arraymodule.c
==============================================================================
--- python/branches/py3k-buffer/Modules/arraymodule.c	(original)
+++ python/branches/py3k-buffer/Modules/arraymodule.c	Tue Aug  7 07:43:49 2007
@@ -26,6 +26,7 @@
 	int itemsize;
 	PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
 	int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
+        const char *formats;
 };
 
 typedef struct arrayobject {
@@ -34,10 +35,19 @@
 	Py_ssize_t allocated;
 	struct arraydescr *ob_descr;
 	PyObject *weakreflist; /* List of weak references */
+        int ob_exports;  /* Number of exported buffers */
 } arrayobject;
 
 static PyTypeObject Arraytype;
 
+#ifdef Py_UNICODE_WIDE
+#define PyArr_UNI 'w'
+static const char *PyArr_UNISTR = "w";
+#else
+#define PyArr_UNI 'u'
+static const char *PyArr_UNISTR = "u";
+#endif
+
 #define array_Check(op) PyObject_TypeCheck(op, &Arraytype)
 #define array_CheckExact(op) (Py_Type(op) == &Arraytype)
 
@@ -59,6 +69,12 @@
 		return 0;
 	}
 
+        if (self->ob_exports > 0) {
+                PyErr_SetString(PyExc_BufferError, 
+                                "cannot resize an array that is exporting data");
+                return -1;
+        }
+
 	/* This over-allocates proportional to the array size, making room
 	 * for additional growth.  The over-allocation is mild, but is
 	 * enough to give linear-time amortized behavior over a long
@@ -370,11 +386,12 @@
 	return 0;
 }
 
+
 /* Description of types */
 static struct arraydescr descriptors[] = {
 	{'b', sizeof(char), b_getitem, b_setitem},
 	{'B', sizeof(char), BB_getitem, BB_setitem},
-	{'u', sizeof(Py_UNICODE), u_getitem, u_setitem},
+	{PyArr_UNI, sizeof(Py_UNICODE), u_getitem, u_setitem},
 	{'h', sizeof(short), h_getitem, h_setitem},
 	{'H', sizeof(short), HH_getitem, HH_setitem},
 	{'i', sizeof(int), i_getitem, i_setitem},
@@ -424,6 +441,7 @@
 	op->ob_descr = descr;
 	op->allocated = size;
 	op->weakreflist = NULL;
+        op->ob_exports = 0;
 	return (PyObject *) op;
 }
 
@@ -1402,10 +1420,10 @@
 
         if (!PyArg_ParseTuple(args, "u#:fromunicode", &ustr, &n))
 		return NULL;
-	if (self->ob_descr->typecode != 'u') {
+	if (self->ob_descr->typecode != PyARR_UNI) {
 		PyErr_SetString(PyExc_ValueError,
 			"fromunicode() may only be called on "
-			"type 'u' arrays");
+			"unicode type arrays");
 		return NULL;
 	}
 	if (n > 0) {
@@ -1430,7 +1448,7 @@
 "fromunicode(ustr)\n\
 \n\
 Extends this array with data from the unicode string ustr.\n\
-The array must be a type 'u' array; otherwise a ValueError\n\
+The array must be a unicode type array; otherwise a ValueError\n\
 is raised.  Use array.fromstring(ustr.decode(...)) to\n\
 append Unicode data to an array of some other type.");
 
@@ -1438,9 +1456,9 @@
 static PyObject *
 array_tounicode(arrayobject *self, PyObject *unused)
 {
-	if (self->ob_descr->typecode != 'u') {
+	if (self->ob_descr->typecode != PyArr_UNI) {
 		PyErr_SetString(PyExc_ValueError,
-			"tounicode() may only be called on type 'u' arrays");
+			"tounicode() may only be called on unicode type arrays");
 		return NULL;
 	}
 	return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, Py_Size(self));
@@ -1450,7 +1468,7 @@
 "tounicode() -> unicode\n\
 \n\
 Convert the array to a unicode string.  The array must be\n\
-a type 'u' array; otherwise a ValueError is raised.  Use\n\
+a unicode type array; otherwise a ValueError is raised.  Use\n\
 array.tostring().decode() to obtain a unicode string from\n\
 an array of some other type.");
 
@@ -1541,7 +1559,7 @@
 	if (len == 0) {
 		return PyUnicode_FromFormat("array('%c')", typecode);
 	}
-        if (typecode == 'u')
+        if (typecode == PyArr_UNI)
 		v = array_tounicode(a, NULL);
 	else
 		v = array_tolist(a, NULL);
@@ -1719,40 +1737,46 @@
 
 static const void *emptybuf = "";
 
-static Py_ssize_t
-array_buffer_getreadbuf(arrayobject *self, Py_ssize_t index, const void **ptr)
-{
-	if ( index != 0 ) {
-		PyErr_SetString(PyExc_SystemError,
-				"Accessing non-existent array segment");
-		return -1;
-	}
-	*ptr = (void *)self->ob_item;
-	if (*ptr == NULL)
-		*ptr = emptybuf;
-	return Py_Size(self)*self->ob_descr->itemsize;
-}
-
-static Py_ssize_t
-array_buffer_getwritebuf(arrayobject *self, Py_ssize_t index, const void **ptr)
+static int
+array_buffer_getbuf(arrayobject *self, PyBuffer *view, int flags)
 {
-	if ( index != 0 ) {
-		PyErr_SetString(PyExc_SystemError,
-				"Accessing non-existent array segment");
-		return -1;
-	}
-	*ptr = (void *)self->ob_item;
-	if (*ptr == NULL)
-		*ptr = emptybuf;
-	return Py_Size(self)*self->ob_descr->itemsize;
+        if ((flags & PyBUF_REQ_LOCKDATA)) {
+                PyErr_SetString(PyExc_BufferError,
+                                "Cannot lock data");
+                return -1;
+        }
+        view->buf = (void *)self->ob_item;
+        view->len = Py_Size(self)*self->ob_descr->itemsize;
+        view->readonly = 0;
+        view->ndim = 1;
+        view->itemsize = self->ob_descr->itemsize;
+        view->suboffsets = NULL;
+        view->internal = NULL;
+        if ((flags & PyBUF_ALW_ND)==PyBUF_ALW_ND) {
+                view->shape = &(Py_Size(self));
+        }
+        else 
+                view->shape = NULL;
+        if ((flags & PyBUF_ALW_STRIDES)==PyBUF_ALW_STRIDES)
+                view->strides = &(view->itemsize);
+        else
+                view->strides = NULL;               
+        if ((flags & PyBUF_REQ_FORMAT) == PyBUF_REQ_FORMAT) {
+                view->format = malloc(2);
+                view->format[0] = (char)self->ob_descr->typecode;
+                view->format[1] = '\0';
+        }
+        else 
+                view->format = NULL;
+        self->ob_exports++;
+        return 0;
 }
 
-static Py_ssize_t
-array_buffer_getsegcount(arrayobject *self, Py_ssize_t *lenp)
+static int
+array_buffer_relbuf(arrayobject *self, PyBuffer *view)
 {
-	if ( lenp )
-		*lenp = Py_Size(self)*self->ob_descr->itemsize;
-	return 1;
+        free(view->format);
+        self->ob_exports--;
 }
 
 static PySequenceMethods array_as_sequence = {
@@ -1769,10 +1793,8 @@
 };
 
 static PyBufferProcs array_as_buffer = {
-	(readbufferproc)array_buffer_getreadbuf,
-	(writebufferproc)array_buffer_getwritebuf,
-	(segcountproc)array_buffer_getsegcount,
-	NULL,
+        (getbufferproc)array_buffer_getbuf,
+        (releasebufferproc)array_buffer_relbuf
 };
 
 static PyObject *
@@ -1791,7 +1813,7 @@
 	if (!(initial == NULL || PyList_Check(initial)
 	      || PyBytes_Check(initial)
 	      || PyString_Check(initial) || PyTuple_Check(initial)
-	      || (c == 'u' && PyUnicode_Check(initial)))) {
+	      || (c == PyArr_UNI && PyUnicode_Check(initial)))) {
 		it = PyObject_GetIter(initial);
 		if (it == NULL)
 			return NULL;
@@ -1899,6 +1921,7 @@
     'H'         unsigned integer   2 \n\
     'i'         signed integer     2 \n\
     'I'         unsigned integer   2 \n\
+    'w'         unicode character  4
     'l'         signed integer     4 \n\
     'L'         unsigned integer   4 \n\
     'f'         floating point     4 \n\

Modified: python/branches/py3k-buffer/Objects/abstract.c
==============================================================================
--- python/branches/py3k-buffer/Objects/abstract.c	(original)
+++ python/branches/py3k-buffer/Objects/abstract.c	Tue Aug  7 07:43:49 2007
@@ -217,8 +217,8 @@
 
 int
 PyObject_AsCharBuffer(PyObject *obj,
-			  const char **buffer,
-			  Py_ssize_t *buffer_len)
+                      const char **buffer,
+                      Py_ssize_t *buffer_len)
 {
 	PyBufferProcs *pb;
 	char *pp;
@@ -230,7 +230,7 @@
 		return -1;
 	}
 	pb = obj->ob_type->tp_as_buffer;
-	if (pb == NULL || pb->bf_getbuffer == NULL) {
+	if (pb == NULL || pb->bf_getbuffer == NULL)
 		PyErr_SetString(PyExc_TypeError,
 				"expected an object with the buffer interface");
 		return -1;
@@ -340,14 +340,13 @@
          return (*(obj->tp_as_buffer->bf_getbuffer))(obj, view, flags);
 }
 
-int 
+void
 PyObject_ReleaseBuffer(PyObject *obj, PyBuffer *view)
 {
         if (obj->tp_as_buffer != NULL && 
             obj->tp_as_buffer->bf_releasebuffer != NULL) {
-                return (*(obj->tp_as_buffer->bf_releasebuffer))(obj, view);
+                (*(obj->tp_as_buffer->bf_releasebuffer))(obj, view);
         }
-        return 0;            
 }
 
 
@@ -608,7 +607,7 @@
                         return -1;
                 }                 
         }
-        if (PyObject_ReleaseBuffer(obj, &view) < 0) return -1;
+        PyObject_ReleaseBuffer(obj, &view);
         return 1;
 }
 
@@ -642,7 +641,8 @@
         if (PyBuffer_IsContiguous(&view, fort)) {
                 /* simplest copy is all that is needed */
                 memcpy(view.buf, buf, len);
-                return PyObject_ReleaseBuffer(obj, &view);
+                PyObject_ReleaseBuffer(obj, &view);
+                return 0;
         }
 
         /* Otherwise a more elaborate scheme is needed */
@@ -676,7 +676,8 @@
         }
                 
         PyMem_Free(indices);
-        return PyObject_ReleaseBuffer(obj, &view);
+        PyObject_ReleaseBuffer(obj, &view);
+        return 0;
 }
 
 
@@ -719,9 +720,8 @@
              PyBuffer_IsContiguous(&src_dest, 'F'))) {
                 /* simplest copy is all that is needed */
                 memcpy(view_dest.buf, view_src.buf, view_src.len);
-                if (PyObject_ReleaseBuffer(dest, &view_dest) < 0 ||
-                    PyObject_ReleaseBuffer(src, &view_src) < 0)
-                        return -1;
+                PyObject_ReleaseBuffer(dest, &view_dest);
+                PyObject_ReleaseBuffer(src, &view_src);
                 return 0;
         }
 
@@ -750,9 +750,8 @@
                 src += itemsize;
         }                
         PyMem_Free(indices);
-        if (PyObject_ReleaseBuffer(dest, &view_dest) < 0 || 
-            PyObject_ReleaseBuffer(src, &view_src) < 0)
-                return -1;
+        PyObject_ReleaseBuffer(dest, &view_dest);
+        PyObject_ReleaseBuffer(src, &view_src);
         return 0;
 }
 

Modified: python/branches/py3k-buffer/Objects/bufferobject.c
==============================================================================
--- python/branches/py3k-buffer/Objects/bufferobject.c	(original)
+++ python/branches/py3k-buffer/Objects/bufferobject.c	Tue Aug  7 07:43:49 2007
@@ -15,80 +15,58 @@
 } PyBufferObject;
 
 
-enum buffer_t {
-    READ_BUFFER,
-    WRITE_BUFFER,
-    CHAR_BUFFER,
-    ANY_BUFFER
-};
-
 static int
-get_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size,
-	enum buffer_t buffer_type)
+get_buf(PyBufferObject *self, PyBuffer *view)
 {
 	if (self->b_base == NULL) {
-		assert (ptr != NULL);
-		*ptr = self->b_ptr;
-		*size = self->b_size;
+		view->buf = self->b_ptr;
+		view->len = self->b_size;
 	}
 	else {
 		Py_ssize_t count, offset;
-		readbufferproc proc = 0;
 		PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
-		if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
-			PyErr_SetString(PyExc_TypeError,
-				"single-segment buffer object expected");
-			return 0;
-		}
-		if ((buffer_type == READ_BUFFER) ||
-			((buffer_type == ANY_BUFFER) && self->b_readonly))
-		    proc = bp->bf_getreadbuffer;
-		else if ((buffer_type == WRITE_BUFFER) ||
-			(buffer_type == ANY_BUFFER))
-    		    proc = (readbufferproc)bp->bf_getwritebuffer;
-		else if (buffer_type == CHAR_BUFFER) {
-		    proc = (readbufferproc)bp->bf_getcharbuffer;
-		}
-		if (!proc) {
-		    char *buffer_type_name;
-		    switch (buffer_type) {
-			case READ_BUFFER:
-			    buffer_type_name = "read";
-			    break;
-			case WRITE_BUFFER:
-			    buffer_type_name = "write";
-			    break;
-			case CHAR_BUFFER:
-			    buffer_type_name = "char";
-			    break;
-			default:
-			    buffer_type_name = "no";
-			    break;
-		    }
-		    PyErr_Format(PyExc_TypeError,
-			    "%s buffer type not available",
-			    buffer_type_name);
-		    return 0;
-		}
-		if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
-			return 0;
+                PyBuffer view;
+                if ((*bp->bf_getbuffer)(self->b_base, view, PyBUF_SIMPLE) < 0) return 0;
+                count = view->len;
 		/* apply constraints to the start/end */
 		if (self->b_offset > count)
 			offset = count;
 		else
 			offset = self->b_offset;
-		*(char **)ptr = *(char **)ptr + offset;
+                view->buf = (char*)view->buf + offset;
 		if (self->b_size == Py_END_OF_BUFFER)
-			*size = count;
+			view->len = count;
 		else
-			*size = self->b_size;
-		if (offset + *size > count)
-			*size = count - offset;
+			view->len = self->b_size;
+		if (offset + view->len > count)
+			view->len = count - offset;
 	}
 	return 1;
 }
 
 
+static int
+buffer_getbuf(PyBufferObject *self, PyBuffer *view, int flags)
+{
+        if (!get_buf(self, view))
+                return -1;
+        return PyBuffer_FillInfo(view, view.buf, view.len, view.readonly, flags);
+}
+
+
+static int
+buffer_releasebuf(PyBufferObject *self, PyBuffer *view) 
+{
+        /* No-op if there is no self->b_base */
+	if (self->b_base != NULL) {
+		PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
+                if (bp->releasebuffer != NULL) {
+                        return (*bp->releasebuffer)(self->b_base, view);
+                }
+        }
+        return 0;
+}
+
 static PyObject *
 buffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr,
 		   int readonly)
@@ -248,12 +226,12 @@
 }
 
 static int
-get_bufx(PyObject *obj, void **ptr, Py_ssize_t *size)
+get_bufx(PyObject *obj, PyBuffer *view)
 {
 	PyBufferProcs *bp;
 
 	if (PyBuffer_Check(obj)) {
-		if (!get_buf((PyBufferObject *)obj, ptr, size, ANY_BUFFER)) {
+		if (!get_buf((PyBufferObject *)obj, view)) {
 			PyErr_Clear();
 			return 0;
 		}
@@ -262,17 +240,11 @@
 	}
 	bp = obj->ob_type->tp_as_buffer;
 	if (bp == NULL ||
-	    bp->bf_getreadbuffer == NULL ||
-	    bp->bf_getsegcount == NULL)
-		return 0;
-	if ((*bp->bf_getsegcount)(obj, NULL) != 1)
+	    bp->bf_getbuffer == NULL)
 		return 0;
-	*size = (*bp->bf_getreadbuffer)(obj, 0, ptr);
-	if (*size < 0) {
-		PyErr_Clear();
+	if ((*bp->bf_getbuffer)(obj, view, PyBUF_SIMPLE) < 0)
 		return 0;
-	}
-	return 1;
+        return 1;
 }
 
 static PyObject *
@@ -281,12 +253,15 @@
 	void *p1, *p2;
 	Py_ssize_t len1, len2, min_len;
 	int cmp, ok;
+        PyBuffer v1, v2;
 
 	ok = 1;
-	if (!get_bufx(self, &p1, &len1))
+	if (!get_bufx(self, &v1))
 		ok = 0;
-	if (!get_bufx(other, &p2, &len2))
+	if (!get_bufx(other, &v2)) {
+                if (ok) PyObject_ReleaseBuffer(self, v1);
 		ok = 0;
+        }
 	if (!ok) {
 		/* If we can't get the buffers,
 		   == and != are still defined
@@ -301,11 +276,17 @@
 		Py_INCREF(result);
 		return result;
 	}
+        len1 = v1.len;
+        len2 = v2.len;
+        p1 = v1.buf;
+        p2 = v2.buf;
 	min_len = (len1 < len2) ? len1 : len2;
 	cmp = memcmp(p1, p2, min_len);
 	if (cmp == 0)
 		cmp = (len1 < len2) ? -1 :
 		      (len1 > len2) ? 1 : 0;
+        PyObject_ReleaseBuffer(self, v1);
+        PyObject_ReleaseBuffer(other, v2);
 	return Py_CmpToRich(op, cmp);
 }
 
@@ -335,6 +316,7 @@
 {
 	void *ptr;
 	Py_ssize_t size;
+        PyBuffer view;
 	register Py_ssize_t len;
 	register unsigned char *p;
 	register long x;
@@ -350,34 +332,40 @@
 	 * be to call tp_hash on the underlying object and see if it raises
 	 * an error. */
 	if ( !self->b_readonly )
-	{
-		PyErr_SetString(PyExc_TypeError,
-				"writable buffers are not hashable");
-		return -1;
-	}
 
-	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+	if (!get_buf(self, &view))
+		return -1;
+        if (!(view.readonly)) {
+                PyErr_SetString(PyExc_TypeError,
+                                "writable buffers are not hashable");
+                PyObject_ReleaseBuffer(self, view);
 		return -1;
-	p = (unsigned char *) ptr;
-	len = size;
+	}
+                
+	p = (unsigned char *) view.buf;
+	len = view.len;
 	x = *p << 7;
 	while (--len >= 0)
 		x = (1000003*x) ^ *p++;
-	x ^= size;
+	x ^= view.len;
 	if (x == -1)
 		x = -2;
 	self->b_hash = x;
+        PyObject_ReleaseBuffer(self, view);
 	return x;
 }
 
 static PyObject *
 buffer_str(PyBufferObject *self)
 {
-	void *ptr;
-	Py_ssize_t size;
-	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+        PyBuffer view;
+        PyObject *res;
+
+	if (!get_buf(self, &view))
 		return NULL;
-	return PyString_FromStringAndSize((const char *)ptr, size);
+	res = PyString_FromStringAndSize((const char *)view.buf, view.len);
+        PyObject_ReleaseBuffer(self, view);
+        return res;
 }
 
 /* Sequence methods */
@@ -385,71 +373,58 @@
 static Py_ssize_t
 buffer_length(PyBufferObject *self)
 {
-	void *ptr;
-	Py_ssize_t size;
-	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+        PyBuffer view;
+
+	if (!get_buf(self, &view))
 		return -1;
-	return size;
+        PyObject_ReleaseBuffer(self, view);
+	return view.len;
 }
 
 static PyObject *
 buffer_concat(PyBufferObject *self, PyObject *other)
 {
 	PyBufferProcs *pb = other->ob_type->tp_as_buffer;
-	void *ptr1, *ptr2;
 	char *p;
-	PyObject *ob;
-	Py_ssize_t size, count;
+	PyObject *ob, *ret=NULL;
+        PyBuffer view, view2;
 
 	if ( pb == NULL ||
-	     pb->bf_getreadbuffer == NULL ||
-	     pb->bf_getsegcount == NULL )
+	     pb->bf_getbuffer == NULL)
 	{
 		PyErr_BadArgument();
 		return NULL;
 	}
-	if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
-	{
-		/* ### use a different exception type/message? */
-		PyErr_SetString(PyExc_TypeError,
-				"single-segment buffer object expected");
-		return NULL;
-	}
 
- 	if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+ 	if (!get_buf(self, &view))
  		return NULL;
  
 	/* optimize special case */
         /* XXX bad idea type-wise */
-	if ( size == 0 )
-	{
-	    Py_INCREF(other);
-	    return other;
-	}
-
-        if (PyUnicode_Check(other)) {
-		/* XXX HACK */
-		if ( (count = (*pb->bf_getcharbuffer)(other, 0,
-                                                      (char **)&ptr2)) < 0 )
-			return NULL;
-	}
-	else {
-		if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
-			return NULL;
-	}
-
-        /* XXX Should return a bytes object, really */
- 	ob = PyString_FromStringAndSize(NULL, size + count);
-	if ( ob == NULL )
-		return NULL;
- 	p = PyString_AS_STRING(ob);
- 	memcpy(p, ptr1, size);
- 	memcpy(p + size, ptr2, count);
-
-	/* there is an extra byte in the string object, so this is safe */
-	p[size + count] = '\0';
-
-	return ob;
+	if ( view.len == 0 ) {
+                PyObject_ReleaseBuffer(self, view);
+                Py_INCREF(other);
+                return other;
+	}
+
+        if (PyObject_GetBuffer(self, view2, PyBUF_SIMPLE) < 0) {
+                PyObject_ReleaseBuffer(self, view);
+                return NULL;
+        }
+
+ 	ob = PyBytes_FromStringAndSize(NULL, view.len+view2.len);
+	if ( ob == NULL ) {
+                PyObject_ReleaseBuffer(self, view);
+                PyObject_ReleaseBuffer(other, view2);
+		return NULL;
+        }
+ 	p = PyBytes_AS_STRING(ob);
+ 	memcpy(p, view.buf, view.len);
+ 	memcpy(p + view.len, view2.buf, view2.len);
+
+        PyObject_ReleaseBuffer(self, view);
+        PyObject_ReleaseBuffer(other, view2);
+        return ob;
 }
 
 static PyObject *
@@ -459,48 +434,49 @@
 	register char *p;
 	void *ptr;
 	Py_ssize_t size;
+        PyBuffer view;
 
 	if ( count < 0 )
 		count = 0;
-	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+	if (!get_buf(self, &view))
 		return NULL;
-	ob = PyString_FromStringAndSize(NULL, size * count);
+	ob = PyBytes_FromStringAndSize(NULL, view.len * count);
 	if ( ob == NULL )
 		return NULL;
 
-	p = PyString_AS_STRING(ob);
+	p = PyBytes_AS_STRING(ob);
 	while ( count-- )
 	{
-	    memcpy(p, ptr, size);
-	    p += size;
+	    memcpy(p, view.buf, view.len);
+	    p += view.len;
 	}
 
-	/* there is an extra byte in the string object, so this is safe */
-	*p = '\0';
-
+        PyObject_ReleaseBuffer(self, view);
 	return ob;
 }
 
 static PyObject *
 buffer_item(PyBufferObject *self, Py_ssize_t idx)
 {
-	void *ptr;
-	Py_ssize_t size;
-	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+        PyBuffer view;
+        PyObject *ob;
+
+	if (!get_buf(self, &view))
 		return NULL;
-	if ( idx < 0 || idx >= size ) {
+	if ( idx < 0 || idx >= view.len ) {
 		PyErr_SetString(PyExc_IndexError, "buffer index out of range");
 		return NULL;
 	}
-	return PyString_FromStringAndSize((char *)ptr + idx, 1);
+	ob = PyBytes_FromStringAndSize((char *)view.buf + idx, 1);
+        PyObject_ReleaseBuffer(self, view);
+        return ob;
 }
 
 static PyObject *
 buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
 {
-	void *ptr;
-	Py_ssize_t size;
-	if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+        PyBuffer view;
+	if (!get_buf(self, &view))
 		return NULL;
 	if ( left < 0 )
 		left = 0;
@@ -510,28 +486,29 @@
 		right = size;
 	if ( right < left )
 		right = left;
-	return PyString_FromStringAndSize((char *)ptr + left,
-					  right - left);
+	ob = PyBytes_FromStringAndSize((char *)view.buf + left,
+                                       right - left);
+        PyObject_ReleaseBuffer(self, view);
+        return ob;
 }
 
 static int
 buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
 {
 	PyBufferProcs *pb;
-	void *ptr1, *ptr2;
-	Py_ssize_t size;
-	Py_ssize_t count;
+        PyBuffer view, view2;
 
-	if ( self->b_readonly ) {
+	if (!get_buf(self, &view))
+		return -1;
+        
+	if ( self->b_readonly || view.readonly ) {
 		PyErr_SetString(PyExc_TypeError,
 				"buffer is read-only");
+                PyObject_ReleaseBuffer(self, view);
 		return -1;
 	}
 
-	if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
-		return -1;
-
-	if (idx < 0 || idx >= size) {
+	if (idx < 0 || idx >= view.len) {
 		PyErr_SetString(PyExc_IndexError,
 				"buffer assignment index out of range");
 		return -1;
@@ -539,29 +516,27 @@
 
 	pb = other ? other->ob_type->tp_as_buffer : NULL;
 	if ( pb == NULL ||
-	     pb->bf_getreadbuffer == NULL ||
-	     pb->bf_getsegcount == NULL )
-	{
+	     pb->bf_getbuffer == NULL) {
 		PyErr_BadArgument();
+                PyObject_ReleaseBuffer(self, view);
 		return -1;
 	}
-	if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
-	{
-		/* ### use a different exception type/message? */
-		PyErr_SetString(PyExc_TypeError,
-				"single-segment buffer object expected");
-		return -1;
-	}
-
-	if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
-		return -1;
-	if ( count != 1 ) {
+        
+        if (PyObject_GetBuffer(other, &view2, PyBUF_SIMPLE) < 0) {
+                PyObject_ReleaseBuffer(self, view);
+                return -1;
+        }
+	if ( view.len != 1 ) {
+                PyObject_ReleaseBuffer(self, view);
+                PyObject_ReleaseBuffer(other, view2);
 		PyErr_SetString(PyExc_TypeError,
 				"right operand must be a single byte");
 		return -1;
 	}
 
-	((char *)ptr1)[idx] = *(char *)ptr2;
+	((char *)(view.buf))[idx] = *((char *)(view2.buf));
+        PyObject_ReleaseBuffer(self, view);
+        PyObject_ReleaseBuffer(other, view2);
 	return 0;
 }
 
@@ -569,36 +544,30 @@
 buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
 {
 	PyBufferProcs *pb;
-	void *ptr1, *ptr2;
-	Py_ssize_t size;
+        PyBuffer v1, v2;
 	Py_ssize_t slice_len;
-	Py_ssize_t count;
-
-	if ( self->b_readonly ) {
-		PyErr_SetString(PyExc_TypeError,
-				"buffer is read-only");
-		return -1;
-	}
 
 	pb = other ? other->ob_type->tp_as_buffer : NULL;
 	if ( pb == NULL ||
-	     pb->bf_getreadbuffer == NULL ||
-	     pb->bf_getsegcount == NULL )
+	     pb->bf_getbuffer == NULL)
 	{
 		PyErr_BadArgument();
 		return -1;
 	}
-	if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
-	{
-		/* ### use a different exception type/message? */
+	if (!get_buf(self, &v1))
+                return -1;
+
+	if ( self->b_readonly || v1.readonly) {
 		PyErr_SetString(PyExc_TypeError,
-				"single-segment buffer object expected");
+				"buffer is read-only");
+                PyObject_ReleaseBuffer(self, v1);
 		return -1;
 	}
-	if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
-		return -1;
-	if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
-		return -1;
+
+        if ((*pb->bf_getbuffer)(other, &v2, PyBUF_SIMPLE) < 0) {
+                PyObject_ReleaseBuffer(self, v1);
+                return -1;
+        }
 
 	if ( left < 0 )
 		left = 0;
@@ -610,7 +579,7 @@
 		right = size;
 	slice_len = right - left;
 
-	if ( count != slice_len ) {
+	if ( v2.len != slice_len ) {
 		PyErr_SetString(
 			PyExc_TypeError,
 			"right operand length must match slice length");
@@ -618,8 +587,10 @@
 	}
 
 	if ( slice_len )
-	    memcpy((char *)ptr1 + left, ptr2, slice_len);
+	    memcpy((char *)v1.buf + left, v2.buf, slice_len);
 
+        PyObject_ReleaseBuffer(self, v1);        
+        PyObject_ReleaseBuffer(other, v2);        
 	return 0;
 }
 

Modified: python/branches/py3k-buffer/Objects/bytesobject.c
==============================================================================
--- python/branches/py3k-buffer/Objects/bytesobject.c	(original)
+++ python/branches/py3k-buffer/Objects/bytesobject.c	Tue Aug  7 07:43:49 2007
@@ -26,6 +26,7 @@
         return 0;
     nullbytes->ob_bytes = NULL;
     Py_Size(nullbytes) = nullbytes->ob_alloc = 0;
+    nullbytes->ob_exports = 0;
     return 1;
 }
 
@@ -48,22 +49,33 @@
     return 1;
 }
 
+static int
+bytes_getbuffer(PyBytesObject *obj, PyBuffer *view, int flags)
+{        
+        int ret;
+        ret = PyBuffer_FillInfo(view, obj->ob_bytes, Py_Size(obj), 0, flags);
+        if (ret >= 0) {
+                obj->ob_exports++;
+        }
+        return ret;
+}
+
+static void
+bytes_releasebuffer(PyBytesObject *obj, PyBuffer *view)
+{
+        obj->ob_exports--;
+}
+
 Py_ssize_t
-_getbuffer(PyObject *obj, void **ptr)
+_getbuffer(PyObject *obj, PyBuffer *view)
 {
     PyBufferProcs *buffer = Py_Type(obj)->tp_as_buffer;
 
     if (buffer == NULL ||
         PyUnicode_Check(obj) ||
-        buffer->bf_getreadbuffer == NULL ||
-        buffer->bf_getsegcount == NULL ||
-        buffer->bf_getsegcount(obj, NULL) != 1)
-    {
-        *ptr = NULL;
-        return -1;
-    }
+        buffer->bf_getbuffer == NULL) return -1;
 
-    return buffer->bf_getreadbuffer(obj, 0, ptr);
+    return buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE);
 }
 
 /* Direct API functions */
@@ -104,6 +116,7 @@
     }
     Py_Size(new) = size;
     new->ob_alloc = alloc;
+    new->ob_exports = 0;
 
     return (PyObject *)new;
 }
@@ -155,6 +168,12 @@
         alloc = size + 1;
     }
 
+    if (((PyBytesObject *)self)->ob_exports > 0) {
+            PyErr_SetString(PyExc_BufferError,
+                            "Existing exports of data: object cannot be re-sized");
+            return -1;
+    }
+
     sval = PyMem_Realloc(((PyBytesObject *)self)->ob_bytes, alloc);
     if (sval == NULL) {
         PyErr_NoMemory();
@@ -172,27 +191,38 @@
 PyObject *
 PyBytes_Concat(PyObject *a, PyObject *b)
 {
-    Py_ssize_t asize, bsize, size;
-    void *aptr, *bptr;
+    Py_ssize_t size;
+    PyBuffer va, vb;
     PyBytesObject *result;
 
-    asize = _getbuffer(a, &aptr);
-    bsize = _getbuffer(b, &bptr);
-    if (asize < 0 || bsize < 0) {
-        PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
-                     Py_Type(a)->tp_name, Py_Type(b)->tp_name);
-        return NULL;
+    va.len = -1;
+    vb.len = -1;
+    if (_getbuffer(a, &va) < 0  ||
+        _getbuffer(b, &vb) < 0) {
+            if (va.len != -1) 
+                    PyObject_ReleaseBuffer(a, &va);
+            if (vb.len != -1)
+                    PyObject_ReleaseBuffer(b, &vb);
+            PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
+                         Py_Type(a)->tp_name, Py_Type(b)->tp_name);
+            return NULL;
     }
 
-    size = asize + bsize;
-    if (size < 0)
-        return PyErr_NoMemory();
+    size = va.len + vb.len;
+    if (size < 0) {
+            PyObject_ReleaseBuffer(a, &va);
+            PyObject_ReleaseBuffer(b, &vb);
+            return PyErr_NoMemory();
+    }
 
     result = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, size);
     if (result != NULL) {
-        memcpy(result->ob_bytes, aptr, asize);
-        memcpy(result->ob_bytes + asize, bptr, bsize);
+        memcpy(result->ob_bytes, va.buf, va.len);
+        memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
     }
+    
+    PyObject_ReleaseBuffer(a, &va);
+    PyObject_ReleaseBuffer(b, &vb);
     return (PyObject *)result;
 }
 
@@ -213,30 +243,31 @@
 static PyObject *
 bytes_iconcat(PyBytesObject *self, PyObject *other)
 {
-    void *optr;
-    Py_ssize_t osize;
     Py_ssize_t mysize;
     Py_ssize_t size;
+    PyBuffer vo;
 
-    /* XXX What if other == self? */
-    osize = _getbuffer(other, &optr);
-    if (osize < 0) {
-        PyErr_Format(PyExc_TypeError,
-                     "can't concat bytes to %.100s", Py_Type(other)->tp_name);
-        return NULL;
+    if (_getbuffer(other, &vo) < 0) {
+            PyErr_Format(PyExc_TypeError,
+                         "can't concat bytes to %.100s", Py_Type(self)->tp_name);
+            return NULL;
     }
 
     mysize = Py_Size(self);
-    size = mysize + osize;
-    if (size < 0)
-        return PyErr_NoMemory();
+    size = mysize + vo.len;
+    if (size < 0) {
+            PyObject_ReleaseBuffer(other, &vo);
+            return PyErr_NoMemory();
+    }
     if (size < self->ob_alloc) {
-        Py_Size(self) = size;
-	self->ob_bytes[Py_Size(self)] = '\0'; /* Trailing null byte */
+            Py_Size(self) = size;
+            self->ob_bytes[Py_Size(self)] = '\0'; /* Trailing null byte */
     }
-    else if (PyBytes_Resize((PyObject *)self, size) < 0)
-        return NULL;
-    memcpy(self->ob_bytes + mysize, optr, osize);
+    else if (PyBytes_Resize((PyObject *)self, size) < 0) {
+            PyObject_ReleaseBuffer(other, &vo);
+            return NULL;
+    }
+    memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
     Py_INCREF(self);
     return (PyObject *)self;
 }
@@ -409,9 +440,12 @@
 {
     Py_ssize_t avail, needed;
     void *bytes;
+    PyBuffer vbytes;
+    int res = 0;
 
+    vbytes.len = -1;
     if (values == (PyObject *)self) {
-        /* Make a copy an call this function recursively */
+        /* Make a copy and call this function recursively */
         int err;
         values = PyBytes_FromObject(values);
         if (values == NULL)
@@ -426,13 +460,14 @@
         needed = 0;
     }
     else {
-        needed = _getbuffer(values, &bytes);
-        if (needed < 0) {
-            PyErr_Format(PyExc_TypeError,
-                         "can't set bytes slice from %.100s",
-                         Py_Type(values)->tp_name);
-            return -1;
-        }
+            if (_getbuffer(values, &vbytes) < 0) {
+                    PyErr_Format(PyExc_TypeError,
+                                 "can't set bytes slice from %.100s",
+                                 Py_Type(values)->tp_name);
+                    return -1;
+            }
+            needed = vbytes.len;
+            bytes = vbytes.buf;
     }
 
     if (lo < 0)
@@ -458,8 +493,10 @@
                     Py_Size(self) - hi);
         }
         if (PyBytes_Resize((PyObject *)self,
-                           Py_Size(self) + needed - avail) < 0)
-            return -1;
+                           Py_Size(self) + needed - avail) < 0) {
+                res = -1;
+                goto finish;
+        }
         if (avail < needed) {
             /*
               0   lo        hi               old_size
@@ -475,7 +512,11 @@
     if (needed > 0)
         memcpy(self->ob_bytes + lo, bytes, needed);
 
-    return 0;
+    
+ finish:
+    if (vbytes.len != -1) 
+            PyObject_ReleaseBuffer(values, &vbytes);
+    return res;
 }
 
 static int
@@ -743,7 +784,8 @@
         }
         return 0;
     }
-
+    
+    /* XXX -> Use the modern buffer interface */
     if (PyObject_CheckReadBuffer(arg)) {
         const void *bytes;
         Py_ssize_t size;
@@ -945,8 +987,12 @@
 }
 
 static Py_ssize_t
-bytes_getbuffer(PyBytesObject *self, Py_ssize_t index, const void **ptr)
+bytes_getbuffer(PyBytesObject *self, PyBuffer *view, int flags)
 {
+        PyBuffer_FillInfo(view, ptr,
+        if (self->ob_bytes == NULL) {
+        }
+        
     if (index != 0) {
         PyErr_SetString(PyExc_SystemError,
                         "accessing non-existent bytes segment");
@@ -959,15 +1005,6 @@
     return Py_Size(self);
 }
 
-static Py_ssize_t
-bytes_getsegcount(PyStringObject *self, Py_ssize_t *lenp)
-{
-    if (lenp)
-        *lenp = Py_Size(self);
-    return 1;
-}
-
-
 
 /* -------------------------------------------------------------------- */
 /* Methods */
@@ -1018,6 +1055,7 @@
         sub = PyBytes_AS_STRING(subobj);
         sub_len = PyBytes_GET_SIZE(subobj);
     }
+    /* XXX --> use the modern buffer interface */
     else if (PyObject_AsCharBuffer(subobj, &sub, &sub_len))
         /* XXX - the "expected a character buffer object" is pretty
            confusing for a non-expert.  remap to something else ? */
@@ -1075,6 +1113,7 @@
         sub = PyBytes_AS_STRING(sub_obj);
         sub_len = PyBytes_GET_SIZE(sub_obj);
     }
+    /* XXX --> use the modern buffer interface */
     else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len))
         return NULL;
 
@@ -1162,6 +1201,7 @@
         sub = PyBytes_AS_STRING(substr);
         slen = PyBytes_GET_SIZE(substr);
     }
+    /* XXX --> Use the modern buffer interface */
     else if (PyObject_AsCharBuffer(substr, &sub, &slen))
         return -1;
     str = PyBytes_AS_STRING(self);
@@ -1297,6 +1337,7 @@
         table1 = PyBytes_AS_STRING(tableobj);
         tablen = PyBytes_GET_SIZE(tableobj);
     }
+    /* XXX -> Use the modern buffer interface */
     else if (PyObject_AsCharBuffer(tableobj, &table1, &tablen))
         return NULL;
 
@@ -1311,6 +1352,7 @@
             del_table = PyBytes_AS_STRING(delobj);
             dellen = PyBytes_GET_SIZE(delobj);
         }
+        /* XXX -> use the modern buffer interface */
         else if (PyObject_AsCharBuffer(delobj, &del_table, &dellen))
             return NULL;
     }
@@ -1984,6 +2026,7 @@
         from_s = PyBytes_AS_STRING(from);
         from_len = PyBytes_GET_SIZE(from);
     }
+    /* XXX -> use the modern buffer interface */
     else if (PyObject_AsCharBuffer(from, &from_s, &from_len))
         return NULL;
 
@@ -1991,6 +2034,7 @@
         to_s = PyBytes_AS_STRING(to);
         to_len = PyBytes_GET_SIZE(to);
     }
+    /* XXX -> use the modern buffer interface */
     else if (PyObject_AsCharBuffer(to, &to_s, &to_len))
         return NULL;
 
@@ -2104,6 +2148,7 @@
         sub = PyBytes_AS_STRING(subobj);
         n = PyBytes_GET_SIZE(subobj);
     }
+    /* XXX -> use the modern buffer interface */
     else if (PyObject_AsCharBuffer(subobj, &sub, &n))
         return NULL;
 
@@ -2261,6 +2306,7 @@
         sub = PyBytes_AS_STRING(subobj);
         n = PyBytes_GET_SIZE(subobj);
     }
+    /* XXX -> Use the modern buffer interface */
     else if (PyObject_AsCharBuffer(subobj, &sub, &n))
         return NULL;
 
@@ -2751,12 +2797,8 @@
 };
 
 static PyBufferProcs bytes_as_buffer = {
-    (readbufferproc)bytes_getbuffer,
-    (writebufferproc)bytes_getbuffer,
-    (segcountproc)bytes_getsegcount,
-    /* XXX Bytes are not characters! But we need to implement
-       bf_getcharbuffer() so we can be used as 't#' argument to codecs. */
-    (charbufferproc)bytes_getbuffer,
+    (getbufferproc)bytes_getbuffer,
+    (releasebufferproc)bytes_releasebuffer,
 };
 
 static PyMethodDef

Modified: python/branches/py3k-buffer/Objects/stringobject.c
==============================================================================
--- python/branches/py3k-buffer/Objects/stringobject.c	(original)
+++ python/branches/py3k-buffer/Objects/stringobject.c	Tue Aug  7 07:43:49 2007
@@ -1236,44 +1236,10 @@
 	}
 }
 
-static Py_ssize_t
-string_buffer_getreadbuf(PyStringObject *self, Py_ssize_t index, const void **ptr)
-{
-	if ( index != 0 ) {
-		PyErr_SetString(PyExc_SystemError,
-				"accessing non-existent string segment");
-		return -1;
-	}
-	*ptr = (void *)self->ob_sval;
-	return Py_Size(self);
-}
-
-static Py_ssize_t
-string_buffer_getwritebuf(PyStringObject *self, Py_ssize_t index, const void **ptr)
-{
-	PyErr_SetString(PyExc_TypeError,
-			"Cannot use string as modifiable buffer");
-	return -1;
-}
-
-static Py_ssize_t
-string_buffer_getsegcount(PyStringObject *self, Py_ssize_t *lenp)
-{
-	if ( lenp )
-		*lenp = Py_Size(self);
-	return 1;
-}
-
-static Py_ssize_t
-string_buffer_getcharbuf(PyStringObject *self, Py_ssize_t index, const char **ptr)
+static int
+string_buffer_getbuffer(PyStringObject *self, PyBuffer *view, int flags)
 {
-	if ( index != 0 ) {
-		PyErr_SetString(PyExc_SystemError,
-				"accessing non-existent string segment");
-		return -1;
-	}
-	*ptr = self->ob_sval;
-	return Py_Size(self);
+        return PyBuffer_FillInfo(view, (void *)self->ob_sval, Py_Size(self), 1, flags);
 }
 
 static PySequenceMethods string_as_sequence = {
@@ -1294,10 +1260,8 @@
 };
 
 static PyBufferProcs string_as_buffer = {
-	(readbufferproc)string_buffer_getreadbuf,
-	(writebufferproc)string_buffer_getwritebuf,
-	(segcountproc)string_buffer_getsegcount,
-	(charbufferproc)string_buffer_getcharbuf,
+	(getbufferproc)string_buffer_getbuffer,
+        NULL,
 };
 
 

Modified: python/branches/py3k-buffer/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k-buffer/Objects/unicodeobject.c	(original)
+++ python/branches/py3k-buffer/Objects/unicodeobject.c	Tue Aug  7 07:43:49 2007
@@ -7788,56 +7788,16 @@
     (objobjargproc)0,			/* mp_ass_subscript */
 };
 
-static Py_ssize_t
-unicode_buffer_getreadbuf(PyUnicodeObject *self,
-			  Py_ssize_t index,
-			  const void **ptr)
-{
-    if (index != 0) {
-        PyErr_SetString(PyExc_SystemError,
-			"accessing non-existent unicode segment");
-        return -1;
-    }
-    *ptr = (void *) self->str;
-    return PyUnicode_GET_DATA_SIZE(self);
-}
-
-static Py_ssize_t
-unicode_buffer_getwritebuf(PyUnicodeObject *self, Py_ssize_t index,
-			   const void **ptr)
-{
-    PyErr_SetString(PyExc_TypeError,
-		    "cannot use unicode as modifiable buffer");
-    return -1;
-}
 
 static int
-unicode_buffer_getsegcount(PyUnicodeObject *self,
-			   Py_ssize_t *lenp)
+unicode_buffer_getbuffer(PyUnicodeObject *self, PyBuffer *view, int flags)
 {
-    if (lenp)
-        *lenp = PyUnicode_GET_DATA_SIZE(self);
-    return 1;
+    int res;
+    
+    return PyBuffer_FillInfo(view, (void *)self->str, PyUnicode_GET_DATA_SIZE(self),
+                             1, flags);
 }
 
-static Py_ssize_t
-unicode_buffer_getcharbuf(PyUnicodeObject *self,
-			  Py_ssize_t index,
-			  const void **ptr)
-{
-    PyObject *str;
-
-    if (index != 0) {
-        PyErr_SetString(PyExc_SystemError,
-			"accessing non-existent unicode segment");
-        return -1;
-    }
-    str = _PyUnicode_AsDefaultEncodedString((PyObject *)self, NULL);
-    if (str == NULL)
-	return -1;
-    *ptr = (void *) PyString_AS_STRING(str);
-    return PyString_GET_SIZE(str);
-}
 
 /* Helpers for PyUnicode_Format() */
 
@@ -8533,10 +8493,8 @@
 }
 
 static PyBufferProcs unicode_as_buffer = {
-    (readbufferproc) unicode_buffer_getreadbuf,
-    (writebufferproc) unicode_buffer_getwritebuf,
-    (segcountproc) unicode_buffer_getsegcount,
-    (charbufferproc) unicode_buffer_getcharbuf,
+    (getbufferproc) unicode_buffer_getbuffer,
+    NULL,
 };
 
 static PyObject *


More information about the Python-3000-checkins mailing list