package org.python.core.buffer;

import org.python.core.BufferProtocol;
import org.python.core.PyBuffer;
import org.python.core.PyException;

/**
 * Read-write buffer API over a one-dimensional array of one-byte items, that are evenly-spaced in a
 * storage array. The storage conventions are described in {@link Strided1DBuffer} of which this is
 * an extension providing write operations and a writable slice.
 */
public class Strided1DWritableBuffer extends Strided1DBuffer {

    /**
     * Provide an instance of Strided1DWritableBuffer on a particular array of bytes
     * specifying a starting index, the number of items in the result, and a byte-indexing stride.
     * The result of byteAt(i) will be equal to storage[index0+stride*i]
     * (whatever the sign of {@code stride}), valid for 0≤{@code i}<{@code count}.
     * 

* The constructed PyBuffer meets the consumer's expectations as expressed in the * flags argument, or an exception will be thrown if these are incompatible with * the type (e.g. the consumer does not specify that it understands the strides array). Note * that the actual range in the storage array, the lowest and highest index, is not * explicitly passed, but is implicit in index0, count and * stride. The caller is responsible for checking these fall within the array, or * the sub-range the caller is allowed to use. * * @param flags consumer requirements * @param obj exporting object (or null) * @param storage raw byte array containing exported data * @param index0 index into storage of item[0] * @param count number of items in the slice * @param stride byte-index distance from one element to the next in the new PyBuffer * @throws NullPointerException if storage is null * @throws ArrayIndexOutOfBoundsException if index0, count and * stride are inconsistent with storage.length * @throws PyException {@code BufferError} when expectations do not correspond with the type */ public Strided1DWritableBuffer(int flags, BufferProtocol obj, byte[] storage, int index0, int count, int stride) throws ArrayIndexOutOfBoundsException, NullPointerException, PyException { super(obj, storage, index0, count, stride); addFeatureFlags(WRITABLE); checkRequestFlags(flags); // Check request is compatible with type } /** * {@inheritDoc} *

* Declared final returning true in * Strided1DWritableBuffer to make checks unnecessary. */ @Override public final boolean isReadonly() { return false; } /** Do nothing: the buffer is writable. */ @Override protected final void checkWritable() {} @Override protected void storeAtImpl(byte value, int byteIndex) { // Implement directly and don't ask whether read-only storage[byteIndex] = value; } /** * {@inheritDoc} *

* Strided1DWritableBuffer provides an implementation that returns a writable * slice. */ @Override public PyBuffer getBufferSlice(int flags, int start, int count, int stride) { if (count > 0) { // Translate start relative to underlying buffer int compStride = this.stride * stride; int compIndex0 = index0 + start * this.stride; // Construct a view, taking a lock on the root object (this or this.root) return new SlicedView(getRoot(), flags, storage, compIndex0, count, compStride); } else { // Special case for count==0 where above logic would fail. Efficient too. return new ZeroByteBuffer.View(getRoot(), flags); } } /** * A Strided1DWritableBuffer.SlicedView represents a non-contiguous subsequence of * a simple buffer. */ static class SlicedView extends Strided1DWritableBuffer { /** The buffer on which this is a slice view */ PyBuffer root; /** * Construct a slice of a one-dimensional byte buffer. * * @param root on which release must be called when this is released * @param flags consumer requirements * @param storage raw byte array containing exported data * @param index0 index into storage of item[0] * @param count number of items in the sliced view * @param stride in between successive elements of the new PyBuffer * @throws PyException {@code BufferError} when expectations do not correspond with the type */ public SlicedView(PyBuffer root, int flags, byte[] storage, int index0, int count, int stride) throws PyException { // Create a new on the buffer passed in (part of the root) super(flags, root.getObj(), storage, index0, count, stride); // Get a lease on the root PyBuffer (writable) this.root = root.getBuffer(FULL); } @Override protected PyBuffer getRoot() { return root; } } }

Ads help maintain this website.