net.i2p.client.streaming.impl

## Class MessageOutputStream

- java.lang.Object
- - java.io.OutputStream
  - - net.i2p.client.streaming.impl.MessageOutputStream

- All Implemented Interfaces:
    Closeable, Flushable, AutoCloseable

      class MessageOutputStream
      extends OutputStream

  An OutputStream implementation that buffers data and forwards it to a `MessageOutputStream.DataReceiver` in chunks upon buffer full or flush. Provides throttling and blocking behavior according to the data receiver's needs. This class maintains an internal buffer with configurable size limits, supports resizing the buffer size during operation (only effective when buffer is empty), and allows passive flushes after inactivity delays to avoid excessive buffering. MessageOutputStream -> ConnectionDataReceiver -> Connection -> PacketQueue -> I2PSession Thread safety: - Write operations synchronize on an internal data lock when manipulating the buffer. - Waiting for buffer acceptance and completion is done outside synchronization to avoid blocking other threads. Performance: - Uses a shared ByteCache for buffer byte arrays to reduce allocations. - Supports a passive flush mechanism to flush buffered data after inactivity. - Minimizes locking time by doing blocking waits outside of synchronized blocks. Note: - Buffer resizing only affects the max size used to determine flush boundaries, buffer reallocation does not occur dynamically. - Stream errors are captured and thrown upon subsequent I/O calls. - Interruptions during wait throw InterruptedIOException accordingly. - Close() flushes any remaining data and releases internal buffers.

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static interface` | `MessageOutputStream.DataReceiver` Interface for receiving data flushed from this stream.
    `static interface` | `MessageOutputStream.WriteStatus` Interface to detect status of an asynchronous write operation.

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `MessageOutputStream(I2PAppContext ctx, SimpleTimer2 timer, MessageOutputStream.DataReceiver receiver, int bufSize, int initBufSize)` Constructs the stream with default passive flush delay.
    `MessageOutputStream(I2PAppContext ctx, SimpleTimer2 timer, MessageOutputStream.DataReceiver receiver, int bufSize, int initBufSize, int passiveFlushDelay)` Constructs the stream with specified passive flush delay.

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `close()` Closes the stream, flushing all buffered data and waiting for any CLOSE packet acknowledgments.
    `(package private) void` | `closeInternal()` Non-blocking internal close used within the package.
    `(package private) void` | `destroy()` Releases resources without flushing.
    `void` | `flush()` Flushes buffered data, blocking until accepted into the send queue.
    `(package private) void` | `flushAvailable(MessageOutputStream.DataReceiver target)` Convenience overload variant with blocking flush.
    `(package private) void` | `flushAvailable(MessageOutputStream.DataReceiver target, boolean blocking)` Attempts to flush buffered data to the target DataReceiver, optionally blocking until accepted.
    `boolean` | `getClosed()` Returns true if the stream is closed.
    `int` | `getWriteTimeout()` Gets the current write timeout.
    `void` | `setBufferSize(int size)` Requests resizing the buffer to the specified size.
    `void` | `setWriteTimeout(int ms)` Sets the write timeout in milliseconds for blocking write operations.
    `(package private) void` | `streamErrorOccurred(IOException ioe)` Records a stream error and clears buffered data.
    `void` | `write(byte[] b)` Writes the specified byte array to the stream, may block waiting for acceptance.
    `void` | `write(byte[] b, int off, int len)` Writes len bytes from the specified byte array starting at offset off.
    `void` | `write(int b)` Writes a single byte to the stream.

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

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### MessageOutputStream

          public MessageOutputStream(I2PAppContext ctx,
                                     SimpleTimer2 timer,
                                     MessageOutputStream.DataReceiver receiver,
                                     int bufSize,
                                     int initBufSize)

      Constructs the stream with default passive flush delay.
      Parameters:
        `ctx` - Application context for logging and utilities
        `timer` - Timer used for scheduling passive flush events
        `receiver` - DataReceiver that handles actual data dispatch
        `bufSize` - Maximum buffer size allowed (will be clamped to preset max values)
        `initBufSize` - Initial buffer size to use for buffering (<= bufSize)

    - #### MessageOutputStream

          public MessageOutputStream(I2PAppContext ctx,
                                     SimpleTimer2 timer,
                                     MessageOutputStream.DataReceiver receiver,
                                     int bufSize,
                                     int initBufSize,
                                     int passiveFlushDelay)

      Constructs the stream with specified passive flush delay.
      Parameters:
        `ctx` - Application context for logging and utilities
        `timer` - Timer used for scheduling passive flush events
        `receiver` - DataReceiver that handles actual data dispatch
        `bufSize` - Maximum buffer size allowed (will be clamped for safety)
        `initBufSize` - Initial buffer size to use for buffering (<= bufSize)
        `passiveFlushDelay` - Delay in ms before passive flush if data is buffered but not flushed

  - ### Method Detail

    - #### close

          public void close()
                     throws IOException

      Closes the stream, flushing all buffered data and waiting for any CLOSE packet acknowledgments.
      Specified by:
        `close` in interface `Closeable`
      Specified by:
        `close` in interface `AutoCloseable`
      Overrides:
        `close` in class `OutputStream`
      Throws:
        `IOException` - if closing encounters an error

    - #### closeInternal

          void closeInternal()

      Non-blocking internal close used within the package. Does not wait for flush or acknowledgment. Marks stream as closed and clears buffer immediately.

    - #### destroy

          void destroy()

      Releases resources without flushing.

    - #### flush

          public void flush()
                     throws IOException

      Flushes buffered data, blocking until accepted into the send queue. Does not wait for ACK from far end, to avoid performance bottlenecks.
      Specified by:
        `flush` in interface `Flushable`
      Overrides:
        `flush` in class `OutputStream`
      Throws:
        `IOException` - if flushing encounters an error

    - #### flushAvailable

          void flushAvailable(MessageOutputStream.DataReceiver target)
                       throws IOException

      Convenience overload variant with blocking flush.
      Parameters:
        `target` - DataReceiver to flush to
      Throws:
        `IOException` - if flush fails or interrupted

    - #### flushAvailable

          void flushAvailable(MessageOutputStream.DataReceiver target,
                              boolean blocking)
                       throws IOException

      Attempts to flush buffered data to the target DataReceiver, optionally blocking until accepted.
      Parameters:
        `target` - the destination DataReceiver
        `blocking` - whether the flush should block until accepted
      Throws:
        `IOException` - if the flush fails or is interrupted

    - #### getClosed

          public boolean getClosed()

      Returns true if the stream is closed.
      Returns:
        true if closed

    - #### getWriteTimeout

          public int getWriteTimeout()

      Gets the current write timeout.
      Returns:
        write timeout in milliseconds

    - #### setBufferSize

          public void setBufferSize(int size)

      Requests resizing the buffer to the specified size. Effective only when the internal buffer is empty, and must be > 0 and <= the original max buffer size. Does not immediately resize the underlying byte array.
      Parameters:
        `size` - New desired buffer size, must be positive and no greater than original buffer size.

    - #### setWriteTimeout

          public void setWriteTimeout(int ms)

      Sets the write timeout in milliseconds for blocking write operations.
      Parameters:
        `ms` - Timeout in milliseconds, -1 for infinite wait.

    - #### streamErrorOccurred

          void streamErrorOccurred(IOException ioe)

      Records a stream error and clears buffered data.
      Parameters:
        `ioe` - The IOException to record

    - #### write

          public void write(byte[] b)
                     throws IOException

      Writes the specified byte array to the stream, may block waiting for acceptance.
      Overrides:
        `write` in class `OutputStream`
      Parameters:
        `b` - byte array to write
      Throws:
        `IOException` - if the stream is closed or write fails

    - #### write

          public void write(byte[] b,
                            int off,
                            int len)
                     throws IOException

      Writes len bytes from the specified byte array starting at offset off. Blocks if buffer becomes full waiting for acceptance.
      Overrides:
        `write` in class `OutputStream`
      Parameters:
        `b` - byte array source
        `off` - start offset in array
        `len` - number of bytes to write
      Throws:
        `IOException` - if the stream is closed or write fails

    - #### write

          public void write(int b)
                     throws IOException

      Writes a single byte to the stream.
      Specified by:
        `write` in class `OutputStream`
      Parameters:
        `b` - byte to write (only least significant 8 bits used)
      Throws:
        `IOException` - if the stream is closed or write fails