* Get the buffer info returning either the old one (passed in) or a new * buffer info which adds holds on to (and thus replaces) the old one. */
| 685 | * buffer info which adds holds on to (and thus replaces) the old one. |
| 686 | */ |
| 687 | static _buffer_info_t* |
| 688 | _buffer_get_info(void **buffer_info_cache_ptr, PyObject *obj, int flags) |
| 689 | { |
| 690 | _buffer_info_t *info = NULL; |
| 691 | _buffer_info_t *stored_info; /* First currently stored buffer info */ |
| 692 | |
| 693 | if (_buffer_info_untag(*buffer_info_cache_ptr, &stored_info, obj) < 0) { |
| 694 | return NULL; |
| 695 | } |
| 696 | _buffer_info_t *old_info = stored_info; |
| 697 | |
| 698 | /* Compute information (it would be nice to skip this in simple cases) */ |
| 699 | info = _buffer_info_new(obj, flags); |
| 700 | if (info == NULL) { |
| 701 | return NULL; |
| 702 | } |
| 703 | |
| 704 | if (old_info != NULL && _buffer_info_cmp(info, old_info) != 0) { |
| 705 | _buffer_info_t *next_info = old_info->next; |
| 706 | old_info = NULL; /* Can't use this one, but possibly next */ |
| 707 | |
| 708 | if (info->ndim > 1 && next_info != NULL) { |
| 709 | /* |
| 710 | * Some arrays are C- and F-contiguous and if they have more |
| 711 | * than one dimension, the buffer-info may differ between the |
| 712 | * two because strides for length 1 dimension may be adjusted. |
| 713 | * If we export both buffers, the first stored one may be |
| 714 | * the one for the other contiguity, so check both. |
| 715 | * This is generally very unlikely in all other cases, since |
| 716 | * in all other cases the first one will match unless array |
| 717 | * metadata was modified in-place (which is discouraged). |
| 718 | */ |
| 719 | if (_buffer_info_cmp(info, next_info) == 0) { |
| 720 | old_info = next_info; |
| 721 | } |
| 722 | } |
| 723 | } |
| 724 | if (old_info != NULL) { |
| 725 | /* |
| 726 | * The two info->format are considered equal if one of them |
| 727 | * has no format set (meaning the format is arbitrary and can |
| 728 | * be modified). If the new info has a format, but we reuse |
| 729 | * the old one, this transfers the ownership to the old one. |
| 730 | */ |
| 731 | if (old_info->format == NULL) { |
| 732 | old_info->format = info->format; |
| 733 | info->format = NULL; |
| 734 | } |
| 735 | _buffer_info_free_untagged(info); |
| 736 | info = old_info; |
| 737 | } |
| 738 | else { |
| 739 | /* Insert new info as first item in the linked buffer-info list. */ |
| 740 | info->next = stored_info; |
| 741 | *buffer_info_cache_ptr = buffer_info_tag(info); |
| 742 | } |
| 743 | |
| 744 | return info; |
no test coverage detected