class MessageInputStream extends InputStream
This class buffers incoming data blocks and reorders them transparently, ensuring a continuous byte stream to the caller. It supports:
Thread Safety: This class is synchronized internally and safe for use by one reader thread and potentially multiple message-receiving threads.
Performance: Designed for high-throughput scenarios such as large file downloads. Avoids unnecessary copying by using ByteArray references.
Lifecycle: The stream can be closed locally or receive an EOF signal remotely. Once closed, no further reads or message receptions are allowed.
Usage:
I2PSession -> MessageHandler -> PacketHandler -> ConnectionPacketHandler -> MessageInputStream
| Constructor and Description |
|---|
MessageInputStream(I2PAppContext ctx,
int maxMessageSize,
int maxWindowSize,
int maxBufferSize)Constructs a new MessageInputStream with the specified buffer limits. |
MessageInputStream(I2PAppContext ctx,
int maxMessageSize,
int maxWindowSize,
int maxBufferSize,
int maxPacketCount)Constructs a new MessageInputStream with the specified buffer limits. |
| Modifier and Type | Method and Description |
|---|---|
int | available()Returns an estimate of bytes readily available to read without blocking. |
boolean | canAccept(long messageId,
int payloadSize)Determines whether the stream can accept a new message. |
void | close()Closes the stream, clears all buffered data, and marks the stream as locally closed. |
void | closeReceived()Notifies the stream that no more messages will be received after the current highest. |
long | getHighestBlockId()Returns the highest block ID received so far, regardless of order. |
long | getHighestReadyBlockId()Returns the highest consecutive block ID that has been fully received and marked ready. |
long[] | getNacks()Gets an array of missing block IDs between the highest ready block and highest received block. |
int | getReadTimeout()Returns the current read timeout in milliseconds. |
int | getTotalReadySize()Gets the total number of bytes queued up in ready buffers. |
boolean | isLocallyClosed()Checks if this stream has been closed locally. |
boolean | messageReceived(long messageId,
ByteArray payload)Accepts a newly received message block. |
int | read()Reads a single byte from the stream. |
int | read(byte[] target)Reads bytes into the given array. |
int | read(byte[] target,
int offset,
int length)Reads up to length bytes into the target array at offset. |
void | setReadTimeout(int timeout)Sets the read timeout in milliseconds. |
(package private) void | streamErrorOccurred(IOException ioe)Records a stream error and marks the stream as locally closed. |
void | updateAcks(PacketLocal packet)Updates the ACK and NACK fields of a packet based on current stream state. |
mark, markSupported, reset, skippublic MessageInputStream(I2PAppContext ctx, int maxMessageSize, int maxWindowSize, int maxBufferSize)
ctx - Application context for logging and utilitiesmaxMessageSize - Max size of a single message blockmaxWindowSize - Max number of messages in the windowmaxBufferSize - Max total size of all buffered datapublic MessageInputStream(I2PAppContext ctx, int maxMessageSize, int maxWindowSize, int maxBufferSize, int maxPacketCount)
ctx - Application context for logging and utilitiesmaxMessageSize - Max size of a single message blockmaxWindowSize - Max number of messages in the windowmaxBufferSize - Max total size of all buffered datamaxPacketCount - Max number of packets regardless of byte sizepublic int available()
throws IOExceptionavailable in class InputStreamIOException - if stream is closed or error occurredpublic boolean canAccept(long messageId,
int payloadSize)messageId - The sequence ID of the messagepayloadSize - Size of the message payloadpublic void close()
close in interface Closeableclose in interface AutoCloseableclose in class InputStreampublic void closeReceived()
public long getHighestBlockId()
public long getHighestReadyBlockId()
public long[] getNacks()
public int getReadTimeout()
public int getTotalReadySize()
public boolean isLocallyClosed()
public boolean messageReceived(long messageId,
ByteArray payload)messageId - The message sequence IDpayload - The message payloadpublic int read()
throws IOExceptionread in class InputStreamIOException - if stream is closed or read failspublic int read(byte[] target)
throws IOExceptionread in class InputStreamtarget - byte array to read intoIOException - if stream is closed or read failspublic int read(byte[] target,
int offset,
int length)
throws IOExceptionlength bytes into the target array at offset.
Blocks until data is available or timeout occurs.The lock is held only during state checks, waits, and index updates.
The actual System.arraycopy(java.lang.Object, int, java.lang.Object, int, int) is performed outside the synchronized
block to reduce contention with the receive thread (messageReceived(long, net.i2p.data.ByteArray)).
This is safe because ByteArray payloads are immutable once stored.
read in class InputStreamtarget - byte array to read intooffset - offset in array to start writinglength - number of bytes to readIOException - if stream is closed or read failspublic void setReadTimeout(int timeout)
timeout - new read timeoutvoid streamErrorOccurred(IOException ioe)
ioe - The IOException that occurredpublic void updateAcks(PacketLocal packet)
packet - Packet to update