Changeset 388 for python/vendor/current/Objects/bufferobject.c
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Objects/bufferobject.c
r2 r388 6 6 7 7 typedef struct { 8 9 10 11 12 13 14 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 15 } PyBufferObject; 16 16 … … 25 25 static int 26 26 get_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size, 27 28 { 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 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 95 } 96 96 … … 98 98 static PyObject * 99 99 buffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr, 100 101 { 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 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 128 } 129 129 … … 131 131 buffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly) 132 132 { 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 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 152 } 153 153 … … 156 156 PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) 157 157 { 158 159 160 161 162 163 164 165 166 167 168 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 169 } 170 170 … … 172 172 PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) 173 173 { 174 175 176 177 178 179 180 181 182 183 184 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 185 } 186 186 … … 188 188 PyBuffer_FromMemory(void *ptr, Py_ssize_t size) 189 189 { 190 190 return buffer_from_memory(NULL, size, 0, ptr, 1); 191 191 } 192 192 … … 194 194 PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size) 195 195 { 196 196 return buffer_from_memory(NULL, size, 0, ptr, 0); 197 197 } 198 198 … … 200 200 PyBuffer_New(Py_ssize_t size) 201 201 { 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 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 228 } 229 229 … … 233 233 buffer_new(PyTypeObject *type, PyObject *args, PyObject *kw) 234 234 { 235 236 237 238 239 240 241 242 243 244 245 246 247 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 248 } 249 249 … … 260 260 buffer_dealloc(PyBufferObject *self) 261 261 { 262 263 262 Py_XDECREF(self->b_base); 263 PyObject_DEL(self); 264 264 } 265 265 … … 267 267 buffer_compare(PyBufferObject *self, PyBufferObject *other) 268 268 { 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 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 284 } 285 285 … … 287 287 buffer_repr(PyBufferObject *self) 288 288 { 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 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 305 } 306 306 … … 308 308 buffer_hash(PyBufferObject *self) 309 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; 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; 345 355 } 346 356 … … 348 358 buffer_str(PyBufferObject *self) 349 359 { 350 351 352 353 354 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); 355 365 } 356 366 … … 360 370 buffer_length(PyBufferObject *self) 361 371 { 362 363 364 365 366 372 void *ptr; 373 Py_ssize_t size; 374 if (!get_buf(self, &ptr, &size, ANY_BUFFER)) 375 return -1; 376 return size; 367 377 } 368 378 … … 370 380 buffer_concat(PyBufferObject *self, PyObject *other) 371 381 { 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 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; 419 429 } 420 430 … … 422 432 buffer_repeat(PyBufferObject *self, Py_ssize_t count) 423 433 { 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 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; 452 462 } 453 463 … … 455 465 buffer_item(PyBufferObject *self, Py_ssize_t idx) 456 466 { 457 458 459 460 461 462 463 464 465 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); 466 476 } 467 477 … … 469 479 buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right) 470 480 { 471 472 473 474 475 476 477 478 479 480 481 482 483 484 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); 485 495 } 486 496 … … 488 498 buffer_subscript(PyBufferObject *self, PyObject *item) 489 499 { 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 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 } 540 550 } 541 551 … … 543 553 buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other) 544 554 { 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 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; 591 601 } 592 602 … … 594 604 buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other) 595 605 { 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 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; 649 659 } 650 660 … … 652 662 buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value) 653 663 { 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 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 } 728 738 } 729 739 … … 733 743 buffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp) 734 744 { 735 736 737 738 739 740 741 742 743 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; 744 754 } 745 755 … … 747 757 buffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp) 748 758 { 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 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; 765 775 } 766 776 … … 768 778 buffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp) 769 779 { 770 771 772 773 774 775 776 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; 777 787 } 778 788 … … 780 790 buffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp) 781 791 { 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; 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); 793 813 } 794 814 795 815 static PySequenceMethods buffer_as_sequence = { 796 797 798 799 800 801 802 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*/ 803 823 }; 804 824 805 825 static PyMappingMethods buffer_as_mapping = { 806 807 808 826 (lenfunc)buffer_length, 827 (binaryfunc)buffer_subscript, 828 (objobjargproc)buffer_ass_subscript, 809 829 }; 810 830 811 831 static PyBufferProcs buffer_as_buffer = { 812 (readbufferproc)buffer_getreadbuf, 813 (writebufferproc)buffer_getwritebuf, 814 (segcountproc)buffer_getsegcount, 815 (charbufferproc)buffer_getcharbuf, 832 (readbufferproc)buffer_getreadbuf, 833 (writebufferproc)buffer_getwritebuf, 834 (segcountproc)buffer_getsegcount, 835 (charbufferproc)buffer_getcharbuf, 836 (getbufferproc)buffer_getbuffer, 816 837 }; 817 838 818 839 PyTypeObject PyBuffer_Type = { 819 820 821 822 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 */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 */ 857 878 };
Note:
See TracChangeset
for help on using the changeset viewer.