public interface PyBuffer extends PyBUF, BufferProtocol, AutoCloseable
Py_buffer
struct. Several concrete types implement
this interface in order to provide tailored support for different storage organisations.Modifier and Type | Interface and Description |
---|---|
static class |
PyBuffer.Pointer
A class that references a
byte[] array and a particular offset within it, as the
return type for methods that give direct access to byte-oriented data exported by a Python
object. |
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 and Type | Method and Description |
---|---|
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.
|
void |
close()
An alias for
release() to satisfy AutoCloseable . |
void |
copyFrom(byte[] src,
int srcPos,
int destIndex,
int length)
Copy bytes from a slice of a (Java) byte array into the buffer.
|
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 length)
Copy a simple slice of the buffer to the destination byte array, defined by a starting index
and length in the source 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.
|
PyBuffer |
getBufferSlice(int flags,
int start,
int length)
Equivalent to
getBufferSlice(int, int, int, int) with stride 1. |
PyBuffer |
getBufferSlice(int flags,
int start,
int length,
int stride)
Get a
PyBuffer that represents a slice of the current one described in terms of
a start index, number of items to include in the slice, and the stride in the current buffer. |
String |
getFormat()
A format string in the language of Python structs describing how the bytes of each item
should be interpreted.
|
ByteBuffer |
getNIOByteBuffer()
Obtain a
ByteBuffer giving access to the bytes that hold the data being
exported to the consumer. |
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.
|
boolean |
hasArray()
Determine 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 |
isReleased()
True only if the buffer has been released with (the required number of calls to)
release() or some equivalent operation. |
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.
|
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.
|
String |
toString()
The toString() method of a buffer reproduces the byte values in the buffer (treated as
unsigned integers) as the character codes of a
String . |
getItemsize, getLen, getNdim, getShape, getStrides, getSuboffsets, isContiguous, isReadonly
byte byteAt(int index) throws IndexOutOfBoundsException
itemsize>1
.index
- to retrieve fromIndexOutOfBoundsException
int intAt(int index) throws IndexOutOfBoundsException
itemsize>1
.index
- to retrieve from=0xff & byteAt(index)
IndexOutOfBoundsException
void storeAt(byte value, int index) throws IndexOutOfBoundsException
itemsize>1
.value
- to storeindex
- to locationIndexOutOfBoundsException
byte byteAt(int... indices) throws IndexOutOfBoundsException
itemsize>1
.indices
- specifying location to retrieve fromIndexOutOfBoundsException
int intAt(int... indices) throws IndexOutOfBoundsException
itemsize>1
.indices
- specifying location to retrieve from=0xff & byteAt(index)
IndexOutOfBoundsException
void storeAt(byte value, int... indices) throws IndexOutOfBoundsException
itemsize>1
.value
- to storeindices
- specifying location to store atIndexOutOfBoundsException
void copyTo(byte[] dest, int destPos) throws IndexOutOfBoundsException, PyException
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.)dest
- destination byte arraydestPos
- index in the destination array of the byte [0]IndexOutOfBoundsException
- if the destination cannot hold itPyException
void copyTo(int srcIndex, byte[] dest, int destPos, int length) throws IndexOutOfBoundsException, PyException
length*itemsize
bytes will be occupied
in the destination.srcIndex
- starting index in the source bufferdest
- destination byte arraydestPos
- index in the destination array of the item [0,...]length
- number of items to copyIndexOutOfBoundsException
- if access out of bounds in source or destinationPyException
void copyFrom(byte[] src, int srcPos, int destIndex, int length) throws IndexOutOfBoundsException, PyException
length*itemsize
bytes will be read from the source.src
- source byte arraysrcPos
- location in source of first byte to copydestIndex
- starting index in the destination (i.e. this
)length
- number of bytes to copy inIndexOutOfBoundsException
- if access out of bounds in source or destinationPyException
- (TypeError) if read-only buffervoid copyFrom(PyBuffer src) throws IndexOutOfBoundsException, PyException
src
- source bufferIndexOutOfBoundsException
- if access out of bounds in source or destinationPyException
- (TypeError) if read-only bufferPyBuffer getBuffer(int flags) throws PyException
release()
on the buffer it
obtained, 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 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 BufferProtocol
flags
- specifying features demanded and the navigational capabilities of the consumerPyException
- (BufferError) when expectations do not correspond with the buffervoid release()
BufferProtocol.getBuffer(int)
or getBuffer(int)
should make a
matching call to 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
.void close()
release()
to satisfy AutoCloseable
.close
in interface AutoCloseable
boolean isReleased()
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
.PyBuffer getBufferSlice(int flags, int start, int length)
getBufferSlice(int, int, int, int)
with stride 1.flags
- specifying features demanded and the navigational capabilities of the consumerstart
- index in the current bufferlength
- number of items in the required slicePyBuffer getBufferSlice(int flags, int start, int length, int stride)
PyBuffer
that represents a slice of the current one described in terms of
a start index, number of items to include in the slice, and the stride in the current buffer.
A consumer that obtains a PyBuffer
with getBufferSlice
must release
it with release()
just as if it had been obtained with
getBuffer(int)
Suppose that x(i) denotes the ith element of the current buffer, that is, the
byte retrieved by this.byteAt(i)
or the unit indicated by
this.getPointer(i)
. A request for a slice where start
= s,
length
= N and stride
= m, results in a buffer
y such that y(k) = x(s+km) where k=0..(N-1). In Python terms, this is
the slice x[s : s+(N-1)m+1 : m] (if m>0) or the slice x[s : s+(N-1)m-1 :
m] (if m<0). Implementations should check that this range is entirely within
the current buffer.
In a simple buffer backed by a contiguous byte array, the result is a strided PyBuffer on the
same storage but where the offset is adjusted by s and the stride is as supplied. If
the current buffer is already strided and/or has an item size larger than single bytes, the
new start
index, length
and stride
will be translated
from the arguments given, through this buffer's stride and item size. The caller always
expresses start
and strides
in terms of the abstract view of this
buffer.
flags
- specifying features demanded and the navigational capabilities of the consumerstart
- index in the current bufferlength
- number of items in the required slicestride
- index-distance in the current buffer between consecutive items in the sliceByteBuffer getNIOByteBuffer()
ByteBuffer
giving access to the bytes that hold the data being
exported to the consumer. For a one-dimensional contiguous buffer, 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
bb.pos()+k
is in the buffer 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
.
The buffer limit is set to the first byte beyond the valid data. A block read or write will
therefore access the contents sequentially.
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]
, and the
limit is one item beyond the valid data. However, it is necessary to navigate bb
using the shape
, strides
and maybe suboffsets
provided
by the API.
boolean hasArray()
PyBuffer.Pointer
), or only supports the
abstract API. See also PyBUF.AS_ARRAY
.PyBuffer.Pointer getBuf()
obj
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.
PyBuffer.Pointer getPointer(int index)
obj
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.
index
- in the buffer to position the pointerPyBuffer.Pointer getPointer(int... indices)
obj
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 units, 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].
indices
- multidimensional index at which to position the pointerString getFormat()
PyBUF.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.