ยปCore Development>Code coverage>Objects/bufferobject.c

Python code coverage for Objects/bufferobject.c

#countcontent
1n/a
2n/a/* Buffer object implementation */
3n/a
4n/a#include "Python.h"
5n/a
6n/a
7n/atypedef struct {
8n/a PyObject_HEAD
9n/a PyObject *b_base;
10n/a void *b_ptr;
11n/a Py_ssize_t b_size;
12n/a Py_ssize_t b_offset;
13n/a int b_readonly;
14n/a long b_hash;
15n/a} PyBufferObject;
16n/a
17n/a
18n/aenum buffer_t {
19n/a READ_BUFFER,
20n/a WRITE_BUFFER,
21n/a CHAR_BUFFER,
22n/a ANY_BUFFER
23n/a};
24n/a
25n/astatic int
26n/aget_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size,
27n/a enum buffer_t buffer_type)
2820332{
2920332 if (self->b_base == NULL) {
3017251 assert (ptr != NULL);
3117251 *ptr = self->b_ptr;
3217251 *size = self->b_size;
33n/a }
34n/a else {
35n/a Py_ssize_t count, offset;
363081 readbufferproc proc = 0;
373081 PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
383081 if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
390 PyErr_SetString(PyExc_TypeError,
40n/a "single-segment buffer object expected");
410 return 0;
42n/a }
436117 if ((buffer_type == READ_BUFFER) ||
44n/a ((buffer_type == ANY_BUFFER) && self->b_readonly))
453036 proc = bp->bf_getreadbuffer;
4645 else if ((buffer_type == WRITE_BUFFER) ||
47n/a (buffer_type == ANY_BUFFER))
480 proc = (readbufferproc)bp->bf_getwritebuffer;
4945 else if (buffer_type == CHAR_BUFFER) {
5045 if (!PyType_HasFeature(self->ob_type,
51n/a Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
520 PyErr_SetString(PyExc_TypeError,
53n/a "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
540 return 0;
55n/a }
5645 proc = (readbufferproc)bp->bf_getcharbuffer;
57n/a }
583081 if (!proc) {
59n/a char *buffer_type_name;
601 switch (buffer_type) {
61n/a case READ_BUFFER:
620 buffer_type_name = "read";
630 break;
64n/a case WRITE_BUFFER:
650 buffer_type_name = "write";
660 break;
67n/a case CHAR_BUFFER:
681 buffer_type_name = "char";
691 break;
70n/a default:
710 buffer_type_name = "no";
72n/a break;
73n/a }
741 PyErr_Format(PyExc_TypeError,
75n/a "%s buffer type not available",
76n/a buffer_type_name);
771 return 0;
78n/a }
793080 if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
800 return 0;
81n/a /* apply constraints to the start/end */
823080 if (self->b_offset > count)
830 offset = count;
84n/a else
853080 offset = self->b_offset;
863080 *(char **)ptr = *(char **)ptr + offset;
873080 if (self->b_size == Py_END_OF_BUFFER)
881199 *size = count;
89n/a else
901881 *size = self->b_size;
913080 if (offset + *size > count)
921810 *size = count - offset;
93n/a }
9420331 return 1;
95n/a}
96n/a
97n/a
98n/astatic PyObject *
99n/abuffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr,
100n/a int readonly)
1019373{
102n/a PyBufferObject * b;
103n/a
1049373 if (size < 0 && size != Py_END_OF_BUFFER) {
1050 PyErr_SetString(PyExc_ValueError,
106n/a "size must be zero or positive");
1070 return NULL;
108n/a }
1099373 if (offset < 0) {
1100 PyErr_SetString(PyExc_ValueError,
111n/a "offset must be zero or positive");
1120 return NULL;
113n/a }
114n/a
1159373 b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
1169373 if ( b == NULL )
1170 return NULL;
118n/a
1199373 Py_XINCREF(base);
1209373 b->b_base = base;
1219373 b->b_ptr = ptr;
1229373 b->b_size = size;
1239373 b->b_offset = offset;
1249373 b->b_readonly = readonly;
1259373 b->b_hash = -1;
126n/a
1279373 return (PyObject *) b;
128n/a}
129n/a
130n/astatic PyObject *
131n/abuffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly)
132748{
133748 if (offset < 0) {
1342 PyErr_SetString(PyExc_ValueError,
135n/a "offset must be zero or positive");
1362 return NULL;
137n/a }
138746 if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
139n/a /* another buffer, refer to the base object */
1408 PyBufferObject *b = (PyBufferObject *)base;
1418 if (b->b_size != Py_END_OF_BUFFER) {
1424 Py_ssize_t base_size = b->b_size - offset;
1434 if (base_size < 0)
1440 base_size = 0;
1454 if (size == Py_END_OF_BUFFER || size > base_size)
1464 size = base_size;
147n/a }
1488 offset += b->b_offset;
1498 base = b->b_base;
150n/a }
151746 return buffer_from_memory(base, size, offset, NULL, readonly);
152n/a}
153n/a
154n/a
155n/aPyObject *
156n/aPyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
157761{
158761 PyBufferProcs *pb = base->ob_type->tp_as_buffer;
159n/a
160761 if ( pb == NULL ||
161n/a pb->bf_getreadbuffer == NULL ||
162n/a pb->bf_getsegcount == NULL )
163n/a {
16413 PyErr_SetString(PyExc_TypeError, "buffer object expected");
16513 return NULL;
166n/a }
167n/a
168748 return buffer_from_object(base, size, offset, 1);
169n/a}
170n/a
171n/aPyObject *
172n/aPyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
1730{
1740 PyBufferProcs *pb = base->ob_type->tp_as_buffer;
175n/a
1760 if ( pb == NULL ||
177n/a pb->bf_getwritebuffer == NULL ||
178n/a pb->bf_getsegcount == NULL )
179n/a {
1800 PyErr_SetString(PyExc_TypeError, "buffer object expected");
1810 return NULL;
182n/a }
183n/a
1840 return buffer_from_object(base, size, offset, 0);
185n/a}
186n/a
187n/aPyObject *
188n/aPyBuffer_FromMemory(void *ptr, Py_ssize_t size)
1898627{
1908627 return buffer_from_memory(NULL, size, 0, ptr, 1);
191n/a}
192n/a
193n/aPyObject *
194n/aPyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
1950{
1960 return buffer_from_memory(NULL, size, 0, ptr, 0);
197n/a}
198n/a
199n/aPyObject *
200n/aPyBuffer_New(Py_ssize_t size)
2015{
202n/a PyObject *o;
203n/a PyBufferObject * b;
204n/a
2055 if (size < 0) {
2060 PyErr_SetString(PyExc_ValueError,
207n/a "size must be zero or positive");
2080 return NULL;
209n/a }
2105 if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
211n/a /* unlikely */
2120 return PyErr_NoMemory();
213n/a }
214n/a /* Inline PyObject_New */
2155 o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
2165 if ( o == NULL )
2170 return PyErr_NoMemory();
2185 b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);
219n/a
2205 b->b_base = NULL;
2215 b->b_ptr = (void *)(b + 1);
2225 b->b_size = size;
2235 b->b_offset = 0;
2245 b->b_readonly = 0;
2255 b->b_hash = -1;
226n/a
2275 return o;
228n/a}
229n/a
230n/a/* Methods */
231n/a
232n/astatic PyObject *
233n/abuffer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
234761{
235n/a PyObject *ob;
236761 Py_ssize_t offset = 0;
237761 Py_ssize_t size = Py_END_OF_BUFFER;
238n/a
239761 if (PyErr_WarnPy3k("buffer() not supported in 3.x", 1) < 0)
2400 return NULL;
241n/a
242761 if (!_PyArg_NoKeywords("buffer()", kw))
2430 return NULL;
244n/a
245761 if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
2460 return NULL;
247761 return PyBuffer_FromObject(ob, offset, size);
248n/a}
249n/a
250n/aPyDoc_STRVAR(buffer_doc,
251n/a"buffer(object [, offset[, size]])\n\
252n/a\n\
253n/aCreate a new buffer object which references the given object.\n\
254n/aThe buffer will reference a slice of the target object from the\n\
255n/astart of the object (or at the specified offset). The slice will\n\
256n/aextend to the end of the target object (or with the specified size).");
257n/a
258n/a
259n/astatic void
260n/abuffer_dealloc(PyBufferObject *self)
2619378{
2629378 Py_XDECREF(self->b_base);
2639378 PyObject_DEL(self);
2649378}
265n/a
266n/astatic int
267n/abuffer_compare(PyBufferObject *self, PyBufferObject *other)
2684{
269n/a void *p1, *p2;
270n/a Py_ssize_t len_self, len_other, min_len;
271n/a int cmp;
272n/a
2734 if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
2740 return -1;
2754 if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
2760 return -1;
2774 min_len = (len_self < len_other) ? len_self : len_other;
2784 if (min_len > 0) {
2794 cmp = memcmp(p1, p2, min_len);
2804 if (cmp != 0)
2811 return cmp < 0 ? -1 : 1;
282n/a }
2833 return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
284n/a}
285n/a
286n/astatic PyObject *
287n/abuffer_repr(PyBufferObject *self)
2881{
2891 const char *status = self->b_readonly ? "read-only" : "read-write";
290n/a
2911 if ( self->b_base == NULL )
2920 return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
293n/a status,
294n/a self->b_ptr,
295n/a self->b_size,
296n/a self);
297n/a else
2981 return PyString_FromFormat(
299n/a "<%s buffer for %p, size %zd, offset %zd at %p>",
300n/a status,
301n/a self->b_base,
302n/a self->b_size,
303n/a self->b_offset,
304n/a self);
305n/a}
306n/a
307n/astatic long
308n/abuffer_hash(PyBufferObject *self)
3091{
310n/a void *ptr;
311n/a Py_ssize_t size;
312n/a register Py_ssize_t len;
313n/a register unsigned char *p;
314n/a register long x;
315n/a
3161 if ( self->b_hash != -1 )
3170 return self->b_hash;
318n/a
319n/a /* XXX potential bugs here, a readonly buffer does not imply that the
320n/a * underlying memory is immutable. b_readonly is a necessary but not
321n/a * sufficient condition for a buffer to be hashable. Perhaps it would
322n/a * be better to only allow hashing if the underlying object is known to
323n/a * be immutable (e.g. PyString_Check() is true). Another idea would
324n/a * be to call tp_hash on the underlying object and see if it raises
325n/a * an error. */
3261 if ( !self->b_readonly )
327n/a {
3280 PyErr_SetString(PyExc_TypeError,
329n/a "writable buffers are not hashable");
3300 return -1;
331n/a }
332n/a
3331 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
3340 return -1;
3351 p = (unsigned char *) ptr;
3361 len = size;
3371 x = *p << 7;
3386 while (--len >= 0)
3394 x = (1000003*x) ^ *p++;
3401 x ^= size;
3411 if (x == -1)
3420 x = -2;
3431 self->b_hash = x;
3441 return x;
345n/a}
346n/a
347n/astatic PyObject *
348n/abuffer_str(PyBufferObject *self)
34922{
350n/a void *ptr;
351n/a Py_ssize_t size;
35222 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
3530 return NULL;
35422 return PyString_FromStringAndSize((const char *)ptr, size);
355n/a}
356n/a
357n/a/* Sequence methods */
358n/a
359n/astatic Py_ssize_t
360n/abuffer_length(PyBufferObject *self)
361625{
362n/a void *ptr;
363n/a Py_ssize_t size;
364625 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
3650 return -1;
366625 return size;
367n/a}
368n/a
369n/astatic PyObject *
370n/abuffer_concat(PyBufferObject *self, PyObject *other)
37130{
37230 PyBufferProcs *pb = other->ob_type->tp_as_buffer;
373n/a void *ptr1, *ptr2;
374n/a char *p;
375n/a PyObject *ob;
376n/a Py_ssize_t size, count;
377n/a
37830 if ( pb == NULL ||
379n/a pb->bf_getreadbuffer == NULL ||
380n/a pb->bf_getsegcount == NULL )
381n/a {
3820 PyErr_BadArgument();
3830 return NULL;
384n/a }
38530 if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
386n/a {
387n/a /* ### use a different exception type/message? */
3880 PyErr_SetString(PyExc_TypeError,
389n/a "single-segment buffer object expected");
3900 return NULL;
391n/a }
392n/a
39330 if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
3940 return NULL;
395n/a
396n/a /* optimize special case */
39730 if ( size == 0 )
398n/a {
3990 Py_INCREF(other);
4000 return other;
401n/a }
402n/a
40330 if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
4040 return NULL;
405n/a
40630 assert(count <= PY_SIZE_MAX - size);
407n/a
40830 ob = PyString_FromStringAndSize(NULL, size + count);
40930 if ( ob == NULL )
4100 return NULL;
41130 p = PyString_AS_STRING(ob);
41230 memcpy(p, ptr1, size);
41330 memcpy(p + size, ptr2, count);
414n/a
415n/a /* there is an extra byte in the string object, so this is safe */
41630 p[size + count] = '\0';
417n/a
41830 return ob;
419n/a}
420n/a
421n/astatic PyObject *
422n/abuffer_repeat(PyBufferObject *self, Py_ssize_t count)
4233{
424n/a PyObject *ob;
425n/a register char *p;
426n/a void *ptr;
427n/a Py_ssize_t size;
428n/a
4293 if ( count < 0 )
4300 count = 0;
4313 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
4320 return NULL;
4333 if (count > PY_SSIZE_T_MAX / size) {
4340 PyErr_SetString(PyExc_MemoryError, "result too large");
4350 return NULL;
436n/a }
4373 ob = PyString_FromStringAndSize(NULL, size * count);
4383 if ( ob == NULL )
4390 return NULL;
440n/a
4413 p = PyString_AS_STRING(ob);
4425158 while ( count-- )
443n/a {
4445152 memcpy(p, ptr, size);
4455152 p += size;
446n/a }
447n/a
448n/a /* there is an extra byte in the string object, so this is safe */
4493 *p = '\0';
450n/a
4513 return ob;
452n/a}
453n/a
454n/astatic PyObject *
455n/abuffer_item(PyBufferObject *self, Py_ssize_t idx)
45621{
457n/a void *ptr;
458n/a Py_ssize_t size;
45921 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
4600 return NULL;
46121 if ( idx < 0 || idx >= size ) {
4620 PyErr_SetString(PyExc_IndexError, "buffer index out of range");
4630 return NULL;
464n/a }
46521 return PyString_FromStringAndSize((char *)ptr + idx, 1);
466n/a}
467n/a
468n/astatic PyObject *
469n/abuffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
47024{
471n/a void *ptr;
472n/a Py_ssize_t size;
47324 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
4740 return NULL;
47524 if ( left < 0 )
4760 left = 0;
47724 if ( right < 0 )
4780 right = 0;
47924 if ( right > size )
4803 right = size;
48124 if ( right < left )
4820 right = left;
48324 return PyString_FromStringAndSize((char *)ptr + left,
484n/a right - left);
485n/a}
486n/a
487n/astatic PyObject *
488n/abuffer_subscript(PyBufferObject *self, PyObject *item)
489921{
490n/a void *p;
491n/a Py_ssize_t size;
492n/a
493921 if (!get_buf(self, &p, &size, ANY_BUFFER))
4940 return NULL;
495921 if (PyIndex_Check(item)) {
49621 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
49721 if (i == -1 && PyErr_Occurred())
4980 return NULL;
49921 if (i < 0)
5000 i += size;
50121 return buffer_item(self, i);
502n/a }
503900 else if (PySlice_Check(item)) {
504n/a Py_ssize_t start, stop, step, slicelength, cur, i;
505n/a
506900 if (PySlice_GetIndicesEx((PySliceObject*)item, size,
507n/a &start, &stop, &step, &slicelength) < 0) {
5080 return NULL;
509n/a }
510n/a
511900 if (slicelength <= 0)
512441 return PyString_FromStringAndSize("", 0);
513459 else if (step == 1)
514102 return PyString_FromStringAndSize((char *)p + start,
515n/a stop - start);
516n/a else {
517n/a PyObject *result;
518357 char *source_buf = (char *)p;
519357 char *result_buf = (char *)PyMem_Malloc(slicelength);
520n/a
521357 if (result_buf == NULL)
5220 return PyErr_NoMemory();
523n/a
52415474 for (cur = start, i = 0; i < slicelength;
52514760 cur += step, i++) {
52614760 result_buf[i] = source_buf[cur];
527n/a }
528n/a
529357 result = PyString_FromStringAndSize(result_buf,
530n/a slicelength);
531357 PyMem_Free(result_buf);
532357 return result;
533n/a }
534n/a }
535n/a else {
5360 PyErr_SetString(PyExc_TypeError,
537n/a "sequence index must be integer");
5380 return NULL;
539n/a }
540n/a}
541n/a
542n/astatic int
543n/abuffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
5440{
545n/a PyBufferProcs *pb;
546n/a void *ptr1, *ptr2;
547n/a Py_ssize_t size;
548n/a Py_ssize_t count;
549n/a
5500 if ( self->b_readonly ) {
5510 PyErr_SetString(PyExc_TypeError,
552n/a "buffer is read-only");
5530 return -1;
554n/a }
555n/a
5560 if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
5570 return -1;
558n/a
5590 if (idx < 0 || idx >= size) {
5600 PyErr_SetString(PyExc_IndexError,
561n/a "buffer assignment index out of range");
5620 return -1;
563n/a }
564n/a
5650 pb = other ? other->ob_type->tp_as_buffer : NULL;
5660 if ( pb == NULL ||
567n/a pb->bf_getreadbuffer == NULL ||
568n/a pb->bf_getsegcount == NULL )
569n/a {
5700 PyErr_BadArgument();
5710 return -1;
572n/a }
5730 if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
574n/a {
575n/a /* ### use a different exception type/message? */
5760 PyErr_SetString(PyExc_TypeError,
577n/a "single-segment buffer object expected");
5780 return -1;
579n/a }
580n/a
5810 if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
5820 return -1;
5830 if ( count != 1 ) {
5840 PyErr_SetString(PyExc_TypeError,
585n/a "right operand must be a single byte");
5860 return -1;
587n/a }
588n/a
5890 ((char *)ptr1)[idx] = *(char *)ptr2;
5900 return 0;
591n/a}
592n/a
593n/astatic int
594n/abuffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
5951{
596n/a PyBufferProcs *pb;
597n/a void *ptr1, *ptr2;
598n/a Py_ssize_t size;
599n/a Py_ssize_t slice_len;
600n/a Py_ssize_t count;
601n/a
6021 if ( self->b_readonly ) {
6031 PyErr_SetString(PyExc_TypeError,
604n/a "buffer is read-only");
6051 return -1;
606n/a }
607n/a
6080 pb = other ? other->ob_type->tp_as_buffer : NULL;
6090 if ( pb == NULL ||
610n/a pb->bf_getreadbuffer == NULL ||
611n/a pb->bf_getsegcount == NULL )
612n/a {
6130 PyErr_BadArgument();
6140 return -1;
615n/a }
6160 if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
617n/a {
618n/a /* ### use a different exception type/message? */
6190 PyErr_SetString(PyExc_TypeError,
620n/a "single-segment buffer object expected");
6210 return -1;
622n/a }
6230 if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
6240 return -1;
6250 if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
6260 return -1;
627n/a
6280 if ( left < 0 )
6290 left = 0;
6300 else if ( left > size )
6310 left = size;
6320 if ( right < left )
6330 right = left;
6340 else if ( right > size )
6350 right = size;
6360 slice_len = right - left;
637n/a
6380 if ( count != slice_len ) {
6390 PyErr_SetString(
640n/a PyExc_TypeError,
641n/a "right operand length must match slice length");
6420 return -1;
643n/a }
644n/a
6450 if ( slice_len )
6460 memcpy((char *)ptr1 + left, ptr2, slice_len);
647n/a
6480 return 0;
649n/a}
650n/a
651n/astatic int
652n/abuffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
6531{
654n/a PyBufferProcs *pb;
655n/a void *ptr1, *ptr2;
656n/a Py_ssize_t selfsize;
657n/a Py_ssize_t othersize;
658n/a
6591 if ( self->b_readonly ) {
6601 PyErr_SetString(PyExc_TypeError,
661n/a "buffer is read-only");
6621 return -1;
663n/a }
664n/a
6650 pb = value ? value->ob_type->tp_as_buffer : NULL;
6660 if ( pb == NULL ||
667n/a pb->bf_getreadbuffer == NULL ||
668n/a pb->bf_getsegcount == NULL )
669n/a {
6700 PyErr_BadArgument();
6710 return -1;
672n/a }
6730 if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
674n/a {
675n/a /* ### use a different exception type/message? */
6760 PyErr_SetString(PyExc_TypeError,
677n/a "single-segment buffer object expected");
6780 return -1;
679n/a }
6800 if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
6810 return -1;
6820 if (PyIndex_Check(item)) {
6830 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
6840 if (i == -1 && PyErr_Occurred())
6850 return -1;
6860 if (i < 0)
6870 i += selfsize;
6880 return buffer_ass_item(self, i, value);
689n/a }
6900 else if (PySlice_Check(item)) {
691n/a Py_ssize_t start, stop, step, slicelength;
692n/a
6930 if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
694n/a &start, &stop, &step, &slicelength) < 0)
6950 return -1;
696n/a
6970 if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
6980 return -1;
699n/a
7000 if (othersize != slicelength) {
7010 PyErr_SetString(
702n/a PyExc_TypeError,
703n/a "right operand length must match slice length");
7040 return -1;
705n/a }
706n/a
7070 if (slicelength == 0)
7080 return 0;
7090 else if (step == 1) {
7100 memcpy((char *)ptr1 + start, ptr2, slicelength);
7110 return 0;
712n/a }
713n/a else {
714n/a Py_ssize_t cur, i;
715n/a
7160 for (cur = start, i = 0; i < slicelength;
7170 cur += step, i++) {
7180 ((char *)ptr1)[cur] = ((char *)ptr2)[i];
719n/a }
720n/a
7210 return 0;
722n/a }
723n/a } else {
7240 PyErr_SetString(PyExc_TypeError,
725n/a "buffer indices must be integers");
7260 return -1;
727n/a }
728n/a}
729n/a
730n/a/* Buffer methods */
731n/a
732n/astatic Py_ssize_t
733n/abuffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
7349290{
735n/a Py_ssize_t size;
7369290 if ( idx != 0 ) {
7370 PyErr_SetString(PyExc_SystemError,
738n/a "accessing non-existent buffer segment");
7390 return -1;
740n/a }
7419290 if (!get_buf(self, pp, &size, READ_BUFFER))
7420 return -1;
7439290 return size;
744n/a}
745n/a
746n/astatic Py_ssize_t
747n/abuffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
7485{
749n/a Py_ssize_t size;
750n/a
7515 if ( self->b_readonly )
752n/a {
7530 PyErr_SetString(PyExc_TypeError, "buffer is read-only");
7540 return -1;
755n/a }
756n/a
7575 if ( idx != 0 ) {
7580 PyErr_SetString(PyExc_SystemError,
759n/a "accessing non-existent buffer segment");
7600 return -1;
761n/a }
7625 if (!get_buf(self, pp, &size, WRITE_BUFFER))
7630 return -1;
7645 return size;
765n/a}
766n/a
767n/astatic Py_ssize_t
768n/abuffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp)
7699337{
770n/a void *ptr;
771n/a Py_ssize_t size;
7729337 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
7730 return -1;
7749337 if (lenp)
7750 *lenp = size;
7769337 return 1;
777n/a}
778n/a
779n/astatic Py_ssize_t
780n/abuffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp)
78145{
782n/a void *ptr;
783n/a Py_ssize_t size;
78445 if ( idx != 0 ) {
7850 PyErr_SetString(PyExc_SystemError,
786n/a "accessing non-existent buffer segment");
7870 return -1;
788n/a }
78945 if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
7901 return -1;
79144 *pp = (const char *)ptr;
79244 return size;
793n/a}
794n/a
795n/astatic PySequenceMethods buffer_as_sequence = {
796n/a (lenfunc)buffer_length, /*sq_length*/
797n/a (binaryfunc)buffer_concat, /*sq_concat*/
798n/a (ssizeargfunc)buffer_repeat, /*sq_repeat*/
799n/a (ssizeargfunc)buffer_item, /*sq_item*/
800n/a (ssizessizeargfunc)buffer_slice, /*sq_slice*/
801n/a (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
802n/a (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
803n/a};
804n/a
805n/astatic PyMappingMethods buffer_as_mapping = {
806n/a (lenfunc)buffer_length,
807n/a (binaryfunc)buffer_subscript,
808n/a (objobjargproc)buffer_ass_subscript,
809n/a};
810n/a
811n/astatic PyBufferProcs buffer_as_buffer = {
812n/a (readbufferproc)buffer_getreadbuf,
813n/a (writebufferproc)buffer_getwritebuf,
814n/a (segcountproc)buffer_getsegcount,
815n/a (charbufferproc)buffer_getcharbuf,
816n/a};
817n/a
818n/aPyTypeObject PyBuffer_Type = {
819n/a PyVarObject_HEAD_INIT(&PyType_Type, 0)
820n/a "buffer",
821n/a sizeof(PyBufferObject),
822n/a 0,
823n/a (destructor)buffer_dealloc, /* tp_dealloc */
824n/a 0, /* tp_print */
825n/a 0, /* tp_getattr */
826n/a 0, /* tp_setattr */
827n/a (cmpfunc)buffer_compare, /* tp_compare */
828n/a (reprfunc)buffer_repr, /* tp_repr */
829n/a 0, /* tp_as_number */
830n/a &buffer_as_sequence, /* tp_as_sequence */
831n/a &buffer_as_mapping, /* tp_as_mapping */
832n/a (hashfunc)buffer_hash, /* tp_hash */
833n/a 0, /* tp_call */
834n/a (reprfunc)buffer_str, /* tp_str */
835n/a PyObject_GenericGetAttr, /* tp_getattro */
836n/a 0, /* tp_setattro */
837n/a &buffer_as_buffer, /* tp_as_buffer */
838n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER, /* tp_flags */
839n/a buffer_doc, /* tp_doc */
840n/a 0, /* tp_traverse */
841n/a 0, /* tp_clear */
842n/a 0, /* tp_richcompare */
843n/a 0, /* tp_weaklistoffset */
844n/a 0, /* tp_iter */
845n/a 0, /* tp_iternext */
846n/a 0, /* tp_methods */
847n/a 0, /* tp_members */
848n/a 0, /* tp_getset */
849n/a 0, /* tp_base */
850n/a 0, /* tp_dict */
851n/a 0, /* tp_descr_get */
852n/a 0, /* tp_descr_set */
853n/a 0, /* tp_dictoffset */
854n/a 0, /* tp_init */
855n/a 0, /* tp_alloc */
856n/a buffer_new, /* tp_new */
857n/a};