All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.org.python.core.buffer.SimpleNIOBuffer Maven / Gradle / Ivy

Go to download

Jython is an implementation of the high-level, dynamic, object-oriented language Python written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform.

There is a newer version: 2.7.4
Show newest version
package org.python.core.buffer;

import java.nio.ByteBuffer;

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

/**
 * Buffer API over a read-only one-dimensional java.nio.ByteBuffer of one-byte items.
 */
public class SimpleNIOBuffer extends BaseNIOBuffer {

    /**
     * Provide an instance of SimpleNIOBuffer with navigation variables initialised,
     * for sub-class use. The buffer ({@link #storage}, {@link #index0}), and the {@link #shape}
     * array will be initialised from the arguments (which are checked for range). The
     * {@link #strides} is set for (one-byte) unit stride. Only the call to
     * {@link #checkRequestFlags(int)}, passing the consumer's request flags, really remains for the
     * sub-class constructor to do.
     *
     * 
     * super(storage.duplicate(), index0, size);
     * checkRequestFlags(flags);        // Check request is compatible with type
     * 
* * @param obj exporting object (or null) * @param storage the ByteBuffer wrapping the exported object state. NOTE: this * PyBuffer keeps a reference and may manipulate the position, mark and * limit hereafter. Use {@link ByteBuffer#duplicate()} to give it an isolated copy. * @param index0 offset where the data starts in that array (item[0]) * @param size the number of bytes occupied * @throws NullPointerException if storage is null * @throws ArrayIndexOutOfBoundsException if index0 and size are * inconsistent with storage.capacity() */ protected SimpleNIOBuffer(BufferProtocol obj, ByteBuffer storage, int index0, int size) throws PyException, ArrayIndexOutOfBoundsException { super(storage, CONTIGUITY | SIMPLE, index0, size, 1); this.obj = obj; // Check arguments using the "all non-negative" trick if ((index0 | size | storage.capacity() - (index0 + size)) < 0) { throw new ArrayIndexOutOfBoundsException(); } } /** * Provide an instance of SimpleNIOBuffer, on a slice of a {@link ByteBuffer}, * meeting the consumer's expectations as expressed in the flags argument, which is * checked against the capabilities of the buffer type. No reference will be kept to the * ByteBuffer passed in. (It is duplicated.) * * @param flags consumer requirements * @param obj exporting object (or null) * @param storage the ByteBuffer wrapping the exported object state * @param index0 offset where the data starts in that buffer (item[0]) * @param size the number of bytes occupied * @throws NullPointerException if storage is null * @throws ArrayIndexOutOfBoundsException if index0 and size are * inconsistent with storage.length * @throws PyException {@code BufferError} when expectations do not correspond with the type */ public SimpleNIOBuffer(int flags, BufferProtocol obj, ByteBuffer storage, int index0, int size) throws PyException, ArrayIndexOutOfBoundsException, NullPointerException { this(obj, storage.duplicate(), index0, size); // Construct checked SimpleNIOBuffer checkRequestFlags(flags); // Check request is compatible with type } /** * Provide an instance of SimpleNIOBuffer, on the entirety of a {@link ByteBuffer}, * with navigation variables initialised, for sub-class use. The buffer ( {@link #storage}, * {@link #index0}), and the navigation ({@link #shape} array) will be initialised from the * argument. * * @param obj exporting object (or null) * @param storage the ByteBuffer wrapping the exported object state. NOTE: this * PyBuffer keeps a reference and may manipulate the position, mark and * limit hereafter. Use {@link ByteBuffer#duplicate()} to give it an isolated copy. * @throws NullPointerException if storage is null */ protected SimpleNIOBuffer(BufferProtocol obj, ByteBuffer storage) throws NullPointerException { this(obj, storage, 0, storage.capacity()); } /** * Provide an instance of SimpleNIOBuffer, on the entirety of a {@link ByteBuffer}, * meeting the consumer's expectations as expressed in the flags argument, which is * checked against the capabilities of the buffer type. No reference will be kept to the * ByteBuffer passed in. (It is duplicated.) * * @param flags consumer requirements * @param obj exporting object (or null) * @param storage the ByteBuffer wrapping the exported object state * @throws NullPointerException if storage is null * @throws PyException {@code BufferError} when expectations do not correspond with the type */ public SimpleNIOBuffer(int flags, BufferProtocol obj, ByteBuffer storage) throws PyException, NullPointerException { this(obj, storage.duplicate()); // Construct SimpleNIOBuffer on whole ByteBuffer checkRequestFlags(flags); // Check request is compatible with type } /** * {@inheritDoc} *

* SimpleNIOBuffer provides an implementation optimised for contiguous bytes in * one-dimension. */ @Override public int getLen() { // Simplify for one-dimensional contiguous bytes return shape[0]; } @Override public final int byteIndex(int index) throws IndexOutOfBoundsException { return index0 + index; } // XXX Consider moving to clauses in getBufferSlice(int, int, int, int) // to avoid delegation loop where that delegates to this but in BaseBuffer the reverse. @Override public PyBuffer getBufferSlice(int flags, int start, int count) { if (count > 0) { // Translate relative to underlying buffer int compIndex0 = index0 + start; // Create the slice from the sub-range of the buffer return new SimpleView(getRoot(), flags, storage, compIndex0, count); } else { // Special case for count==0 where above logic would fail. Efficient too. return new ZeroByteBuffer.View(getRoot(), flags); } } /** * {@inheritDoc} *

* SimpleNIOBuffer provides an implementation for slicing contiguous bytes in one * dimension. In that case, x(i) = u(r+i) for i = 0..L-1 where u is the underlying * buffer, and r and L are the start and count with which x was created * from u. Thus y(k) = u(r+s+km), that is, the composite offset is r+s and * the stride is m. */ @Override public PyBuffer getBufferSlice(int flags, int start, int count, int stride) { if (stride == 1 || count < 2) { // Unstrided slice of simple buffer is special case return getBufferSlice(flags, start, count); } else { // Translate relative to underlying buffer int compIndex0 = index0 + start; // Construct a view, taking a lock on the root object (this or this.root) return new Strided1DNIOBuffer.SlicedView(getRoot(), flags, storage, compIndex0, count, stride); } } /** * A SimpleNIOBuffer.SimpleView represents a contiguous subsequence of another * SimpleNIOBuffer. */ static class SimpleView extends SimpleNIOBuffer { /** The buffer on which this is a slice view */ PyBuffer root; /** * Construct a slice of a SimpleNIOBuffer. * * @param root buffer which will be acquired and must be released ultimately * @param flags the request flags of the consumer that requested the slice * @param storage ByteBuffer wrapping exported data (no reference kept) * @param offset where the data starts in that buffer (item[0]) * @param count the number of items in the sliced view */ public SimpleView(PyBuffer root, int flags, ByteBuffer storage, int offset, int count) { // Create a new SimpleNIOBuffer on the buffer passed in (part of the root) super(flags, root.getObj(), storage, offset, count); // Get a lease on the root PyBuffer this.root = root.getBuffer(FULL_RO); } @Override protected PyBuffer getRoot() { return root; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy