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 }; 879