net.i2p.client.streaming.impl
Class MessageInputStream

java.lang.Object
  extended by java.io.InputStream
      extended by net.i2p.client.streaming.impl.MessageInputStream
All Implemented Interfaces:
Closeable

 class MessageInputStream
extends InputStream

Stream that can be given messages out of order yet present them in order.

I2PSession -> MessageHandler -> PacketHandler -> ConnectionPacketHandler -> MessageInputStream

This buffers unlimited data via messageReceived() - limiting / blocking is done in ConnectionPacketHandler.receivePacket().


Constructor Summary
MessageInputStream(I2PAppContext ctx, int maxMessageSize, int maxWindowSize, int maxBufferSize)
           
 
Method Summary
 int available()
           
 boolean canAccept(long messageId, int payloadSize)
          Determine if this packet will fit in our buffering limits.
 void close()
           
 void closeReceived()
          There is no more data coming from the I2P side.
 long getHighestBlockId()
           
 long getHighestReadyBlockId()
          What is the highest block ID we've completely received through?
 long[] getNacks()
          Retrieve the message IDs that are holes in our sequence - ones past the highest ready ID and below the highest received message ID.
 int getReadTimeout()
          how long a read() call should block (if less than 0, block indefinitely, but if it is 0, do not block at all)
 int getTotalReadySize()
          Same as available() but doesn't throw IOE
 boolean messageReceived(long messageId, ByteArray payload)
          A new message has arrived - toss it on the appropriate queue (moving previously pending messages to the ready queue if it fills the gap, etc).
 void notifyActivity()
           
 int read()
          On a read timeout, this returns -1 (doesn't throw SocketTimeoutException like Socket) (doesn't throw InterruptedIOException like our javadocs say)
 int read(byte[] target)
          On a read timeout, this returns 0 (doesn't throw SocketTimeoutException like Socket) (doesn't throw InterruptedIOException like our javadocs say)
 int read(byte[] target, int offset, int length)
          On a read timeout, this returns 0 (doesn't throw SocketTimeoutException like Socket) (doesn't throw InterruptedIOException like our javadocs say)
 void setReadTimeout(int timeout)
          how long a read() call should block (if less than 0, block indefinitely, but if it is 0, do not block at all)
(package private)  void streamErrorOccurred(IOException ioe)
          Stream b0rked, die with the given error
 void updateAcks(PacketLocal packet)
          Adds the ack-through and nack fields to a packet we are building for transmission
 
Methods inherited from class java.io.InputStream
mark, markSupported, reset, skip
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

MessageInputStream

public MessageInputStream(I2PAppContext ctx,
                          int maxMessageSize,
                          int maxWindowSize,
                          int maxBufferSize)
Method Detail

getHighestReadyBlockId

public long getHighestReadyBlockId()
What is the highest block ID we've completely received through?

Returns:
highest data block ID completely received or -1 for none

getHighestBlockId

public long getHighestBlockId()
Returns:
highest data block ID received or -1 for none

canAccept

public boolean canAccept(long messageId,
                         int payloadSize)
Determine if this packet will fit in our buffering limits.

Returns:
true if we have room. If false, do not call messageReceived()
Since:
0.9.20 moved from ConnectionPacketHandler.receivePacket() so it can all be under one lock, and we can efficiently do several checks

getNacks

public long[] getNacks()
Retrieve the message IDs that are holes in our sequence - ones past the highest ready ID and below the highest received message ID. This may return null if there are no such IDs.

Returns:
array of message ID holes, or null if none

updateAcks

public void updateAcks(PacketLocal packet)
Adds the ack-through and nack fields to a packet we are building for transmission


getReadTimeout

public int getReadTimeout()
how long a read() call should block (if less than 0, block indefinitely, but if it is 0, do not block at all)

Returns:
how long read calls should block, 0 for nonblocking, negative to indefinitely block

setReadTimeout

public void setReadTimeout(int timeout)
how long a read() call should block (if less than 0, block indefinitely, but if it is 0, do not block at all)

Parameters:
timeout - how long read calls should block, 0 for nonblocking, negative to indefinitely block

closeReceived

public void closeReceived()
There is no more data coming from the I2P side. Does NOT clear pending data. messageReceived() MUST have been called previously with the messageId of the CLOSE packet.


notifyActivity

public void notifyActivity()

messageReceived

public boolean messageReceived(long messageId,
                               ByteArray payload)
A new message has arrived - toss it on the appropriate queue (moving previously pending messages to the ready queue if it fills the gap, etc). This does no limiting of pending data - see canAccept() for limiting.

Parameters:
messageId - ID of the message
payload - message payload, may be null or have null or zero-length data
Returns:
true if this is a new packet, false if it is a dup

read

public int read()
         throws IOException
On a read timeout, this returns -1 (doesn't throw SocketTimeoutException like Socket) (doesn't throw InterruptedIOException like our javadocs say)

Specified by:
read in class InputStream
Throws:
IOException

read

public int read(byte[] target)
         throws IOException
On a read timeout, this returns 0 (doesn't throw SocketTimeoutException like Socket) (doesn't throw InterruptedIOException like our javadocs say)

Overrides:
read in class InputStream
Throws:
IOException

read

public int read(byte[] target,
                int offset,
                int length)
         throws IOException
On a read timeout, this returns 0 (doesn't throw SocketTimeoutException like Socket) (doesn't throw InterruptedIOException like our javadocs say)

Overrides:
read in class InputStream
Throws:
IOException

available

public int available()
              throws IOException
Overrides:
available in class InputStream
Throws:
IOException

getTotalReadySize

public int getTotalReadySize()
Same as available() but doesn't throw IOE


close

public void close()
Specified by:
close in interface Closeable
Overrides:
close in class InputStream

streamErrorOccurred

void streamErrorOccurred(IOException ioe)
Stream b0rked, die with the given error