]> git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.2/Objects/bufferobject.c
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / 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 (offset + *size > count)
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 x = *p << 7;
338 while (--len >= 0)
339 x = (1000003*x) ^ *p++;
340 x ^= size;
341 if (x == -1)
342 x = -2;
343 self->b_hash = x;
344 return x;
345 }
346
347 static PyObject *
348 buffer_str(PyBufferObject *self)
349 {
350 void *ptr;
351 Py_ssize_t size;
352 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
353 return NULL;
354 return PyString_FromStringAndSize((const char *)ptr, size);
355 }
356
357 /* Sequence methods */
358
359 static Py_ssize_t
360 buffer_length(PyBufferObject *self)
361 {
362 void *ptr;
363 Py_ssize_t size;
364 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
365 return -1;
366 return size;
367 }
368
369 static PyObject *
370 buffer_concat(PyBufferObject *self, PyObject *other)
371 {
372 PyBufferProcs *pb = other->ob_type->tp_as_buffer;
373 void *ptr1, *ptr2;
374 char *p;
375 PyObject *ob;
376 Py_ssize_t size, count;
377
378 if ( pb == NULL ||
379 pb->bf_getreadbuffer == NULL ||
380 pb->bf_getsegcount == NULL )
381 {
382 PyErr_BadArgument();
383 return NULL;
384 }
385 if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
386 {
387 /* ### use a different exception type/message? */
388 PyErr_SetString(PyExc_TypeError,
389 "single-segment buffer object expected");
390 return NULL;
391 }
392
393 if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
394 return NULL;
395
396 /* optimize special case */
397 if ( size == 0 )
398 {
399 Py_INCREF(other);
400 return other;
401 }
402
403 if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
404 return NULL;
405
406 assert(count <= PY_SIZE_MAX - size);
407
408 ob = PyString_FromStringAndSize(NULL, size + count);
409 if ( ob == NULL )
410 return NULL;
411 p = PyString_AS_STRING(ob);
412 memcpy(p, ptr1, size);
413 memcpy(p + size, ptr2, count);
414
415 /* there is an extra byte in the string object, so this is safe */
416 p[size + count] = '\0';
417
418 return ob;
419 }
420
421 static PyObject *
422 buffer_repeat(PyBufferObject *self, Py_ssize_t count)
423 {
424 PyObject *ob;
425 register char *p;
426 void *ptr;
427 Py_ssize_t size;
428
429 if ( count < 0 )
430 count = 0;
431 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
432 return NULL;
433 if (count > PY_SSIZE_T_MAX / size) {
434 PyErr_SetString(PyExc_MemoryError, "result too large");
435 return NULL;
436 }
437 ob = PyString_FromStringAndSize(NULL, size * count);
438 if ( ob == NULL )
439 return NULL;
440
441 p = PyString_AS_STRING(ob);
442 while ( count-- )
443 {
444 memcpy(p, ptr, size);
445 p += size;
446 }
447
448 /* there is an extra byte in the string object, so this is safe */
449 *p = '\0';
450
451 return ob;
452 }
453
454 static PyObject *
455 buffer_item(PyBufferObject *self, Py_ssize_t idx)
456 {
457 void *ptr;
458 Py_ssize_t size;
459 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
460 return NULL;
461 if ( idx < 0 || idx >= size ) {
462 PyErr_SetString(PyExc_IndexError, "buffer index out of range");
463 return NULL;
464 }
465 return PyString_FromStringAndSize((char *)ptr + idx, 1);
466 }
467
468 static PyObject *
469 buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
470 {
471 void *ptr;
472 Py_ssize_t size;
473 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
474 return NULL;
475 if ( left < 0 )
476 left = 0;
477 if ( right < 0 )
478 right = 0;
479 if ( right > size )
480 right = size;
481 if ( right < left )
482 right = left;
483 return PyString_FromStringAndSize((char *)ptr + left,
484 right - left);
485 }
486
487 static PyObject *
488 buffer_subscript(PyBufferObject *self, PyObject *item)
489 {
490 void *p;
491 Py_ssize_t size;
492
493 if (!get_buf(self, &p, &size, ANY_BUFFER))
494 return NULL;
495 if (PyIndex_Check(item)) {
496 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
497 if (i == -1 && PyErr_Occurred())
498 return NULL;
499 if (i < 0)
500 i += size;
501 return buffer_item(self, i);
502 }
503 else if (PySlice_Check(item)) {
504 Py_ssize_t start, stop, step, slicelength, cur, i;
505
506 if (PySlice_GetIndicesEx((PySliceObject*)item, size,
507 &start, &stop, &step, &slicelength) < 0) {
508 return NULL;
509 }
510
511 if (slicelength <= 0)
512 return PyString_FromStringAndSize("", 0);
513 else if (step == 1)
514 return PyString_FromStringAndSize((char *)p + start,
515 stop - start);
516 else {
517 PyObject *result;
518 char *source_buf = (char *)p;
519 char *result_buf = (char *)PyMem_Malloc(slicelength);
520
521 if (result_buf == NULL)
522 return PyErr_NoMemory();
523
524 for (cur = start, i = 0; i < slicelength;
525 cur += step, i++) {
526 result_buf[i] = source_buf[cur];
527 }
528
529 result = PyString_FromStringAndSize(result_buf,
530 slicelength);
531 PyMem_Free(result_buf);
532 return result;
533 }
534 }
535 else {
536 PyErr_SetString(PyExc_TypeError,
537 "sequence index must be integer");
538 return NULL;
539 }
540 }
541
542 static int
543 buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
544 {
545 PyBufferProcs *pb;
546 void *ptr1, *ptr2;
547 Py_ssize_t size;
548 Py_ssize_t count;
549
550 if ( self->b_readonly ) {
551 PyErr_SetString(PyExc_TypeError,
552 "buffer is read-only");
553 return -1;
554 }
555
556 if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
557 return -1;
558
559 if (idx < 0 || idx >= size) {
560 PyErr_SetString(PyExc_IndexError,
561 "buffer assignment index out of range");
562 return -1;
563 }
564
565 pb = other ? other->ob_type->tp_as_buffer : NULL;
566 if ( pb == NULL ||
567 pb->bf_getreadbuffer == NULL ||
568 pb->bf_getsegcount == NULL )
569 {
570 PyErr_BadArgument();
571 return -1;
572 }
573 if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
574 {
575 /* ### use a different exception type/message? */
576 PyErr_SetString(PyExc_TypeError,
577 "single-segment buffer object expected");
578 return -1;
579 }
580
581 if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
582 return -1;
583 if ( count != 1 ) {
584 PyErr_SetString(PyExc_TypeError,
585 "right operand must be a single byte");
586 return -1;
587 }
588
589 ((char *)ptr1)[idx] = *(char *)ptr2;
590 return 0;
591 }
592
593 static int
594 buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
595 {
596 PyBufferProcs *pb;
597 void *ptr1, *ptr2;
598 Py_ssize_t size;
599 Py_ssize_t slice_len;
600 Py_ssize_t count;
601
602 if ( self->b_readonly ) {
603 PyErr_SetString(PyExc_TypeError,
604 "buffer is read-only");
605 return -1;
606 }
607
608 pb = other ? other->ob_type->tp_as_buffer : NULL;
609 if ( pb == NULL ||
610 pb->bf_getreadbuffer == NULL ||
611 pb->bf_getsegcount == NULL )
612 {
613 PyErr_BadArgument();
614 return -1;
615 }
616 if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
617 {
618 /* ### use a different exception type/message? */
619 PyErr_SetString(PyExc_TypeError,
620 "single-segment buffer object expected");
621 return -1;
622 }
623 if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
624 return -1;
625 if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
626 return -1;
627
628 if ( left < 0 )
629 left = 0;
630 else if ( left > size )
631 left = size;
632 if ( right < left )
633 right = left;
634 else if ( right > size )
635 right = size;
636 slice_len = right - left;
637
638 if ( count != slice_len ) {
639 PyErr_SetString(
640 PyExc_TypeError,
641 "right operand length must match slice length");
642 return -1;
643 }
644
645 if ( slice_len )
646 memcpy((char *)ptr1 + left, ptr2, slice_len);
647
648 return 0;
649 }
650
651 static int
652 buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
653 {
654 PyBufferProcs *pb;
655 void *ptr1, *ptr2;
656 Py_ssize_t selfsize;
657 Py_ssize_t othersize;
658
659 if ( self->b_readonly ) {
660 PyErr_SetString(PyExc_TypeError,
661 "buffer is read-only");
662 return -1;
663 }
664
665 pb = value ? value->ob_type->tp_as_buffer : NULL;
666 if ( pb == NULL ||
667 pb->bf_getreadbuffer == NULL ||
668 pb->bf_getsegcount == NULL )
669 {
670 PyErr_BadArgument();
671 return -1;
672 }
673 if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
674 {
675 /* ### use a different exception type/message? */
676 PyErr_SetString(PyExc_TypeError,
677 "single-segment buffer object expected");
678 return -1;
679 }
680 if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
681 return -1;
682 if (PyIndex_Check(item)) {
683 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
684 if (i == -1 && PyErr_Occurred())
685 return -1;
686 if (i < 0)
687 i += selfsize;
688 return buffer_ass_item(self, i, value);
689 }
690 else if (PySlice_Check(item)) {
691 Py_ssize_t start, stop, step, slicelength;
692
693 if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
694 &start, &stop, &step, &slicelength) < 0)
695 return -1;
696
697 if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
698 return -1;
699
700 if (othersize != slicelength) {
701 PyErr_SetString(
702 PyExc_TypeError,
703 "right operand length must match slice length");
704 return -1;
705 }
706
707 if (slicelength == 0)
708 return 0;
709 else if (step == 1) {
710 memcpy((char *)ptr1 + start, ptr2, slicelength);
711 return 0;
712 }
713 else {
714 Py_ssize_t cur, i;
715
716 for (cur = start, i = 0; i < slicelength;
717 cur += step, i++) {
718 ((char *)ptr1)[cur] = ((char *)ptr2)[i];
719 }
720
721 return 0;
722 }
723 } else {
724 PyErr_SetString(PyExc_TypeError,
725 "buffer indices must be integers");
726 return -1;
727 }
728 }
729
730 /* Buffer methods */
731
732 static Py_ssize_t
733 buffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
734 {
735 Py_ssize_t size;
736 if ( idx != 0 ) {
737 PyErr_SetString(PyExc_SystemError,
738 "accessing non-existent buffer segment");
739 return -1;
740 }
741 if (!get_buf(self, pp, &size, READ_BUFFER))
742 return -1;
743 return size;
744 }
745
746 static Py_ssize_t
747 buffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
748 {
749 Py_ssize_t size;
750
751 if ( self->b_readonly )
752 {
753 PyErr_SetString(PyExc_TypeError, "buffer is read-only");
754 return -1;
755 }
756
757 if ( idx != 0 ) {
758 PyErr_SetString(PyExc_SystemError,
759 "accessing non-existent buffer segment");
760 return -1;
761 }
762 if (!get_buf(self, pp, &size, WRITE_BUFFER))
763 return -1;
764 return size;
765 }
766
767 static Py_ssize_t
768 buffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp)
769 {
770 void *ptr;
771 Py_ssize_t size;
772 if (!get_buf(self, &ptr, &size, ANY_BUFFER))
773 return -1;
774 if (lenp)
775 *lenp = size;
776 return 1;
777 }
778
779 static Py_ssize_t
780 buffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp)
781 {
782 void *ptr;
783 Py_ssize_t size;
784 if ( idx != 0 ) {
785 PyErr_SetString(PyExc_SystemError,
786 "accessing non-existent buffer segment");
787 return -1;
788 }
789 if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
790 return -1;
791 *pp = (const char *)ptr;
792 return size;
793 }
794
795 static PySequenceMethods buffer_as_sequence = {
796 (lenfunc)buffer_length, /*sq_length*/
797 (binaryfunc)buffer_concat, /*sq_concat*/
798 (ssizeargfunc)buffer_repeat, /*sq_repeat*/
799 (ssizeargfunc)buffer_item, /*sq_item*/
800 (ssizessizeargfunc)buffer_slice, /*sq_slice*/
801 (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
802 (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
803 };
804
805 static PyMappingMethods buffer_as_mapping = {
806 (lenfunc)buffer_length,
807 (binaryfunc)buffer_subscript,
808 (objobjargproc)buffer_ass_subscript,
809 };
810
811 static PyBufferProcs buffer_as_buffer = {
812 (readbufferproc)buffer_getreadbuf,
813 (writebufferproc)buffer_getwritebuf,
814 (segcountproc)buffer_getsegcount,
815 (charbufferproc)buffer_getcharbuf,
816 };
817
818 PyTypeObject PyBuffer_Type = {
819 PyVarObject_HEAD_INIT(&PyType_Type, 0)
820 "buffer",
821 sizeof(PyBufferObject),
822 0,
823 (destructor)buffer_dealloc, /* tp_dealloc */
824 0, /* tp_print */
825 0, /* tp_getattr */
826 0, /* tp_setattr */
827 (cmpfunc)buffer_compare, /* tp_compare */
828 (reprfunc)buffer_repr, /* tp_repr */
829 0, /* tp_as_number */
830 &buffer_as_sequence, /* tp_as_sequence */
831 &buffer_as_mapping, /* tp_as_mapping */
832 (hashfunc)buffer_hash, /* tp_hash */
833 0, /* tp_call */
834 (reprfunc)buffer_str, /* tp_str */
835 PyObject_GenericGetAttr, /* tp_getattro */
836 0, /* tp_setattro */
837 &buffer_as_buffer, /* tp_as_buffer */
838 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER, /* tp_flags */
839 buffer_doc, /* tp_doc */
840 0, /* tp_traverse */
841 0, /* tp_clear */
842 0, /* tp_richcompare */
843 0, /* tp_weaklistoffset */
844 0, /* tp_iter */
845 0, /* tp_iternext */
846 0, /* tp_methods */
847 0, /* tp_members */
848 0, /* tp_getset */
849 0, /* tp_base */
850 0, /* tp_dict */
851 0, /* tp_descr_get */
852 0, /* tp_descr_set */
853 0, /* tp_dictoffset */
854 0, /* tp_init */
855 0, /* tp_alloc */
856 buffer_new, /* tp_new */
857 };