bufferobject.c revision 799124718ddfbb95440470037d8d7760b821646f
12e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum/***********************************************************
2fd71b9e9d496caa510dec56a9b69966558d6ba5dGuido van RossumCopyright (c) 2000, BeOpen.com.
3fd71b9e9d496caa510dec56a9b69966558d6ba5dGuido van RossumCopyright (c) 1995-2000, Corporation for National Research Initiatives.
4fd71b9e9d496caa510dec56a9b69966558d6ba5dGuido van RossumCopyright (c) 1990-1995, Stichting Mathematisch Centrum.
5fd71b9e9d496caa510dec56a9b69966558d6ba5dGuido van RossumAll rights reserved.
6fd71b9e9d496caa510dec56a9b69966558d6ba5dGuido van Rossum
7fd71b9e9d496caa510dec56a9b69966558d6ba5dGuido van RossumSee the file "Misc/COPYRIGHT" for information on usage and
8fd71b9e9d496caa510dec56a9b69966558d6ba5dGuido van Rossumredistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
92e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum******************************************************************/
102e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
112e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum/* Buffer object implementation */
122e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
132e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum#include "Python.h"
142e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
152e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
162e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumtypedef struct {
172e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyObject_HEAD
182e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyObject *b_base;
192e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	void *b_ptr;
202e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	int b_size;
212e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	int b_readonly;
222e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum#ifdef CACHE_HASH
232e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	long b_hash;
242e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum#endif
252e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum} PyBufferObject;
262e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
272e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
282e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
29799124718ddfbb95440470037d8d7760b821646fFred Drake_PyBuffer_FromMemory(PyObject *base, void *ptr, int size, int readonly)
302e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
312e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyBufferObject * b;
322e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3349ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum	if ( size < 0 ) {
3449ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum		PyErr_SetString(PyExc_ValueError,
3549ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum				"size must be zero or positive");
3649ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum		return NULL;
3749ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum	}
3849ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum
392e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
402e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( b == NULL )
412e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return NULL;
422e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
432e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	Py_XINCREF(base);
442e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	b->b_base = base;
452e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	b->b_ptr = ptr;
462e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	b->b_size = size;
472e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	b->b_readonly = readonly;
482e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum#ifdef CACHE_HASH
492e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	b->b_hash = -1;
502e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum#endif
512e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
522e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return (PyObject *) b;
532e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
542e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
552e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
56799124718ddfbb95440470037d8d7760b821646fFred Drake_PyBuffer_FromObject(PyObject *base, int offset, int size,
57799124718ddfbb95440470037d8d7760b821646fFred Drake                     getreadbufferproc proc, int readonly)
582e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
592e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyBufferProcs *pb = base->ob_type->tp_as_buffer;
602e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	void *p;
612e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	int count;
622e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
6349ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum	if ( offset < 0 ) {
6449ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum		PyErr_SetString(PyExc_ValueError,
6549ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum				"offset must be zero or positive");
6649ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum		return NULL;
6749ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum	}
6849ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum
692e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( (*pb->bf_getsegcount)(base, NULL) != 1 )
702e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
71cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum		PyErr_SetString(PyExc_TypeError,
72cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum				"single-segment buffer object expected");
732e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return NULL;
742e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
752e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( (count = (*proc)(base, 0, &p)) < 0 )
762e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return NULL;
772e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
782e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	/* apply constraints to the start/end */
7949ded3ec004c49088ec26c808f9b7c931a35cf0fGuido van Rossum	if ( size == Py_END_OF_BUFFER || size < 0 )
802e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		size = count;
812e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( offset > count )
822e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		offset = count;
832e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( offset + size > count )
842e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		size = count - offset;
852e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
862e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	/* if the base object is another buffer, then "deref" it */
872e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( PyBuffer_Check(base) )
882e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		base = ((PyBufferObject *)base)->b_base;
892e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
902e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return _PyBuffer_FromMemory(base, (char *)p + offset, size, readonly);
912e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
922e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
932e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
942e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van RossumPyObject *
95799124718ddfbb95440470037d8d7760b821646fFred DrakePyBuffer_FromObject(PyObject *base, int offset, int size)
962e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
972e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyBufferProcs *pb = base->ob_type->tp_as_buffer;
982e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
992e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( pb == NULL ||
1002e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	     pb->bf_getreadbuffer == NULL ||
1012e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	     pb->bf_getsegcount == NULL )
1022e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
1032e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_SetString(PyExc_TypeError, "buffer object expected");
1042e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return NULL;
1052e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
1062e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
107cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum	return _PyBuffer_FromObject(base, offset, size,
108cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum				    pb->bf_getreadbuffer, 1);
1092e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1102e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1112e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van RossumPyObject *
112799124718ddfbb95440470037d8d7760b821646fFred DrakePyBuffer_FromReadWriteObject(PyObject *base, int offset, int size)
1132e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
1142e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyBufferProcs *pb = base->ob_type->tp_as_buffer;
1152e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1162e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( pb == NULL ||
1172e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	     pb->bf_getwritebuffer == NULL ||
1182e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	     pb->bf_getsegcount == NULL )
1192e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
1202e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_SetString(PyExc_TypeError, "buffer object expected");
1212e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return NULL;
1222e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
1232e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
124cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum	return _PyBuffer_FromObject(base, offset, size,
125cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum				    (getreadbufferproc)pb->bf_getwritebuffer,
126cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum				    0);
1272e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1282e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1292e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van RossumPyObject *
130799124718ddfbb95440470037d8d7760b821646fFred DrakePyBuffer_FromMemory(void *ptr, int size)
1312e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
1322e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return _PyBuffer_FromMemory(NULL, ptr, size, 1);
1332e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1342e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1352e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van RossumPyObject *
136799124718ddfbb95440470037d8d7760b821646fFred DrakePyBuffer_FromReadWriteMemory(void *ptr, int size)
1372e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
1382e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return _PyBuffer_FromMemory(NULL, ptr, size, 0);
1392e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1402e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1412e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van RossumPyObject *
142799124718ddfbb95440470037d8d7760b821646fFred DrakePyBuffer_New(int size)
1432e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
1442e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyBufferObject * b;
1452e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1464574f23115e2c0b35a2e1a4cac0aa7c855144639Fred Drake	if (size < 0) {
1474574f23115e2c0b35a2e1a4cac0aa7c855144639Fred Drake		PyErr_SetString(PyExc_ValueError,
1484574f23115e2c0b35a2e1a4cac0aa7c855144639Fred Drake				"size must be zero or positive");
1494574f23115e2c0b35a2e1a4cac0aa7c855144639Fred Drake		return NULL;
1504574f23115e2c0b35a2e1a4cac0aa7c855144639Fred Drake	}
151b18618dab7b6b85bb05b084693706e59211fa180Guido van Rossum	/* PyObject_New is inlined */
152b18618dab7b6b85bb05b084693706e59211fa180Guido van Rossum	b = (PyBufferObject *) PyObject_MALLOC(sizeof(*b) + size);
1532e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( b == NULL )
1544574f23115e2c0b35a2e1a4cac0aa7c855144639Fred Drake		return PyErr_NoMemory();
155b18618dab7b6b85bb05b084693706e59211fa180Guido van Rossum	PyObject_INIT((PyObject *)b, &PyBuffer_Type);
1562e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1572e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	b->b_base = NULL;
1582e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	b->b_ptr = (void *)(b + 1);
1592e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	b->b_size = size;
1602e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	b->b_readonly = 0;
1612e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum#ifdef CACHE_HASH
1622e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	b->b_hash = -1;
1632e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum#endif
1642e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1652e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return (PyObject *) b;
1662e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1672e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1682e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum/* Methods */
1692e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1702e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic void
171799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_dealloc(PyBufferObject *self)
1722e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
1732e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	Py_XDECREF(self->b_base);
174b18618dab7b6b85bb05b084693706e59211fa180Guido van Rossum	PyObject_DEL(self);
1752e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1762e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1772e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic int
178799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_compare(PyBufferObject *self, PyBufferObject *other)
1792e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
1802e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	int len_self = self->b_size;
1812e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	int len_other = other->b_size;
1822e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	int min_len = (len_self < len_other) ? len_self : len_other;
1832e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	int cmp;
1842e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if (min_len > 0) {
1852e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		cmp = memcmp(self->b_ptr, other->b_ptr, min_len);
1862e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		if (cmp != 0)
1872e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum			return cmp;
1882e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
1892e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
1902e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1912e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1922e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
193799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_repr(PyBufferObject *self)
1942e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
1952e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	char buf[300];
1962e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	char *status = self->b_readonly ? "read-only" : "read-write";
1972e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1982e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( self->b_base == NULL )
1992e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
200a44d353e2b6d947d36ab9d36c1fc84335a0878feFred Drake		sprintf(buf, "<%s buffer ptr %p, size %d at %p>",
2012e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum			status,
202a44d353e2b6d947d36ab9d36c1fc84335a0878feFred Drake			self->b_ptr,
2032e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum			self->b_size,
204a44d353e2b6d947d36ab9d36c1fc84335a0878feFred Drake			self);
2052e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
2062e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	else
2072e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
208a44d353e2b6d947d36ab9d36c1fc84335a0878feFred Drake		sprintf(buf, "<%s buffer for %p, ptr %p, size %d at %p>",
2092e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum			status,
210a44d353e2b6d947d36ab9d36c1fc84335a0878feFred Drake			self->b_base,
211a44d353e2b6d947d36ab9d36c1fc84335a0878feFred Drake			self->b_ptr,
2122e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum			self->b_size,
213a44d353e2b6d947d36ab9d36c1fc84335a0878feFred Drake			self);
2142e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
2152e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2162e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return PyString_FromString(buf);
2172e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
2182e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2192e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic long
220799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_hash(PyBufferObject *self)
2212e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
2222e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	register int len;
2232e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	register unsigned char *p;
2242e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	register long x;
2252e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2262e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum#ifdef CACHE_HASH
2272e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( self->b_hash != -1 )
2282e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return self->b_hash;
2292e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum#endif
2302e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2312e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( !self->b_readonly )
2322e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
2332e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		/* ### use different wording, since this is conditional? */
2342e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_SetString(PyExc_TypeError, "unhashable type");
2352e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
2362e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
2372e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2382e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	len = self->b_size;
2392e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	p = (unsigned char *) self->b_ptr;
2402e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	x = *p << 7;
2412e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	while (--len >= 0)
2422e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		x = (1000003*x) ^ *p++;
2432e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	x ^= self->b_size;
2442e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if (x == -1)
2452e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		x = -2;
2462e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum#ifdef CACHE_HASH
2472e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	self->b_hash = x;
2482e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum#endif
2492e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return x;
2502e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
2512e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2522e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
253799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_str(PyBufferObject *self)
2542e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
2552e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return PyString_FromStringAndSize(self->b_ptr, self->b_size);
2562e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
2572e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2582e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum/* Sequence methods */
2592e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2602e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic int
261799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_length(PyBufferObject *self)
2622e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
2632e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return self->b_size;
2642e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
2652e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2662e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
267799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_concat(PyBufferObject *self, PyObject *other)
2682e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
2692e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyBufferProcs *pb = other->ob_type->tp_as_buffer;
2702e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	char *p1;
2712e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	void *p2;
2722e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyObject *ob;
2732e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	int count;
2742e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2752e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( pb == NULL ||
2762e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	     pb->bf_getreadbuffer == NULL ||
2772e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	     pb->bf_getsegcount == NULL )
2782e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
2792e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_BadArgument();
2802e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return NULL;
2812e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
2822e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
2832e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
2842e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		/* ### use a different exception type/message? */
285cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum		PyErr_SetString(PyExc_TypeError,
286cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum				"single-segment buffer object expected");
2872e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return NULL;
2882e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
2892e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2902e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	/* optimize special case */
2912e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( self->b_size == 0 )
2922e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
2932e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	    Py_INCREF(other);
2942e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	    return other;
2952e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
2962e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2972e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( (count = (*pb->bf_getreadbuffer)(other, 0, &p2)) < 0 )
2982e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return NULL;
2992e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3002e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	/* optimize special case */
3012e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( count == 0 )
3022e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
3032e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	    Py_INCREF(self);
3042e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	    return (PyObject *)self;
3052e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
3062e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3072e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	ob = PyString_FromStringAndSize(NULL, self->b_size + count);
3082e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	p1 = PyString_AS_STRING(ob);
3092e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	memcpy(p1, self->b_ptr, self->b_size);
3102e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	memcpy(p1 + self->b_size, p2, count);
3112e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3122e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	/* there is an extra byte in the string object, so this is safe */
3132e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	p1[self->b_size + count] = '\0';
3142e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3152e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return ob;
3162e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
3172e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3182e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
319799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_repeat(PyBufferObject *self, int count)
3202e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
3212e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyObject *ob;
3222e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	register char *p;
3232e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	void *ptr = self->b_ptr;
3242e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	int size = self->b_size;
3252e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3262e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( count < 0 )
3272e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		count = 0;
3282e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	ob = PyString_FromStringAndSize(NULL, size * count);
3292e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( ob == NULL )
3302e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return NULL;
3312e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3322e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	p = PyString_AS_STRING(ob);
3332e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	while ( count-- )
3342e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
3352e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	    memcpy(p, ptr, size);
3362e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	    p += size;
3372e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
3382e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3392e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	/* there is an extra byte in the string object, so this is safe */
3402e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	*p = '\0';
3412e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3422e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return ob;
3432e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
3442e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3452e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
346799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_item(PyBufferObject *self, int idx)
3472e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
3482e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( idx < 0 || idx >= self->b_size )
3492e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
3502e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_SetString(PyExc_IndexError, "buffer index out of range");
3512e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return NULL;
3522e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
3532e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return PyString_FromStringAndSize((char *)self->b_ptr + idx, 1);
3542e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
3552e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3562e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
357799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_slice(PyBufferObject *self, int left, int right)
3582e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
3592e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( left < 0 )
3602e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		left = 0;
3612e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( right < 0 )
3622e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		right = 0;
3632e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( right > self->b_size )
3642e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		right = self->b_size;
3652e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( left == 0 && right == self->b_size )
3662e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
3672e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		/* same as self */
3682e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		Py_INCREF(self);
3692e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return (PyObject *)self;
3702e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
3712e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( right < left )
3722e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		right = left;
373cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum	return PyString_FromStringAndSize((char *)self->b_ptr + left,
374cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum					  right - left);
3752e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
3762e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3772e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic int
378799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_ass_item(PyBufferObject *self, int idx, PyObject *other)
3792e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
3802e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyBufferProcs *pb;
3812e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	void *p;
3822e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	int count;
3832e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3842e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( self->b_readonly ) {
3852e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_SetString(PyExc_TypeError,
3862e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum				"buffer is read-only");
3872e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
3882e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
3892e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3902e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if (idx < 0 || idx >= self->b_size) {
3912e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_SetString(PyExc_IndexError,
3922e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum				"buffer assignment index out of range");
3932e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
3942e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
3952e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3962e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	pb = other ? other->ob_type->tp_as_buffer : NULL;
3972e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( pb == NULL ||
3982e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	     pb->bf_getreadbuffer == NULL ||
3992e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	     pb->bf_getsegcount == NULL )
4002e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
4012e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_BadArgument();
4022e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
4032e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
4042e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
4052e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
4062e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		/* ### use a different exception type/message? */
407cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum		PyErr_SetString(PyExc_TypeError,
408cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum				"single-segment buffer object expected");
4092e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
4102e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
4112e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4122e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( (count = (*pb->bf_getreadbuffer)(other, 0, &p)) < 0 )
4132e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
4142e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( count != 1 ) {
4152e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_SetString(PyExc_TypeError,
4162e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum				"right operand must be a single byte");
4172e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
4182e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
4192e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4202e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	((char *)self->b_ptr)[idx] = *(char *)p;
4212e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return 0;
4222e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
4232e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4242e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic int
425799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_ass_slice(PyBufferObject *self, int left, int right, PyObject *other)
4262e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
4272e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyBufferProcs *pb;
4282e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	void *p;
4292e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	int slice_len;
4302e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	int count;
4312e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4322e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( self->b_readonly ) {
4332e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_SetString(PyExc_TypeError,
4342e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum				"buffer is read-only");
4352e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
4362e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
4372e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4382e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	pb = other ? other->ob_type->tp_as_buffer : NULL;
4392e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( pb == NULL ||
4402e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	     pb->bf_getreadbuffer == NULL ||
4412e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	     pb->bf_getsegcount == NULL )
4422e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
4432e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_BadArgument();
4442e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
4452e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
4462e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
4472e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
4482e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		/* ### use a different exception type/message? */
449cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum		PyErr_SetString(PyExc_TypeError,
450cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum				"single-segment buffer object expected");
4512e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
4522e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
4532e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( (count = (*pb->bf_getreadbuffer)(other, 0, &p)) < 0 )
4542e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
4552e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4562e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( left < 0 )
4572e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		left = 0;
4582e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	else if ( left > self->b_size )
4592e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		left = self->b_size;
4602e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( right < left )
4612e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		right = left;
4622e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	else if ( right > self->b_size )
4632e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		right = self->b_size;
4642e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	slice_len = right - left;
4652e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4662e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( count != slice_len ) {
467cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum		PyErr_SetString(
468cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum			PyExc_TypeError,
469cd037e7bed8535f11df4be01c040b939c9e2ad60Guido van Rossum			"right operand length must match slice length");
4702e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
4712e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
4722e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4732e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( slice_len )
4742e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	    memcpy((char *)self->b_ptr + left, p, slice_len);
4752e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4762e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return 0;
4772e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
4782e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4792e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum/* Buffer methods */
4802e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4812e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic int
482799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_getreadbuf(PyBufferObject *self, int idx, void **pp)
4832e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
4842e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( idx != 0 ) {
4852e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_SetString(PyExc_SystemError,
4861db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum				"accessing non-existent buffer segment");
4872e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
4882e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
4892e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	*pp = self->b_ptr;
4902e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return self->b_size;
4912e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
4922e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4932e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic int
494799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_getwritebuf(PyBufferObject *self, int idx, void **pp)
4952e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
4962e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( self->b_readonly )
4972e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	{
4982e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		PyErr_SetString(PyExc_TypeError, "buffer is read-only");
4992e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		return -1;
5002e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	}
5012e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return buffer_getreadbuf(self, idx, pp);
5022e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
5032e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
5042e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic int
505799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_getsegcount(PyBufferObject *self, int *lenp)
5062e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
5072e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	if ( lenp )
5082e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum		*lenp = self->b_size;
5092e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	return 1;
5102e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
5112e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
5121db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossumstatic int
513799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_getcharbuf(PyBufferObject *self, int idx, const char **pp)
5141db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum{
5151db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum	if ( idx != 0 ) {
5161db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum		PyErr_SetString(PyExc_SystemError,
5171db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum				"accessing non-existent buffer segment");
5181db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum		return -1;
5191db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum	}
5201db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum	*pp = (const char *)self->b_ptr;
5211db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum	return self->b_size;
5221db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum}
5231db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum
5242e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
5252e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PySequenceMethods buffer_as_sequence = {
5262e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(inquiry)buffer_length, /*sq_length*/
5272e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(binaryfunc)buffer_concat, /*sq_concat*/
5282e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(intargfunc)buffer_repeat, /*sq_repeat*/
5292e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(intargfunc)buffer_item, /*sq_item*/
5302e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(intintargfunc)buffer_slice, /*sq_slice*/
5312e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(intobjargproc)buffer_ass_item, /*sq_ass_item*/
5322e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(intintobjargproc)buffer_ass_slice, /*sq_ass_slice*/
5332e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum};
5342e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
5352e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyBufferProcs buffer_as_buffer = {
5362e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(getreadbufferproc)buffer_getreadbuf,
5372e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(getwritebufferproc)buffer_getwritebuf,
5382e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(getsegcountproc)buffer_getsegcount,
5391db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum	(getcharbufferproc)buffer_getcharbuf,
5402e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum};
5412e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
5422e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van RossumPyTypeObject PyBuffer_Type = {
5432e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	PyObject_HEAD_INIT(&PyType_Type)
5442e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	0,
5452e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	"buffer",
5462e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	sizeof(PyBufferObject),
5472e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	0,
5482e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(destructor)buffer_dealloc, /*tp_dealloc*/
5492e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	0,		/*tp_print*/
5502e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	0,		/*tp_getattr*/
5512e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	0,		/*tp_setattr*/
5522e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(cmpfunc)buffer_compare, /*tp_compare*/
5532e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(reprfunc)buffer_repr, /*tp_repr*/
5542e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	0,		/*tp_as_number*/
5552e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	&buffer_as_sequence,	/*tp_as_sequence*/
5562e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	0,		/*tp_as_mapping*/
5572e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(hashfunc)buffer_hash,	/*tp_hash*/
5582e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	0,		/*tp_call*/
5592e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	(reprfunc)buffer_str,		/*tp_str*/
5602e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	0,		/*tp_getattro*/
5612e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	0,		/*tp_setattro*/
5622e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	&buffer_as_buffer,	/*tp_as_buffer*/
5631db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum	Py_TPFLAGS_DEFAULT,	/*tp_flags*/
5642e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum	0,		/*tp_doc*/
5652e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum};
566