public static byte[] ToArray(this IPythonBuffer buffer) { if (buffer.IsCContiguous()) { return(buffer.AsReadOnlySpan().ToArray()); } else { var bytes = new byte[buffer.NumBytes()]; int i = 0; foreach (byte b in buffer.EnumerateBytes()) { bytes[i++] = b; } return(bytes); } }
public MemoryHolder(IPythonBuffer buffer, int offset, int size) { if (buffer.IsReadOnly) { throw new ArgumentException("Buffer must be writable."); } if (!buffer.IsCContiguous()) { throw new ArgumentException("Buffer must be c-contiguous."); } if (size < 0) { throw new ArgumentOutOfRangeException(nameof(size), size, "Non-negative number required."); } if (offset < 0) { throw new ArgumentOutOfRangeException(nameof(offset), offset, "Non-negative number required."); } int bufSize = buffer.NumBytes(); ReadOnlySpan <byte> memblock = buffer.AsSpan(); if (memblock.Length != bufSize) { new ArgumentException("Invalid buffer."); } if (size > bufSize - offset) { throw new ArgumentException("Requested memory block exceeds buffer boundaries."); } _buffer = buffer; _handle = buffer.Pin(); unsafe { _data = (IntPtr)_handle.Pointer + offset; } _size = size; }
private static IEnumerable <int> EnumerateDimension(IPythonBuffer buffer, int ofs, int dim) { IReadOnlyList <int>?shape = buffer.Shape; IReadOnlyList <int>?strides = buffer.Strides; if (shape == null || strides == null) { // simple C-contiguous case Debug.Assert(buffer.Offset == 0); int len = buffer.NumBytes(); for (int i = 0; i < len; i++) { yield return(i); } } else if (dim >= shape.Count) { // iterate individual element (scalar) for (int i = 0; i < buffer.ItemSize; i++) { yield return(ofs + i); } } else { for (int i = 0; i < shape[dim]; i++) { // iterate all bytes from a subdimension foreach (int j in EnumerateDimension(buffer, ofs, dim + 1)) { yield return(j); } ofs += strides[dim]; } } }