Class AbstractChunkTransformInputStream

java.lang.Object
java.io.InputStream
java.io.FilterInputStream
zeroecho.core.io.AbstractChunkTransformInputStream
All Implemented Interfaces:
Closeable, AutoCloseable

public abstract class AbstractChunkTransformInputStream extends FilterInputStream
InputStream that transforms data in fixed-size chunks with optional finalization.

This abstract class provides a framework for streaming transformations where the input is processed in aligned blocks of inChunkSize bytes, producing corresponding output blocks of outChunkSize bytes. Subclasses implement the transformation logic in transform(byte[], int, int, byte[]) and handle any trailing input in doFinal(byte[], int, int, byte[], int).

Design and invariants

  • Input bytes are read from the wrapped InputStream into inBuf, preferably in multiples of inChunkSize.
  • transform(byte[], int, int, byte[]) is invoked for all complete chunks. Its contract is to consume inChunks * inChunkSize bytes from in and produce contiguous output bytes into out.
  • If the final read yields a partial chunk smaller than inChunkSize, doFinal(byte[], int, int, byte[], int) is invoked to process the remainder and emit any trailer (e.g., padding block or authentication tag).
  • Output bytes are staged in outBuf and consumed by read() and read(byte[], int, int).

Buffer sizing and finalization headroom

The primary constructor sizes both input and output buffers to chunks * inChunkSize and chunks * outChunkSize, respectively. An overloaded constructor adds finalizationOutputChunks to the output-side capacity only, resulting in outChunkSize * (chunks + finalizationOutputChunks). This headroom guarantees that the last doFinal(...) call can emit trailer bytes (for example, a padding block or AEAD tag) even when the steady-state output window is full.

Typical values when outChunkSize == 16 (AES-sized):

  • No padding modes (e.g., AES/CBC/NOPADDING): finalizationOutputChunks = 0.
  • Padding modes (e.g., AES/CBC/PKCS5PADDING): 1 to cover a full padding block.
  • AEAD modes (e.g., AES/GCM/NOPADDING with 16-byte tag): 2 to cover tail bytes (up to 15) plus the tag (commonly 16).

Thread-safety

Instances are not thread-safe. If a single instance is shared across threads, external synchronization is required.

Example

// Example subclass wiring (pseudocode)
final class MyCipherStream extends AbstractChunkTransformInputStream {
    private final Cipher cipher;
    MyCipherStream(InputStream in, Cipher c) {
        super(in, 16, 16, 256, 2); // +2 output chunks headroom (e.g., AES-GCM)
        this.cipher = c;
    }
    @Override protected int transform(byte[] src, int off, int chunks, byte[] dst) throws IOException {
        try {
            return cipher.update(src, off, chunks * 16, dst, 0);
        } catch (ShortBufferException e) {
            throw new IOException(e);
        }
    }
    @Override protected int doFinal(byte[] src, int off, int len, byte[] dst, int dstOff) throws IOException {
        try {
            int out = 0;
            if (len > 0) { out = cipher.update(src, off, len, dst, dstOff); dstOff += out; }
            out += cipher.doFinal(dst, dstOff);
            return out;
        } catch (GeneralSecurityException | ShortBufferException e) {
            throw new IOException(e);
        }
    }
}
Author:
Leo Galambos
Since:
1.0
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    protected boolean
    Flag indicating that end-of-stream has been reached.
    protected final byte[]
    Input buffer storing data read from the upstream stream.
    protected final int
    Size of one logical input chunk.
    protected int
    Number of valid bytes currently in inBuf.
    protected byte[]
    Output buffer storing transformed bytes awaiting consumption.
    protected final int
    Size of one logical output chunk.
    protected int
    Number of valid bytes currently in outBuf.
    protected int
    Current read position within outBuf.

    Fields inherited from class FilterInputStream

    in
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    protected
    AbstractChunkTransformInputStream(InputStream upstream, int inChunkSize, int outChunkSize, int chunks)
    Constructs a new chunk-transforming input stream with symmetric input and output capacities.
    protected
    AbstractChunkTransformInputStream(InputStream upstream, int inChunkSize, int outChunkSize, int chunks, int finalizationOutputChunks)
    Constructs a new chunk-transforming input stream with extra output headroom for finalization.
  • Method Summary

    Modifier and Type
    Method
    Description
    protected abstract int
    doFinal(byte[] in, int inOff, int len, byte[] out, int outOff)
    Finalizes the transformation with an optional trailing incomplete chunk.
    int
    Reads the next transformed byte.
    int
    read(byte[] b)
    Reads transformed bytes into the given array.
    int
    read(byte[] b, int off, int len)
    Reads up to len transformed bytes into the target buffer.
    protected abstract int
    transform(byte[] in, int inOff, int inChunks, byte[] out)
    Transforms one or more full input chunks into output bytes.

    Methods inherited from class FilterInputStream

    available, close, mark, markSupported, reset, skip

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • inBuf

      protected final byte[] inBuf
      Input buffer storing data read from the upstream stream.
    • outBuf

      protected byte[] outBuf
      Output buffer storing transformed bytes awaiting consumption.
    • inLen

      protected int inLen
      Number of valid bytes currently in inBuf.
    • outPtr

      protected int outPtr
      Current read position within outBuf.
    • outLen

      protected int outLen
      Number of valid bytes currently in outBuf.
    • eofSeen

      protected boolean eofSeen
      Flag indicating that end-of-stream has been reached.
    • inChunkSize

      protected final int inChunkSize
      Size of one logical input chunk.
    • outChunkSize

      protected final int outChunkSize
      Size of one logical output chunk.
  • Constructor Details

    • AbstractChunkTransformInputStream

      protected AbstractChunkTransformInputStream(InputStream upstream, int inChunkSize, int outChunkSize, int chunks)
      Constructs a new chunk-transforming input stream with symmetric input and output capacities.

      The input buffer is sized to inChunkSize * chunks and the output buffer to outChunkSize * chunks. No extra output headroom is reserved for finalization.

      Parameters:
      upstream - the underlying input stream
      inChunkSize - size of input chunks expected by the transform (must be > 1)
      outChunkSize - size of output chunks produced by the transform (must be > 0)
      chunks - number of chunks buffered at once (must be > 0)
      Throws:
      IllegalArgumentException - if a size is outside its documented range or a buffer size overflows
    • AbstractChunkTransformInputStream

      protected AbstractChunkTransformInputStream(InputStream upstream, int inChunkSize, int outChunkSize, int chunks, int finalizationOutputChunks)
      Constructs a new chunk-transforming input stream with extra output headroom for finalization.

      The input buffer is sized to inChunkSize * chunks. The output buffer is sized to outChunkSize * (chunks + finalizationOutputChunks) so that the last call to doFinal(byte[], int, int, byte[], int) can emit trailer bytes even when the steady-state output region is full.

      Parameters:
      upstream - the underlying input stream
      inChunkSize - size of input chunks expected by the transform (must be > 1)
      outChunkSize - size of output chunks produced by the transform (must be > 0)
      chunks - number of chunks buffered at once for steady-state (must be > 0)
      finalizationOutputChunks - number of extra output chunks reserved for finalization (must be >= 0)
      Throws:
      IllegalArgumentException - if a size is outside its documented range or a buffer size overflows
  • Method Details

    • transform

      protected abstract int transform(byte[] in, int inOff, int inChunks, byte[] out) throws IOException
      Transforms one or more full input chunks into output bytes.
      Parameters:
      in - buffer containing input data
      inOff - offset in in where chunks begin
      inChunks - number of complete input chunks available
      out - destination buffer for transformed bytes
      Returns:
      number of bytes written to out
      Throws:
      IOException - if transformation fails
    • doFinal

      protected abstract int doFinal(byte[] in, int inOff, int len, byte[] out, int outOff) throws IOException
      Finalizes the transformation with an optional trailing incomplete chunk.

      Invoked at EOF if the last read produced fewer than inChunkSize bytes. Implementations may perform padding, compute an authentication tag, or flush any provider-internal state. The outOff argument specifies where to start writing the final bytes in out.

      Parameters:
      in - buffer containing the final partial chunk (may be empty)
      inOff - offset of the partial data
      len - number of available bytes (< inChunkSize)
      out - destination buffer for transformed bytes
      outOff - offset in out where bytes should be written
      Returns:
      number of bytes written to out
      Throws:
      IOException - if finalization fails or the provider reports an error
    • read

      public int read() throws IOException
      Reads the next transformed byte.
      Overrides:
      read in class FilterInputStream
      Returns:
      the next byte as an unsigned int in the range 0-255, or -1 if end-of-stream has been reached
      Throws:
      IOException - if an I/O error occurs
    • read

      public int read(byte[] b) throws IOException
      Reads transformed bytes into the given array.

      This implementation delegates to read(byte[], int, int).

      Overrides:
      read in class FilterInputStream
      Parameters:
      b - target buffer
      Returns:
      number of bytes read, or -1 at EOF
      Throws:
      IOException - if an I/O error occurs
    • read

      public int read(byte[] b, int off, int len) throws IOException
      Reads up to len transformed bytes into the target buffer.

      Blocks until at least one byte is available or EOF is reached.

      Overrides:
      read in class FilterInputStream
      Parameters:
      b - target buffer
      off - offset in b where data should be stored
      len - maximum number of bytes to read
      Returns:
      number of bytes read, or -1 if EOF and no data returned
      Throws:
      IOException - if an I/O error occurs