org.python.core.buffer

## Class ZeroByteBuffer

- java.lang.Object
- - org.python.core.buffer.BaseBuffer
  - - org.python.core.buffer.Base1DBuffer
    - - org.python.core.buffer.BaseArrayBuffer
      - - org.python.core.buffer.ZeroByteBuffer

All Implemented Interfaces:
  java.lang.AutoCloseable, BufferProtocol, PyBUF, PyBuffer

    public class ZeroByteBuffer
    extends BaseArrayBuffer

Buffer API over a zero length, one-dimensional array of one-byte items. The buffer is nominally writable, but since there is nowhere to write to, any attempt to write or read throws an `IndexOutOfBoundsException`. This class exists mostly to represent zero-length arrays, and particularly, zero-length slices for which implementations of `PyBuffer.getBufferSlice(int, int, int, int)` in any case need special logic. Bulk operations like `copyTo(byte[], int)`) and `toString()` efficiently do nothing, instead of calling complicated logic that finally does nothing.

### Nested Class Summary

### Nested classes/interfaces inherited from interface org.python.core.PyBuffer

`PyBuffer.Pointer`

### Field Summary

### Fields inherited from interface org.python.core.PyBUF

`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`

### Constructor Summary

Constructors
Constructor and Description
`ZeroByteBuffer(int flags, BufferProtocol obj, boolean readonly, boolean hasArray)` Construct an instance of a zero-length buffer, choosing whether it should report itself to be read-only through `BaseBuffer.isReadonly()` or as having a backing array through `BaseBuffer.hasArray()`.

### Method Summary

All Methods Instance Methods Concrete Methods
`int` `byteIndex(int... indices)` In a ZeroByteBuffer, if the dimensions are right, the index is out of bounds anyway.
`int` `byteIndex(int index)` In a ZeroByteBuffer, the index is always out of bounds.
`void` `copyFrom(byte[] src, int srcPos, int destIndex, int count)` In a ZeroByteBuffer, there is no room for anything, so this throws unless the source count is zero.
`void` `copyFrom(PyBuffer src)` In a ZeroByteBuffer, there is no room for anything, so this throws unless the source count is zero.
`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.
`PyBuffer.Pointer` `getBuf()` Return a structure describing the slice of a byte array that holds the data being exported to the consumer.
`PyBuffer` `getBufferSlice(int flags, int start, int count)` Only a zero-length slice at zero is valid (in which case, the present buffer will do nicely as a result, with the export count incremented.
`PyBuffer` `getBufferSlice(int flags, int start, int count, int stride)` Only a zero-length slice at zero is valid (in which case, the present buffer will do nicely as a result, with the export count incremented.
`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.
`java.lang.String` `toString()` For a ZeroByteBuffer, it's the empty string.

### Methods inherited from class org.python.core.buffer.Base1DBuffer

`isContiguous`

### Methods inherited from class org.python.core.buffer.BaseBuffer

`byteAt, byteAt, close, getBuffer, getBufferAgain, getFormat, getItemsize, getNdim, getNIOByteBuffer, getObj, getPointer, getPointer, getShape, getStrides, getSuboffsets, hasArray, intAt, intAt, isReadonly, isReleased, release, storeAt, storeAt`

### Methods inherited from class java.lang.Object

`equals, getClass, hashCode, notify, notifyAll, wait, wait, wait`

### Constructor Detail

#### ZeroByteBuffer

    public ZeroByteBuffer(int flags,
                          BufferProtocol obj,
                          boolean readonly,
                          boolean hasArray)
                   throws PyException

Construct an instance of a zero-length buffer, choosing whether it should report itself to be read-only through `BaseBuffer.isReadonly()` or as having a backing array through `BaseBuffer.hasArray()`. These properties are moot, as any attempt to write to the pretended backing array produces an `IndexOutOfBoundsException`, but it is less surprising for client code that may ask, if the results are customary for the exporting object.

Parameters:
  `flags` - consumer requirements
  `obj` - exporting object (or `null`)
  `readonly` - set true if not to be considered writable
  `hasArray` - set true if to be considered as backed by an array
Throws:
  `PyException` - `BufferError` when client expectations do not correspond with the type

### Method Detail

#### getLen

    public int getLen()

Description copied from interface: `PyBUF`
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.

Specified by:
  `getLen` in interface `PyBUF`
Overrides:
  `getLen` in class `Base1DBuffer`
Returns:
  the total number of bytes represented.

#### byteIndex

    public int byteIndex(int index)
                  throws java.lang.IndexOutOfBoundsException

In a ZeroByteBuffer, the index is always out of bounds.

Specified by:
  `byteIndex` in interface `PyBuffer`
Overrides:
  `byteIndex` in class `BaseBuffer`
Parameters:
  `index` - item-index from consumer
Returns:
  corresponding byte-index in actual storage
Throws:
  `java.lang.IndexOutOfBoundsException`

#### byteIndex

    public int byteIndex(int... indices)
                  throws java.lang.IndexOutOfBoundsException

In a ZeroByteBuffer, if the dimensions are right, the index is out of bounds anyway.

Specified by:
  `byteIndex` in interface `PyBuffer`
Overrides:
  `byteIndex` in class `BaseArrayBuffer`
Parameters:
  `indices` - n-dimensional item-index from consumer
Returns:
  corresponding byte-index in actual storage
Throws:
  `java.lang.IndexOutOfBoundsException`

#### copyTo

    public void copyTo(byte[] dest,
                       int destPos)
                throws java.lang.IndexOutOfBoundsException

Copy the contents of the buffer to the destination byte array. The number of bytes will be that returned by `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.

In a ZeroByteBuffer, there is simply nothing to copy.

Specified by:
  `copyTo` in interface `PyBuffer`
Overrides:
  `copyTo` in class `BaseBuffer`
Parameters:
  `dest` - destination byte array
  `destPos` - byte-index in the destination array of the byte [0]
Throws:
  `java.lang.IndexOutOfBoundsException` - if the destination cannot hold it

#### copyTo

    public void copyTo(int srcIndex,
                       byte[] dest,
                       int destPos,
                       int count)
                throws java.lang.IndexOutOfBoundsException,
                       PyException

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. 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.

The implementation in `BaseArrayBuffer` deals with the general one-dimensional case of arbitrary item size and stride.

In a ZeroByteBuffer, there is simply nothing to copy.

Specified by:
  `copyTo` in interface `PyBuffer`
Overrides:
  `copyTo` in class `BaseArrayBuffer`
Parameters:
  `srcIndex` - starting item-index in the source buffer
  `dest` - destination byte array
  `destPos` - byte-index in the destination array of the source item [0,...]
  `count` - number of items to copy
Throws:
  `java.lang.IndexOutOfBoundsException` - if access out of bounds in source or destination
  `PyException`

#### copyFrom

    public void copyFrom(byte[] src,
                         int srcPos,
                         int destIndex,
                         int count)
                  throws java.lang.IndexOutOfBoundsException,
                         PyException

In a ZeroByteBuffer, there is no room for anything, so this throws unless the source count is zero.

Specified by:
  `copyFrom` in interface `PyBuffer`
Overrides:
  `copyFrom` in class `BaseArrayBuffer`
Parameters:
  `src` - source byte array
  `srcPos` - location in source of first byte to copy
  `destIndex` - starting item-index in the destination (i.e. `this`)
  `count` - number of items to copy in
Throws:
  `java.lang.IndexOutOfBoundsException` - if access out of bounds in source or destination
  `PyException` - `TypeError` if read-only buffer

#### copyFrom

    public void copyFrom(PyBuffer src)
                  throws java.lang.IndexOutOfBoundsException,
                         PyException

In a ZeroByteBuffer, there is no room for anything, so this throws unless the source count is zero.

Specified by:
  `copyFrom` in interface `PyBuffer`
Overrides:
  `copyFrom` in class `BaseArrayBuffer`
Parameters:
  `src` - source buffer
Throws:
  `java.lang.IndexOutOfBoundsException` - if access out of bounds in source or destination
  `PyException` - `TypeError` if read-only buffer

#### getBufferSlice

    public PyBuffer getBufferSlice(int flags,
                                   int start,
                                   int count)

Only a zero-length slice at zero is valid (in which case, the present buffer will do nicely as a result, with the export count incremented.

Specified by:
  `getBufferSlice` in interface `PyBuffer`
Overrides:
  `getBufferSlice` in class `BaseBuffer`
Parameters:
  `flags` - specifying features demanded and the navigational capabilities of the consumer
  `start` - index in the current buffer
  `count` - number of items in the required slice
Returns:
  a buffer representing the slice

#### getBufferSlice

    public PyBuffer getBufferSlice(int flags,
                                   int start,
                                   int count,
                                   int stride)

Only a zero-length slice at zero is valid (in which case, the present buffer will do nicely as a result, with the export count incremented.

Parameters:
  `flags` - specifying features demanded and the navigational capabilities of the consumer
  `start` - index in the current buffer
  `count` - number of items in the required slice
  `stride` - index-distance in the current buffer between consecutive items in the slice
Returns:
  a buffer representing the slice

#### getBuf

    public PyBuffer.Pointer getBuf()

Return a structure describing the slice of a byte array that holds 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();
     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.

`BaseArrayBuffer` provides a reference to the storage array even when the buffer is intended not to be writable. There can be no enforcement of read-only character once a reference to the byte array has been handed out.

The implementation in `ZeroByteBuffer` efficiently returns an empty buffer.

Specified by:
  `getBuf` in interface `PyBuffer`
Overrides:
  `getBuf` in class `BaseArrayBuffer`
Returns:
  structure defining the byte[] slice that is the shared data

#### toString

    public java.lang.String toString()

For a ZeroByteBuffer, it's the empty string.

Specified by:
  `toString` in interface `PyBuffer`
Overrides:
  `toString` in class `BaseBuffer`