Class Assembler

java.lang.Object
io.github.mahmoudimus.quic.connection.Assembler

public final class Assembler extends Object
Reassembles STREAM or CRYPTO frame data that arrives out of order, duplicated or overlapping, into the stream's bytes (RFC 9000 section 2.2).

Data is read either in order, as a byte stream, or unordered, as chunks with their offsets. A stream starts ordered; it may switch to unordered reads once, but never back.

Bounded buffering. Inserted buffers are kept as views, not copied, and their backing allocation is accounted for: when a peer's small or gapped frames pin much more memory than the data they carry, or the number of buffered pieces grows past a bound, the assembler copies the pieces into fresh compact buffers. A peer that keeps more than 1024 separate pieces after compaction makes insert(long, java.nio.ByteBuffer, int) fail. The total buffered is bounded by flow control, which the caller enforces.

Threads. Not thread-safe; an assembler belongs to one stream of one connection, which serializes access.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    The most separate pieces kept for one stream.
  • Constructor Summary

    Constructors
    Constructor
    Description
    An empty, ordered assembler.
  • Method Summary

    Modifier and Type
    Method
    Description
    long
    The number of bytes the application has read.
    void
    Discards all buffered data, keeping the read offset.
    long
    end()
    One past the highest offset received.
    boolean
    ensureOrdering(boolean ordered)
    Selects ordered or unordered reads.
    boolean
    insert(long offset, ByteBuffer bytes)
    Adds received data held in a buffer of its own; see insert(long, ByteBuffer, int).
    boolean
    insert(long offset, ByteBuffer bytes, int allocationSize)
    Adds received data.
    boolean
    Whether reads are ordered.
    read(int maxLength, boolean ordered)
    Takes the next chunk.
    void
    Discards everything and returns to the initial, ordered state.

    Methods inherited from class java.lang.Object

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

    • MAX_CHUNKS

      public static final int MAX_CHUNKS
      The most separate pieces kept for one stream. An insert fails only if compaction cannot get the count back down to this.
      See Also:
  • Constructor Details

    • Assembler

      public Assembler()
      An empty, ordered assembler.
  • Method Details

    • reinit

      public void reinit()
      Discards everything and returns to the initial, ordered state.
    • ensureOrdering

      public boolean ensureOrdering(boolean ordered)
      Selects ordered or unordered reads. Switching to unordered is allowed once; an ordered read after that is not.
      Parameters:
      ordered - whether the next reads are ordered
      Returns:
      false if ordered is requested after an unordered read
    • isOrdered

      public boolean isOrdered()
      Whether reads are ordered.
      Returns:
      false once ensureOrdering(false) has been called
    • read

      public Chunk read(int maxLength, boolean ordered)
      Takes the next chunk.
      Parameters:
      maxLength - the most bytes to return
      ordered - true for the bytes at the read offset, false for any buffered chunk
      Returns:
      the chunk, or null if nothing (in order) is buffered
    • insert

      public boolean insert(long offset, ByteBuffer bytes, int allocationSize)
      Adds received data. The assembler keeps a view of bytes, so the caller must not reuse its contents afterwards; copy data out of a reusable packet buffer first.
      Parameters:
      offset - the stream offset of the first byte
      bytes - the data, between its position and limit; the buffer itself is not changed
      allocationSize - the size of the allocation behind bytes, at least its length; pass the length for a buffer that holds only this data
      Returns:
      false if the stream is fragmented into too many pieces, which only a misbehaving peer causes
    • insert

      public boolean insert(long offset, ByteBuffer bytes)
      Adds received data held in a buffer of its own; see insert(long, ByteBuffer, int).
      Parameters:
      offset - the stream offset of the first byte
      bytes - the data, between its position and limit
      Returns:
      false if the stream is fragmented into too many pieces
    • bytesRead

      public long bytesRead()
      The number of bytes the application has read.
      Returns:
      in ordered mode, the read offset
    • end

      public long end()
      One past the highest offset received.
      Returns:
      the high-water mark
    • clear

      public void clear()
      Discards all buffered data, keeping the read offset.