org.python.core.buffer

## Class SimpleStringBuffer

- java.lang.Object
- - org.python.core.buffer.BaseBuffer
  - - org.python.core.buffer.SimpleBuffer
    - - org.python.core.buffer.SimpleStringBuffer

All Implemented Interfaces:
  AutoCloseable, BufferProtocol, PyBUF, PyBuffer

    public class SimpleStringBuffer
    extends SimpleBuffer

Buffer API that appears to be a one-dimensional array of one-byte items providing read-only API, but which is actually backed by a Java String. Some of the buffer API absolutely needs access to the data as a byte array (those parts that involve a `PyBuffer.Pointer` result), and therefore this class must create a byte array from the String for them. However, it defers creation of a byte array until that part of the API is actually used. Where possible, this class overrides those methods in SimpleBuffer that would otherwise access the byte array attribute to use the String instead.

### 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
`SimpleStringBuffer(int flags, String bufString)` Provide an instance of SimpleStringBuffer meeting the consumer's expectations as expressed in the flags argument.

### Method Summary

Methods
`byte` `byteAt(int index)` Return the byte indexed from a one-dimensional buffer with item size one.
`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` `getBufferSlice(int flags, int start, int length)` Equivalent to `PyBuffer.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.
`int` `getLen()` The total number of units (bytes) stored, which will be the product of the elements of the `shape` array, and the item size in units.
`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.
`int` `intAt(int index)` Return the unsigned byte value indexed from a one-dimensional buffer with item size one.
`String` `toString()` The `toString()` method of a `SimpleStringBuffer` simply produces the underlying `String`.

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

`byteAt, isReadonly`

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

`close, copyFrom, copyFrom, copyTo, getBuffer, getBufferAgain, getFormat, getItemsize, getNdim, getShape, getStrides, getSuboffsets, hasArray, intAt, isContiguous, isReleased, release, storeAt, storeAt`

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

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

### Constructor Detail

#### SimpleStringBuffer

    public SimpleStringBuffer(int flags,
                      String bufString)

Provide an instance of SimpleStringBuffer meeting the consumer's expectations as expressed in the flags argument.

Parameters:
  `bufString` - storing the implementation of the object
  `flags` - consumer requirements

### Method Detail

#### getLen

    public int getLen()

The total number of units (bytes) stored, which will be the product of the elements of the `shape` array, and the item size in units.

The default implementation in `BaseBuffer` deals with the general one-dimensional case, with any item size and stride.

`SimpleBuffer` provides an implementation optimised for contiguous bytes in one-dimension.

This method uses `String.length()` rather than create an actual byte buffer.

Specified by:
  `getLen` in interface `PyBUF`
Overrides:
  `getLen` in class `SimpleBuffer`
Returns:
  the total number of units stored.

#### byteAt

    public byte byteAt(int index)
                throws IndexOutOfBoundsException

Return the byte indexed from a one-dimensional buffer with item size one. This is part of the fully-encapsulated API: the buffer implementation exported takes care of navigating the structure of the buffer. Results are undefined where the number of dimensions is not one or if `itemsize>1`.

`SimpleBuffer` provides an implementation optimised for contiguous bytes in one-dimension.

This method uses `String.charAt(int)` rather than create an actual byte buffer.

Specified by:
  `byteAt` in interface `PyBuffer`
Overrides:
  `byteAt` in class `SimpleBuffer`
Parameters:
  `index` - to retrieve from
Returns:
  the item at index, which is a byte
Throws:
  `IndexOutOfBoundsException`

#### intAt

    public int intAt(int index)
              throws IndexOutOfBoundsException

Return the unsigned byte value indexed from a one-dimensional buffer with item size one. This is part of the fully-encapsulated API: the exporter takes care of navigating the structure of the buffer. Results are undefined where the number of dimensions is not one or if `itemsize>1`.

`SimpleBuffer` provides an implementation optimised for contiguous bytes in one-dimension.

This method uses `String.charAt(int)` rather than create an actual byte buffer.

Specified by:
  `intAt` in interface `PyBuffer`
Overrides:
  `intAt` in class `SimpleBuffer`
Parameters:
  `index` - to retrieve from
Returns:
  the item at index, treated as an unsigned byte, `=0xff & byteAt(index)`
Throws:
  `IndexOutOfBoundsException`

#### copyTo

    public void copyTo(int srcIndex,
              byte[] dest,
              int destPos,
              int length)
                throws IndexOutOfBoundsException

Copy a simple slice of the buffer to the destination byte array, defined by a starting index and length in the source buffer. This may validly be done only for a one-dimensional buffer, as the meaning of the starting index is otherwise not defined. The length (like the source index) is in source buffer items: `length*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.

`SimpleBuffer` provides an implementation optimised for contiguous bytes in one-dimension.

This method uses `String.charAt(int)` rather than create an actual byte buffer.

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

#### getBufferSlice

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

Equivalent to `PyBuffer.getBufferSlice(int, int, int, int)` with stride 1.

The `SimpleStringBuffer` implementation avoids creation of a byte buffer.

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

#### getBufferSlice

    public 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. A consumer that obtains a `PyBuffer` with `getBufferSlice` must release it with `PyBuffer.release()` just as if it had been obtained with `PyBuffer.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.

`SimpleBuffer` 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 length 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.

The `SimpleStringBuffer` implementation creates an actual byte buffer.

Specified by:
  `getBufferSlice` in interface `PyBuffer`
Overrides:
  `getBufferSlice` in class `SimpleBuffer`
Parameters:
  `flags` - specifying features demanded and the navigational capabilities of the consumer
  `start` - index in the current buffer
  `length` - 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

#### getNIOByteBuffer

    public ByteBuffer getNIOByteBuffer()

Description copied from interface: `PyBuffer`
Obtain a `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.

Specified by:
  `getNIOByteBuffer` in interface `PyBuffer`
Overrides:
  `getNIOByteBuffer` in class `SimpleBuffer`
Returns:
  a ByteBuffer equivalent to the exported data contents.

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

This method creates an actual byte array from the underlying String if none yet exists.

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

#### getPointer

    public 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. For a one-dimensional contiguous buffer, assuming the following client code where `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.

This method creates an actual byte array from the underlying String if none yet exists.

Specified by:
  `getPointer` in interface `PyBuffer`
Overrides:
  `getPointer` in class `SimpleBuffer`
Parameters:
  `index` - in the buffer to position the pointer
Returns:
  structure defining the byte[] slice that is the shared data

#### getPointer

    public 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. For a 3-dimensional contiguous buffer, assuming the following client code where `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].

This method creates an actual byte array from the underlying String if none yet exists.

Specified by:
  `getPointer` in interface `PyBuffer`
Overrides:
  `getPointer` in class `SimpleBuffer`
Parameters:
  `indices` - multidimensional index at which to position the pointer
Returns:
  structure defining the byte[] slice that is the shared data

#### toString

    public String toString()

The `toString()` method of a `SimpleStringBuffer` simply produces the underlying `String`.

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