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