ZeroByteBuffer (Jython API documentation)
Date: 2024-08-18

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
    Modifier and Type | Method and Description
    --- | ---
    `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`

Jython homepage