public abstract class BaseBuffer extends java.lang.Object implements PyBuffer
This class leaves undefined the storage mechanism for the bytes (typically byte[] or
java.nio.ByteBuffer), while remaining definite that it is an indexable sequence of
bytes. A concrete class that extends this one must provide elementary accessors
byteAtImpl(int), storeAtImpl(byte, int) that abstract this storage, a factory
getNIOByteBufferImpl() for ByteBuffers that wrap the storage, and a factory
for slices PyBuffer.getBufferSlice(int, int, int, int).
The sub-class constructor must specify the feature flags (see
BaseBuffer(int, int, int[], int[])), set index0, shape and
strides, and finally check the client capabilities with checkRequestFlags(int).
A sub-class intended to represent slices of an exporter that counts its exports, as part of a
locking protocol like bytearray's, must override getRoot() so that a call
to release() on a view of slice, propagates to the buffer view that provided the slice.
Access methods provided here necessarily work with the abstracted byteAtImpl(int),
storeAtImpl(byte, int) interface, but subclasses are able to override them with more
efficient versions that employ knowledge of the particular storage type used.
This base implementation is writable only if PyBUF.WRITABLE is in the feature flags
passed to the constructor. Otherwise, all methods for write access raise a TypeError
and isReadonly() returns true. However, a client intending to write should
have presented PyBUF.WRITABLE in its client request flags when getting the buffer, and
been prevented by a BufferError exception at that point.
At the time of writing, only one-dimensional buffers of item size one are used in the Jython core.
PyBuffer.Pointer| Modifier and Type | Field and Description |
|---|---|
protected int |
exports
Count the number of times
release() must be called before actual release actions
need to take place. |
protected int |
index0
Absolute byte-index in the storage of
item[0]. |
protected BufferProtocol |
obj
The object that exported this buffer (or
null if the subclass or exporter
chooses not to supply a reference). |
protected int[] |
shape
The dimensions of the array represented by the buffer.
|
protected int[] |
strides
Step sizes in the underlying buffer essential to correct translation of an index (or indices)
into an index into the storage.
|
ANY_CONTIGUOUS, AS_ARRAY, C_CONTIGUOUS, CONTIG, CONTIG_RO, CONTIGUITY, F_CONTIGUOUS, FORMAT, FULL, FULL_RO, INDIRECT, IS_C_CONTIGUOUS, IS_F_CONTIGUOUS, MAX_NDIM, NAVIGATION, ND, RECORDS, RECORDS_RO, SIMPLE, STRIDED, STRIDED_RO, STRIDES, WRITABLE| Modifier | Constructor and Description |
|---|---|
protected |
BaseBuffer(int featureFlags,
int index0,
int[] shape,
int[] strides)
Construct an instance of
BaseBuffer in support of a sub-class, specifying the
'feature flags', or at least a starting set to be adjusted later. |
| Modifier and Type | Method and Description |
|---|---|
protected void |
addFeatureFlags(int flags)
Add to the features of this buffer expressed using the constants defined in
PyBUF,
setting individual flags specified while leaving those already set. |
protected static PyException |
bufferIsNot(java.lang.String property)
Convenience method to create (for the caller to throw) a
BufferError("underlying buffer is not {property}"). |
protected static PyException |
bufferReleased(java.lang.String operation)
Convenience method to create (for the caller to throw) a
BufferError("{operation} operation forbidden on released buffer object"). |
protected static PyException |
bufferRequires(java.lang.String feature)
Convenience method to create (for the caller to throw) a
BufferError("buffer structure requires consumer to use {feature}"). |
byte |
byteAt(int... indices)
Return the byte indexed from an N-dimensional buffer with item size one.
|
byte |
byteAt(int index)
Return the byte indexed from a one-dimensional buffer with item size one.
|
protected abstract byte |
byteAtImpl(int byteIndex)
Retrieve the byte at the given index in the underlying storage treated as a flat sequence of
bytes.
|
int |
byteIndex(int... indices)
Convert a multi-dimensional item index to an absolute byte index in the storage shared by the
exporter.
|
int |
byteIndex(int index)
Convert an item index (for a one-dimensional buffer) to an absolute byte index in the storage
shared by the exporter.
|
protected int |
calcGreatestIndex()
Calculate the absolute byte index in the storage array of the last item of the exported data
(if we are not using indirection).
|
protected int |
calcLeastIndex()
Calculate the absolute byte index in the storage array of the first item of the exported data
(if we are not using indirection).
|
protected void |
checkHasArray()
Check that the buffer is backed by an array the client can access as byte[].
|
protected void |
checkRequestFlags(int flags)
General purpose method to check the consumer request flags (typically the argument to
BufferProtocol.getBuffer(int)) against the feature flags (see
getFeatureFlags()) that characterise the features of the buffer, and to raise an
exception (Python BufferError) with an appropriate message in the case of a
mismatch. |
protected void |
checkWritable()
Check that the buffer is writable.
|
void |
close()
An alias for
PyBuffer.release() to satisfy AutoCloseable. |
void |
copyFrom(byte[] src,
int srcPos,
int destIndex,
int count)
Copy from a slice of a (Java) byte array into the buffer starting at a given destination
item-index.
|
void |
copyFrom(PyBuffer src)
Copy the whole of another
PyBuffer into this buffer. |
void |
copyTo(byte[] dest,
int destPos)
Copy the contents of the buffer to the destination byte array.
|
void |
copyTo(int srcIndex,
byte[] dest,
int destPos,
int count)
Copy a simple slice of the buffer-view to the destination byte array, defined by a starting
item-index in the source buffer and the
count of items to copy. |
protected static PyException |
differentStructure()
Convenience method to create (for the caller to throw) a
ValueError("buffer ... |
PyBuffer.Pointer |
getBuf()
Return a structure describing the slice of a byte array that holds the data being exported to
the consumer.
|
PyBuffer |
getBuffer(int flags)
Method by which the consumer requests the buffer from the exporter.
|
BaseBuffer |
getBufferAgain(int flags)
Allow an exporter to re-use this object again even if it has been "finally" released.
|
PyBuffer |
getBufferSlice(int flags,
int start,
int count)
Equivalent to
PyBuffer.getBufferSlice(int, int, int, int) with stride 1. |
protected int |
getFeatureFlags()
Get the features of this buffer expressed using the constants defined in
PyBUF. |
java.lang.String |
getFormat()
A format string in the language of Python structs describing how the bytes of each item
should be interpreted.
|
int |
getItemsize()
The number of bytes stored in each indexable item.
|
int |
getLen()
The total number of bytes represented by the view, which will be the product of the elements
of the
shape array, and the item size in bytes. |
int |
getNdim()
The number of dimensions to the buffer.
|
java.nio.ByteBuffer |
getNIOByteBuffer()
Obtain a
ByteBuffer giving access to the bytes that hold the data being
exported by the original object. |
protected abstract java.nio.ByteBuffer |
getNIOByteBufferImpl()
Create a new
java.nio.ByteBuffer on the underlying storage, such that
positioning this buffer to a particular byte using byteIndex(int) or
byteIndex(int[]) positions it at the first byte of the item so indexed. |
BufferProtocol |
getObj()
Return the underlying exporting object (or
null if no object implementing the
BufferProtocol is in that role). |
PyBuffer.Pointer |
getPointer(int... indices)
Return a structure describing the position in a byte array of a single item from the data
being exported to the consumer, in the case that array may be multi-dimensional.
|
PyBuffer.Pointer |
getPointer(int index)
Return a structure describing the position in a byte array of a single item from the data
being exported to the consumer.
|
protected PyBuffer |
getRoot()
Some
PyBuffers, those created by slicing a PyBuffer, are related to
a root PyBuffer. |
int[] |
getShape()
An array reporting the size of the buffer, considered as a multidimensional array, in each
dimension and (by its length) giving the number of dimensions.
|
protected int |
getSize() |
int[] |
getStrides()
The
strides array gives the distance in the storage array between adjacent items (in
each dimension). |
int[] |
getSuboffsets()
The
suboffsets array is a further part of the support for interpreting the buffer as
an n-dimensional array of items, where the array potentially uses indirect addressing (like a
real Java array of arrays, in fact). |
boolean |
hasArray()
Report whether the exporter is able to offer direct access to the exported storage as a Java
byte array (through the API that involves class
PyBuffer.Pointer), or only supports the
abstract API. |
int |
intAt(int... indices)
Return the unsigned byte value indexed from an N-dimensional buffer with item size one.
|
int |
intAt(int index)
Return the unsigned byte value indexed from a one-dimensional buffer with item size one.
|
boolean |
isContiguous(char order)
Enquire whether the array is represented contiguously in the backing storage, according to C
or Fortran ordering.
|
boolean |
isReadonly()
Determine whether the consumer is entitled to write to the exported storage.
|
boolean |
isReleased()
True only if the buffer has been released with (the required number of calls to)
PyBuffer.release() or some equivalent operation. |
protected static PyException |
notWritable()
Convenience method to create (for the caller to throw) a
TypeError("cannot modify read-only memory"). |
void |
release()
A buffer is (usually) a view onto to the internal state of an exporting object, and that
object may have to restrict its behaviour while the buffer exists.
|
protected void |
releaseAction()
This method will be called when the number of calls to
release() on this buffer is
equal to the number of calls to PyBuffer.getBuffer(int) and to
BufferProtocol.getBuffer(int) that returned this buffer. |
protected void |
removeFeatureFlags(int flags)
Remove features from this buffer expressed using the constants defined in
PyBUF,
clearing individual flags specified while leaving others already set. |
protected void |
setFeatureFlags(int flags)
Set the features of this buffer expressed using the constants defined in
PyBUF,
replacing any previous set. |
void |
storeAt(byte value,
int... indices)
Store the given byte at the indexed location in of an N-dimensional buffer with item size
one.
|
void |
storeAt(byte value,
int index)
Store the given byte at the indexed location in of a one-dimensional buffer with item size
one.
|
protected abstract void |
storeAtImpl(byte value,
int byteIndex)
Store the byte at the given index in the underlying storage treated as a flat sequence of
bytes.
|
java.lang.String |
toString()
The toString() method of a buffer reproduces the values in the buffer (as unsigned integers)
as the character codes of a
String. |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitgetBufferSliceprotected BufferProtocol obj
null if the subclass or exporter
chooses not to supply a reference).protected int[] shape
shape
array is the number of dimensions. The shape array should always be created and
filled (difference from CPython). This value is returned by getShape().protected int[] strides
strides array should always be created and
correctly filled to at least the length of the shape array (difference from
CPython). This value is returned by getStrides().protected int index0
item[0]. In one dimension, for a positive
stride this is equal to the offset of the first byte used in whatever
byte-storage is provided, and for a negative stride it is the first byte of the
last item. In an N-dimensional buffer with strides of mixed sign, it could be anywhere in the
data.protected int exports
release() must be called before actual release actions
need to take place. Equivalently, this is the number of calls to
BufferProtocol.getBuffer(int) that have returned this object: one for the call on the
original exporting object that constructed this, and one for each subsequent
call to PyBuffer.getBuffer(int) that returned this.protected BaseBuffer(int featureFlags,
int index0,
int[] shape,
int[] strides)
BaseBuffer in support of a sub-class, specifying the
'feature flags', or at least a starting set to be adjusted later. Also specify the navigation
( index0, shape, and strides). These 'feature flags' are the
features of the buffer exported, not the flags that form the consumer's request. The buffer
will be read-only unless PyBUF.WRITABLE is set. PyBUF.FORMAT is implicitly
added to the feature flags.
To complete initialisation, the sub-class normally must create its own wrapped byte-storage,
and call checkRequestFlags(int) passing the consumer's request flags.
featureFlags - bit pattern that specifies the features allowedindex0 - index into storage of item[0,...,0]shape - elements in each dimensionstrides - between successive elements in each dimensionprotected final int getFeatureFlags()
PyBUF. A
client request may be tested against the consumer's request flags with
checkRequestFlags(int).protected final void setFeatureFlags(int flags)
PyBUF,
replacing any previous set. Set individual flags or add to those already set by using
addFeatureFlags(int).flags - new value for the feature flagsprotected final void addFeatureFlags(int flags)
PyBUF,
setting individual flags specified while leaving those already set. Equivalent to
setFeatureFlags(flags | getFeatureFlags()).flags - to set within the feature flagsprotected final void removeFeatureFlags(int flags)
PyBUF,
clearing individual flags specified while leaving others already set. Equivalent to
setFeatureFlags(~flags & getFeatureFlags()).flags - to clear within the feature flagsprotected void checkRequestFlags(int flags)
throws PyException
BufferProtocol.getBuffer(int)) against the feature flags (see
getFeatureFlags()) that characterise the features of the buffer, and to raise an
exception (Python BufferError) with an appropriate message in the case of a
mismatch. The flags are defined in the interface PyBUF and are used in two ways.
In a subset of the flags, the consumer specifies assumptions it makes about the index order
(contiguity) of the buffer, and whether it is writable. When the buffer implementation calls
this check method, it has already specified in setFeatureFlags(int) what
capabilities this type (or instance) buffer actually has. It is an error, for the consumer to
specify in its request a feature that the buffer does not offer.
In a subset of the flags, the consumer specifies the set of navigation arrays (
shape, strides, and suboffsets) it intends to use in
navigating the buffer. When the buffer implementation calls this check method, it has already
specified in setFeatureFlags(int) what navigation is necessary for the consumer to
make sense of the buffer. It is an error for the consumer not to specify the flag
corresponding to an array that the buffer deems necessary.
flags - capabilities of and navigation assumed by the consumerPyException - BufferError when expectations do not correspond with the bufferpublic boolean isReadonly()
PyBUFisReadonly in interface PyBUFpublic int getNdim()
PyBUFshape array.
The actual storage may be a linear array, but this is the number of dimensions in the
interpretation that the exporting object gives the data.public int[] getShape()
PyBUFshape array is always
returned (difference from CPython).protected int getSize()
public int getLen()
PyBUFshape array, and the item size in bytes.public final BufferProtocol getObj()
PyBuffernull if no object implementing the
BufferProtocol is in that role). This will often be a PyObject.protected abstract byte byteAtImpl(int byteIndex)
throws java.lang.IndexOutOfBoundsException
index0, shape, strides,
and the item size. The caller is responsible for validating the original item-index and
raising (typically) an IndexOutOfBoundsException. Misuse of this method may
still result in unchecked exceptions characteristic of the storage implementation.byteIndex - byte-index of location to retrievejava.lang.IndexOutOfBoundsExceptionprotected abstract void storeAtImpl(byte value,
int byteIndex)
throws java.lang.IndexOutOfBoundsException,
PyException
index0, shape, strides,
and the item size. The caller is responsible for validating the original item-index and
raising (typically) an IndexOutOfBoundsException. Misuse of this method may
still result in unchecked exceptions characteristic of the storage implementation. This
method must implement the check for read-only character, raising a BufferError
in the case of a violation.value - to storebyteIndex - byte-index of location to retrievePyException - BufferError if this object is read-only.java.lang.IndexOutOfBoundsExceptionpublic byte byteAt(int index)
throws java.lang.IndexOutOfBoundsException
itemsize>1.
The BaseBuffer implementation delegates to byteAtImpl(int) via
byteAtImpl(byteIndex(index)).
public int intAt(int index)
throws java.lang.IndexOutOfBoundsException
itemsize>1.
The BaseBuffer implementation delegates to byteAtImpl(int) via
byteAtImpl(byteIndex(index)), cast unsigned to an int.
public void storeAt(byte value,
int index)
throws java.lang.IndexOutOfBoundsException,
PyException
itemsize>1.
The BaseBuffer implementation delegates to storeAtImpl(byte, int) via
storeAtImpl(value, byteIndex(index)).
storeAt in interface PyBuffervalue - to storeindex - to locationjava.lang.IndexOutOfBoundsExceptionPyExceptionpublic byte byteAt(int... indices)
throws java.lang.IndexOutOfBoundsException
itemsize>1.
The BaseBuffer implementation delegates to byteAtImpl(int) via
byteAtImpl(byteIndex(indices)).
public int intAt(int... indices)
throws java.lang.IndexOutOfBoundsException
itemsize>1.
The BaseBuffer implementation delegates to byteAtImpl(int) via
byteAtImpl(byteIndex(indices)), cast unsigned to an int.
public void storeAt(byte value,
int... indices)
throws java.lang.IndexOutOfBoundsException,
PyException
itemsize>1.
The BaseBuffer implementation delegates to storeAtImpl(byte, int) via
storeAtImpl(value, byteIndex(indices)).
storeAt in interface PyBuffervalue - to storeindices - specifying location to store atjava.lang.IndexOutOfBoundsExceptionPyExceptionpublic int byteIndex(int index)
throws java.lang.IndexOutOfBoundsException
PyBufferPyBuffer is a linearly-indexed
sequence of bytes, although it may not actually be a heap-allocated Java byte[]
object. The purpose of this method is to allow the exporter to define the relationship
between the item index (as used in PyBuffer.byteAt(int)) and the byte-index (as used with the
ByteBuffer returned by PyBuffer.getNIOByteBuffer()). See
PyBuffer.byteIndex(int[]) for discussion of the multi-dimensional case.public int byteIndex(int... indices)
throws java.lang.IndexOutOfBoundsException
PyBufferPyBuffer is a linearly-indexed sequence of
bytes, although it may not actually be a heap-allocated Java byte[] object. The
purpose of this method is to allow the exporter to define the relationship between the item
index (as used in PyBuffer.byteAt(int...) and the byte-index (as used with the
ByteBuffer returned by PyBuffer.getNIOByteBuffer()).protected int calcGreatestIndex()
byteIndex(int...). The first byte not used will be one itemsize more
than the returned value.protected int calcLeastIndex()
byteIndex(int...).public void copyTo(byte[] dest,
int destPos)
throws java.lang.IndexOutOfBoundsException
PyBUF.getLen(), and the order is the storage order in the exporter.
(Note: Correct ordering for multidimensional arrays, including those with indirection needs
further study.)
The default implementation in BaseBuffer deals with the general one-dimensional
case of arbitrary item size and stride.
public void copyTo(int srcIndex,
byte[] dest,
int destPos,
int count)
throws java.lang.IndexOutOfBoundsException,
PyException
count of items to copy. This may validly
be done only for a one-dimensional buffer, as the meaning of the starting item-index is
otherwise not defined. count*itemsize bytes will be occupied in the destination.
The default implementation in BaseBuffer deals with the general one-dimensional
case of arbitrary item size and stride, but is unable to optimise access to sequential bytes.
copyTo in interface PyBuffersrcIndex - starting item-index in the source bufferdest - destination byte arraydestPos - byte-index in the destination array of the source item [0,...]count - number of items to copyjava.lang.IndexOutOfBoundsException - if access out of bounds in source or destinationPyExceptionpublic void copyFrom(byte[] src,
int srcPos,
int destIndex,
int count)
throws java.lang.IndexOutOfBoundsException,
PyException
count*itemsize bytes will be read
from the source.
The default implementation in BaseBuffer deals with the general one-dimensional
case of arbitrary item size and stride, but is unable to optimise access to sequential bytes.
copyFrom in interface PyBuffersrc - source byte arraysrcPos - location in source of first byte to copydestIndex - starting item-index in the destination (i.e. this)count - number of items to copy injava.lang.IndexOutOfBoundsException - if access out of bounds in source or destinationPyException - TypeError if read-only bufferpublic void copyFrom(PyBuffer src) throws java.lang.IndexOutOfBoundsException, PyException
PyBuffer into this buffer. This may validly be done
only for buffers that are consistent in their dimensions. When it is necessary to copy
partial buffers, this may be achieved using a buffer slice on the source or destination.
The default implementation in BaseBuffer deals with the general one-dimensional
case of arbitrary item size and stride, but is unable to optimise access to sequential bytes.
copyFrom in interface PyBuffersrc - source bufferjava.lang.IndexOutOfBoundsException - if access out of bounds in source or destinationPyException - TypeError if read-only bufferpublic PyBuffer getBuffer(int flags)
PyBufferPyBuffer.release() on the buffer it obtained, or PyBuffer.close() using
try-with-resources, since some objects alter their behaviour while buffers are exported.
When a PyBuffer is the target, the same checks are carried out on the consumer
flags, and a return will normally be a reference to that buffer. A Jython
PyBuffer keeps count of these re-exports in order to match them with the number
of calls to PyBuffer.release(). When the last matching release() arrives it is
considered "final", and release actions may then take place on the exporting object. After
the final release of a buffer, a call to getBuffer should raise an exception.
getBuffer in interface BufferProtocolgetBuffer in interface PyBufferflags - specifying features demanded and the navigational capabilities of the consumerpublic BaseBuffer getBufferAgain(int flags)
BaseBytes can be re-used even after a final release by consumers,
simply by incrementing the exports count again: the navigation arrays and the
buffer view of the exporter's state all remain valid. We do not let consumers do this through
the PyBuffer interface: from their perspective, calling PyBuffer.release()
should mean the end of their access, although we can't stop them holding a reference to the
PyBuffer. Only the exporting object, which handles the implementation type is trusted to know
when re-use is safe.
An exporter will use this method as part of its implementation of
BufferProtocol.getBuffer(int). On return from that, the buffer and the exporting
object must then be in effectively the same state as if the buffer had just been
constructed by that method. Exporters that destroy related resources on final release of
their buffer (by overriding releaseAction()), or permit themselves structural change
invalidating the buffer, must either reconstruct the missing resources or avoid
getBufferAgain.
public void release()
BufferProtocol.getBuffer(int) or PyBuffer.getBuffer(int) should make a
matching call to PyBuffer.release(). The consumer may be sharing the PyBuffer
with other consumers and the buffer uses the pairing of getBuffer and
release to manage the lock on behalf of the exporter. It is an error to make
more than one call to release for a single call to getBuffer.
When the final matching release occurs (that is the number of release calls
equals the number of getBuffer calls), the implementation here calls
releaseAction(), which the implementer of a specific buffer type should override if
it needs specific actions to take place.
Note that, when this is a sliced view obtained from another PyBuffer the
implementation in BaseBuffer automatically sends one release()
Sub-classes should not propagate the release themselves when overriding
releaseAction().
public void close()
PyBufferPyBuffer.release() to satisfy AutoCloseable.public boolean isReleased()
PyBufferPyBuffer.release() or some equivalent operation. The consumer may be sharing the reference
with other consumers and the buffer only achieves the released state when all consumers who
called getBuffer have called release.isReleased in interface PyBufferpublic PyBuffer getBufferSlice(int flags, int start, int count)
PyBufferPyBuffer.getBufferSlice(int, int, int, int) with stride 1.getBufferSlice in interface PyBufferflags - specifying features demanded and the navigational capabilities of the consumerstart - index in the current buffercount - number of items in the required sliceprotected abstract java.nio.ByteBuffer getNIOByteBufferImpl()
java.nio.ByteBuffer on the underlying storage, such that
positioning this buffer to a particular byte using byteIndex(int) or
byteIndex(int[]) positions it at the first byte of the item so indexed.public java.nio.ByteBuffer getNIOByteBuffer()
PyBufferByteBuffer giving access to the bytes that hold the data being
exported by the original object. The position of the buffer is at the first byte of the item
with zero index (quite possibly not the lowest valid byte-index), the limit of the buffer is
beyond the largest valid byte index, and the mark is undefined.
For a one-dimensional contiguous buffer, the limit is one byte beyond the last item, so that
consecutive reads from the ByteBuffer return the data in order. Assuming the
following client code where obj has type BufferProtocol:
PyBuffer a = obj.getBuffer(PyBUF.SIMPLE); int itemsize = a.getItemsize(); ByteBuffer bb = a.getNIOBuffer();the item with index
k is in bb at positions
bb.pos()+k*itemsize to bb.pos()+(k+1)*itemsize - 1 inclusive. And
if itemsize==1, the item is simply the byte at position bb.pos()+k.
If the buffer is multidimensional or non-contiguous (strided), the buffer position is still
the (first byte of) the item at index [0] or [0,...,0]. However, it
is necessary to navigate bb using the shape, strides
and maybe suboffsets provided by the API.
getNIOByteBuffer in interface PyBufferByteBuffer onto the exported data contents.public boolean hasArray()
PyBufferPyBuffer.Pointer), or only supports the
abstract API. See also PyBUF.AS_ARRAY.public PyBuffer.Pointer getBuf()
PyBufferobj has type BufferProtocol:
PyBuffer a = obj.getBuffer(PyBUF.SIMPLE); int itemsize = a.getItemsize(); PyBuffer.Pointer b = a.getBuf();the item with index
k is in the array b.storage at index
[b.offset + k*itemsize] to [b.offset + (k+1)*itemsize - 1]
inclusive. And if itemsize==1, the item is simply the byte
b.storage[b.offset + k]
If the buffer is multidimensional or non-contiguous, storage[offset] is still
the (first byte of) the item at index [0] or [0,...,0]. However, it is necessary to navigate
b.storage using the shape, strides and maybe
suboffsets provided by the API.
public PyBuffer.Pointer getPointer(int index) throws java.lang.IndexOutOfBoundsException
PyBufferobj has type BufferProtocol:
int k = ... ; PyBuffer a = obj.getBuffer(PyBUF.FULL); int itemsize = a.getItemsize(); PyBuffer.Pointer b = a.getPointer(k);the item with index
k is in the array b.storage at index
[b.offset] to [b.offset + itemsize - 1] inclusive. And if
itemsize==1, the item is simply the byte b.storage[b.offset]
Essentially this is a method for computing the offset of a particular index. The client is
free to navigate the underlying buffer b.storage without respecting these
boundaries.
getPointer in interface PyBufferindex - in the buffer to position the pointerjava.lang.IndexOutOfBoundsExceptionpublic PyBuffer.Pointer getPointer(int... indices) throws java.lang.IndexOutOfBoundsException
PyBufferobj
has type BufferProtocol:
int i, j, k; // ... calculation that assigns i, j, k PyBuffer a = obj.getBuffer(PyBUF.FULL); int itemsize = a.getItemsize(); PyBuffer.Pointer b = a.getPointer(i,j,k);the item with index
[i,j,k] is in the array b.storage at index
[b.offset] to [b.offset + itemsize - 1] inclusive. And if
itemsize==1, the item is simply the byte b.storage[b.offset]
Essentially this is a method for computing the offset of a particular index. The client is
free to navigate the underlying buffer b.storage without respecting these
boundaries. If the buffer is non-contiguous, the above description is still valid (since a
multi-byte item must itself be contiguously stored), but in any additional navigation of
b.storage[] to other items, the client must use the shape, strides and
sub-offsets provided by the API. Normally one starts b = a.getBuf() in order to
establish the offset of index [0,...,0].
getPointer in interface PyBufferindices - multidimensional index at which to position the pointerjava.lang.IndexOutOfBoundsExceptionpublic int[] getStrides()
PyBUFstrides array gives the distance in the storage array between adjacent items (in
each dimension). In the rawest parts of the buffer API, the consumer of the buffer is able to
navigate the exported storage. The "strides" array is part of the support for interpreting
the buffer as an n-dimensional array of items. It provides the coefficients of the
"addressing polynomial". (More on this in the CPython documentation.) The consumer must not
modify this array. A valid strides array is always returned (difference from
CPython).getStrides in interface PyBUFpublic int[] getSuboffsets()
PyBUFsuboffsets array is a further part of the support for interpreting the buffer as
an n-dimensional array of items, where the array potentially uses indirect addressing (like a
real Java array of arrays, in fact). This is only applicable when there is more than 1
dimension, and it works in conjunction with the strides array. (More on this in the
CPython documentation.) When used, suboffsets[k] is an integer index, not a byte
offset as in CPython. The consumer must not modify this array. When not needed for navigation
null is returned (as in CPython).getSuboffsets in interface PyBUFnull if not necessary for navigationpublic boolean isContiguous(char order)
PyBUFisContiguous in interface PyBUForder - 'C', 'F' or 'A', as the storage order is C, Fortran or either.public java.lang.String getFormat()
PyBufferPyBUF.FORMAT bit in the consumer's call to
getBuffer, a valid format string is always returned (difference
from CPython).
Jython only implements "B" so far, and it is debatable whether anything fancier than "<n>B" can be supported in Java.
public int getItemsize()
PyBUFgetItemsize in interface PyBUFprotected void releaseAction()
release() on this buffer is
equal to the number of calls to PyBuffer.getBuffer(int) and to
BufferProtocol.getBuffer(int) that returned this buffer. The default implementation
does nothing. Override this method to add release behaviour specific to an exporter. A common
convention is to do this within the definition of BufferProtocol.getBuffer(int)
within the exporting class, where a nested class is ultimately defined.protected PyBuffer getRoot()
PyBuffers, those created by slicing a PyBuffer, are related to
a root PyBuffer. During creation of such a slice, we need to supply a value for
this root. If the present object is not itself a slice, this root is the object itself; if
the buffer is already a slice, it is the root it was given at creation time. Often this is
the only difference between a slice-view and a directly-exported buffer. Override this method
in slices to return the root buffer of the slice.public java.lang.String toString()
String.protected void checkWritable()
throws PyException
PyException - TypeError if notprotected void checkHasArray()
throws PyException
PyException - BufferError if notprotected static PyException notWritable()
TypeError("cannot modify read-only memory").protected static PyException bufferIsNot(java.lang.String property)
BufferError("underlying buffer is not {property}").property - protected static PyException differentStructure()
ValueError("buffer ... different structures").protected static PyException bufferRequires(java.lang.String feature)
BufferError("buffer structure requires consumer to use {feature}").feature - protected static PyException bufferReleased(java.lang.String operation)
BufferError("{operation} operation forbidden on released buffer object").operation - name of operation or null