1 /* Memoryview object implementation */ 2 3 #include "Python.h" 4 #include "pystrhex.h" 5 #include <stddef.h> 6 7 8 /****************************************************************************/ 9 /* ManagedBuffer Object */ 10 /****************************************************************************/ 11 12 /* 13 ManagedBuffer Object: 14 --------------------- 15 16 The purpose of this object is to facilitate the handling of chained 17 memoryviews that have the same underlying exporting object. PEP-3118 18 allows the underlying object to change while a view is exported. This 19 could lead to unexpected results when constructing a new memoryview 20 from an existing memoryview. 21 22 Rather than repeatedly redirecting buffer requests to the original base 23 object, all chained memoryviews use a single buffer snapshot. This 24 snapshot is generated by the constructor _PyManagedBuffer_FromObject(). 25 26 Ownership rules: 27 ---------------- 28 29 The master buffer inside a managed buffer is filled in by the original 30 base object. shape, strides, suboffsets and format are read-only for 31 all consumers. 32 33 A memoryview's buffer is a private copy of the exporter's buffer. shape, 34 strides and suboffsets belong to the memoryview and are thus writable. 35 36 If a memoryview itself exports several buffers via memory_getbuf(), all 37 buffer copies share shape, strides and suboffsets. In this case, the 38 arrays are NOT writable. 39 40 Reference count assumptions: 41 ---------------------------- 42 43 The 'obj' member of a Py_buffer must either be NULL or refer to the 44 exporting base object. In the Python codebase, all getbufferprocs 45 return a new reference to view.obj (example: bytes_buffer_getbuffer()). 46 47 PyBuffer_Release() decrements view.obj (if non-NULL), so the 48 releasebufferprocs must NOT decrement view.obj. 49 */ 50 51 52 #define CHECK_MBUF_RELEASED(mbuf) \ 53 if (((_PyManagedBufferObject *)mbuf)->flags&_Py_MANAGED_BUFFER_RELEASED) { \ 54 PyErr_SetString(PyExc_ValueError, \ 55 "operation forbidden on released memoryview object"); \ 56 return NULL; \ 57 } 58 59 60 static inline _PyManagedBufferObject * 61 mbuf_alloc(void) 62 { 63 _PyManagedBufferObject *mbuf; 64 65 mbuf = (_PyManagedBufferObject *) 66 PyObject_GC_New(_PyManagedBufferObject, &_PyManagedBuffer_Type); 67 if (mbuf == NULL) 68 return NULL; 69 mbuf->flags = 0; 70 mbuf->exports = 0; 71 mbuf->master.obj = NULL; 72 _PyObject_GC_TRACK(mbuf); 73 74 return mbuf; 75 } 76 77 static PyObject * 78 _PyManagedBuffer_FromObject(PyObject *base) 79 { 80 _PyManagedBufferObject *mbuf; 81 82 mbuf = mbuf_alloc(); 83 if (mbuf == NULL) 84 return NULL; 85 86 if (PyObject_GetBuffer(base, &mbuf->master, PyBUF_FULL_RO) < 0) { 87 mbuf->master.obj = NULL; 88 Py_DECREF(mbuf); 89 return NULL; 90 } 91 92 return (PyObject *)mbuf; 93 } 94 95 static void 96 mbuf_release(_PyManagedBufferObject *self) 97 { 98 if (self->flags&_Py_MANAGED_BUFFER_RELEASED) 99 return; 100 101 /* NOTE: at this point self->exports can still be > 0 if this function 102 is called from mbuf_clear() to break up a reference cycle. */ 103 self->flags |= _Py_MANAGED_BUFFER_RELEASED; 104 105 /* PyBuffer_Release() decrements master->obj and sets it to NULL. */ 106 _PyObject_GC_UNTRACK(self); 107 PyBuffer_Release(&self->master); 108 } 109 110 static void 111 mbuf_dealloc(_PyManagedBufferObject *self) 112 { 113 assert(self->exports == 0); 114 mbuf_release(self); 115 if (self->flags&_Py_MANAGED_BUFFER_FREE_FORMAT) 116 PyMem_Free(self->master.format); 117 PyObject_GC_Del(self); 118 } 119 120 static int 121 mbuf_traverse(_PyManagedBufferObject *self, visitproc visit, void *arg) 122 { 123 Py_VISIT(self->master.obj); 124 return 0; 125 } 126 127 static int 128 mbuf_clear(_PyManagedBufferObject *self) 129 { 130 assert(self->exports >= 0); 131 mbuf_release(self); 132 return 0; 133 } 134 135 PyTypeObject _PyManagedBuffer_Type = { 136 PyVarObject_HEAD_INIT(&PyType_Type, 0) 137 "managedbuffer", 138 sizeof(_PyManagedBufferObject), 139 0, 140 (destructor)mbuf_dealloc, /* tp_dealloc */ 141 0, /* tp_print */ 142 0, /* tp_getattr */ 143 0, /* tp_setattr */ 144 0, /* tp_reserved */ 145 0, /* tp_repr */ 146 0, /* tp_as_number */ 147 0, /* tp_as_sequence */ 148 0, /* tp_as_mapping */ 149 0, /* tp_hash */ 150 0, /* tp_call */ 151 0, /* tp_str */ 152 PyObject_GenericGetAttr, /* tp_getattro */ 153 0, /* tp_setattro */ 154 0, /* tp_as_buffer */ 155 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 156 0, /* tp_doc */ 157 (traverseproc)mbuf_traverse, /* tp_traverse */ 158 (inquiry)mbuf_clear /* tp_clear */ 159 }; 160 161 162 /****************************************************************************/ 163 /* MemoryView Object */ 164 /****************************************************************************/ 165 166 /* In the process of breaking reference cycles mbuf_release() can be 167 called before memory_release(). */ 168 #define BASE_INACCESSIBLE(mv) \ 169 (((PyMemoryViewObject *)mv)->flags&_Py_MEMORYVIEW_RELEASED || \ 170 ((PyMemoryViewObject *)mv)->mbuf->flags&_Py_MANAGED_BUFFER_RELEASED) 171 172 #define CHECK_RELEASED(mv) \ 173 if (BASE_INACCESSIBLE(mv)) { \ 174 PyErr_SetString(PyExc_ValueError, \ 175 "operation forbidden on released memoryview object"); \ 176 return NULL; \ 177 } 178 179 #define CHECK_RELEASED_INT(mv) \ 180 if (BASE_INACCESSIBLE(mv)) { \ 181 PyErr_SetString(PyExc_ValueError, \ 182 "operation forbidden on released memoryview object"); \ 183 return -1; \ 184 } 185 186 #define CHECK_LIST_OR_TUPLE(v) \ 187 if (!PyList_Check(v) && !PyTuple_Check(v)) { \ 188 PyErr_SetString(PyExc_TypeError, \ 189 #v " must be a list or a tuple"); \ 190 return NULL; \ 191 } 192 193 #define VIEW_ADDR(mv) (&((PyMemoryViewObject *)mv)->view) 194 195 /* Check for the presence of suboffsets in the first dimension. */ 196 #define HAVE_PTR(suboffsets, dim) (suboffsets && suboffsets[dim] >= 0) 197 /* Adjust ptr if suboffsets are present. */ 198 #define ADJUST_PTR(ptr, suboffsets, dim) \ 199 (HAVE_PTR(suboffsets, dim) ? *((char**)ptr) + suboffsets[dim] : ptr) 200 201 /* Memoryview buffer properties */ 202 #define MV_C_CONTIGUOUS(flags) (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C)) 203 #define MV_F_CONTIGUOUS(flags) \ 204 (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_FORTRAN)) 205 #define MV_ANY_CONTIGUOUS(flags) \ 206 (flags&(_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN)) 207 208 /* Fast contiguity test. Caller must ensure suboffsets==NULL and ndim==1. */ 209 #define MV_CONTIGUOUS_NDIM1(view) \ 210 ((view)->shape[0] == 1 || (view)->strides[0] == (view)->itemsize) 211 212 /* getbuffer() requests */ 213 #define REQ_INDIRECT(flags) ((flags&PyBUF_INDIRECT) == PyBUF_INDIRECT) 214 #define REQ_C_CONTIGUOUS(flags) ((flags&PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) 215 #define REQ_F_CONTIGUOUS(flags) ((flags&PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) 216 #define REQ_ANY_CONTIGUOUS(flags) ((flags&PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS) 217 #define REQ_STRIDES(flags) ((flags&PyBUF_STRIDES) == PyBUF_STRIDES) 218 #define REQ_SHAPE(flags) ((flags&PyBUF_ND) == PyBUF_ND) 219 #define REQ_WRITABLE(flags) (flags&PyBUF_WRITABLE) 220 #define REQ_FORMAT(flags) (flags&PyBUF_FORMAT) 221 222 223 PyDoc_STRVAR(memory_doc, 224 "memoryview(object)\n--\n\ 225 \n\ 226 Create a new memoryview object which references the given object."); 227 228 229 /**************************************************************************/ 230 /* Copy memoryview buffers */ 231 /**************************************************************************/ 232 233 /* The functions in this section take a source and a destination buffer 234 with the same logical structure: format, itemsize, ndim and shape 235 are identical, with ndim > 0. 236 237 NOTE: All buffers are assumed to have PyBUF_FULL information, which 238 is the case for memoryviews! */ 239 240 241 /* Assumptions: ndim >= 1. The macro tests for a corner case that should 242 perhaps be explicitly forbidden in the PEP. */ 243 #define HAVE_SUBOFFSETS_IN_LAST_DIM(view) \ 244 (view->suboffsets && view->suboffsets[dest->ndim-1] >= 0) 245 246 static inline int 247 last_dim_is_contiguous(const Py_buffer *dest, const Py_buffer *src) 248 { 249 assert(dest->ndim > 0 && src->ndim > 0); 250 return (!HAVE_SUBOFFSETS_IN_LAST_DIM(dest) && 251 !HAVE_SUBOFFSETS_IN_LAST_DIM(src) && 252 dest->strides[dest->ndim-1] == dest->itemsize && 253 src->strides[src->ndim-1] == src->itemsize); 254 } 255 256 /* This is not a general function for determining format equivalence. 257 It is used in copy_single() and copy_buffer() to weed out non-matching 258 formats. Skipping the '@' character is specifically used in slice 259 assignments, where the lvalue is already known to have a single character 260 format. This is a performance hack that could be rewritten (if properly 261 benchmarked). */ 262 static inline int 263 equiv_format(const Py_buffer *dest, const Py_buffer *src) 264 { 265 const char *dfmt, *sfmt; 266 267 assert(dest->format && src->format); 268 dfmt = dest->format[0] == '@' ? dest->format+1 : dest->format; 269 sfmt = src->format[0] == '@' ? src->format+1 : src->format; 270 271 if (strcmp(dfmt, sfmt) != 0 || 272 dest->itemsize != src->itemsize) { 273 return 0; 274 } 275 276 return 1; 277 } 278 279 /* Two shapes are equivalent if they are either equal or identical up 280 to a zero element at the same position. For example, in NumPy arrays 281 the shapes [1, 0, 5] and [1, 0, 7] are equivalent. */ 282 static inline int 283 equiv_shape(const Py_buffer *dest, const Py_buffer *src) 284 { 285 int i; 286 287 if (dest->ndim != src->ndim) 288 return 0; 289 290 for (i = 0; i < dest->ndim; i++) { 291 if (dest->shape[i] != src->shape[i]) 292 return 0; 293 if (dest->shape[i] == 0) 294 break; 295 } 296 297 return 1; 298 } 299 300 /* Check that the logical structure of the destination and source buffers 301 is identical. */ 302 static int 303 equiv_structure(const Py_buffer *dest, const Py_buffer *src) 304 { 305 if (!equiv_format(dest, src) || 306 !equiv_shape(dest, src)) { 307 PyErr_SetString(PyExc_ValueError, 308 "memoryview assignment: lvalue and rvalue have different " 309 "structures"); 310 return 0; 311 } 312 313 return 1; 314 } 315 316 /* Base case for recursive multi-dimensional copying. Contiguous arrays are 317 copied with very little overhead. Assumptions: ndim == 1, mem == NULL or 318 sizeof(mem) == shape[0] * itemsize. */ 319 static void 320 copy_base(const Py_ssize_t *shape, Py_ssize_t itemsize, 321 char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets, 322 char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets, 323 char *mem) 324 { 325 if (mem == NULL) { /* contiguous */ 326 Py_ssize_t size = shape[0] * itemsize; 327 if (dptr + size < sptr || sptr + size < dptr) 328 memcpy(dptr, sptr, size); /* no overlapping */ 329 else 330 memmove(dptr, sptr, size); 331 } 332 else { 333 char *p; 334 Py_ssize_t i; 335 for (i=0, p=mem; i < shape[0]; p+=itemsize, sptr+=sstrides[0], i++) { 336 char *xsptr = ADJUST_PTR(sptr, ssuboffsets, 0); 337 memcpy(p, xsptr, itemsize); 338 } 339 for (i=0, p=mem; i < shape[0]; p+=itemsize, dptr+=dstrides[0], i++) { 340 char *xdptr = ADJUST_PTR(dptr, dsuboffsets, 0); 341 memcpy(xdptr, p, itemsize); 342 } 343 } 344 345 } 346 347 /* Recursively copy a source buffer to a destination buffer. The two buffers 348 have the same ndim, shape and itemsize. */ 349 static void 350 copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize, 351 char *dptr, const Py_ssize_t *dstrides, const Py_ssize_t *dsuboffsets, 352 char *sptr, const Py_ssize_t *sstrides, const Py_ssize_t *ssuboffsets, 353 char *mem) 354 { 355 Py_ssize_t i; 356 357 assert(ndim >= 1); 358 359 if (ndim == 1) { 360 copy_base(shape, itemsize, 361 dptr, dstrides, dsuboffsets, 362 sptr, sstrides, ssuboffsets, 363 mem); 364 return; 365 } 366 367 for (i = 0; i < shape[0]; dptr+=dstrides[0], sptr+=sstrides[0], i++) { 368 char *xdptr = ADJUST_PTR(dptr, dsuboffsets, 0); 369 char *xsptr = ADJUST_PTR(sptr, ssuboffsets, 0); 370 371 copy_rec(shape+1, ndim-1, itemsize, 372 xdptr, dstrides+1, dsuboffsets ? dsuboffsets+1 : NULL, 373 xsptr, sstrides+1, ssuboffsets ? ssuboffsets+1 : NULL, 374 mem); 375 } 376 } 377 378 /* Faster copying of one-dimensional arrays. */ 379 static int 380 copy_single(Py_buffer *dest, Py_buffer *src) 381 { 382 char *mem = NULL; 383 384 assert(dest->ndim == 1); 385 386 if (!equiv_structure(dest, src)) 387 return -1; 388 389 if (!last_dim_is_contiguous(dest, src)) { 390 mem = PyMem_Malloc(dest->shape[0] * dest->itemsize); 391 if (mem == NULL) { 392 PyErr_NoMemory(); 393 return -1; 394 } 395 } 396 397 copy_base(dest->shape, dest->itemsize, 398 dest->buf, dest->strides, dest->suboffsets, 399 src->buf, src->strides, src->suboffsets, 400 mem); 401 402 if (mem) 403 PyMem_Free(mem); 404 405 return 0; 406 } 407 408 /* Recursively copy src to dest. Both buffers must have the same basic 409 structure. Copying is atomic, the function never fails with a partial 410 copy. */ 411 static int 412 copy_buffer(Py_buffer *dest, Py_buffer *src) 413 { 414 char *mem = NULL; 415 416 assert(dest->ndim > 0); 417 418 if (!equiv_structure(dest, src)) 419 return -1; 420 421 if (!last_dim_is_contiguous(dest, src)) { 422 mem = PyMem_Malloc(dest->shape[dest->ndim-1] * dest->itemsize); 423 if (mem == NULL) { 424 PyErr_NoMemory(); 425 return -1; 426 } 427 } 428 429 copy_rec(dest->shape, dest->ndim, dest->itemsize, 430 dest->buf, dest->strides, dest->suboffsets, 431 src->buf, src->strides, src->suboffsets, 432 mem); 433 434 if (mem) 435 PyMem_Free(mem); 436 437 return 0; 438 } 439 440 /* Initialize strides for a C-contiguous array. */ 441 static inline void 442 init_strides_from_shape(Py_buffer *view) 443 { 444 Py_ssize_t i; 445 446 assert(view->ndim > 0); 447 448 view->strides[view->ndim-1] = view->itemsize; 449 for (i = view->ndim-2; i >= 0; i--) 450 view->strides[i] = view->strides[i+1] * view->shape[i+1]; 451 } 452 453 /* Initialize strides for a Fortran-contiguous array. */ 454 static inline void 455 init_fortran_strides_from_shape(Py_buffer *view) 456 { 457 Py_ssize_t i; 458 459 assert(view->ndim > 0); 460 461 view->strides[0] = view->itemsize; 462 for (i = 1; i < view->ndim; i++) 463 view->strides[i] = view->strides[i-1] * view->shape[i-1]; 464 } 465 466 /* Copy src to a contiguous representation. order is one of 'C', 'F' (Fortran) 467 or 'A' (Any). Assumptions: src has PyBUF_FULL information, src->ndim >= 1, 468 len(mem) == src->len. */ 469 static int 470 buffer_to_contiguous(char *mem, Py_buffer *src, char order) 471 { 472 Py_buffer dest; 473 Py_ssize_t *strides; 474 int ret; 475 476 assert(src->ndim >= 1); 477 assert(src->shape != NULL); 478 assert(src->strides != NULL); 479 480 strides = PyMem_Malloc(src->ndim * (sizeof *src->strides)); 481 if (strides == NULL) { 482 PyErr_NoMemory(); 483 return -1; 484 } 485 486 /* initialize dest */ 487 dest = *src; 488 dest.buf = mem; 489 /* shape is constant and shared: the logical representation of the 490 array is unaltered. */ 491 492 /* The physical representation determined by strides (and possibly 493 suboffsets) may change. */ 494 dest.strides = strides; 495 if (order == 'C' || order == 'A') { 496 init_strides_from_shape(&dest); 497 } 498 else { 499 init_fortran_strides_from_shape(&dest); 500 } 501 502 dest.suboffsets = NULL; 503 504 ret = copy_buffer(&dest, src); 505 506 PyMem_Free(strides); 507 return ret; 508 } 509 510 511 /****************************************************************************/ 512 /* Constructors */ 513 /****************************************************************************/ 514 515 /* Initialize values that are shared with the managed buffer. */ 516 static inline void 517 init_shared_values(Py_buffer *dest, const Py_buffer *src) 518 { 519 dest->obj = src->obj; 520 dest->buf = src->buf; 521 dest->len = src->len; 522 dest->itemsize = src->itemsize; 523 dest->readonly = src->readonly; 524 dest->format = src->format ? src->format : "B"; 525 dest->internal = src->internal; 526 } 527 528 /* Copy shape and strides. Reconstruct missing values. */ 529 static void 530 init_shape_strides(Py_buffer *dest, const Py_buffer *src) 531 { 532 Py_ssize_t i; 533 534 if (src->ndim == 0) { 535 dest->shape = NULL; 536 dest->strides = NULL; 537 return; 538 } 539 if (src->ndim == 1) { 540 dest->shape[0] = src->shape ? src->shape[0] : src->len / src->itemsize; 541 dest->strides[0] = src->strides ? src->strides[0] : src->itemsize; 542 return; 543 } 544 545 for (i = 0; i < src->ndim; i++) 546 dest->shape[i] = src->shape[i]; 547 if (src->strides) { 548 for (i = 0; i < src->ndim; i++) 549 dest->strides[i] = src->strides[i]; 550 } 551 else { 552 init_strides_from_shape(dest); 553 } 554 } 555 556 static inline void 557 init_suboffsets(Py_buffer *dest, const Py_buffer *src) 558 { 559 Py_ssize_t i; 560 561 if (src->suboffsets == NULL) { 562 dest->suboffsets = NULL; 563 return; 564 } 565 for (i = 0; i < src->ndim; i++) 566 dest->suboffsets[i] = src->suboffsets[i]; 567 } 568 569 /* len = product(shape) * itemsize */ 570 static inline void 571 init_len(Py_buffer *view) 572 { 573 Py_ssize_t i, len; 574 575 len = 1; 576 for (i = 0; i < view->ndim; i++) 577 len *= view->shape[i]; 578 len *= view->itemsize; 579 580 view->len = len; 581 } 582 583 /* Initialize memoryview buffer properties. */ 584 static void 585 init_flags(PyMemoryViewObject *mv) 586 { 587 const Py_buffer *view = &mv->view; 588 int flags = 0; 589 590 switch (view->ndim) { 591 case 0: 592 flags |= (_Py_MEMORYVIEW_SCALAR|_Py_MEMORYVIEW_C| 593 _Py_MEMORYVIEW_FORTRAN); 594 break; 595 case 1: 596 if (MV_CONTIGUOUS_NDIM1(view)) 597 flags |= (_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN); 598 break; 599 default: 600 if (PyBuffer_IsContiguous(view, 'C')) 601 flags |= _Py_MEMORYVIEW_C; 602 if (PyBuffer_IsContiguous(view, 'F')) 603 flags |= _Py_MEMORYVIEW_FORTRAN; 604 break; 605 } 606 607 if (view->suboffsets) { 608 flags |= _Py_MEMORYVIEW_PIL; 609 flags &= ~(_Py_MEMORYVIEW_C|_Py_MEMORYVIEW_FORTRAN); 610 } 611 612 mv->flags = flags; 613 } 614 615 /* Allocate a new memoryview and perform basic initialization. New memoryviews 616 are exclusively created through the mbuf_add functions. */ 617 static inline PyMemoryViewObject * 618 memory_alloc(int ndim) 619 { 620 PyMemoryViewObject *mv; 621 622 mv = (PyMemoryViewObject *) 623 PyObject_GC_NewVar(PyMemoryViewObject, &PyMemoryView_Type, 3*ndim); 624 if (mv == NULL) 625 return NULL; 626 627 mv->mbuf = NULL; 628 mv->hash = -1; 629 mv->flags = 0; 630 mv->exports = 0; 631 mv->view.ndim = ndim; 632 mv->view.shape = mv->ob_array; 633 mv->view.strides = mv->ob_array + ndim; 634 mv->view.suboffsets = mv->ob_array + 2 * ndim; 635 mv->weakreflist = NULL; 636 637 _PyObject_GC_TRACK(mv); 638 return mv; 639 } 640 641 /* 642 Return a new memoryview that is registered with mbuf. If src is NULL, 643 use mbuf->master as the underlying buffer. Otherwise, use src. 644 645 The new memoryview has full buffer information: shape and strides 646 are always present, suboffsets as needed. Arrays are copied to 647 the memoryview's ob_array field. 648 */ 649 static PyObject * 650 mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src) 651 { 652 PyMemoryViewObject *mv; 653 Py_buffer *dest; 654 655 if (src == NULL) 656 src = &mbuf->master; 657 658 if (src->ndim > PyBUF_MAX_NDIM) { 659 PyErr_SetString(PyExc_ValueError, 660 "memoryview: number of dimensions must not exceed " 661 Py_STRINGIFY(PyBUF_MAX_NDIM)); 662 return NULL; 663 } 664 665 mv = memory_alloc(src->ndim); 666 if (mv == NULL) 667 return NULL; 668 669 dest = &mv->view; 670 init_shared_values(dest, src); 671 init_shape_strides(dest, src); 672 init_suboffsets(dest, src); 673 init_flags(mv); 674 675 mv->mbuf = mbuf; 676 Py_INCREF(mbuf); 677 mbuf->exports++; 678 679 return (PyObject *)mv; 680 } 681 682 /* Register an incomplete view: shape, strides, suboffsets and flags still 683 need to be initialized. Use 'ndim' instead of src->ndim to determine the 684 size of the memoryview's ob_array. 685 686 Assumption: ndim <= PyBUF_MAX_NDIM. */ 687 static PyObject * 688 mbuf_add_incomplete_view(_PyManagedBufferObject *mbuf, const Py_buffer *src, 689 int ndim) 690 { 691 PyMemoryViewObject *mv; 692 Py_buffer *dest; 693 694 if (src == NULL) 695 src = &mbuf->master; 696 697 assert(ndim <= PyBUF_MAX_NDIM); 698 699 mv = memory_alloc(ndim); 700 if (mv == NULL) 701 return NULL; 702 703 dest = &mv->view; 704 init_shared_values(dest, src); 705 706 mv->mbuf = mbuf; 707 Py_INCREF(mbuf); 708 mbuf->exports++; 709 710 return (PyObject *)mv; 711 } 712 713 /* Expose a raw memory area as a view of contiguous bytes. flags can be 714 PyBUF_READ or PyBUF_WRITE. view->format is set to "B" (unsigned bytes). 715 The memoryview has complete buffer information. */ 716 PyObject * 717 PyMemoryView_FromMemory(char *mem, Py_ssize_t size, int flags) 718 { 719 _PyManagedBufferObject *mbuf; 720 PyObject *mv; 721 int readonly; 722 723 assert(mem != NULL); 724 assert(flags == PyBUF_READ || flags == PyBUF_WRITE); 725 726 mbuf = mbuf_alloc(); 727 if (mbuf == NULL) 728 return NULL; 729 730 readonly = (flags == PyBUF_WRITE) ? 0 : 1; 731 (void)PyBuffer_FillInfo(&mbuf->master, NULL, mem, size, readonly, 732 PyBUF_FULL_RO); 733 734 mv = mbuf_add_view(mbuf, NULL); 735 Py_DECREF(mbuf); 736 737 return mv; 738 } 739 740 /* Create a memoryview from a given Py_buffer. For simple byte views, 741 PyMemoryView_FromMemory() should be used instead. 742 This function is the only entry point that can create a master buffer 743 without full information. Because of this fact init_shape_strides() 744 must be able to reconstruct missing values. */ 745 PyObject * 746 PyMemoryView_FromBuffer(Py_buffer *info) 747 { 748 _PyManagedBufferObject *mbuf; 749 PyObject *mv; 750 751 if (info->buf == NULL) { 752 PyErr_SetString(PyExc_ValueError, 753 "PyMemoryView_FromBuffer(): info->buf must not be NULL"); 754 return NULL; 755 } 756 757 mbuf = mbuf_alloc(); 758 if (mbuf == NULL) 759 return NULL; 760 761 /* info->obj is either NULL or a borrowed reference. This reference 762 should not be decremented in PyBuffer_Release(). */ 763 mbuf->master = *info; 764 mbuf->master.obj = NULL; 765 766 mv = mbuf_add_view(mbuf, NULL); 767 Py_DECREF(mbuf); 768 769 return mv; 770 } 771 772 /* Create a memoryview from an object that implements the buffer protocol. 773 If the object is a memoryview, the new memoryview must be registered 774 with the same managed buffer. Otherwise, a new managed buffer is created. */ 775 PyObject * 776 PyMemoryView_FromObject(PyObject *v) 777 { 778 _PyManagedBufferObject *mbuf; 779 780 if (PyMemoryView_Check(v)) { 781 PyMemoryViewObject *mv = (PyMemoryViewObject *)v; 782 CHECK_RELEASED(mv); 783 return mbuf_add_view(mv->mbuf, &mv->view); 784 } 785 else if (PyObject_CheckBuffer(v)) { 786 PyObject *ret; 787 mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v); 788 if (mbuf == NULL) 789 return NULL; 790 ret = mbuf_add_view(mbuf, NULL); 791 Py_DECREF(mbuf); 792 return ret; 793 } 794 795 PyErr_Format(PyExc_TypeError, 796 "memoryview: a bytes-like object is required, not '%.200s'", 797 Py_TYPE(v)->tp_name); 798 return NULL; 799 } 800 801 /* Copy the format string from a base object that might vanish. */ 802 static int 803 mbuf_copy_format(_PyManagedBufferObject *mbuf, const char *fmt) 804 { 805 if (fmt != NULL) { 806 char *cp = PyMem_Malloc(strlen(fmt)+1); 807 if (cp == NULL) { 808 PyErr_NoMemory(); 809 return -1; 810 } 811 mbuf->master.format = strcpy(cp, fmt); 812 mbuf->flags |= _Py_MANAGED_BUFFER_FREE_FORMAT; 813 } 814 815 return 0; 816 } 817 818 /* 819 Return a memoryview that is based on a contiguous copy of src. 820 Assumptions: src has PyBUF_FULL_RO information, src->ndim > 0. 821 822 Ownership rules: 823 1) As usual, the returned memoryview has a private copy 824 of src->shape, src->strides and src->suboffsets. 825 2) src->format is copied to the master buffer and released 826 in mbuf_dealloc(). The releasebufferproc of the bytes 827 object is NULL, so it does not matter that mbuf_release() 828 passes the altered format pointer to PyBuffer_Release(). 829 */ 830 static PyObject * 831 memory_from_contiguous_copy(Py_buffer *src, char order) 832 { 833 _PyManagedBufferObject *mbuf; 834 PyMemoryViewObject *mv; 835 PyObject *bytes; 836 Py_buffer *dest; 837 int i; 838 839 assert(src->ndim > 0); 840 assert(src->shape != NULL); 841 842 bytes = PyBytes_FromStringAndSize(NULL, src->len); 843 if (bytes == NULL) 844 return NULL; 845 846 mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes); 847 Py_DECREF(bytes); 848 if (mbuf == NULL) 849 return NULL; 850 851 if (mbuf_copy_format(mbuf, src->format) < 0) { 852 Py_DECREF(mbuf); 853 return NULL; 854 } 855 856 mv = (PyMemoryViewObject *)mbuf_add_incomplete_view(mbuf, NULL, src->ndim); 857 Py_DECREF(mbuf); 858 if (mv == NULL) 859 return NULL; 860 861 dest = &mv->view; 862 863 /* shared values are initialized correctly except for itemsize */ 864 dest->itemsize = src->itemsize; 865 866 /* shape and strides */ 867 for (i = 0; i < src->ndim; i++) { 868 dest->shape[i] = src->shape[i]; 869 } 870 if (order == 'C' || order == 'A') { 871 init_strides_from_shape(dest); 872 } 873 else { 874 init_fortran_strides_from_shape(dest); 875 } 876 /* suboffsets */ 877 dest->suboffsets = NULL; 878 879 /* flags */ 880 init_flags(mv); 881 882 if (copy_buffer(dest, src) < 0) { 883 Py_DECREF(mv); 884 return NULL; 885 } 886 887 return (PyObject *)mv; 888 } 889 890 /* 891 Return a new memoryview object based on a contiguous exporter with 892 buffertype={PyBUF_READ, PyBUF_WRITE} and order={'C', 'F'ortran, or 'A'ny}. 893 The logical structure of the input and output buffers is the same 894 (i.e. tolist(input) == tolist(output)), but the physical layout in 895 memory can be explicitly chosen. 896 897 As usual, if buffertype=PyBUF_WRITE, the exporter's buffer must be writable, 898 otherwise it may be writable or read-only. 899 900 If the exporter is already contiguous with the desired target order, 901 the memoryview will be directly based on the exporter. 902 903 Otherwise, if the buffertype is PyBUF_READ, the memoryview will be 904 based on a new bytes object. If order={'C', 'A'ny}, use 'C' order, 905 'F'ortran order otherwise. 906 */ 907 PyObject * 908 PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order) 909 { 910 PyMemoryViewObject *mv; 911 PyObject *ret; 912 Py_buffer *view; 913 914 assert(buffertype == PyBUF_READ || buffertype == PyBUF_WRITE); 915 assert(order == 'C' || order == 'F' || order == 'A'); 916 917 mv = (PyMemoryViewObject *)PyMemoryView_FromObject(obj); 918 if (mv == NULL) 919 return NULL; 920 921 view = &mv->view; 922 if (buffertype == PyBUF_WRITE && view->readonly) { 923 PyErr_SetString(PyExc_BufferError, 924 "underlying buffer is not writable"); 925 Py_DECREF(mv); 926 return NULL; 927 } 928 929 if (PyBuffer_IsContiguous(view, order)) 930 return (PyObject *)mv; 931 932 if (buffertype == PyBUF_WRITE) { 933 PyErr_SetString(PyExc_BufferError, 934 "writable contiguous buffer requested " 935 "for a non-contiguous object."); 936 Py_DECREF(mv); 937 return NULL; 938 } 939 940 ret = memory_from_contiguous_copy(view, order); 941 Py_DECREF(mv); 942 return ret; 943 } 944 945 946 static PyObject * 947 memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) 948 { 949 PyObject *obj; 950 static char *kwlist[] = {"object", NULL}; 951 952 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist, 953 &obj)) { 954 return NULL; 955 } 956 957 return PyMemoryView_FromObject(obj); 958 } 959 960 961 /****************************************************************************/ 962 /* Previously in abstract.c */ 963 /****************************************************************************/ 964 965 typedef struct { 966 Py_buffer view; 967 Py_ssize_t array[1]; 968 } Py_buffer_full; 969 970 int 971 PyBuffer_ToContiguous(void *buf, Py_buffer *src, Py_ssize_t len, char order) 972 { 973 Py_buffer_full *fb = NULL; 974 int ret; 975 976 assert(order == 'C' || order == 'F' || order == 'A'); 977 978 if (len != src->len) { 979 PyErr_SetString(PyExc_ValueError, 980 "PyBuffer_ToContiguous: len != view->len"); 981 return -1; 982 } 983 984 if (PyBuffer_IsContiguous(src, order)) { 985 memcpy((char *)buf, src->buf, len); 986 return 0; 987 } 988 989 /* buffer_to_contiguous() assumes PyBUF_FULL */ 990 fb = PyMem_Malloc(sizeof *fb + 3 * src->ndim * (sizeof *fb->array)); 991 if (fb == NULL) { 992 PyErr_NoMemory(); 993 return -1; 994 } 995 fb->view.ndim = src->ndim; 996 fb->view.shape = fb->array; 997 fb->view.strides = fb->array + src->ndim; 998 fb->view.suboffsets = fb->array + 2 * src->ndim; 999 1000 init_shared_values(&fb->view, src); 1001 init_shape_strides(&fb->view, src); 1002 init_suboffsets(&fb->view, src); 1003 1004 src = &fb->view; 1005 1006 ret = buffer_to_contiguous(buf, src, order); 1007 PyMem_Free(fb); 1008 return ret; 1009 } 1010 1011 1012 /****************************************************************************/ 1013 /* Release/GC management */ 1014 /****************************************************************************/ 1015 1016 /* Inform the managed buffer that this particular memoryview will not access 1017 the underlying buffer again. If no other memoryviews are registered with 1018 the managed buffer, the underlying buffer is released instantly and 1019 marked as inaccessible for both the memoryview and the managed buffer. 1020 1021 This function fails if the memoryview itself has exported buffers. */ 1022 static int 1023 _memory_release(PyMemoryViewObject *self) 1024 { 1025 if (self->flags & _Py_MEMORYVIEW_RELEASED) 1026 return 0; 1027 1028 if (self->exports == 0) { 1029 self->flags |= _Py_MEMORYVIEW_RELEASED; 1030 assert(self->mbuf->exports > 0); 1031 if (--self->mbuf->exports == 0) 1032 mbuf_release(self->mbuf); 1033 return 0; 1034 } 1035 if (self->exports > 0) { 1036 PyErr_Format(PyExc_BufferError, 1037 "memoryview has %zd exported buffer%s", self->exports, 1038 self->exports==1 ? "" : "s"); 1039 return -1; 1040 } 1041 1042 Py_FatalError("_memory_release(): negative export count"); 1043 return -1; 1044 } 1045 1046 static PyObject * 1047 memory_release(PyMemoryViewObject *self, PyObject *noargs) 1048 { 1049 if (_memory_release(self) < 0) 1050 return NULL; 1051 Py_RETURN_NONE; 1052 } 1053 1054 static void 1055 memory_dealloc(PyMemoryViewObject *self) 1056 { 1057 assert(self->exports == 0); 1058 _PyObject_GC_UNTRACK(self); 1059 (void)_memory_release(self); 1060 Py_CLEAR(self->mbuf); 1061 if (self->weakreflist != NULL) 1062 PyObject_ClearWeakRefs((PyObject *) self); 1063 PyObject_GC_Del(self); 1064 } 1065 1066 static int 1067 memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg) 1068 { 1069 Py_VISIT(self->mbuf); 1070 return 0; 1071 } 1072 1073 static int 1074 memory_clear(PyMemoryViewObject *self) 1075 { 1076 (void)_memory_release(self); 1077 Py_CLEAR(self->mbuf); 1078 return 0; 1079 } 1080 1081 static PyObject * 1082 memory_enter(PyObject *self, PyObject *args) 1083 { 1084 CHECK_RELEASED(self); 1085 Py_INCREF(self); 1086 return self; 1087 } 1088 1089 static PyObject * 1090 memory_exit(PyObject *self, PyObject *args) 1091 { 1092 return memory_release((PyMemoryViewObject *)self, NULL); 1093 } 1094 1095 1096 /****************************************************************************/ 1097 /* Casting format and shape */ 1098 /****************************************************************************/ 1099 1100 #define IS_BYTE_FORMAT(f) (f == 'b' || f == 'B' || f == 'c') 1101 1102 static inline Py_ssize_t 1103 get_native_fmtchar(char *result, const char *fmt) 1104 { 1105 Py_ssize_t size = -1; 1106 1107 if (fmt[0] == '@') fmt++; 1108 1109 switch (fmt[0]) { 1110 case 'c': case 'b': case 'B': size = sizeof(char); break; 1111 case 'h': case 'H': size = sizeof(short); break; 1112 case 'i': case 'I': size = sizeof(int); break; 1113 case 'l': case 'L': size = sizeof(long); break; 1114 case 'q': case 'Q': size = sizeof(long long); break; 1115 case 'n': case 'N': size = sizeof(Py_ssize_t); break; 1116 case 'f': size = sizeof(float); break; 1117 case 'd': size = sizeof(double); break; 1118 case '?': size = sizeof(_Bool); break; 1119 case 'P': size = sizeof(void *); break; 1120 } 1121 1122 if (size > 0 && fmt[1] == '\0') { 1123 *result = fmt[0]; 1124 return size; 1125 } 1126 1127 return -1; 1128 } 1129 1130 static inline const char * 1131 get_native_fmtstr(const char *fmt) 1132 { 1133 int at = 0; 1134 1135 if (fmt[0] == '@') { 1136 at = 1; 1137 fmt++; 1138 } 1139 if (fmt[0] == '\0' || fmt[1] != '\0') { 1140 return NULL; 1141 } 1142 1143 #define RETURN(s) do { return at ? "@" s : s; } while (0) 1144 1145 switch (fmt[0]) { 1146 case 'c': RETURN("c"); 1147 case 'b': RETURN("b"); 1148 case 'B': RETURN("B"); 1149 case 'h': RETURN("h"); 1150 case 'H': RETURN("H"); 1151 case 'i': RETURN("i"); 1152 case 'I': RETURN("I"); 1153 case 'l': RETURN("l"); 1154 case 'L': RETURN("L"); 1155 case 'q': RETURN("q"); 1156 case 'Q': RETURN("Q"); 1157 case 'n': RETURN("n"); 1158 case 'N': RETURN("N"); 1159 case 'f': RETURN("f"); 1160 case 'd': RETURN("d"); 1161 case '?': RETURN("?"); 1162 case 'P': RETURN("P"); 1163 } 1164 1165 return NULL; 1166 } 1167 1168 1169 /* Cast a memoryview's data type to 'format'. The input array must be 1170 C-contiguous. At least one of input-format, output-format must have 1171 byte size. The output array is 1-D, with the same byte length as the 1172 input array. Thus, view->len must be a multiple of the new itemsize. */ 1173 static int 1174 cast_to_1D(PyMemoryViewObject *mv, PyObject *format) 1175 { 1176 Py_buffer *view = &mv->view; 1177 PyObject *asciifmt; 1178 char srcchar, destchar; 1179 Py_ssize_t itemsize; 1180 int ret = -1; 1181 1182 assert(view->ndim >= 1); 1183 assert(Py_SIZE(mv) == 3*view->ndim); 1184 assert(view->shape == mv->ob_array); 1185 assert(view->strides == mv->ob_array + view->ndim); 1186 assert(view->suboffsets == mv->ob_array + 2*view->ndim); 1187 1188 asciifmt = PyUnicode_AsASCIIString(format); 1189 if (asciifmt == NULL) 1190 return ret; 1191 1192 itemsize = get_native_fmtchar(&destchar, PyBytes_AS_STRING(asciifmt)); 1193 if (itemsize < 0) { 1194 PyErr_SetString(PyExc_ValueError, 1195 "memoryview: destination format must be a native single " 1196 "character format prefixed with an optional '@'"); 1197 goto out; 1198 } 1199 1200 if ((get_native_fmtchar(&srcchar, view->format) < 0 || 1201 !IS_BYTE_FORMAT(srcchar)) && !IS_BYTE_FORMAT(destchar)) { 1202 PyErr_SetString(PyExc_TypeError, 1203 "memoryview: cannot cast between two non-byte formats"); 1204 goto out; 1205 } 1206 if (view->len % itemsize) { 1207 PyErr_SetString(PyExc_TypeError, 1208 "memoryview: length is not a multiple of itemsize"); 1209 goto out; 1210 } 1211 1212 view->format = (char *)get_native_fmtstr(PyBytes_AS_STRING(asciifmt)); 1213 if (view->format == NULL) { 1214 /* NOT_REACHED: get_native_fmtchar() already validates the format. */ 1215 PyErr_SetString(PyExc_RuntimeError, 1216 "memoryview: internal error"); 1217 goto out; 1218 } 1219 view->itemsize = itemsize; 1220 1221 view->ndim = 1; 1222 view->shape[0] = view->len / view->itemsize; 1223 view->strides[0] = view->itemsize; 1224 view->suboffsets = NULL; 1225 1226 init_flags(mv); 1227 1228 ret = 0; 1229 1230 out: 1231 Py_DECREF(asciifmt); 1232 return ret; 1233 } 1234 1235 /* The memoryview must have space for 3*len(seq) elements. */ 1236 static Py_ssize_t 1237 copy_shape(Py_ssize_t *shape, const PyObject *seq, Py_ssize_t ndim, 1238 Py_ssize_t itemsize) 1239 { 1240 Py_ssize_t x, i; 1241 Py_ssize_t len = itemsize; 1242 1243 for (i = 0; i < ndim; i++) { 1244 PyObject *tmp = PySequence_Fast_GET_ITEM(seq, i); 1245 if (!PyLong_Check(tmp)) { 1246 PyErr_SetString(PyExc_TypeError, 1247 "memoryview.cast(): elements of shape must be integers"); 1248 return -1; 1249 } 1250 x = PyLong_AsSsize_t(tmp); 1251 if (x == -1 && PyErr_Occurred()) { 1252 return -1; 1253 } 1254 if (x <= 0) { 1255 /* In general elements of shape may be 0, but not for casting. */ 1256 PyErr_Format(PyExc_ValueError, 1257 "memoryview.cast(): elements of shape must be integers > 0"); 1258 return -1; 1259 } 1260 if (x > PY_SSIZE_T_MAX / len) { 1261 PyErr_Format(PyExc_ValueError, 1262 "memoryview.cast(): product(shape) > SSIZE_MAX"); 1263 return -1; 1264 } 1265 len *= x; 1266 shape[i] = x; 1267 } 1268 1269 return len; 1270 } 1271 1272 /* Cast a 1-D array to a new shape. The result array will be C-contiguous. 1273 If the result array does not have exactly the same byte length as the 1274 input array, raise ValueError. */ 1275 static int 1276 cast_to_ND(PyMemoryViewObject *mv, const PyObject *shape, int ndim) 1277 { 1278 Py_buffer *view = &mv->view; 1279 Py_ssize_t len; 1280 1281 assert(view->ndim == 1); /* ndim from cast_to_1D() */ 1282 assert(Py_SIZE(mv) == 3*(ndim==0?1:ndim)); /* ndim of result array */ 1283 assert(view->shape == mv->ob_array); 1284 assert(view->strides == mv->ob_array + (ndim==0?1:ndim)); 1285 assert(view->suboffsets == NULL); 1286 1287 view->ndim = ndim; 1288 if (view->ndim == 0) { 1289 view->shape = NULL; 1290 view->strides = NULL; 1291 len = view->itemsize; 1292 } 1293 else { 1294 len = copy_shape(view->shape, shape, ndim, view->itemsize); 1295 if (len < 0) 1296 return -1; 1297 init_strides_from_shape(view); 1298 } 1299 1300 if (view->len != len) { 1301 PyErr_SetString(PyExc_TypeError, 1302 "memoryview: product(shape) * itemsize != buffer size"); 1303 return -1; 1304 } 1305 1306 init_flags(mv); 1307 1308 return 0; 1309 } 1310 1311 static int 1312 zero_in_shape(PyMemoryViewObject *mv) 1313 { 1314 Py_buffer *view = &mv->view; 1315 Py_ssize_t i; 1316 1317 for (i = 0; i < view->ndim; i++) 1318 if (view->shape[i] == 0) 1319 return 1; 1320 1321 return 0; 1322 } 1323 1324 /* 1325 Cast a copy of 'self' to a different view. The input view must 1326 be C-contiguous. The function always casts the input view to a 1327 1-D output according to 'format'. At least one of input-format, 1328 output-format must have byte size. 1329 1330 If 'shape' is given, the 1-D view from the previous step will 1331 be cast to a C-contiguous view with new shape and strides. 1332 1333 All casts must result in views that will have the exact byte 1334 size of the original input. Otherwise, an error is raised. 1335 */ 1336 static PyObject * 1337 memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds) 1338 { 1339 static char *kwlist[] = {"format", "shape", NULL}; 1340 PyMemoryViewObject *mv = NULL; 1341 PyObject *shape = NULL; 1342 PyObject *format; 1343 Py_ssize_t ndim = 1; 1344 1345 CHECK_RELEASED(self); 1346 1347 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, 1348 &format, &shape)) { 1349 return NULL; 1350 } 1351 if (!PyUnicode_Check(format)) { 1352 PyErr_SetString(PyExc_TypeError, 1353 "memoryview: format argument must be a string"); 1354 return NULL; 1355 } 1356 if (!MV_C_CONTIGUOUS(self->flags)) { 1357 PyErr_SetString(PyExc_TypeError, 1358 "memoryview: casts are restricted to C-contiguous views"); 1359 return NULL; 1360 } 1361 if ((shape || self->view.ndim != 1) && zero_in_shape(self)) { 1362 PyErr_SetString(PyExc_TypeError, 1363 "memoryview: cannot cast view with zeros in shape or strides"); 1364 return NULL; 1365 } 1366 if (shape) { 1367 CHECK_LIST_OR_TUPLE(shape) 1368 ndim = PySequence_Fast_GET_SIZE(shape); 1369 if (ndim > PyBUF_MAX_NDIM) { 1370 PyErr_SetString(PyExc_ValueError, 1371 "memoryview: number of dimensions must not exceed " 1372 Py_STRINGIFY(PyBUF_MAX_NDIM)); 1373 return NULL; 1374 } 1375 if (self->view.ndim != 1 && ndim != 1) { 1376 PyErr_SetString(PyExc_TypeError, 1377 "memoryview: cast must be 1D -> ND or ND -> 1D"); 1378 return NULL; 1379 } 1380 } 1381 1382 mv = (PyMemoryViewObject *) 1383 mbuf_add_incomplete_view(self->mbuf, &self->view, ndim==0 ? 1 : (int)ndim); 1384 if (mv == NULL) 1385 return NULL; 1386 1387 if (cast_to_1D(mv, format) < 0) 1388 goto error; 1389 if (shape && cast_to_ND(mv, shape, (int)ndim) < 0) 1390 goto error; 1391 1392 return (PyObject *)mv; 1393 1394 error: 1395 Py_DECREF(mv); 1396 return NULL; 1397 } 1398 1399 1400 /**************************************************************************/ 1401 /* getbuffer */ 1402 /**************************************************************************/ 1403 1404 static int 1405 memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) 1406 { 1407 Py_buffer *base = &self->view; 1408 int baseflags = self->flags; 1409 1410 CHECK_RELEASED_INT(self); 1411 1412 /* start with complete information */ 1413 *view = *base; 1414 view->obj = NULL; 1415 1416 if (REQ_WRITABLE(flags) && base->readonly) { 1417 PyErr_SetString(PyExc_BufferError, 1418 "memoryview: underlying buffer is not writable"); 1419 return -1; 1420 } 1421 if (!REQ_FORMAT(flags)) { 1422 /* NULL indicates that the buffer's data type has been cast to 'B'. 1423 view->itemsize is the _previous_ itemsize. If shape is present, 1424 the equality product(shape) * itemsize = len still holds at this 1425 point. The equality calcsize(format) = itemsize does _not_ hold 1426 from here on! */ 1427 view->format = NULL; 1428 } 1429 1430 if (REQ_C_CONTIGUOUS(flags) && !MV_C_CONTIGUOUS(baseflags)) { 1431 PyErr_SetString(PyExc_BufferError, 1432 "memoryview: underlying buffer is not C-contiguous"); 1433 return -1; 1434 } 1435 if (REQ_F_CONTIGUOUS(flags) && !MV_F_CONTIGUOUS(baseflags)) { 1436 PyErr_SetString(PyExc_BufferError, 1437 "memoryview: underlying buffer is not Fortran contiguous"); 1438 return -1; 1439 } 1440 if (REQ_ANY_CONTIGUOUS(flags) && !MV_ANY_CONTIGUOUS(baseflags)) { 1441 PyErr_SetString(PyExc_BufferError, 1442 "memoryview: underlying buffer is not contiguous"); 1443 return -1; 1444 } 1445 if (!REQ_INDIRECT(flags) && (baseflags & _Py_MEMORYVIEW_PIL)) { 1446 PyErr_SetString(PyExc_BufferError, 1447 "memoryview: underlying buffer requires suboffsets"); 1448 return -1; 1449 } 1450 if (!REQ_STRIDES(flags)) { 1451 if (!MV_C_CONTIGUOUS(baseflags)) { 1452 PyErr_SetString(PyExc_BufferError, 1453 "memoryview: underlying buffer is not C-contiguous"); 1454 return -1; 1455 } 1456 view->strides = NULL; 1457 } 1458 if (!REQ_SHAPE(flags)) { 1459 /* PyBUF_SIMPLE or PyBUF_WRITABLE: at this point buf is C-contiguous, 1460 so base->buf = ndbuf->data. */ 1461 if (view->format != NULL) { 1462 /* PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT do 1463 not make sense. */ 1464 PyErr_Format(PyExc_BufferError, 1465 "memoryview: cannot cast to unsigned bytes if the format flag " 1466 "is present"); 1467 return -1; 1468 } 1469 /* product(shape) * itemsize = len and calcsize(format) = itemsize 1470 do _not_ hold from here on! */ 1471 view->ndim = 1; 1472 view->shape = NULL; 1473 } 1474 1475 1476 view->obj = (PyObject *)self; 1477 Py_INCREF(view->obj); 1478 self->exports++; 1479 1480 return 0; 1481 } 1482 1483 static void 1484 memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view) 1485 { 1486 self->exports--; 1487 return; 1488 /* PyBuffer_Release() decrements view->obj after this function returns. */ 1489 } 1490 1491 /* Buffer methods */ 1492 static PyBufferProcs memory_as_buffer = { 1493 (getbufferproc)memory_getbuf, /* bf_getbuffer */ 1494 (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */ 1495 }; 1496 1497 1498 /****************************************************************************/ 1499 /* Optimized pack/unpack for all native format specifiers */ 1500 /****************************************************************************/ 1501 1502 /* 1503 Fix exceptions: 1504 1) Include format string in the error message. 1505 2) OverflowError -> ValueError. 1506 3) The error message from PyNumber_Index() is not ideal. 1507 */ 1508 static int 1509 type_error_int(const char *fmt) 1510 { 1511 PyErr_Format(PyExc_TypeError, 1512 "memoryview: invalid type for format '%s'", fmt); 1513 return -1; 1514 } 1515 1516 static int 1517 value_error_int(const char *fmt) 1518 { 1519 PyErr_Format(PyExc_ValueError, 1520 "memoryview: invalid value for format '%s'", fmt); 1521 return -1; 1522 } 1523 1524 static int 1525 fix_error_int(const char *fmt) 1526 { 1527 assert(PyErr_Occurred()); 1528 if (PyErr_ExceptionMatches(PyExc_TypeError)) { 1529 PyErr_Clear(); 1530 return type_error_int(fmt); 1531 } 1532 else if (PyErr_ExceptionMatches(PyExc_OverflowError) || 1533 PyErr_ExceptionMatches(PyExc_ValueError)) { 1534 PyErr_Clear(); 1535 return value_error_int(fmt); 1536 } 1537 1538 return -1; 1539 } 1540 1541 /* Accept integer objects or objects with an __index__() method. */ 1542 static long 1543 pylong_as_ld(PyObject *item) 1544 { 1545 PyObject *tmp; 1546 long ld; 1547 1548 tmp = PyNumber_Index(item); 1549 if (tmp == NULL) 1550 return -1; 1551 1552 ld = PyLong_AsLong(tmp); 1553 Py_DECREF(tmp); 1554 return ld; 1555 } 1556 1557 static unsigned long 1558 pylong_as_lu(PyObject *item) 1559 { 1560 PyObject *tmp; 1561 unsigned long lu; 1562 1563 tmp = PyNumber_Index(item); 1564 if (tmp == NULL) 1565 return (unsigned long)-1; 1566 1567 lu = PyLong_AsUnsignedLong(tmp); 1568 Py_DECREF(tmp); 1569 return lu; 1570 } 1571 1572 static long long 1573 pylong_as_lld(PyObject *item) 1574 { 1575 PyObject *tmp; 1576 long long lld; 1577 1578 tmp = PyNumber_Index(item); 1579 if (tmp == NULL) 1580 return -1; 1581 1582 lld = PyLong_AsLongLong(tmp); 1583 Py_DECREF(tmp); 1584 return lld; 1585 } 1586 1587 static unsigned long long 1588 pylong_as_llu(PyObject *item) 1589 { 1590 PyObject *tmp; 1591 unsigned long long llu; 1592 1593 tmp = PyNumber_Index(item); 1594 if (tmp == NULL) 1595 return (unsigned long long)-1; 1596 1597 llu = PyLong_AsUnsignedLongLong(tmp); 1598 Py_DECREF(tmp); 1599 return llu; 1600 } 1601 1602 static Py_ssize_t 1603 pylong_as_zd(PyObject *item) 1604 { 1605 PyObject *tmp; 1606 Py_ssize_t zd; 1607 1608 tmp = PyNumber_Index(item); 1609 if (tmp == NULL) 1610 return -1; 1611 1612 zd = PyLong_AsSsize_t(tmp); 1613 Py_DECREF(tmp); 1614 return zd; 1615 } 1616 1617 static size_t 1618 pylong_as_zu(PyObject *item) 1619 { 1620 PyObject *tmp; 1621 size_t zu; 1622 1623 tmp = PyNumber_Index(item); 1624 if (tmp == NULL) 1625 return (size_t)-1; 1626 1627 zu = PyLong_AsSize_t(tmp); 1628 Py_DECREF(tmp); 1629 return zu; 1630 } 1631 1632 /* Timings with the ndarray from _testbuffer.c indicate that using the 1633 struct module is around 15x slower than the two functions below. */ 1634 1635 #define UNPACK_SINGLE(dest, ptr, type) \ 1636 do { \ 1637 type x; \ 1638 memcpy((char *)&x, ptr, sizeof x); \ 1639 dest = x; \ 1640 } while (0) 1641 1642 /* Unpack a single item. 'fmt' can be any native format character in struct 1643 module syntax. This function is very sensitive to small changes. With this 1644 layout gcc automatically generates a fast jump table. */ 1645 static inline PyObject * 1646 unpack_single(const char *ptr, const char *fmt) 1647 { 1648 unsigned long long llu; 1649 unsigned long lu; 1650 size_t zu; 1651 long long lld; 1652 long ld; 1653 Py_ssize_t zd; 1654 double d; 1655 unsigned char uc; 1656 void *p; 1657 1658 switch (fmt[0]) { 1659 1660 /* signed integers and fast path for 'B' */ 1661 case 'B': uc = *((unsigned char *)ptr); goto convert_uc; 1662 case 'b': ld = *((signed char *)ptr); goto convert_ld; 1663 case 'h': UNPACK_SINGLE(ld, ptr, short); goto convert_ld; 1664 case 'i': UNPACK_SINGLE(ld, ptr, int); goto convert_ld; 1665 case 'l': UNPACK_SINGLE(ld, ptr, long); goto convert_ld; 1666 1667 /* boolean */ 1668 case '?': UNPACK_SINGLE(ld, ptr, _Bool); goto convert_bool; 1669 1670 /* unsigned integers */ 1671 case 'H': UNPACK_SINGLE(lu, ptr, unsigned short); goto convert_lu; 1672 case 'I': UNPACK_SINGLE(lu, ptr, unsigned int); goto convert_lu; 1673 case 'L': UNPACK_SINGLE(lu, ptr, unsigned long); goto convert_lu; 1674 1675 /* native 64-bit */ 1676 case 'q': UNPACK_SINGLE(lld, ptr, long long); goto convert_lld; 1677 case 'Q': UNPACK_SINGLE(llu, ptr, unsigned long long); goto convert_llu; 1678 1679 /* ssize_t and size_t */ 1680 case 'n': UNPACK_SINGLE(zd, ptr, Py_ssize_t); goto convert_zd; 1681 case 'N': UNPACK_SINGLE(zu, ptr, size_t); goto convert_zu; 1682 1683 /* floats */ 1684 case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double; 1685 case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double; 1686 1687 /* bytes object */ 1688 case 'c': goto convert_bytes; 1689 1690 /* pointer */ 1691 case 'P': UNPACK_SINGLE(p, ptr, void *); goto convert_pointer; 1692 1693 /* default */ 1694 default: goto err_format; 1695 } 1696 1697 convert_uc: 1698 /* PyLong_FromUnsignedLong() is slower */ 1699 return PyLong_FromLong(uc); 1700 convert_ld: 1701 return PyLong_FromLong(ld); 1702 convert_lu: 1703 return PyLong_FromUnsignedLong(lu); 1704 convert_lld: 1705 return PyLong_FromLongLong(lld); 1706 convert_llu: 1707 return PyLong_FromUnsignedLongLong(llu); 1708 convert_zd: 1709 return PyLong_FromSsize_t(zd); 1710 convert_zu: 1711 return PyLong_FromSize_t(zu); 1712 convert_double: 1713 return PyFloat_FromDouble(d); 1714 convert_bool: 1715 return PyBool_FromLong(ld); 1716 convert_bytes: 1717 return PyBytes_FromStringAndSize(ptr, 1); 1718 convert_pointer: 1719 return PyLong_FromVoidPtr(p); 1720 err_format: 1721 PyErr_Format(PyExc_NotImplementedError, 1722 "memoryview: format %s not supported", fmt); 1723 return NULL; 1724 } 1725 1726 #define PACK_SINGLE(ptr, src, type) \ 1727 do { \ 1728 type x; \ 1729 x = (type)src; \ 1730 memcpy(ptr, (char *)&x, sizeof x); \ 1731 } while (0) 1732 1733 /* Pack a single item. 'fmt' can be any native format character in 1734 struct module syntax. */ 1735 static int 1736 pack_single(char *ptr, PyObject *item, const char *fmt) 1737 { 1738 unsigned long long llu; 1739 unsigned long lu; 1740 size_t zu; 1741 long long lld; 1742 long ld; 1743 Py_ssize_t zd; 1744 double d; 1745 void *p; 1746 1747 switch (fmt[0]) { 1748 /* signed integers */ 1749 case 'b': case 'h': case 'i': case 'l': 1750 ld = pylong_as_ld(item); 1751 if (ld == -1 && PyErr_Occurred()) 1752 goto err_occurred; 1753 switch (fmt[0]) { 1754 case 'b': 1755 if (ld < SCHAR_MIN || ld > SCHAR_MAX) goto err_range; 1756 *((signed char *)ptr) = (signed char)ld; break; 1757 case 'h': 1758 if (ld < SHRT_MIN || ld > SHRT_MAX) goto err_range; 1759 PACK_SINGLE(ptr, ld, short); break; 1760 case 'i': 1761 if (ld < INT_MIN || ld > INT_MAX) goto err_range; 1762 PACK_SINGLE(ptr, ld, int); break; 1763 default: /* 'l' */ 1764 PACK_SINGLE(ptr, ld, long); break; 1765 } 1766 break; 1767 1768 /* unsigned integers */ 1769 case 'B': case 'H': case 'I': case 'L': 1770 lu = pylong_as_lu(item); 1771 if (lu == (unsigned long)-1 && PyErr_Occurred()) 1772 goto err_occurred; 1773 switch (fmt[0]) { 1774 case 'B': 1775 if (lu > UCHAR_MAX) goto err_range; 1776 *((unsigned char *)ptr) = (unsigned char)lu; break; 1777 case 'H': 1778 if (lu > USHRT_MAX) goto err_range; 1779 PACK_SINGLE(ptr, lu, unsigned short); break; 1780 case 'I': 1781 if (lu > UINT_MAX) goto err_range; 1782 PACK_SINGLE(ptr, lu, unsigned int); break; 1783 default: /* 'L' */ 1784 PACK_SINGLE(ptr, lu, unsigned long); break; 1785 } 1786 break; 1787 1788 /* native 64-bit */ 1789 case 'q': 1790 lld = pylong_as_lld(item); 1791 if (lld == -1 && PyErr_Occurred()) 1792 goto err_occurred; 1793 PACK_SINGLE(ptr, lld, long long); 1794 break; 1795 case 'Q': 1796 llu = pylong_as_llu(item); 1797 if (llu == (unsigned long long)-1 && PyErr_Occurred()) 1798 goto err_occurred; 1799 PACK_SINGLE(ptr, llu, unsigned long long); 1800 break; 1801 1802 /* ssize_t and size_t */ 1803 case 'n': 1804 zd = pylong_as_zd(item); 1805 if (zd == -1 && PyErr_Occurred()) 1806 goto err_occurred; 1807 PACK_SINGLE(ptr, zd, Py_ssize_t); 1808 break; 1809 case 'N': 1810 zu = pylong_as_zu(item); 1811 if (zu == (size_t)-1 && PyErr_Occurred()) 1812 goto err_occurred; 1813 PACK_SINGLE(ptr, zu, size_t); 1814 break; 1815 1816 /* floats */ 1817 case 'f': case 'd': 1818 d = PyFloat_AsDouble(item); 1819 if (d == -1.0 && PyErr_Occurred()) 1820 goto err_occurred; 1821 if (fmt[0] == 'f') { 1822 PACK_SINGLE(ptr, d, float); 1823 } 1824 else { 1825 PACK_SINGLE(ptr, d, double); 1826 } 1827 break; 1828 1829 /* bool */ 1830 case '?': 1831 ld = PyObject_IsTrue(item); 1832 if (ld < 0) 1833 return -1; /* preserve original error */ 1834 PACK_SINGLE(ptr, ld, _Bool); 1835 break; 1836 1837 /* bytes object */ 1838 case 'c': 1839 if (!PyBytes_Check(item)) 1840 return type_error_int(fmt); 1841 if (PyBytes_GET_SIZE(item) != 1) 1842 return value_error_int(fmt); 1843 *ptr = PyBytes_AS_STRING(item)[0]; 1844 break; 1845 1846 /* pointer */ 1847 case 'P': 1848 p = PyLong_AsVoidPtr(item); 1849 if (p == NULL && PyErr_Occurred()) 1850 goto err_occurred; 1851 PACK_SINGLE(ptr, p, void *); 1852 break; 1853 1854 /* default */ 1855 default: goto err_format; 1856 } 1857 1858 return 0; 1859 1860 err_occurred: 1861 return fix_error_int(fmt); 1862 err_range: 1863 return value_error_int(fmt); 1864 err_format: 1865 PyErr_Format(PyExc_NotImplementedError, 1866 "memoryview: format %s not supported", fmt); 1867 return -1; 1868 } 1869 1870 1871 /****************************************************************************/ 1872 /* unpack using the struct module */ 1873 /****************************************************************************/ 1874 1875 /* For reasonable performance it is necessary to cache all objects required 1876 for unpacking. An unpacker can handle the format passed to unpack_from(). 1877 Invariant: All pointer fields of the struct should either be NULL or valid 1878 pointers. */ 1879 struct unpacker { 1880 PyObject *unpack_from; /* Struct.unpack_from(format) */ 1881 PyObject *mview; /* cached memoryview */ 1882 char *item; /* buffer for mview */ 1883 Py_ssize_t itemsize; /* len(item) */ 1884 }; 1885 1886 static struct unpacker * 1887 unpacker_new(void) 1888 { 1889 struct unpacker *x = PyMem_Malloc(sizeof *x); 1890 1891 if (x == NULL) { 1892 PyErr_NoMemory(); 1893 return NULL; 1894 } 1895 1896 x->unpack_from = NULL; 1897 x->mview = NULL; 1898 x->item = NULL; 1899 x->itemsize = 0; 1900 1901 return x; 1902 } 1903 1904 static void 1905 unpacker_free(struct unpacker *x) 1906 { 1907 if (x) { 1908 Py_XDECREF(x->unpack_from); 1909 Py_XDECREF(x->mview); 1910 PyMem_Free(x->item); 1911 PyMem_Free(x); 1912 } 1913 } 1914 1915 /* Return a new unpacker for the given format. */ 1916 static struct unpacker * 1917 struct_get_unpacker(const char *fmt, Py_ssize_t itemsize) 1918 { 1919 PyObject *structmodule; /* XXX cache these two */ 1920 PyObject *Struct = NULL; /* XXX in globals? */ 1921 PyObject *structobj = NULL; 1922 PyObject *format = NULL; 1923 struct unpacker *x = NULL; 1924 1925 structmodule = PyImport_ImportModule("struct"); 1926 if (structmodule == NULL) 1927 return NULL; 1928 1929 Struct = PyObject_GetAttrString(structmodule, "Struct"); 1930 Py_DECREF(structmodule); 1931 if (Struct == NULL) 1932 return NULL; 1933 1934 x = unpacker_new(); 1935 if (x == NULL) 1936 goto error; 1937 1938 format = PyBytes_FromString(fmt); 1939 if (format == NULL) 1940 goto error; 1941 1942 structobj = PyObject_CallFunctionObjArgs(Struct, format, NULL); 1943 if (structobj == NULL) 1944 goto error; 1945 1946 x->unpack_from = PyObject_GetAttrString(structobj, "unpack_from"); 1947 if (x->unpack_from == NULL) 1948 goto error; 1949 1950 x->item = PyMem_Malloc(itemsize); 1951 if (x->item == NULL) { 1952 PyErr_NoMemory(); 1953 goto error; 1954 } 1955 x->itemsize = itemsize; 1956 1957 x->mview = PyMemoryView_FromMemory(x->item, itemsize, PyBUF_WRITE); 1958 if (x->mview == NULL) 1959 goto error; 1960 1961 1962 out: 1963 Py_XDECREF(Struct); 1964 Py_XDECREF(format); 1965 Py_XDECREF(structobj); 1966 return x; 1967 1968 error: 1969 unpacker_free(x); 1970 x = NULL; 1971 goto out; 1972 } 1973 1974 /* unpack a single item */ 1975 static PyObject * 1976 struct_unpack_single(const char *ptr, struct unpacker *x) 1977 { 1978 PyObject *v; 1979 1980 memcpy(x->item, ptr, x->itemsize); 1981 v = PyObject_CallFunctionObjArgs(x->unpack_from, x->mview, NULL); 1982 if (v == NULL) 1983 return NULL; 1984 1985 if (PyTuple_GET_SIZE(v) == 1) { 1986 PyObject *tmp = PyTuple_GET_ITEM(v, 0); 1987 Py_INCREF(tmp); 1988 Py_DECREF(v); 1989 return tmp; 1990 } 1991 1992 return v; 1993 } 1994 1995 1996 /****************************************************************************/ 1997 /* Representations */ 1998 /****************************************************************************/ 1999 2000 /* allow explicit form of native format */ 2001 static inline const char * 2002 adjust_fmt(const Py_buffer *view) 2003 { 2004 const char *fmt; 2005 2006 fmt = (view->format[0] == '@') ? view->format+1 : view->format; 2007 if (fmt[0] && fmt[1] == '\0') 2008 return fmt; 2009 2010 PyErr_Format(PyExc_NotImplementedError, 2011 "memoryview: unsupported format %s", view->format); 2012 return NULL; 2013 } 2014 2015 /* Base case for multi-dimensional unpacking. Assumption: ndim == 1. */ 2016 static PyObject * 2017 tolist_base(const char *ptr, const Py_ssize_t *shape, 2018 const Py_ssize_t *strides, const Py_ssize_t *suboffsets, 2019 const char *fmt) 2020 { 2021 PyObject *lst, *item; 2022 Py_ssize_t i; 2023 2024 lst = PyList_New(shape[0]); 2025 if (lst == NULL) 2026 return NULL; 2027 2028 for (i = 0; i < shape[0]; ptr+=strides[0], i++) { 2029 const char *xptr = ADJUST_PTR(ptr, suboffsets, 0); 2030 item = unpack_single(xptr, fmt); 2031 if (item == NULL) { 2032 Py_DECREF(lst); 2033 return NULL; 2034 } 2035 PyList_SET_ITEM(lst, i, item); 2036 } 2037 2038 return lst; 2039 } 2040 2041 /* Unpack a multi-dimensional array into a nested list. 2042 Assumption: ndim >= 1. */ 2043 static PyObject * 2044 tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape, 2045 const Py_ssize_t *strides, const Py_ssize_t *suboffsets, 2046 const char *fmt) 2047 { 2048 PyObject *lst, *item; 2049 Py_ssize_t i; 2050 2051 assert(ndim >= 1); 2052 assert(shape != NULL); 2053 assert(strides != NULL); 2054 2055 if (ndim == 1) 2056 return tolist_base(ptr, shape, strides, suboffsets, fmt); 2057 2058 lst = PyList_New(shape[0]); 2059 if (lst == NULL) 2060 return NULL; 2061 2062 for (i = 0; i < shape[0]; ptr+=strides[0], i++) { 2063 const char *xptr = ADJUST_PTR(ptr, suboffsets, 0); 2064 item = tolist_rec(xptr, ndim-1, shape+1, 2065 strides+1, suboffsets ? suboffsets+1 : NULL, 2066 fmt); 2067 if (item == NULL) { 2068 Py_DECREF(lst); 2069 return NULL; 2070 } 2071 PyList_SET_ITEM(lst, i, item); 2072 } 2073 2074 return lst; 2075 } 2076 2077 /* Return a list representation of the memoryview. Currently only buffers 2078 with native format strings are supported. */ 2079 static PyObject * 2080 memory_tolist(PyMemoryViewObject *mv, PyObject *noargs) 2081 { 2082 const Py_buffer *view = &(mv->view); 2083 const char *fmt; 2084 2085 CHECK_RELEASED(mv); 2086 2087 fmt = adjust_fmt(view); 2088 if (fmt == NULL) 2089 return NULL; 2090 if (view->ndim == 0) { 2091 return unpack_single(view->buf, fmt); 2092 } 2093 else if (view->ndim == 1) { 2094 return tolist_base(view->buf, view->shape, 2095 view->strides, view->suboffsets, 2096 fmt); 2097 } 2098 else { 2099 return tolist_rec(view->buf, view->ndim, view->shape, 2100 view->strides, view->suboffsets, 2101 fmt); 2102 } 2103 } 2104 2105 static PyObject * 2106 memory_tobytes(PyMemoryViewObject *self, PyObject *dummy) 2107 { 2108 Py_buffer *src = VIEW_ADDR(self); 2109 PyObject *bytes = NULL; 2110 2111 CHECK_RELEASED(self); 2112 2113 if (MV_C_CONTIGUOUS(self->flags)) { 2114 return PyBytes_FromStringAndSize(src->buf, src->len); 2115 } 2116 2117 bytes = PyBytes_FromStringAndSize(NULL, src->len); 2118 if (bytes == NULL) 2119 return NULL; 2120 2121 if (buffer_to_contiguous(PyBytes_AS_STRING(bytes), src, 'C') < 0) { 2122 Py_DECREF(bytes); 2123 return NULL; 2124 } 2125 2126 return bytes; 2127 } 2128 2129 static PyObject * 2130 memory_hex(PyMemoryViewObject *self, PyObject *dummy) 2131 { 2132 Py_buffer *src = VIEW_ADDR(self); 2133 PyObject *bytes; 2134 PyObject *ret; 2135 2136 CHECK_RELEASED(self); 2137 2138 if (MV_C_CONTIGUOUS(self->flags)) { 2139 return _Py_strhex(src->buf, src->len); 2140 } 2141 2142 bytes = memory_tobytes(self, dummy); 2143 if (bytes == NULL) 2144 return NULL; 2145 2146 ret = _Py_strhex(PyBytes_AS_STRING(bytes), Py_SIZE(bytes)); 2147 Py_DECREF(bytes); 2148 2149 return ret; 2150 } 2151 2152 static PyObject * 2153 memory_repr(PyMemoryViewObject *self) 2154 { 2155 if (self->flags & _Py_MEMORYVIEW_RELEASED) 2156 return PyUnicode_FromFormat("<released memory at %p>", self); 2157 else 2158 return PyUnicode_FromFormat("<memory at %p>", self); 2159 } 2160 2161 2162 /**************************************************************************/ 2163 /* Indexing and slicing */ 2164 /**************************************************************************/ 2165 2166 static char * 2167 lookup_dimension(Py_buffer *view, char *ptr, int dim, Py_ssize_t index) 2168 { 2169 Py_ssize_t nitems; /* items in the given dimension */ 2170 2171 assert(view->shape); 2172 assert(view->strides); 2173 2174 nitems = view->shape[dim]; 2175 if (index < 0) { 2176 index += nitems; 2177 } 2178 if (index < 0 || index >= nitems) { 2179 PyErr_Format(PyExc_IndexError, 2180 "index out of bounds on dimension %d", dim + 1); 2181 return NULL; 2182 } 2183 2184 ptr += view->strides[dim] * index; 2185 2186 ptr = ADJUST_PTR(ptr, view->suboffsets, dim); 2187 2188 return ptr; 2189 } 2190 2191 /* Get the pointer to the item at index. */ 2192 static char * 2193 ptr_from_index(Py_buffer *view, Py_ssize_t index) 2194 { 2195 char *ptr = (char *)view->buf; 2196 return lookup_dimension(view, ptr, 0, index); 2197 } 2198 2199 /* Get the pointer to the item at tuple. */ 2200 static char * 2201 ptr_from_tuple(Py_buffer *view, PyObject *tup) 2202 { 2203 char *ptr = (char *)view->buf; 2204 Py_ssize_t dim, nindices = PyTuple_GET_SIZE(tup); 2205 2206 if (nindices > view->ndim) { 2207 PyErr_Format(PyExc_TypeError, 2208 "cannot index %zd-dimension view with %zd-element tuple", 2209 view->ndim, nindices); 2210 return NULL; 2211 } 2212 2213 for (dim = 0; dim < nindices; dim++) { 2214 Py_ssize_t index; 2215 index = PyNumber_AsSsize_t(PyTuple_GET_ITEM(tup, dim), 2216 PyExc_IndexError); 2217 if (index == -1 && PyErr_Occurred()) 2218 return NULL; 2219 ptr = lookup_dimension(view, ptr, (int)dim, index); 2220 if (ptr == NULL) 2221 return NULL; 2222 } 2223 return ptr; 2224 } 2225 2226 /* Return the item at index. In a one-dimensional view, this is an object 2227 with the type specified by view->format. Otherwise, the item is a sub-view. 2228 The function is used in memory_subscript() and memory_as_sequence. */ 2229 static PyObject * 2230 memory_item(PyMemoryViewObject *self, Py_ssize_t index) 2231 { 2232 Py_buffer *view = &(self->view); 2233 const char *fmt; 2234 2235 CHECK_RELEASED(self); 2236 2237 fmt = adjust_fmt(view); 2238 if (fmt == NULL) 2239 return NULL; 2240 2241 if (view->ndim == 0) { 2242 PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory"); 2243 return NULL; 2244 } 2245 if (view->ndim == 1) { 2246 char *ptr = ptr_from_index(view, index); 2247 if (ptr == NULL) 2248 return NULL; 2249 return unpack_single(ptr, fmt); 2250 } 2251 2252 PyErr_SetString(PyExc_NotImplementedError, 2253 "multi-dimensional sub-views are not implemented"); 2254 return NULL; 2255 } 2256 2257 /* Return the item at position *key* (a tuple of indices). */ 2258 static PyObject * 2259 memory_item_multi(PyMemoryViewObject *self, PyObject *tup) 2260 { 2261 Py_buffer *view = &(self->view); 2262 const char *fmt; 2263 Py_ssize_t nindices = PyTuple_GET_SIZE(tup); 2264 char *ptr; 2265 2266 CHECK_RELEASED(self); 2267 2268 fmt = adjust_fmt(view); 2269 if (fmt == NULL) 2270 return NULL; 2271 2272 if (nindices < view->ndim) { 2273 PyErr_SetString(PyExc_NotImplementedError, 2274 "sub-views are not implemented"); 2275 return NULL; 2276 } 2277 ptr = ptr_from_tuple(view, tup); 2278 if (ptr == NULL) 2279 return NULL; 2280 return unpack_single(ptr, fmt); 2281 } 2282 2283 static inline int 2284 init_slice(Py_buffer *base, PyObject *key, int dim) 2285 { 2286 Py_ssize_t start, stop, step, slicelength; 2287 2288 if (PySlice_GetIndicesEx(key, base->shape[dim], 2289 &start, &stop, &step, &slicelength) < 0) { 2290 return -1; 2291 } 2292 2293 2294 if (base->suboffsets == NULL || dim == 0) { 2295 adjust_buf: 2296 base->buf = (char *)base->buf + base->strides[dim] * start; 2297 } 2298 else { 2299 Py_ssize_t n = dim-1; 2300 while (n >= 0 && base->suboffsets[n] < 0) 2301 n--; 2302 if (n < 0) 2303 goto adjust_buf; /* all suboffsets are negative */ 2304 base->suboffsets[n] = base->suboffsets[n] + base->strides[dim] * start; 2305 } 2306 base->shape[dim] = slicelength; 2307 base->strides[dim] = base->strides[dim] * step; 2308 2309 return 0; 2310 } 2311 2312 static int 2313 is_multislice(PyObject *key) 2314 { 2315 Py_ssize_t size, i; 2316 2317 if (!PyTuple_Check(key)) 2318 return 0; 2319 size = PyTuple_GET_SIZE(key); 2320 if (size == 0) 2321 return 0; 2322 2323 for (i = 0; i < size; i++) { 2324 PyObject *x = PyTuple_GET_ITEM(key, i); 2325 if (!PySlice_Check(x)) 2326 return 0; 2327 } 2328 return 1; 2329 } 2330 2331 static Py_ssize_t 2332 is_multiindex(PyObject *key) 2333 { 2334 Py_ssize_t size, i; 2335 2336 if (!PyTuple_Check(key)) 2337 return 0; 2338 size = PyTuple_GET_SIZE(key); 2339 for (i = 0; i < size; i++) { 2340 PyObject *x = PyTuple_GET_ITEM(key, i); 2341 if (!PyIndex_Check(x)) 2342 return 0; 2343 } 2344 return 1; 2345 } 2346 2347 /* mv[obj] returns an object holding the data for one element if obj 2348 fully indexes the memoryview or another memoryview object if it 2349 does not. 2350 2351 0-d memoryview objects can be referenced using mv[...] or mv[()] 2352 but not with anything else. */ 2353 static PyObject * 2354 memory_subscript(PyMemoryViewObject *self, PyObject *key) 2355 { 2356 Py_buffer *view; 2357 view = &(self->view); 2358 2359 CHECK_RELEASED(self); 2360 2361 if (view->ndim == 0) { 2362 if (PyTuple_Check(key) && PyTuple_GET_SIZE(key) == 0) { 2363 const char *fmt = adjust_fmt(view); 2364 if (fmt == NULL) 2365 return NULL; 2366 return unpack_single(view->buf, fmt); 2367 } 2368 else if (key == Py_Ellipsis) { 2369 Py_INCREF(self); 2370 return (PyObject *)self; 2371 } 2372 else { 2373 PyErr_SetString(PyExc_TypeError, 2374 "invalid indexing of 0-dim memory"); 2375 return NULL; 2376 } 2377 } 2378 2379 if (PyIndex_Check(key)) { 2380 Py_ssize_t index; 2381 index = PyNumber_AsSsize_t(key, PyExc_IndexError); 2382 if (index == -1 && PyErr_Occurred()) 2383 return NULL; 2384 return memory_item(self, index); 2385 } 2386 else if (PySlice_Check(key)) { 2387 PyMemoryViewObject *sliced; 2388 2389 sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view); 2390 if (sliced == NULL) 2391 return NULL; 2392 2393 if (init_slice(&sliced->view, key, 0) < 0) { 2394 Py_DECREF(sliced); 2395 return NULL; 2396 } 2397 init_len(&sliced->view); 2398 init_flags(sliced); 2399 2400 return (PyObject *)sliced; 2401 } 2402 else if (is_multiindex(key)) { 2403 return memory_item_multi(self, key); 2404 } 2405 else if (is_multislice(key)) { 2406 PyErr_SetString(PyExc_NotImplementedError, 2407 "multi-dimensional slicing is not implemented"); 2408 return NULL; 2409 } 2410 2411 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key"); 2412 return NULL; 2413 } 2414 2415 static int 2416 memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) 2417 { 2418 Py_buffer *view = &(self->view); 2419 Py_buffer src; 2420 const char *fmt; 2421 char *ptr; 2422 2423 CHECK_RELEASED_INT(self); 2424 2425 fmt = adjust_fmt(view); 2426 if (fmt == NULL) 2427 return -1; 2428 2429 if (view->readonly) { 2430 PyErr_SetString(PyExc_TypeError, "cannot modify read-only memory"); 2431 return -1; 2432 } 2433 if (value == NULL) { 2434 PyErr_SetString(PyExc_TypeError, "cannot delete memory"); 2435 return -1; 2436 } 2437 if (view->ndim == 0) { 2438 if (key == Py_Ellipsis || 2439 (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) { 2440 ptr = (char *)view->buf; 2441 return pack_single(ptr, value, fmt); 2442 } 2443 else { 2444 PyErr_SetString(PyExc_TypeError, 2445 "invalid indexing of 0-dim memory"); 2446 return -1; 2447 } 2448 } 2449 2450 if (PyIndex_Check(key)) { 2451 Py_ssize_t index; 2452 if (1 < view->ndim) { 2453 PyErr_SetString(PyExc_NotImplementedError, 2454 "sub-views are not implemented"); 2455 return -1; 2456 } 2457 index = PyNumber_AsSsize_t(key, PyExc_IndexError); 2458 if (index == -1 && PyErr_Occurred()) 2459 return -1; 2460 ptr = ptr_from_index(view, index); 2461 if (ptr == NULL) 2462 return -1; 2463 return pack_single(ptr, value, fmt); 2464 } 2465 /* one-dimensional: fast path */ 2466 if (PySlice_Check(key) && view->ndim == 1) { 2467 Py_buffer dest; /* sliced view */ 2468 Py_ssize_t arrays[3]; 2469 int ret = -1; 2470 2471 /* rvalue must be an exporter */ 2472 if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) < 0) 2473 return ret; 2474 2475 dest = *view; 2476 dest.shape = &arrays[0]; dest.shape[0] = view->shape[0]; 2477 dest.strides = &arrays[1]; dest.strides[0] = view->strides[0]; 2478 if (view->suboffsets) { 2479 dest.suboffsets = &arrays[2]; dest.suboffsets[0] = view->suboffsets[0]; 2480 } 2481 2482 if (init_slice(&dest, key, 0) < 0) 2483 goto end_block; 2484 dest.len = dest.shape[0] * dest.itemsize; 2485 2486 ret = copy_single(&dest, &src); 2487 2488 end_block: 2489 PyBuffer_Release(&src); 2490 return ret; 2491 } 2492 if (is_multiindex(key)) { 2493 char *ptr; 2494 if (PyTuple_GET_SIZE(key) < view->ndim) { 2495 PyErr_SetString(PyExc_NotImplementedError, 2496 "sub-views are not implemented"); 2497 return -1; 2498 } 2499 ptr = ptr_from_tuple(view, key); 2500 if (ptr == NULL) 2501 return -1; 2502 return pack_single(ptr, value, fmt); 2503 } 2504 if (PySlice_Check(key) || is_multislice(key)) { 2505 /* Call memory_subscript() to produce a sliced lvalue, then copy 2506 rvalue into lvalue. This is already implemented in _testbuffer.c. */ 2507 PyErr_SetString(PyExc_NotImplementedError, 2508 "memoryview slice assignments are currently restricted " 2509 "to ndim = 1"); 2510 return -1; 2511 } 2512 2513 PyErr_SetString(PyExc_TypeError, "memoryview: invalid slice key"); 2514 return -1; 2515 } 2516 2517 static Py_ssize_t 2518 memory_length(PyMemoryViewObject *self) 2519 { 2520 CHECK_RELEASED_INT(self); 2521 return self->view.ndim == 0 ? 1 : self->view.shape[0]; 2522 } 2523 2524 /* As mapping */ 2525 static PyMappingMethods memory_as_mapping = { 2526 (lenfunc)memory_length, /* mp_length */ 2527 (binaryfunc)memory_subscript, /* mp_subscript */ 2528 (objobjargproc)memory_ass_sub, /* mp_ass_subscript */ 2529 }; 2530 2531 /* As sequence */ 2532 static PySequenceMethods memory_as_sequence = { 2533 (lenfunc)memory_length, /* sq_length */ 2534 0, /* sq_concat */ 2535 0, /* sq_repeat */ 2536 (ssizeargfunc)memory_item, /* sq_item */ 2537 }; 2538 2539 2540 /**************************************************************************/ 2541 /* Comparisons */ 2542 /**************************************************************************/ 2543 2544 #define MV_COMPARE_EX -1 /* exception */ 2545 #define MV_COMPARE_NOT_IMPL -2 /* not implemented */ 2546 2547 /* Translate a StructError to "not equal". Preserve other exceptions. */ 2548 static int 2549 fix_struct_error_int(void) 2550 { 2551 assert(PyErr_Occurred()); 2552 /* XXX Cannot get at StructError directly? */ 2553 if (PyErr_ExceptionMatches(PyExc_ImportError) || 2554 PyErr_ExceptionMatches(PyExc_MemoryError)) { 2555 return MV_COMPARE_EX; 2556 } 2557 /* StructError: invalid or unknown format -> not equal */ 2558 PyErr_Clear(); 2559 return 0; 2560 } 2561 2562 /* Unpack and compare single items of p and q using the struct module. */ 2563 static int 2564 struct_unpack_cmp(const char *p, const char *q, 2565 struct unpacker *unpack_p, struct unpacker *unpack_q) 2566 { 2567 PyObject *v, *w; 2568 int ret; 2569 2570 /* At this point any exception from the struct module should not be 2571 StructError, since both formats have been accepted already. */ 2572 v = struct_unpack_single(p, unpack_p); 2573 if (v == NULL) 2574 return MV_COMPARE_EX; 2575 2576 w = struct_unpack_single(q, unpack_q); 2577 if (w == NULL) { 2578 Py_DECREF(v); 2579 return MV_COMPARE_EX; 2580 } 2581 2582 /* MV_COMPARE_EX == -1: exceptions are preserved */ 2583 ret = PyObject_RichCompareBool(v, w, Py_EQ); 2584 Py_DECREF(v); 2585 Py_DECREF(w); 2586 2587 return ret; 2588 } 2589 2590 /* Unpack and compare single items of p and q. If both p and q have the same 2591 single element native format, the comparison uses a fast path (gcc creates 2592 a jump table and converts memcpy into simple assignments on x86/x64). 2593 2594 Otherwise, the comparison is delegated to the struct module, which is 2595 30-60x slower. */ 2596 #define CMP_SINGLE(p, q, type) \ 2597 do { \ 2598 type x; \ 2599 type y; \ 2600 memcpy((char *)&x, p, sizeof x); \ 2601 memcpy((char *)&y, q, sizeof y); \ 2602 equal = (x == y); \ 2603 } while (0) 2604 2605 static inline int 2606 unpack_cmp(const char *p, const char *q, char fmt, 2607 struct unpacker *unpack_p, struct unpacker *unpack_q) 2608 { 2609 int equal; 2610 2611 switch (fmt) { 2612 2613 /* signed integers and fast path for 'B' */ 2614 case 'B': return *((unsigned char *)p) == *((unsigned char *)q); 2615 case 'b': return *((signed char *)p) == *((signed char *)q); 2616 case 'h': CMP_SINGLE(p, q, short); return equal; 2617 case 'i': CMP_SINGLE(p, q, int); return equal; 2618 case 'l': CMP_SINGLE(p, q, long); return equal; 2619 2620 /* boolean */ 2621 case '?': CMP_SINGLE(p, q, _Bool); return equal; 2622 2623 /* unsigned integers */ 2624 case 'H': CMP_SINGLE(p, q, unsigned short); return equal; 2625 case 'I': CMP_SINGLE(p, q, unsigned int); return equal; 2626 case 'L': CMP_SINGLE(p, q, unsigned long); return equal; 2627 2628 /* native 64-bit */ 2629 case 'q': CMP_SINGLE(p, q, long long); return equal; 2630 case 'Q': CMP_SINGLE(p, q, unsigned long long); return equal; 2631 2632 /* ssize_t and size_t */ 2633 case 'n': CMP_SINGLE(p, q, Py_ssize_t); return equal; 2634 case 'N': CMP_SINGLE(p, q, size_t); return equal; 2635 2636 /* floats */ 2637 /* XXX DBL_EPSILON? */ 2638 case 'f': CMP_SINGLE(p, q, float); return equal; 2639 case 'd': CMP_SINGLE(p, q, double); return equal; 2640 2641 /* bytes object */ 2642 case 'c': return *p == *q; 2643 2644 /* pointer */ 2645 case 'P': CMP_SINGLE(p, q, void *); return equal; 2646 2647 /* use the struct module */ 2648 case '_': 2649 assert(unpack_p); 2650 assert(unpack_q); 2651 return struct_unpack_cmp(p, q, unpack_p, unpack_q); 2652 } 2653 2654 /* NOT REACHED */ 2655 PyErr_SetString(PyExc_RuntimeError, 2656 "memoryview: internal error in richcompare"); 2657 return MV_COMPARE_EX; 2658 } 2659 2660 /* Base case for recursive array comparisons. Assumption: ndim == 1. */ 2661 static int 2662 cmp_base(const char *p, const char *q, const Py_ssize_t *shape, 2663 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets, 2664 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets, 2665 char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q) 2666 { 2667 Py_ssize_t i; 2668 int equal; 2669 2670 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) { 2671 const char *xp = ADJUST_PTR(p, psuboffsets, 0); 2672 const char *xq = ADJUST_PTR(q, qsuboffsets, 0); 2673 equal = unpack_cmp(xp, xq, fmt, unpack_p, unpack_q); 2674 if (equal <= 0) 2675 return equal; 2676 } 2677 2678 return 1; 2679 } 2680 2681 /* Recursively compare two multi-dimensional arrays that have the same 2682 logical structure. Assumption: ndim >= 1. */ 2683 static int 2684 cmp_rec(const char *p, const char *q, 2685 Py_ssize_t ndim, const Py_ssize_t *shape, 2686 const Py_ssize_t *pstrides, const Py_ssize_t *psuboffsets, 2687 const Py_ssize_t *qstrides, const Py_ssize_t *qsuboffsets, 2688 char fmt, struct unpacker *unpack_p, struct unpacker *unpack_q) 2689 { 2690 Py_ssize_t i; 2691 int equal; 2692 2693 assert(ndim >= 1); 2694 assert(shape != NULL); 2695 assert(pstrides != NULL); 2696 assert(qstrides != NULL); 2697 2698 if (ndim == 1) { 2699 return cmp_base(p, q, shape, 2700 pstrides, psuboffsets, 2701 qstrides, qsuboffsets, 2702 fmt, unpack_p, unpack_q); 2703 } 2704 2705 for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) { 2706 const char *xp = ADJUST_PTR(p, psuboffsets, 0); 2707 const char *xq = ADJUST_PTR(q, qsuboffsets, 0); 2708 equal = cmp_rec(xp, xq, ndim-1, shape+1, 2709 pstrides+1, psuboffsets ? psuboffsets+1 : NULL, 2710 qstrides+1, qsuboffsets ? qsuboffsets+1 : NULL, 2711 fmt, unpack_p, unpack_q); 2712 if (equal <= 0) 2713 return equal; 2714 } 2715 2716 return 1; 2717 } 2718 2719 static PyObject * 2720 memory_richcompare(PyObject *v, PyObject *w, int op) 2721 { 2722 PyObject *res; 2723 Py_buffer wbuf, *vv; 2724 Py_buffer *ww = NULL; 2725 struct unpacker *unpack_v = NULL; 2726 struct unpacker *unpack_w = NULL; 2727 char vfmt, wfmt; 2728 int equal = MV_COMPARE_NOT_IMPL; 2729 2730 if (op != Py_EQ && op != Py_NE) 2731 goto result; /* Py_NotImplemented */ 2732 2733 assert(PyMemoryView_Check(v)); 2734 if (BASE_INACCESSIBLE(v)) { 2735 equal = (v == w); 2736 goto result; 2737 } 2738 vv = VIEW_ADDR(v); 2739 2740 if (PyMemoryView_Check(w)) { 2741 if (BASE_INACCESSIBLE(w)) { 2742 equal = (v == w); 2743 goto result; 2744 } 2745 ww = VIEW_ADDR(w); 2746 } 2747 else { 2748 if (PyObject_GetBuffer(w, &wbuf, PyBUF_FULL_RO) < 0) { 2749 PyErr_Clear(); 2750 goto result; /* Py_NotImplemented */ 2751 } 2752 ww = &wbuf; 2753 } 2754 2755 if (!equiv_shape(vv, ww)) { 2756 PyErr_Clear(); 2757 equal = 0; 2758 goto result; 2759 } 2760 2761 /* Use fast unpacking for identical primitive C type formats. */ 2762 if (get_native_fmtchar(&vfmt, vv->format) < 0) 2763 vfmt = '_'; 2764 if (get_native_fmtchar(&wfmt, ww->format) < 0) 2765 wfmt = '_'; 2766 if (vfmt == '_' || wfmt == '_' || vfmt != wfmt) { 2767 /* Use struct module unpacking. NOTE: Even for equal format strings, 2768 memcmp() cannot be used for item comparison since it would give 2769 incorrect results in the case of NaNs or uninitialized padding 2770 bytes. */ 2771 vfmt = '_'; 2772 unpack_v = struct_get_unpacker(vv->format, vv->itemsize); 2773 if (unpack_v == NULL) { 2774 equal = fix_struct_error_int(); 2775 goto result; 2776 } 2777 unpack_w = struct_get_unpacker(ww->format, ww->itemsize); 2778 if (unpack_w == NULL) { 2779 equal = fix_struct_error_int(); 2780 goto result; 2781 } 2782 } 2783 2784 if (vv->ndim == 0) { 2785 equal = unpack_cmp(vv->buf, ww->buf, 2786 vfmt, unpack_v, unpack_w); 2787 } 2788 else if (vv->ndim == 1) { 2789 equal = cmp_base(vv->buf, ww->buf, vv->shape, 2790 vv->strides, vv->suboffsets, 2791 ww->strides, ww->suboffsets, 2792 vfmt, unpack_v, unpack_w); 2793 } 2794 else { 2795 equal = cmp_rec(vv->buf, ww->buf, vv->ndim, vv->shape, 2796 vv->strides, vv->suboffsets, 2797 ww->strides, ww->suboffsets, 2798 vfmt, unpack_v, unpack_w); 2799 } 2800 2801 result: 2802 if (equal < 0) { 2803 if (equal == MV_COMPARE_NOT_IMPL) 2804 res = Py_NotImplemented; 2805 else /* exception */ 2806 res = NULL; 2807 } 2808 else if ((equal && op == Py_EQ) || (!equal && op == Py_NE)) 2809 res = Py_True; 2810 else 2811 res = Py_False; 2812 2813 if (ww == &wbuf) 2814 PyBuffer_Release(ww); 2815 2816 unpacker_free(unpack_v); 2817 unpacker_free(unpack_w); 2818 2819 Py_XINCREF(res); 2820 return res; 2821 } 2822 2823 /**************************************************************************/ 2824 /* Hash */ 2825 /**************************************************************************/ 2826 2827 static Py_hash_t 2828 memory_hash(PyMemoryViewObject *self) 2829 { 2830 if (self->hash == -1) { 2831 Py_buffer *view = &self->view; 2832 char *mem = view->buf; 2833 Py_ssize_t ret; 2834 char fmt; 2835 2836 CHECK_RELEASED_INT(self); 2837 2838 if (!view->readonly) { 2839 PyErr_SetString(PyExc_ValueError, 2840 "cannot hash writable memoryview object"); 2841 return -1; 2842 } 2843 ret = get_native_fmtchar(&fmt, view->format); 2844 if (ret < 0 || !IS_BYTE_FORMAT(fmt)) { 2845 PyErr_SetString(PyExc_ValueError, 2846 "memoryview: hashing is restricted to formats 'B', 'b' or 'c'"); 2847 return -1; 2848 } 2849 if (view->obj != NULL && PyObject_Hash(view->obj) == -1) { 2850 /* Keep the original error message */ 2851 return -1; 2852 } 2853 2854 if (!MV_C_CONTIGUOUS(self->flags)) { 2855 mem = PyMem_Malloc(view->len); 2856 if (mem == NULL) { 2857 PyErr_NoMemory(); 2858 return -1; 2859 } 2860 if (buffer_to_contiguous(mem, view, 'C') < 0) { 2861 PyMem_Free(mem); 2862 return -1; 2863 } 2864 } 2865 2866 /* Can't fail */ 2867 self->hash = _Py_HashBytes(mem, view->len); 2868 2869 if (mem != view->buf) 2870 PyMem_Free(mem); 2871 } 2872 2873 return self->hash; 2874 } 2875 2876 2877 /**************************************************************************/ 2878 /* getters */ 2879 /**************************************************************************/ 2880 2881 static PyObject * 2882 _IntTupleFromSsizet(int len, Py_ssize_t *vals) 2883 { 2884 int i; 2885 PyObject *o; 2886 PyObject *intTuple; 2887 2888 if (vals == NULL) 2889 return PyTuple_New(0); 2890 2891 intTuple = PyTuple_New(len); 2892 if (!intTuple) 2893 return NULL; 2894 for (i=0; i<len; i++) { 2895 o = PyLong_FromSsize_t(vals[i]); 2896 if (!o) { 2897 Py_DECREF(intTuple); 2898 return NULL; 2899 } 2900 PyTuple_SET_ITEM(intTuple, i, o); 2901 } 2902 return intTuple; 2903 } 2904 2905 static PyObject * 2906 memory_obj_get(PyMemoryViewObject *self) 2907 { 2908 Py_buffer *view = &self->view; 2909 2910 CHECK_RELEASED(self); 2911 if (view->obj == NULL) { 2912 Py_RETURN_NONE; 2913 } 2914 Py_INCREF(view->obj); 2915 return view->obj; 2916 } 2917 2918 static PyObject * 2919 memory_nbytes_get(PyMemoryViewObject *self) 2920 { 2921 CHECK_RELEASED(self); 2922 return PyLong_FromSsize_t(self->view.len); 2923 } 2924 2925 static PyObject * 2926 memory_format_get(PyMemoryViewObject *self) 2927 { 2928 CHECK_RELEASED(self); 2929 return PyUnicode_FromString(self->view.format); 2930 } 2931 2932 static PyObject * 2933 memory_itemsize_get(PyMemoryViewObject *self) 2934 { 2935 CHECK_RELEASED(self); 2936 return PyLong_FromSsize_t(self->view.itemsize); 2937 } 2938 2939 static PyObject * 2940 memory_shape_get(PyMemoryViewObject *self) 2941 { 2942 CHECK_RELEASED(self); 2943 return _IntTupleFromSsizet(self->view.ndim, self->view.shape); 2944 } 2945 2946 static PyObject * 2947 memory_strides_get(PyMemoryViewObject *self) 2948 { 2949 CHECK_RELEASED(self); 2950 return _IntTupleFromSsizet(self->view.ndim, self->view.strides); 2951 } 2952 2953 static PyObject * 2954 memory_suboffsets_get(PyMemoryViewObject *self) 2955 { 2956 CHECK_RELEASED(self); 2957 return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets); 2958 } 2959 2960 static PyObject * 2961 memory_readonly_get(PyMemoryViewObject *self) 2962 { 2963 CHECK_RELEASED(self); 2964 return PyBool_FromLong(self->view.readonly); 2965 } 2966 2967 static PyObject * 2968 memory_ndim_get(PyMemoryViewObject *self) 2969 { 2970 CHECK_RELEASED(self); 2971 return PyLong_FromLong(self->view.ndim); 2972 } 2973 2974 static PyObject * 2975 memory_c_contiguous(PyMemoryViewObject *self, PyObject *dummy) 2976 { 2977 CHECK_RELEASED(self); 2978 return PyBool_FromLong(MV_C_CONTIGUOUS(self->flags)); 2979 } 2980 2981 static PyObject * 2982 memory_f_contiguous(PyMemoryViewObject *self, PyObject *dummy) 2983 { 2984 CHECK_RELEASED(self); 2985 return PyBool_FromLong(MV_F_CONTIGUOUS(self->flags)); 2986 } 2987 2988 static PyObject * 2989 memory_contiguous(PyMemoryViewObject *self, PyObject *dummy) 2990 { 2991 CHECK_RELEASED(self); 2992 return PyBool_FromLong(MV_ANY_CONTIGUOUS(self->flags)); 2993 } 2994 2995 PyDoc_STRVAR(memory_obj_doc, 2996 "The underlying object of the memoryview."); 2997 PyDoc_STRVAR(memory_nbytes_doc, 2998 "The amount of space in bytes that the array would use in\n" 2999 " a contiguous representation."); 3000 PyDoc_STRVAR(memory_readonly_doc, 3001 "A bool indicating whether the memory is read only."); 3002 PyDoc_STRVAR(memory_itemsize_doc, 3003 "The size in bytes of each element of the memoryview."); 3004 PyDoc_STRVAR(memory_format_doc, 3005 "A string containing the format (in struct module style)\n" 3006 " for each element in the view."); 3007 PyDoc_STRVAR(memory_ndim_doc, 3008 "An integer indicating how many dimensions of a multi-dimensional\n" 3009 " array the memory represents."); 3010 PyDoc_STRVAR(memory_shape_doc, 3011 "A tuple of ndim integers giving the shape of the memory\n" 3012 " as an N-dimensional array."); 3013 PyDoc_STRVAR(memory_strides_doc, 3014 "A tuple of ndim integers giving the size in bytes to access\n" 3015 " each element for each dimension of the array."); 3016 PyDoc_STRVAR(memory_suboffsets_doc, 3017 "A tuple of integers used internally for PIL-style arrays."); 3018 PyDoc_STRVAR(memory_c_contiguous_doc, 3019 "A bool indicating whether the memory is C contiguous."); 3020 PyDoc_STRVAR(memory_f_contiguous_doc, 3021 "A bool indicating whether the memory is Fortran contiguous."); 3022 PyDoc_STRVAR(memory_contiguous_doc, 3023 "A bool indicating whether the memory is contiguous."); 3024 3025 3026 static PyGetSetDef memory_getsetlist[] = { 3027 {"obj", (getter)memory_obj_get, NULL, memory_obj_doc}, 3028 {"nbytes", (getter)memory_nbytes_get, NULL, memory_nbytes_doc}, 3029 {"readonly", (getter)memory_readonly_get, NULL, memory_readonly_doc}, 3030 {"itemsize", (getter)memory_itemsize_get, NULL, memory_itemsize_doc}, 3031 {"format", (getter)memory_format_get, NULL, memory_format_doc}, 3032 {"ndim", (getter)memory_ndim_get, NULL, memory_ndim_doc}, 3033 {"shape", (getter)memory_shape_get, NULL, memory_shape_doc}, 3034 {"strides", (getter)memory_strides_get, NULL, memory_strides_doc}, 3035 {"suboffsets", (getter)memory_suboffsets_get, NULL, memory_suboffsets_doc}, 3036 {"c_contiguous", (getter)memory_c_contiguous, NULL, memory_c_contiguous_doc}, 3037 {"f_contiguous", (getter)memory_f_contiguous, NULL, memory_f_contiguous_doc}, 3038 {"contiguous", (getter)memory_contiguous, NULL, memory_contiguous_doc}, 3039 {NULL, NULL, NULL, NULL}, 3040 }; 3041 3042 PyDoc_STRVAR(memory_release_doc, 3043 "release($self, /)\n--\n\ 3044 \n\ 3045 Release the underlying buffer exposed by the memoryview object."); 3046 PyDoc_STRVAR(memory_tobytes_doc, 3047 "tobytes($self, /)\n--\n\ 3048 \n\ 3049 Return the data in the buffer as a byte string."); 3050 PyDoc_STRVAR(memory_hex_doc, 3051 "hex($self, /)\n--\n\ 3052 \n\ 3053 Return the data in the buffer as a string of hexadecimal numbers."); 3054 PyDoc_STRVAR(memory_tolist_doc, 3055 "tolist($self, /)\n--\n\ 3056 \n\ 3057 Return the data in the buffer as a list of elements."); 3058 PyDoc_STRVAR(memory_cast_doc, 3059 "cast($self, /, format, *, shape)\n--\n\ 3060 \n\ 3061 Cast a memoryview to a new format or shape."); 3062 3063 static PyMethodDef memory_methods[] = { 3064 {"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc}, 3065 {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, memory_tobytes_doc}, 3066 {"hex", (PyCFunction)memory_hex, METH_NOARGS, memory_hex_doc}, 3067 {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc}, 3068 {"cast", (PyCFunction)memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc}, 3069 {"__enter__", memory_enter, METH_NOARGS, NULL}, 3070 {"__exit__", memory_exit, METH_VARARGS, NULL}, 3071 {NULL, NULL} 3072 }; 3073 3074 3075 PyTypeObject PyMemoryView_Type = { 3076 PyVarObject_HEAD_INIT(&PyType_Type, 0) 3077 "memoryview", /* tp_name */ 3078 offsetof(PyMemoryViewObject, ob_array), /* tp_basicsize */ 3079 sizeof(Py_ssize_t), /* tp_itemsize */ 3080 (destructor)memory_dealloc, /* tp_dealloc */ 3081 0, /* tp_print */ 3082 0, /* tp_getattr */ 3083 0, /* tp_setattr */ 3084 0, /* tp_reserved */ 3085 (reprfunc)memory_repr, /* tp_repr */ 3086 0, /* tp_as_number */ 3087 &memory_as_sequence, /* tp_as_sequence */ 3088 &memory_as_mapping, /* tp_as_mapping */ 3089 (hashfunc)memory_hash, /* tp_hash */ 3090 0, /* tp_call */ 3091 0, /* tp_str */ 3092 PyObject_GenericGetAttr, /* tp_getattro */ 3093 0, /* tp_setattro */ 3094 &memory_as_buffer, /* tp_as_buffer */ 3095 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 3096 memory_doc, /* tp_doc */ 3097 (traverseproc)memory_traverse, /* tp_traverse */ 3098 (inquiry)memory_clear, /* tp_clear */ 3099 memory_richcompare, /* tp_richcompare */ 3100 offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */ 3101 0, /* tp_iter */ 3102 0, /* tp_iternext */ 3103 memory_methods, /* tp_methods */ 3104 0, /* tp_members */ 3105 memory_getsetlist, /* tp_getset */ 3106 0, /* tp_base */ 3107 0, /* tp_dict */ 3108 0, /* tp_descr_get */ 3109 0, /* tp_descr_set */ 3110 0, /* tp_dictoffset */ 3111 0, /* tp_init */ 3112 0, /* tp_alloc */ 3113 memory_new, /* tp_new */ 3114 }; 3115