12e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
22e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum/* Buffer object implementation */
32e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
42e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum#include "Python.h"
52e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
62e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
72e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumtypedef struct {
8c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyObject_HEAD
9c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyObject *b_base;
10c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *b_ptr;
11c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t b_size;
12c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t b_offset;
13c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    int b_readonly;
14c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    long b_hash;
152e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum} PyBufferObject;
162e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
172e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
18de3b0522160df86b45075708cd42a0e7d62a9b71Brett Cannonenum buffer_t {
19c48b0e6657691be44a01415ee6654e37590980c2Brett Cannon    READ_BUFFER,
20c48b0e6657691be44a01415ee6654e37590980c2Brett Cannon    WRITE_BUFFER,
21c48b0e6657691be44a01415ee6654e37590980c2Brett Cannon    CHAR_BUFFER,
22da587ab43e4f4dab223ff1544c89c80a1442b3ccMartin v. Löwis    ANY_BUFFER
23de3b0522160df86b45075708cd42a0e7d62a9b71Brett Cannon};
24de3b0522160df86b45075708cd42a0e7d62a9b71Brett Cannon
254252a7a5d1c0bbc41abeab2ae5ce29f42cd9ace8Neil Schemenauerstatic int
26de3b0522160df86b45075708cd42a0e7d62a9b71Brett Cannonget_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size,
27c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    enum buffer_t buffer_type)
284252a7a5d1c0bbc41abeab2ae5ce29f42cd9ace8Neil Schemenauer{
29c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (self->b_base == NULL) {
30c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        assert (ptr != NULL);
31c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        *ptr = self->b_ptr;
32c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        *size = self->b_size;
33c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
34c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    else {
35c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        Py_ssize_t count, offset;
36c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        readbufferproc proc = 0;
37c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
38c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
39c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            PyErr_SetString(PyExc_TypeError,
40c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                "single-segment buffer object expected");
41c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return 0;
42c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        }
43c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if ((buffer_type == READ_BUFFER) ||
44c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            ((buffer_type == ANY_BUFFER) && self->b_readonly))
45c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            proc = bp->bf_getreadbuffer;
46c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        else if ((buffer_type == WRITE_BUFFER) ||
47c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            (buffer_type == ANY_BUFFER))
48c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            proc = (readbufferproc)bp->bf_getwritebuffer;
49c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        else if (buffer_type == CHAR_BUFFER) {
50c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            if (!PyType_HasFeature(self->ob_type,
51c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
52c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            PyErr_SetString(PyExc_TypeError,
53c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
54c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return 0;
55c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            }
56c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            proc = (readbufferproc)bp->bf_getcharbuffer;
57c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        }
58c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (!proc) {
59c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            char *buffer_type_name;
60c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            switch (buffer_type) {
61c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            case READ_BUFFER:
62c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                buffer_type_name = "read";
63c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                break;
64c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            case WRITE_BUFFER:
65c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                buffer_type_name = "write";
66c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                break;
67c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            case CHAR_BUFFER:
68c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                buffer_type_name = "char";
69c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                break;
70c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            default:
71c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                buffer_type_name = "no";
72c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                break;
73c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            }
74c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            PyErr_Format(PyExc_TypeError,
75c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                "%s buffer type not available",
76c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                buffer_type_name);
77c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return 0;
78c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        }
79c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
80c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return 0;
81c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        /* apply constraints to the start/end */
82c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (self->b_offset > count)
83c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            offset = count;
84c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        else
85c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            offset = self->b_offset;
86c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        *(char **)ptr = *(char **)ptr + offset;
87c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (self->b_size == Py_END_OF_BUFFER)
88c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            *size = count;
89c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        else
90c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            *size = self->b_size;
91550b945fd66f1c6837a53fbf29dc8e524297b8c3Benjamin Peterson        if (*size > count - offset)
92c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            *size = count - offset;
93c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
94c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return 1;
954252a7a5d1c0bbc41abeab2ae5ce29f42cd9ace8Neil Schemenauer}
964252a7a5d1c0bbc41abeab2ae5ce29f42cd9ace8Neil Schemenauer
974252a7a5d1c0bbc41abeab2ae5ce29f42cd9ace8Neil Schemenauer
982e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
9918e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisbuffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr,
100c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                   int readonly)
1012e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
102c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyBufferObject * b;
103c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
104c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (size < 0 && size != Py_END_OF_BUFFER) {
105c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
106c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "size must be zero or positive");
107c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
108c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
109c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (offset < 0) {
110c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
111c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "offset must be zero or positive");
112c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
113c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
114c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
115c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
116c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( b == NULL )
117c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
118c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
119c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_XINCREF(base);
120c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b->b_base = base;
121c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b->b_ptr = ptr;
122c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b->b_size = size;
123c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b->b_offset = offset;
124c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b->b_readonly = readonly;
125c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b->b_hash = -1;
126c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
127c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return (PyObject *) b;
1282e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1292e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1302e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
13118e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisbuffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly)
1322e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
133c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (offset < 0) {
134c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
135c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "offset must be zero or positive");
136c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
137c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
138c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
139c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        /* another buffer, refer to the base object */
140c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyBufferObject *b = (PyBufferObject *)base;
141c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (b->b_size != Py_END_OF_BUFFER) {
142c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            Py_ssize_t base_size = b->b_size - offset;
143c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            if (base_size < 0)
144c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                base_size = 0;
145c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            if (size == Py_END_OF_BUFFER || size > base_size)
146c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                size = base_size;
147c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        }
148c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        offset += b->b_offset;
149c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        base = b->b_base;
150c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
151c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return buffer_from_memory(base, size, offset, NULL, readonly);
1522e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1532e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1542e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1552e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van RossumPyObject *
15618e165558b24d29e7e0ca501842b9236589b012aMartin v. LöwisPyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
1572e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
158c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyBufferProcs *pb = base->ob_type->tp_as_buffer;
1592e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
160c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( pb == NULL ||
161c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou         pb->bf_getreadbuffer == NULL ||
162c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou         pb->bf_getsegcount == NULL )
163c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
164c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError, "buffer object expected");
165c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
166c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
1672e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
168c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return buffer_from_object(base, size, offset, 1);
1692e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1702e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1712e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van RossumPyObject *
17218e165558b24d29e7e0ca501842b9236589b012aMartin v. LöwisPyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
1732e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
174c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyBufferProcs *pb = base->ob_type->tp_as_buffer;
1752e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
176c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( pb == NULL ||
177c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou         pb->bf_getwritebuffer == NULL ||
178c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou         pb->bf_getsegcount == NULL )
179c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
180c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError, "buffer object expected");
181c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
182c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
1832e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
184c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return buffer_from_object(base, size,  offset, 0);
1852e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1862e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1872e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van RossumPyObject *
18818e165558b24d29e7e0ca501842b9236589b012aMartin v. LöwisPyBuffer_FromMemory(void *ptr, Py_ssize_t size)
1892e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
190c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return buffer_from_memory(NULL, size, 0, ptr, 1);
1912e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1922e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1932e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van RossumPyObject *
19418e165558b24d29e7e0ca501842b9236589b012aMartin v. LöwisPyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
1952e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
196c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return buffer_from_memory(NULL, size, 0, ptr, 0);
1972e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
1982e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
1992e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van RossumPyObject *
20018e165558b24d29e7e0ca501842b9236589b012aMartin v. LöwisPyBuffer_New(Py_ssize_t size)
2012e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
202c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyObject *o;
203c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyBufferObject * b;
204c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
205c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (size < 0) {
206c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_ValueError,
207c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "size must be zero or positive");
208c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
209c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
210c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
211c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        /* unlikely */
212c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return PyErr_NoMemory();
213c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
214c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    /* Inline PyObject_New */
215c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
216c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( o == NULL )
217c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return PyErr_NoMemory();
218c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);
219c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
220c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b->b_base = NULL;
221c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b->b_ptr = (void *)(b + 1);
222c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b->b_size = size;
223c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b->b_offset = 0;
224c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b->b_readonly = 0;
225c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    b->b_hash = -1;
226c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
227c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return o;
2282e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
2292e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2302e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum/* Methods */
2312e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
232bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossumstatic PyObject *
233bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossumbuffer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
234bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossum{
235c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyObject *ob;
236c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t offset = 0;
237c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size = Py_END_OF_BUFFER;
238c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
239c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (PyErr_WarnPy3k("buffer() not supported in 3.x", 1) < 0)
240c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
241c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
242c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!_PyArg_NoKeywords("buffer()", kw))
243c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
244c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
245c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
246c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
247c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return PyBuffer_FromObject(ob, offset, size);
248bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossum}
249bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossum
250bea18ccde6bc12e061c21bb6b944379d8b123845Guido van RossumPyDoc_STRVAR(buffer_doc,
251bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossum"buffer(object [, offset[, size]])\n\
252bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossum\n\
253bea18ccde6bc12e061c21bb6b944379d8b123845Guido van RossumCreate a new buffer object which references the given object.\n\
254bea18ccde6bc12e061c21bb6b944379d8b123845Guido van RossumThe buffer will reference a slice of the target object from the\n\
255bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossumstart of the object (or at the specified offset). The slice will\n\
256bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossumextend to the end of the target object (or with the specified size).");
257bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossum
258bea18ccde6bc12e061c21bb6b944379d8b123845Guido van Rossum
2592e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic void
260799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_dealloc(PyBufferObject *self)
2612e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
262c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_XDECREF(self->b_base);
263c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyObject_DEL(self);
2642e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
2652e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2662e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic int
267799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_compare(PyBufferObject *self, PyBufferObject *other)
2682e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
269c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *p1, *p2;
270c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t len_self, len_other, min_len;
271c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    int cmp;
272c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
273c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
274c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
275c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
276c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
277c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    min_len = (len_self < len_other) ? len_self : len_other;
278c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (min_len > 0) {
279c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        cmp = memcmp(p1, p2, min_len);
280c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (cmp != 0)
281c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return cmp < 0 ? -1 : 1;
282c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
283c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
2842e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
2852e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
2862e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
287799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_repr(PyBufferObject *self)
2882e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
289c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    const char *status = self->b_readonly ? "read-only" : "read-write";
290c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
291c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( self->b_base == NULL )
292c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
293c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                                   status,
294c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                                   self->b_ptr,
295c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                                   self->b_size,
296c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                                   self);
297c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    else
298c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return PyString_FromFormat(
299c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            "<%s buffer for %p, size %zd, offset %zd at %p>",
300c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            status,
301c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            self->b_base,
302c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            self->b_size,
303c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            self->b_offset,
304c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            self);
3052e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
3062e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3072e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic long
308799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_hash(PyBufferObject *self)
3092e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
310c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *ptr;
311c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
312c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    register Py_ssize_t len;
313c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    register unsigned char *p;
314c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    register long x;
315c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
316c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( self->b_hash != -1 )
317c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return self->b_hash;
318c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
319c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    /* XXX potential bugs here, a readonly buffer does not imply that the
320c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou     * underlying memory is immutable.  b_readonly is a necessary but not
321c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou     * sufficient condition for a buffer to be hashable.  Perhaps it would
322c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou     * be better to only allow hashing if the underlying object is known to
323c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou     * be immutable (e.g. PyString_Check() is true).  Another idea would
324c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou     * be to call tp_hash on the underlying object and see if it raises
325c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou     * an error. */
326c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( !self->b_readonly )
327c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
328c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
329c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "writable buffers are not hashable");
330c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
331c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
332c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
333c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
334c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
335c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    p = (unsigned char *) ptr;
336c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    len = size;
3371e13eb084f72d5993cbb726e45b36bdb69c83a24Barry Warsaw    /*
3381e13eb084f72d5993cbb726e45b36bdb69c83a24Barry Warsaw      We make the hash of the empty buffer be 0, rather than using
3391e13eb084f72d5993cbb726e45b36bdb69c83a24Barry Warsaw      (prefix ^ suffix), since this slightly obfuscates the hash secret
3401e13eb084f72d5993cbb726e45b36bdb69c83a24Barry Warsaw    */
3411e13eb084f72d5993cbb726e45b36bdb69c83a24Barry Warsaw    if (len == 0) {
3421e13eb084f72d5993cbb726e45b36bdb69c83a24Barry Warsaw        self->b_hash = 0;
3431e13eb084f72d5993cbb726e45b36bdb69c83a24Barry Warsaw        return 0;
3441e13eb084f72d5993cbb726e45b36bdb69c83a24Barry Warsaw    }
3451e13eb084f72d5993cbb726e45b36bdb69c83a24Barry Warsaw    x = _Py_HashSecret.prefix;
3461e13eb084f72d5993cbb726e45b36bdb69c83a24Barry Warsaw    x ^= *p << 7;
347c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    while (--len >= 0)
348c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        x = (1000003*x) ^ *p++;
349c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    x ^= size;
3501e13eb084f72d5993cbb726e45b36bdb69c83a24Barry Warsaw    x ^= _Py_HashSecret.suffix;
351c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (x == -1)
352c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        x = -2;
353c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    self->b_hash = x;
354c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return x;
3552e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
3562e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3572e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
358799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_str(PyBufferObject *self)
3592e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
360c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *ptr;
361c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
362c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
363c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
364c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return PyString_FromStringAndSize((const char *)ptr, size);
3652e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
3662e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3672e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum/* Sequence methods */
3682e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
36918e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisstatic Py_ssize_t
370799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_length(PyBufferObject *self)
3712e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
372c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *ptr;
373c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
374c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
375c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
376c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return size;
3772e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
3782e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
3792e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
380799124718ddfbb95440470037d8d7760b821646fFred Drakebuffer_concat(PyBufferObject *self, PyObject *other)
3812e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
382c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyBufferProcs *pb = other->ob_type->tp_as_buffer;
383c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *ptr1, *ptr2;
384c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    char *p;
385c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyObject *ob;
386c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size, count;
387c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
388c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( pb == NULL ||
389c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou         pb->bf_getreadbuffer == NULL ||
390c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou         pb->bf_getsegcount == NULL )
391c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
392c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_BadArgument();
393c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
394c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
395c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
396c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
397c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        /* ### use a different exception type/message? */
398c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
399c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "single-segment buffer object expected");
400c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
401c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
402c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
403c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
404c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
405c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
406c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    /* optimize special case */
407c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( size == 0 )
408c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
409c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        Py_INCREF(other);
410c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return other;
411c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
412c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
413c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
414c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
415c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
416c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    assert(count <= PY_SIZE_MAX - size);
417c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
418c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    ob = PyString_FromStringAndSize(NULL, size + count);
419c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( ob == NULL )
420c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
421c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    p = PyString_AS_STRING(ob);
422c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    memcpy(p, ptr1, size);
423c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    memcpy(p + size, ptr2, count);
424c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
425c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    /* there is an extra byte in the string object, so this is safe */
426c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    p[size + count] = '\0';
427c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
428c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return ob;
4292e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
4302e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4312e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
43218e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisbuffer_repeat(PyBufferObject *self, Py_ssize_t count)
4332e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
434c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyObject *ob;
435c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    register char *p;
436c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *ptr;
437c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
438c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
439c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( count < 0 )
440c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        count = 0;
441c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
442c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
443c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (count > PY_SSIZE_T_MAX / size) {
444c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_MemoryError, "result too large");
445c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
446c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
447c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    ob = PyString_FromStringAndSize(NULL, size * count);
448c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( ob == NULL )
449c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
450c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
451c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    p = PyString_AS_STRING(ob);
452c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    while ( count-- )
453c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
454c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        memcpy(p, ptr, size);
455c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        p += size;
456c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
457c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
458c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    /* there is an extra byte in the string object, so this is safe */
459c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    *p = '\0';
460c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
461c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return ob;
4622e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
4632e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4642e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
46518e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisbuffer_item(PyBufferObject *self, Py_ssize_t idx)
4662e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
467c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *ptr;
468c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
469c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
470c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
471c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( idx < 0 || idx >= size ) {
472c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_IndexError, "buffer index out of range");
473c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
474c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
475c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return PyString_FromStringAndSize((char *)ptr + idx, 1);
4762e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
4772e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4782e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyObject *
47918e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisbuffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
4802e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
481c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *ptr;
482c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
483c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
484c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
485c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( left < 0 )
486c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        left = 0;
487c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( right < 0 )
488c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        right = 0;
489c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( right > size )
490c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        right = size;
491c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( right < left )
492c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        right = left;
493c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return PyString_FromStringAndSize((char *)ptr + left,
494c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                                      right - left);
4952e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
4962e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
4973ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Woutersstatic PyObject *
4983ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Woutersbuffer_subscript(PyBufferObject *self, PyObject *item)
4993ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Wouters{
500c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *p;
501c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
502c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
503c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &p, &size, ANY_BUFFER))
504c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
505c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (PyIndex_Check(item)) {
506c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
507c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (i == -1 && PyErr_Occurred())
508c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return NULL;
509c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (i < 0)
510c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            i += size;
511c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return buffer_item(self, i);
512c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
513c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    else if (PySlice_Check(item)) {
514c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        Py_ssize_t start, stop, step, slicelength, cur, i;
515c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
516c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (PySlice_GetIndicesEx((PySliceObject*)item, size,
517c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                         &start, &stop, &step, &slicelength) < 0) {
518c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return NULL;
519c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        }
520c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
521c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (slicelength <= 0)
522c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return PyString_FromStringAndSize("", 0);
523c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        else if (step == 1)
524c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return PyString_FromStringAndSize((char *)p + start,
525c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                                              stop - start);
526c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        else {
527c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            PyObject *result;
528c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            char *source_buf = (char *)p;
529c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            char *result_buf = (char *)PyMem_Malloc(slicelength);
530c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
531c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            if (result_buf == NULL)
532c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                return PyErr_NoMemory();
533c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
534c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            for (cur = start, i = 0; i < slicelength;
535c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                 cur += step, i++) {
536c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                result_buf[i] = source_buf[cur];
537c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            }
538c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
539c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            result = PyString_FromStringAndSize(result_buf,
540c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                                                slicelength);
541c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            PyMem_Free(result_buf);
542c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return result;
543c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        }
544c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
545c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    else {
546c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
547c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "sequence index must be integer");
548c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return NULL;
549c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
5503ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Wouters}
5513ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Wouters
5522e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic int
55318e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisbuffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
5542e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
555c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyBufferProcs *pb;
556c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *ptr1, *ptr2;
557c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
558c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t count;
559c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
560c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( self->b_readonly ) {
561c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
562c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "buffer is read-only");
563c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
564c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
565c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
566c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
567c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
568c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
569c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (idx < 0 || idx >= size) {
570c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_IndexError,
571c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "buffer assignment index out of range");
572c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
573c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
574c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
575c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    pb = other ? other->ob_type->tp_as_buffer : NULL;
576c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( pb == NULL ||
577c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou         pb->bf_getreadbuffer == NULL ||
578c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou         pb->bf_getsegcount == NULL )
579c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
580c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_BadArgument();
581c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
582c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
583c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
584c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
585c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        /* ### use a different exception type/message? */
586c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
587c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "single-segment buffer object expected");
588c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
589c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
590c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
591c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
592c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
593c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( count != 1 ) {
594c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
595c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "right operand must be a single byte");
596c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
597c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
598c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
599c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    ((char *)ptr1)[idx] = *(char *)ptr2;
600c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return 0;
6012e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
6022e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
6032e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic int
60418e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisbuffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
6052e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
606c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyBufferProcs *pb;
607c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *ptr1, *ptr2;
608c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
609c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t slice_len;
610c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t count;
611c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
612c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( self->b_readonly ) {
613c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
614c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "buffer is read-only");
615c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
616c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
617c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
618c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    pb = other ? other->ob_type->tp_as_buffer : NULL;
619c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( pb == NULL ||
620c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou         pb->bf_getreadbuffer == NULL ||
621c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou         pb->bf_getsegcount == NULL )
622c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
623c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_BadArgument();
624c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
625c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
626c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
627c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
628c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        /* ### use a different exception type/message? */
629c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
630c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "single-segment buffer object expected");
631c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
632c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
633c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
634c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
635c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
636c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
637c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
638c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( left < 0 )
639c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        left = 0;
640c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    else if ( left > size )
641c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        left = size;
642c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( right < left )
643c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        right = left;
644c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    else if ( right > size )
645c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        right = size;
646c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    slice_len = right - left;
647c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
648c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( count != slice_len ) {
649c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(
650c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            PyExc_TypeError,
651c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            "right operand length must match slice length");
652c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
653c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
654c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
655c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( slice_len )
656c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        memcpy((char *)ptr1 + left, ptr2, slice_len);
657c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
658c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return 0;
6592e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
6602e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
6613ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Woutersstatic int
6623ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Woutersbuffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
6633ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Wouters{
664c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyBufferProcs *pb;
665c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *ptr1, *ptr2;
666c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t selfsize;
667c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t othersize;
668c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
669c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( self->b_readonly ) {
670c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
671c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "buffer is read-only");
672c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
673c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
674c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
675c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    pb = value ? value->ob_type->tp_as_buffer : NULL;
676c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( pb == NULL ||
677c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou         pb->bf_getreadbuffer == NULL ||
678c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou         pb->bf_getsegcount == NULL )
679c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
680c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_BadArgument();
681c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
682c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
683c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
684c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
685c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        /* ### use a different exception type/message? */
686c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
687c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "single-segment buffer object expected");
688c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
689c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
690c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
691c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
692c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (PyIndex_Check(item)) {
693c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
694c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (i == -1 && PyErr_Occurred())
695c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return -1;
696c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (i < 0)
697c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            i += selfsize;
698c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return buffer_ass_item(self, i, value);
699c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
700c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    else if (PySlice_Check(item)) {
701c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        Py_ssize_t start, stop, step, slicelength;
702c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
703c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
704c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        &start, &stop, &step, &slicelength) < 0)
705c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return -1;
706c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
707c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
708c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return -1;
709c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
710c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (othersize != slicelength) {
711c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            PyErr_SetString(
712c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                PyExc_TypeError,
713c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                "right operand length must match slice length");
714c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return -1;
715c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        }
716c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
717c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        if (slicelength == 0)
718c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return 0;
719c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        else if (step == 1) {
720c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            memcpy((char *)ptr1 + start, ptr2, slicelength);
721c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return 0;
722c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        }
723c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        else {
724c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            Py_ssize_t cur, i;
725c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
726c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            for (cur = start, i = 0; i < slicelength;
727c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                 cur += step, i++) {
728c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                ((char *)ptr1)[cur] = ((char *)ptr2)[i];
729c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            }
730c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
731c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou            return 0;
732c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        }
733c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    } else {
734c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError,
735c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "buffer indices must be integers");
736c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
737c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
7383ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Wouters}
7393ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Wouters
7402e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum/* Buffer methods */
7412e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
74218e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisstatic Py_ssize_t
74318e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisbuffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
7442e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
745c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
746c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( idx != 0 ) {
747c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_SystemError,
748c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "accessing non-existent buffer segment");
749c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
750c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
751c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, pp, &size, READ_BUFFER))
752c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
753c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return size;
7542e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
7552e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
75618e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisstatic Py_ssize_t
75718e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisbuffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
7582e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
759c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
760c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
761c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( self->b_readonly )
762c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    {
763c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_TypeError, "buffer is read-only");
764c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
765c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
766c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou
767c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( idx != 0 ) {
768c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_SystemError,
769c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "accessing non-existent buffer segment");
770c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
771c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
772c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, pp, &size, WRITE_BUFFER))
773c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
774c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return size;
7752e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
7762e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
77718e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisstatic Py_ssize_t
77818e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisbuffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp)
7792e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum{
780c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *ptr;
781c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
782c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
783c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
784c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (lenp)
785c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        *lenp = size;
786c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return 1;
7872e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum}
7882e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
78918e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisstatic Py_ssize_t
79018e165558b24d29e7e0ca501842b9236589b012aMartin v. Löwisbuffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp)
7911db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum{
792c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    void *ptr;
793c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    Py_ssize_t size;
794c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if ( idx != 0 ) {
795c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        PyErr_SetString(PyExc_SystemError,
796c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou                        "accessing non-existent buffer segment");
797c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
798c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    }
799c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
800c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou        return -1;
801c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    *pp = (const char *)ptr;
802c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    return size;
8031db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum}
8041db7070217d80f0889aed44ceb1f11a82265b3f0Guido van Rossum
8051d108bc7148336f01d6df066ba1b27678c9bd1caKristján Valur Jónssonstatic int buffer_getbuffer(PyBufferObject *self, Py_buffer *buf, int flags)
8061d108bc7148336f01d6df066ba1b27678c9bd1caKristján Valur Jónsson{
8071d108bc7148336f01d6df066ba1b27678c9bd1caKristján Valur Jónsson    void *ptr;
8081d108bc7148336f01d6df066ba1b27678c9bd1caKristján Valur Jónsson    Py_ssize_t size;
8091d108bc7148336f01d6df066ba1b27678c9bd1caKristján Valur Jónsson    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
8101d108bc7148336f01d6df066ba1b27678c9bd1caKristján Valur Jónsson        return -1;
8111d108bc7148336f01d6df066ba1b27678c9bd1caKristján Valur Jónsson    return PyBuffer_FillInfo(buf, (PyObject*)self, ptr, size,
8121d108bc7148336f01d6df066ba1b27678c9bd1caKristján Valur Jónsson                             self->b_readonly, flags);
8131d108bc7148336f01d6df066ba1b27678c9bd1caKristján Valur Jónsson}
8141d108bc7148336f01d6df066ba1b27678c9bd1caKristján Valur Jónsson
8152e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PySequenceMethods buffer_as_sequence = {
816c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (lenfunc)buffer_length, /*sq_length*/
817c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (binaryfunc)buffer_concat, /*sq_concat*/
818c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (ssizeargfunc)buffer_repeat, /*sq_repeat*/
819c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (ssizeargfunc)buffer_item, /*sq_item*/
820c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (ssizessizeargfunc)buffer_slice, /*sq_slice*/
821c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
822c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
8232e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum};
8242e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
8253ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Woutersstatic PyMappingMethods buffer_as_mapping = {
826c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (lenfunc)buffer_length,
827c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (binaryfunc)buffer_subscript,
828c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (objobjargproc)buffer_ass_subscript,
8293ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Wouters};
8303ccec68a05abae43cf74dc7821c61ba88ab6cb46Thomas Wouters
8312e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossumstatic PyBufferProcs buffer_as_buffer = {
832c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (readbufferproc)buffer_getreadbuf,
833c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (writebufferproc)buffer_getwritebuf,
834c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (segcountproc)buffer_getsegcount,
835c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (charbufferproc)buffer_getcharbuf,
8361d108bc7148336f01d6df066ba1b27678c9bd1caKristján Valur Jónsson    (getbufferproc)buffer_getbuffer,
8372e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum};
8382e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van Rossum
8392e19bd7cc7520052b0c6e3d3da6baf45fb3b5e6bGuido van RossumPyTypeObject PyBuffer_Type = {
840c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyVarObject_HEAD_INIT(&PyType_Type, 0)
841c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    "buffer",
842c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    sizeof(PyBufferObject),
843c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,
844c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (destructor)buffer_dealloc,                 /* tp_dealloc */
845c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_print */
846c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_getattr */
847c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_setattr */
848c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (cmpfunc)buffer_compare,                    /* tp_compare */
849c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (reprfunc)buffer_repr,                      /* tp_repr */
850c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_as_number */
851c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    &buffer_as_sequence,                        /* tp_as_sequence */
852c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    &buffer_as_mapping,                         /* tp_as_mapping */
853c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (hashfunc)buffer_hash,                      /* tp_hash */
854c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_call */
855c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    (reprfunc)buffer_str,                       /* tp_str */
856c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    PyObject_GenericGetAttr,                    /* tp_getattro */
857c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_setattro */
858c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    &buffer_as_buffer,                          /* tp_as_buffer */
8591d108bc7148336f01d6df066ba1b27678c9bd1caKristján Valur Jónsson    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
860c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    buffer_doc,                                 /* tp_doc */
861c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_traverse */
862c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_clear */
863c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_richcompare */
864c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_weaklistoffset */
865c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_iter */
866c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_iternext */
867c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_methods */
868c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_members */
869c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_getset */
870c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_base */
871c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_dict */
872c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_descr_get */
873c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_descr_set */
874c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_dictoffset */
875c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_init */
876c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    0,                                          /* tp_alloc */
877c7c96a90bcf1366ac6f350f5506d0afee611e351Antoine Pitrou    buffer_new,                                 /* tp_new */
878550b945fd66f1c6837a53fbf29dc8e524297b8c3Benjamin Peterson};
879