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