]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.10/Objects/bufferobject.c
AppPkg/Applications/Python/Python-2.7.10: Initial Checkin part 3/5.
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Objects / bufferobject.c
1
2 /* Buffer object implementation */
3
4 #include "Python.h"
5
6
7 typedef struct {
8 PyObject_HEAD
9 PyObject *b_base;
10 void *b_ptr;
11 Py_ssize_t b_size;
12 Py_ssize_t b_offset;
13 int b_readonly;
14 long b_hash;
15 } PyBufferObject;
16
17
18 enum buffer_t {
19 READ_BUFFER,
20 WRITE_BUFFER,
21 CHAR_BUFFER,
22 ANY_BUFFER
23 };
24
25 static int
26 get_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size,
27 enum buffer_t buffer_type)
28 {
29 if (self->b_base == NULL) {
30 assert (ptr != NULL);
31 *ptr = self->b_ptr;
32 *size = self->b_size;
33 }
34 else {
35 Py_ssize_t count, offset;
36 readbufferproc proc = 0;
37 PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
38 if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
39 PyErr_SetString(PyExc_TypeError,
40 "single-segment buffer object expected");
41 return 0;
42 }
43 if ((buffer_type == READ_BUFFER) ||
44 ((buffer_type == ANY_BUFFER) && self->b_readonly))
45 proc = bp->bf_getreadbuffer;
46 else if ((buffer_type == WRITE_BUFFER) ||
47 (buffer_type == ANY_BUFFER))
48 proc = (readbufferproc)bp->bf_getwritebuffer;
49 else if (buffer_type == CHAR_BUFFER) {
50 if (!PyType_HasFeature(self->ob_type,
51 Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
52 PyErr_SetString(PyExc_TypeError,
53 "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
54 return 0;
55 }
56 proc = (readbufferproc)bp->bf_getcharbuffer;
57 }
58 if (!proc) {
59 char *buffer_type_name;
60 switch (buffer_type) {
61 case READ_BUFFER:
62 buffer_type_name = "read";
63 break;
64 case WRITE_BUFFER:
65 buffer_type_name = "write";
66 break;
67 case CHAR_BUFFER:
68 buffer_type_name = "char";
69 break;
70 default:
71 buffer_type_name = "no";
72 break;
73 }
74 PyErr_Format(PyExc_TypeError,
75 "%s buffer type not available",
76 buffer_type_name);
77 return 0;
78 }
79 if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
80 return 0;
81 /* apply constraints to the start/end */
82 if (self->b_offset > count)
83 offset = count;
84 else
85 offset = self->b_offset;
86 *(char **)ptr = *(char **)ptr + offset;
87 if (self->b_size == Py_END_OF_BUFFER)
88 *size = count;
89 else
90 *size = self->b_size;
91 if (*size > count - offset)
92 *size = count - offset;
93 }
94 return 1;
95 }
96
97
98 static PyObject *
99 buffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr,
100 int readonly)
101 {
102 PyBufferObject * b;
103
104 if (size < 0 && size != Py_END_OF_BUFFER) {
105 PyErr_SetString(PyExc_ValueError,
106 "size must be zero or positive");
107 return NULL;
108 }
109 if (offset < 0) {
110 PyErr_SetString(PyExc_ValueError,
111 "offset must be zero or positive");
112 return NULL;
113 }
114
115 b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
116 if ( b == NULL )
117 return NULL;
118
119 Py_XINCREF(base);
120 b->b_base = base;
121 b->b_ptr = ptr;
122 b->b_size = size;
123 b->b_offset = offset;
124 b->b_readonly = readonly;
125 b->b_hash = -1;
126
127 return (PyObject *) b;
128 }
129
130 static PyObject *
131 buffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly)
132 {
133 if (offset < 0) {
134 PyErr_SetString(PyExc_ValueError,
135 "offset must be zero or positive");
136 return NULL;
137 }
138 if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
139 /* another buffer, refer to the base object */
140 PyBufferObject *b = (PyBufferObject *)base;
141 if (b->b_size != Py_END_OF_BUFFER) {
142 Py_ssize_t base_size = b->b_size - offset;
143 if (base_size < 0)
144 base_size = 0;
145 if (size == Py_END_OF_BUFFER || size > base_size)
146 size = base_size;
147 }
148 offset += b->b_offset;
149 base = b->b_base;
150 }
151 return buffer_from_memory(base, size, offset, NULL, readonly);
152 }
153
154
155 PyObject *
156 PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
157 {
158 PyBufferProcs *pb = base->ob_type->tp_as_buffer;
159
160 if ( pb == NULL ||
161 pb->bf_getreadbuffer == NULL ||
162 pb->bf_getsegcount == NULL )
163 {
164 PyErr_SetString(PyExc_TypeError, "buffer object expected");
165 return NULL;
166 }
167
168 return buffer_from_object(base, size, offset, 1);
169 }
170
171 PyObject *
172 PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
173 {
174 PyBufferProcs *pb = base->ob_type->tp_as_buffer;
175
176 if ( pb == NULL ||
177 pb->bf_getwritebuffer == NULL ||
178 pb->bf_getsegcount == NULL )
179 {
180 PyErr_SetString(PyExc_TypeError, "buffer object expected");
181 return NULL;
182 }
183
184 return buffer_from_object(base, size, offset, 0);
185 }
186
187 PyObject *
188 PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
189 {
190 return buffer_from_memory(NULL, size, 0, ptr, 1);
191 }
192
193 PyObject *
194 PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
195 {
196 return buffer_from_memory(NULL, size, 0, ptr, 0);
197 }
198
199 PyObject *
200 PyBuffer_New(Py_ssize_t size)
201 {
202 PyObject *o;
203 PyBufferObject * b;
204
205 if (size < 0) {
206 PyErr_SetString(PyExc_ValueError,
207 "size must be zero or positive");
208 return NULL;
209 }
210 if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
211 /* unlikely */
212 return PyErr_NoMemory();
213 }
214 /* Inline PyObject_New */
215 o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
216 if ( o == NULL )
217 return PyErr_NoMemory();
218 b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);
219
220 b->b_base = NULL;
221 b->b_ptr = (void *)(b + 1);
222 b->b_size = size;
223 b->b_offset = 0;
224 b->b_readonly = 0;
225 b->b_hash = -1;
226
227 return o;
228 }
229
230 /* Methods */
231
232 static PyObject *
233 buffer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
234 {
235 PyObject *ob;
236 Py_ssize_t offset = 0;
237 Py_ssize_t size = Py_END_OF_BUFFER;
238
239 if (PyErr_WarnPy3k("buffer() not supported in 3.x", 1) < 0)
240 return NULL;
241
242 if (!_PyArg_NoKeywords("buffer()", kw))
243 return NULL;
244
245 if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
246 return NULL;
247 return PyBuffer_FromObject(ob, offset, size);
248 }
249
250 PyDoc_STRVAR(buffer_doc,
251 "buffer(object [, offset[, size]])\n\
252 \n\
253 Create a new buffer object which references the given object.\n\
254 The buffer will reference a slice of the target object from the\n\
255 start of the object (or at the specified offset). The slice will\n\
256 extend to the end of the target object (or with the specified size).");
257
258
259 static void
260 buffer_dealloc(PyBufferObject *self)
261 {
262 Py_XDECREF(self->b_base);
263 PyObject_DEL(self);
264 }
265
266 static int
267 buffer_compare(PyBufferObject *self, PyBufferObject *other)
268 {
269 void *p1, *p2;
270 Py_ssize_t len_self, len_other, min_len;
271 int cmp;
272
273 if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
274 return -1;
275 if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
276 return -1;
277 min_len = (len_self < len_other) ? len_self : len_other;
278 if (min_len > 0) {
279 cmp = memcmp(p1, p2, min_len);
280 if (cmp != 0)
281 return cmp < 0 ? -1 : 1;
282 }
283 return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
284 }
285
286 static PyObject *
287 buffer_repr(PyBufferObject *self)
288 {
289 const char *status = self->b_readonly ? "read-only" : "read-write";
290
291 if ( self->b_base == NULL )
292 return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
293 status,
294 self->b_ptr,
295 self->b_size,
296 self);
297 else
298 return PyString_FromFormat(
299 "<%s buffer for %p, size %zd, offset %zd at %p>",
300 status,
301 self->b_base,
302 self->b_size,
303 self->b_offset,
304 self);
305 }
306
307 static long
308 buffer_hash(PyBufferObject *self)
309 {
310 void *ptr;
311 Py_ssize_t size;
312 register Py_ssize_t len;
313 register unsigned char *p;
314 register long x;
315
316 if ( self->b_hash != -1 )
317 return self->b_hash;
318
319 /* XXX potential bugs here, a readonly buffer does not imply that the
320 * underlying memory is immutable. b_readonly is a necessary but not
321 * sufficient condition for a buffer to be hashable. Perhaps it would
322 * be better to only allow hashing if the underlying object is known to
323 * be immutable (e.g. PyString_Check() is true). Another idea would
324 * be to call tp_hash on the underlying object and see if it raises
325 * an error. */
326 if ( !self->b_readonly )
327 {
328 PyErr_SetString(PyExc_TypeError,
329 "writable buffers are not hashable");
330 return -1;
331 }
332
333 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
334 return -1;
335 p = (unsigned char *) ptr;
336 len = size;
337 /*
338 We make the hash of the empty buffer be 0, rather than using
339 (prefix ^ suffix), since this slightly obfuscates the hash secret
340 */
341 if (len == 0) {
342 self->b_hash = 0;
343 return 0;
344 }
345 x = _Py_HashSecret.prefix;
346 x ^= *p << 7;
347 while (--len >= 0)
348 x = (1000003*x) ^ *p++;
349 x ^= size;
350 x ^= _Py_HashSecret.suffix;
351 if (x == -1)
352 x = -2;
353 self->b_hash = x;
354 return x;
355 }
356
357 static PyObject *
358 buffer_str(PyBufferObject *self)
359 {
360 void *ptr;
361 Py_ssize_t size;
362 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
363 return NULL;
364 return PyString_FromStringAndSize((const char *)ptr, size);
365 }
366
367 /* Sequence methods */
368
369 static Py_ssize_t
370 buffer_length(PyBufferObject *self)
371 {
372 void *ptr;
373 Py_ssize_t size;
374 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
375 return -1;
376 return size;
377 }
378
379 static PyObject *
380 buffer_concat(PyBufferObject *self, PyObject *other)
381 {
382 PyBufferProcs *pb = other->ob_type->tp_as_buffer;
383 void *ptr1, *ptr2;
384 char *p;
385 PyObject *ob;
386 Py_ssize_t size, count;
387
388 if ( pb == NULL ||
389 pb->bf_getreadbuffer == NULL ||
390 pb->bf_getsegcount == NULL )
391 {
392 PyErr_BadArgument();
393 return NULL;
394 }
395 if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
396 {
397 /* ### use a different exception type/message? */
398 PyErr_SetString(PyExc_TypeError,
399 "single-segment buffer object expected");
400 return NULL;
401 }
402
403 if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
404 return NULL;
405
406 /* optimize special case */
407 if ( size == 0 )
408 {
409 Py_INCREF(other);
410 return other;
411 }
412
413 if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
414 return NULL;
415
416 assert(count <= PY_SIZE_MAX - size);
417
418 ob = PyString_FromStringAndSize(NULL, size + count);
419 if ( ob == NULL )
420 return NULL;
421 p = PyString_AS_STRING(ob);
422 memcpy(p, ptr1, size);
423 memcpy(p + size, ptr2, count);
424
425 /* there is an extra byte in the string object, so this is safe */
426 p[size + count] = '\0';
427
428 return ob;
429 }
430
431 static PyObject *
432 buffer_repeat(PyBufferObject *self, Py_ssize_t count)
433 {
434 PyObject *ob;
435 register char *p;
436 void *ptr;
437 Py_ssize_t size;
438
439 if ( count < 0 )
440 count = 0;
441 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
442 return NULL;
443 if (count > PY_SSIZE_T_MAX / size) {
444 PyErr_SetString(PyExc_MemoryError, "result too large");
445 return NULL;
446 }
447 ob = PyString_FromStringAndSize(NULL, size * count);
448 if ( ob == NULL )
449 return NULL;
450
451 p = PyString_AS_STRING(ob);
452 while ( count-- )
453 {
454 memcpy(p, ptr, size);
455 p += size;
456 }
457
458 /* there is an extra byte in the string object, so this is safe */
459 *p = '\0';
460
461 return ob;
462 }
463
464 static PyObject *
465 buffer_item(PyBufferObject *self, Py_ssize_t idx)
466 {
467 void *ptr;
468 Py_ssize_t size;
469 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
470 return NULL;
471 if ( idx < 0 || idx >= size ) {
472 PyErr_SetString(PyExc_IndexError, "buffer index out of range");
473 return NULL;
474 }
475 return PyString_FromStringAndSize((char *)ptr + idx, 1);
476 }
477
478 static PyObject *
479 buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
480 {
481 void *ptr;
482 Py_ssize_t size;
483 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
484 return NULL;
485 if ( left < 0 )
486 left = 0;
487 if ( right < 0 )
488 right = 0;
489 if ( right > size )
490 right = size;
491 if ( right < left )
492 right = left;
493 return PyString_FromStringAndSize((char *)ptr + left,
494 right - left);
495 }
496
497 static PyObject *
498 buffer_subscript(PyBufferObject *self, PyObject *item)
499 {
500 void *p;
501 Py_ssize_t size;
502
503 if (!get_buf(self, &p, &size, ANY_BUFFER))
504 return NULL;
505 if (PyIndex_Check(item)) {
506 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
507 if (i == -1 && PyErr_Occurred())
508 return NULL;
509 if (i < 0)
510 i += size;
511 return buffer_item(self, i);
512 }
513 else if (PySlice_Check(item)) {
514 Py_ssize_t start, stop, step, slicelength, cur, i;
515
516 if (PySlice_GetIndicesEx((PySliceObject*)item, size,
517 &start, &stop, &step, &slicelength) < 0) {
518 return NULL;
519 }
520
521 if (slicelength <= 0)
522 return PyString_FromStringAndSize("", 0);
523 else if (step == 1)
524 return PyString_FromStringAndSize((char *)p + start,
525 stop - start);
526 else {
527 PyObject *result;
528 char *source_buf = (char *)p;
529 char *result_buf = (char *)PyMem_Malloc(slicelength);
530
531 if (result_buf == NULL)
532 return PyErr_NoMemory();
533
534 for (cur = start, i = 0; i < slicelength;
535 cur += step, i++) {
536 result_buf[i] = source_buf[cur];
537 }
538
539 result = PyString_FromStringAndSize(result_buf,
540 slicelength);
541 PyMem_Free(result_buf);
542 return result;
543 }
544 }
545 else {
546 PyErr_SetString(PyExc_TypeError,
547 "sequence index must be integer");
548 return NULL;
549 }
550 }
551
552 static int
553 buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
554 {
555 PyBufferProcs *pb;
556 void *ptr1, *ptr2;
557 Py_ssize_t size;
558 Py_ssize_t count;
559
560 if ( self->b_readonly ) {
561 PyErr_SetString(PyExc_TypeError,
562 "buffer is read-only");
563 return -1;
564 }
565
566 if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
567 return -1;
568
569 if (idx < 0 || idx >= size) {
570 PyErr_SetString(PyExc_IndexError,
571 "buffer assignment index out of range");
572 return -1;
573 }
574
575 pb = other ? other->ob_type->tp_as_buffer : NULL;
576 if ( pb == NULL ||
577 pb->bf_getreadbuffer == NULL ||
578 pb->bf_getsegcount == NULL )
579 {
580 PyErr_BadArgument();
581 return -1;
582 }
583 if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
584 {
585 /* ### use a different exception type/message? */
586 PyErr_SetString(PyExc_TypeError,
587 "single-segment buffer object expected");
588 return -1;
589 }
590
591 if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
592 return -1;
593 if ( count != 1 ) {
594 PyErr_SetString(PyExc_TypeError,
595 "right operand must be a single byte");
596 return -1;
597 }
598
599 ((char *)ptr1)[idx] = *(char *)ptr2;
600 return 0;
601 }
602
603 static int
604 buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
605 {
606 PyBufferProcs *pb;
607 void *ptr1, *ptr2;
608 Py_ssize_t size;
609 Py_ssize_t slice_len;
610 Py_ssize_t count;
611
612 if ( self->b_readonly ) {
613 PyErr_SetString(PyExc_TypeError,
614 "buffer is read-only");
615 return -1;
616 }
617
618 pb = other ? other->ob_type->tp_as_buffer : NULL;
619 if ( pb == NULL ||
620 pb->bf_getreadbuffer == NULL ||
621 pb->bf_getsegcount == NULL )
622 {
623 PyErr_BadArgument();
624 return -1;
625 }
626 if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
627 {
628 /* ### use a different exception type/message? */
629 PyErr_SetString(PyExc_TypeError,
630 "single-segment buffer object expected");
631 return -1;
632 }
633 if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
634 return -1;
635 if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
636 return -1;
637
638 if ( left < 0 )
639 left = 0;
640 else if ( left > size )
641 left = size;
642 if ( right < left )
643 right = left;
644 else if ( right > size )
645 right = size;
646 slice_len = right - left;
647
648 if ( count != slice_len ) {
649 PyErr_SetString(
650 PyExc_TypeError,
651 "right operand length must match slice length");
652 return -1;
653 }
654
655 if ( slice_len )
656 memcpy((char *)ptr1 + left, ptr2, slice_len);
657
658 return 0;
659 }
660
661 static int
662 buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
663 {
664 PyBufferProcs *pb;
665 void *ptr1, *ptr2;
666 Py_ssize_t selfsize;
667 Py_ssize_t othersize;
668
669 if ( self->b_readonly ) {
670 PyErr_SetString(PyExc_TypeError,
671 "buffer is read-only");
672 return -1;
673 }
674
675 pb = value ? value->ob_type->tp_as_buffer : NULL;
676 if ( pb == NULL ||
677 pb->bf_getreadbuffer == NULL ||
678 pb->bf_getsegcount == NULL )
679 {
680 PyErr_BadArgument();
681 return -1;
682 }
683 if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
684 {
685 /* ### use a different exception type/message? */
686 PyErr_SetString(PyExc_TypeError,
687 "single-segment buffer object expected");
688 return -1;
689 }
690 if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
691 return -1;
692 if (PyIndex_Check(item)) {
693 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
694 if (i == -1 && PyErr_Occurred())
695 return -1;
696 if (i < 0)
697 i += selfsize;
698 return buffer_ass_item(self, i, value);
699 }
700 else if (PySlice_Check(item)) {
701 Py_ssize_t start, stop, step, slicelength;
702
703 if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
704 &start, &stop, &step, &slicelength) < 0)
705 return -1;
706
707 if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
708 return -1;
709
710 if (othersize != slicelength) {
711 PyErr_SetString(
712 PyExc_TypeError,
713 "right operand length must match slice length");
714 return -1;
715 }
716
717 if (slicelength == 0)
718 return 0;
719 else if (step == 1) {
720 memcpy((char *)ptr1 + start, ptr2, slicelength);
721 return 0;
722 }
723 else {
724 Py_ssize_t cur, i;
725
726 for (cur = start, i = 0; i < slicelength;
727 cur += step, i++) {
728 ((char *)ptr1)[cur] = ((char *)ptr2)[i];
729 }
730
731 return 0;
732 }
733 } else {
734 PyErr_SetString(PyExc_TypeError,
735 "buffer indices must be integers");
736 return -1;
737 }
738 }
739
740 /* Buffer methods */
741
742 static Py_ssize_t
743 buffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
744 {
745 Py_ssize_t size;
746 if ( idx != 0 ) {
747 PyErr_SetString(PyExc_SystemError,
748 "accessing non-existent buffer segment");
749 return -1;
750 }
751 if (!get_buf(self, pp, &size, READ_BUFFER))
752 return -1;
753 return size;
754 }
755
756 static Py_ssize_t
757 buffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
758 {
759 Py_ssize_t size;
760
761 if ( self->b_readonly )
762 {
763 PyErr_SetString(PyExc_TypeError, "buffer is read-only");
764 return -1;
765 }
766
767 if ( idx != 0 ) {
768 PyErr_SetString(PyExc_SystemError,
769 "accessing non-existent buffer segment");
770 return -1;
771 }
772 if (!get_buf(self, pp, &size, WRITE_BUFFER))
773 return -1;
774 return size;
775 }
776
777 static Py_ssize_t
778 buffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp)
779 {
780 void *ptr;
781 Py_ssize_t size;
782 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
783 return -1;
784 if (lenp)
785 *lenp = size;
786 return 1;
787 }
788
789 static Py_ssize_t
790 buffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp)
791 {
792 void *ptr;
793 Py_ssize_t size;
794 if ( idx != 0 ) {
795 PyErr_SetString(PyExc_SystemError,
796 "accessing non-existent buffer segment");
797 return -1;
798 }
799 if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
800 return -1;
801 *pp = (const char *)ptr;
802 return size;
803 }
804
805 static int buffer_getbuffer(PyBufferObject *self, Py_buffer *buf, int flags)
806 {
807 void *ptr;
808 Py_ssize_t size;
809 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
810 return -1;
811 return PyBuffer_FillInfo(buf, (PyObject*)self, ptr, size,
812 self->b_readonly, flags);
813 }
814
815 static PySequenceMethods buffer_as_sequence = {
816 (lenfunc)buffer_length, /*sq_length*/
817 (binaryfunc)buffer_concat, /*sq_concat*/
818 (ssizeargfunc)buffer_repeat, /*sq_repeat*/
819 (ssizeargfunc)buffer_item, /*sq_item*/
820 (ssizessizeargfunc)buffer_slice, /*sq_slice*/
821 (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
822 (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
823 };
824
825 static PyMappingMethods buffer_as_mapping = {
826 (lenfunc)buffer_length,
827 (binaryfunc)buffer_subscript,
828 (objobjargproc)buffer_ass_subscript,
829 };
830
831 static PyBufferProcs buffer_as_buffer = {
832 (readbufferproc)buffer_getreadbuf,
833 (writebufferproc)buffer_getwritebuf,
834 (segcountproc)buffer_getsegcount,
835 (charbufferproc)buffer_getcharbuf,
836 (getbufferproc)buffer_getbuffer,
837 };
838
839 PyTypeObject PyBuffer_Type = {
840 PyVarObject_HEAD_INIT(&PyType_Type, 0)
841 "buffer",
842 sizeof(PyBufferObject),
843 0,
844 (destructor)buffer_dealloc, /* tp_dealloc */
845 0, /* tp_print */
846 0, /* tp_getattr */
847 0, /* tp_setattr */
848 (cmpfunc)buffer_compare, /* tp_compare */
849 (reprfunc)buffer_repr, /* tp_repr */
850 0, /* tp_as_number */
851 &buffer_as_sequence, /* tp_as_sequence */
852 &buffer_as_mapping, /* tp_as_mapping */
853 (hashfunc)buffer_hash, /* tp_hash */
854 0, /* tp_call */
855 (reprfunc)buffer_str, /* tp_str */
856 PyObject_GenericGetAttr, /* tp_getattro */
857 0, /* tp_setattro */
858 &buffer_as_buffer, /* tp_as_buffer */
859 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
860 buffer_doc, /* tp_doc */
861 0, /* tp_traverse */
862 0, /* tp_clear */
863 0, /* tp_richcompare */
864 0, /* tp_weaklistoffset */
865 0, /* tp_iter */
866 0, /* tp_iternext */
867 0, /* tp_methods */
868 0, /* tp_members */
869 0, /* tp_getset */
870 0, /* tp_base */
871 0, /* tp_dict */
872 0, /* tp_descr_get */
873 0, /* tp_descr_set */
874 0, /* tp_dictoffset */
875 0, /* tp_init */
876 0, /* tp_alloc */
877 buffer_new, /* tp_new */
878 };