Package org.eclipse.net4j.buffer

## Interface IBuffer

- All Known Subinterfaces:
    `InternalBuffer`

      public interface IBuffer

  Basic unit of transport in Net4j.

  A buffer is well prepared for the usage with asynchronous `IChannel`s but can also be used with pure `SocketChannel`s. All methods of `IBuffer` are non-blocking.

  Usually buffers are obtained from a `IBufferProvider`. Buffers can be accessed, passed around and finally `released` to their original provider. The capacity of a buffer is determined by its provider.

  In addition to its payload data each buffer contains an internal header of four bytes, two of them representing a channel identifier the other two of them denoting the length of the payload data. The payload data may be accessed through a `ByteBuffer`.

  This interface is not intended to be implemented by clients.

  An example for putting values into a buffer and writing it to a `SocketChannel`:

       // Obtain a fresh buffer
       Buffer buffer = bufferProvider.getBuffer(); // Start filling the buffer for channelID 4711 ByteBuffer byteBuffer =
       buffer.startPutting(4711); byteBuffer.putDouble(15.47); // Write the contents of the Buffer to a // SocketChannel
       without blocking while (!buffer.write(socketChannel)) { // Do something else }

  An example for reading a buffer from a `SocketChannel` and getting values from it:

       // Obtain a fresh buffer
       Buffer buffer = bufferProvider.getBuffer();

       // Read the contents of the Buffer from a SocketChannel without blocking
       ByteBuffer byteBuffer;
       while ((byteBuffer = buffer.startGetting(socketChannel)) == null)
       {
         // Do something else
       }

       // Access the contents of the buffer and release it to its provider
       double value = byteBuffer.getDouble();
       buffer.release();

  Author:
    Eike Stepper
  See Also:
    `IBufferProvider`, `IChannel.sendBuffer(IBuffer)`, `IChannel.setReceiveHandler(IBufferHandler)`, `IBufferHandler.handleBuffer(IBuffer)`
  No Implement
    This interface is not intended to be implemented by clients.
  No Extend
    This interface is not intended to be extended by clients.

- - ### Field Summary

    Fields
    Modifier and Type | Field | Description
    --- | --- | ---
    `static int` | `CHANNEL_ID_BYTES` |
    `static int` | `CHANNEL_ID_POS` |
    `static short` | `HEADER_SIZE` |
    `static short` | `MAX_CHANNEL` |
    `static short` | `MIN_CHANNEL` |
    `static short` | `NO_CHANNEL` | Possible argument value of `startPutting(short)` and possible return value of `getChannelID()` that indicates that this buffer is not intended to be passed to a `SocketChannel`.
    `static int` | `PAYLOAD_SIZE_BYTES` |
    `static int` | `PAYLOAD_SIZE_POS` |

  - ### Method Summary

    All Methods Instance Methods Abstract Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `void` | `clear()` | Turns the state of this buffer from any state into `INITIAL`.
    `void` | `compact()` |
    `void` | `flip()` | Turns the state of this buffer from `PUTTING` into `GETTING`.
    `java.lang.String` | `formatContent​(boolean showHeader)` |
    `byte` | `get()` |
    `void` | `get​(byte[] dst)` |
    `IBufferProvider` | `getBufferProvider()` | Returns the `IBufferProvider` that has provided this buffer and that this buffer will be returned to when its `release()` method is called.
    `java.nio.ByteBuffer` | `getByteBuffer()` | Returns the `ByteBuffer` that can be used for putting or getting data.
    `short` | `getCapacity()` | Returns the capacity of this buffer.
    `short` | `getChannelID()` | Returns the channel index value stored in the header of this buffer.
    `org.eclipse.net4j.util.IErrorHandler` | `getErrorHandler()` |
    `int` | `getInt()` |
    `int` | `getLimit()` |
    `int` | `getPosition()` |
    `short` | `getShort()` |
    `BufferState` | `getState()` | Returns the internal state of this buffer.
    `java.lang.String` | `getString()` |
    `boolean` | `hasRemaining()` |
    `boolean` | `isCCAM()` | Returns the Close Channel After Me flag.
    `boolean` | `isEOS()` | Returns the End Of Stream flag to indicate whether this buffer is the last buffer in a stream (typically a signal) of buffers.
    `void` | `put​(byte b)` |
    `void` | `put​(byte[] src, int offset, int length)` |
    `void` | `putShort​(short value)` |
    `void` | `release()` | Releases this buffer to its original `IBufferProvider`.
    `void` | `setCCAM​(boolean ccam)` | Sets the Close Channel After Me flag.
    `void` | `setEOS​(boolean eos)` | Sets the End Of Stream flag to indicate whether this buffer is the last buffer in a stream (typically a signal) of buffers.
    `void` | `setErrorHandler​(org.eclipse.net4j.util.IErrorHandler errorHandler)` |
    `void` | `setLimit​(int limit)` |
    `void` | `setPosition​(int position)` |
    `java.nio.ByteBuffer` | `startGetting​(java.nio.channels.SocketChannel socketChannel)` | Tries to read a `ByteBuffer` from a `SocketChannel` that can be used for getting data.
    `java.nio.ByteBuffer` | `startPutting​(short channelID)` | Returns a `ByteBuffer` that can be used for putting data.
    `boolean` | `write​(java.nio.channels.SocketChannel socketChannel)` | Tries to write the data of this buffer to a `SocketChannel`.

- - ### Field Detail

    - #### NO_CHANNEL

          static final short NO_CHANNEL

      Possible argument value of `startPutting(short)` and possible return value of `getChannelID()` that indicates that this buffer is not intended to be passed to a `SocketChannel`.
      See Also:
        Constant Field Values

    - #### MIN_CHANNEL

          static final short MIN_CHANNEL

      Since:
        2.0
      See Also:
        Constant Field Values

    - #### MAX_CHANNEL

          static final short MAX_CHANNEL

      Since:
        2.0
      See Also:
        Constant Field Values

    - #### CHANNEL_ID_BYTES

          static final int CHANNEL_ID_BYTES

      Since:
        4.8
      See Also:
        Constant Field Values

    - #### PAYLOAD_SIZE_BYTES

          static final int PAYLOAD_SIZE_BYTES

      Since:
        4.8
      See Also:
        Constant Field Values

    - #### HEADER_SIZE

          static final short HEADER_SIZE

      See Also:
        Constant Field Values

    - #### CHANNEL_ID_POS

          static final int CHANNEL_ID_POS

      Since:
        4.10
      See Also:
        Constant Field Values

    - #### PAYLOAD_SIZE_POS

          static final int PAYLOAD_SIZE_POS

      Since:
        4.10
      See Also:
        Constant Field Values

  - ### Method Detail

    - #### getBufferProvider

          IBufferProvider getBufferProvider()

      Returns the `IBufferProvider` that has provided this buffer and that this buffer will be returned to when its `release()` method is called.

    - #### getChannelID

          short getChannelID()

      Returns the channel index value stored in the header of this buffer.
      Since:
        2.0

    - #### getCapacity

          short getCapacity()

      Returns the capacity of this buffer.

      The capacity of this buffer is equal to the `capacity` of the `IBufferProvider` that has provided this buffer.

    - #### getState

          BufferState getState()

      Returns the internal state of this buffer.

    - #### startGetting

          java.nio.ByteBuffer startGetting​(java.nio.channels.SocketChannel socketChannel)
                                    throws java.lang.IllegalStateException,
                                           java.io.IOException

      Tries to read a `ByteBuffer` from a `SocketChannel` that can be used for getting data.

      This method is non-blocking and it can be necessary to repeatedly call it. If it was not possible to read a complete header from the `SocketChannel` `null` is returned and the state of this buffer is `READING_HEADER`. If it was not possible to read a complete body from the `SocketChannel` `null` is returned and the state of this buffer is `READING_BODY`.

      If a `ByteBuffer` is returned it may only be used for getting data. It is left to the responsibility of the caller that only the following methods of that `ByteBuffer` are used:

      - `ByteBuffer.get()`
      - `ByteBuffer.get(byte[])`
      - `ByteBuffer.get(int)`
      - `ByteBuffer.get(byte[], int, int)`
      - `ByteBuffer.getChar()`
      - `ByteBuffer.getChar(int)`
      - `ByteBuffer.getDouble()`
      - `ByteBuffer.getDouble(int)`
      - `ByteBuffer.getFloat()`
      - `ByteBuffer.getFloat(int)`
      - `ByteBuffer.getInt()`
      - `ByteBuffer.getInt(int)`
      - `ByteBuffer.getLong()`
      - `ByteBuffer.getLong(int)`
      - `ByteBuffer.getShort()`
      - `ByteBuffer.getShort(int)`
      - all other methods that do not influence `Buffer.position()`, `Buffer.limit()` and `Buffer.capacity()`
      Parameters:
        `socketChannel` - The `socketChannel` to read the `ByteBuffer` from.
      Returns:
        A `ByteBuffer` that can be used for getting data if it was possible to completely read the data from the given `SocketChannel`, `null` otherwise.
      Throws:
        `java.lang.IllegalStateException` - If the state of this buffer is not `INITIAL`, `READING_HEADER` or `READING_BODY`.
        `java.io.IOException` - If the `SocketChannel` has been closed or discovers other I/O problems.

    - #### startPutting

          java.nio.ByteBuffer startPutting​(short channelID)
                                    throws java.lang.IllegalStateException

      Returns a `ByteBuffer` that can be used for putting data.

      Turns the `state` of this buffer into `PUTTING`.

      The returned `ByteBuffer` may only be used for putting data. It is left to the responsibility of the caller that only the following methods of that `ByteBuffer` are used:

      - `ByteBuffer.put(byte)`
      - `ByteBuffer.put(byte[])`
      - `ByteBuffer.put(ByteBuffer)`
      - `ByteBuffer.put(int, byte)`
      - `ByteBuffer.put(byte[], int, int)`
      - `ByteBuffer.putChar(char)`
      - `ByteBuffer.putChar(int, char)`
      - `ByteBuffer.putDouble(double)`
      - `ByteBuffer.putDouble(int, double)`
      - `ByteBuffer.putFloat(float)`
      - `ByteBuffer.putFloat(int, float)`
      - `ByteBuffer.putInt(int)`
      - `ByteBuffer.putInt(int, int)`
      - `ByteBuffer.putLong(long)`
      - `ByteBuffer.putLong(int, long)`
      - `ByteBuffer.putShort(short)`
      - `ByteBuffer.putShort(int, short)`
      - all other methods that do not influence `Buffer.position()`, `Buffer.limit()` and `Buffer.capacity()`
      Parameters:
        `channelID` - The index of an `IChannel` that this buffer is intended to be passed to later or `NO_CHANNEL` .
      Returns:
        A `ByteBuffer` that can be used for putting data.
      Throws:
        `java.lang.IllegalStateException` - If the state of this buffer is not `INITIAL` (`PUTTING` is allowed but meaningless if and only if the given `channelID` is equal to the existing `channelID` of this buffer).

    - #### write

          boolean write​(java.nio.channels.SocketChannel socketChannel)
                 throws java.lang.IllegalStateException,
                        java.io.IOException

      Tries to write the data of this buffer to a `SocketChannel`.

      This method is non-blocking and it can be necessary to repeatedly call it. If it was not possible to completely write the data to the `SocketChannel` `false` is returned and the state of this buffer remains `WRITING`.

      Parameters:
        `socketChannel` - The `socketChannel` to write the data to.
      Returns:
        `true` if it was possible to completely write the data to the `SocketChannel`, `false` otherwise.
      Throws:
        `java.lang.IllegalStateException` - If the state of this buffer is not `PUTTING` or `WRITING`.
        `java.io.IOException` - If the `SocketChannel` has been closed or discovers other I/O problems.

    - #### flip

          void flip()
             throws java.lang.IllegalStateException

      Turns the state of this buffer from `PUTTING` into `GETTING`.
      Throws:
        `java.lang.IllegalStateException` - If the state of this buffer is not `PUTTING`.

    - #### getByteBuffer

          java.nio.ByteBuffer getByteBuffer()
                                     throws java.lang.IllegalStateException

      Returns the `ByteBuffer` that can be used for putting or getting data.
      Throws:
        `java.lang.IllegalStateException` - If the state of this buffer is not `PUTTING` or `GETTING`.

    - #### isEOS

          boolean isEOS()

      Returns the End Of Stream flag to indicate whether this buffer is the last buffer in a stream (typically a signal) of buffers.

    - #### setEOS

          void setEOS​(boolean eos)

      Sets the End Of Stream flag to indicate whether this buffer is the last buffer in a stream (typically a signal) of buffers.

    - #### isCCAM

          boolean isCCAM()

      Returns the Close Channel After Me flag.
      Since:
        4.4

    - #### setCCAM

          void setCCAM​(boolean ccam)

      Sets the Close Channel After Me flag.
      Since:
        4.4

    - #### release

          void release()

      Releases this buffer to its original `IBufferProvider`.

    - #### clear

          void clear()

      Turns the state of this buffer from any state into `INITIAL`.

    - #### formatContent

          java.lang.String formatContent​(boolean showHeader)

    - #### getErrorHandler

          org.eclipse.net4j.util.IErrorHandler getErrorHandler()

      Since:
        2.0

    - #### setErrorHandler

          void setErrorHandler​(org.eclipse.net4j.util.IErrorHandler errorHandler)

      Since:
        2.0

    - #### compact

          void compact()

      Since:
        4.7

    - #### getPosition

          int getPosition()

      Since:
        4.7

    - #### setPosition

          void setPosition​(int position)

      Since:
        4.7

    - #### getLimit

          int getLimit()

      Since:
        4.7

    - #### setLimit

          void setLimit​(int limit)

      Since:
        4.7

    - #### hasRemaining

          boolean hasRemaining()

      Since:
        4.7

    - #### get

          byte get()

      Since:
        4.7

    - #### get

          void get​(byte[] dst)

      Since:
        4.7

    - #### getShort

          short getShort()

      Since:
        4.7

    - #### getInt

          int getInt()

      Since:
        4.7

    - #### getString

          java.lang.String getString()

      Since:
        4.7

    - #### put

          void put​(byte b)

      Since:
        4.7

    - #### put

          void put​(byte[] src,
                   int offset,
                   int length)

      Since:
        4.7

    - #### putShort

          void putShort​(short value)

      Since:
        4.7