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