packet.mark ();
final int packetSize = packet.getInt ();
Preconditions.checkArgument (packetSize == packet.remaining (), "invalid outbound packet encoding");
packet.reset ();
} catch (final IllegalArgumentException exception) {
throw (new IgnoredException (exception, "unexpected validation error encountered while polling outbound packet; aborting!"));
}
this.outputPending = packet;
}
}
} else {
if (this.outputPending != null) {
this.transcript.traceError ("discarding outbound packet due to closed outbound flow;");
this.outputPending = null;
}
}
try {
if ((this.inputPending != null) && (this.inputKey == null))
this.inputKey = ((SelectableChannel) this.input).register (this.selector, SelectionKey.OP_READ);
else if ((this.inputKey != null) && (this.inputPending == null)) {
this.inputKey.cancel ();
this.inputKey = null;
}
if ((this.outputPending != null) && (this.outputKey == null) && this.output.isOpen ())
this.outputKey = ((SelectableChannel) this.output).register (this.selector, SelectionKey.OP_WRITE);
else if ((this.outputKey != null) && (this.outputPending == null)) {
this.outputKey.cancel ();
this.outputKey = null;
}
} catch (final IOException exception) {
throw (new IgnoredException (exception, "i/o error encountered while polling flows; aborting!"));
}
try {
this.selector.select (this.pollTimeout);
} catch (final IOException exception) {
throw (new IgnoredException (exception, "i/o error encountered while polling flows; aborting!"));
}
final boolean inputValid;
final boolean outputValid;
if (this.inputKey != null) {
inputValid = this.inputKey.isValid () && this.input.isOpen ();
if (inputValid && this.inputKey.isReadable ()) {
this.transcript.traceDebugging ("accessing input flow...");
try {
try {
final int outcome = this.input.read (this.inputPending);
if (outcome == -1)
this.input.close ();
} catch (final ClosedChannelException exception) {
this.exceptions.traceIgnoredException (exception);
}
} catch (final IOException exception) {
throw (new IgnoredException (exception, "i/o error encountered while accessing input flow; aborting!"));
}
}
} else
inputValid = true;
if (this.outputKey != null) {
outputValid = this.outputKey.isValid () && this.output.isOpen ();
if (outputValid && this.outputKey.isWritable ()) {
this.transcript.traceDebugging ("accessing output flow...");
try {
try {
this.output.write (this.outputPending);
} catch (final ClosedChannelException exception) {
this.exceptions.traceIgnoredException (exception);
}
} catch (final IOException exception) {
throw (new IgnoredException (exception, "i/o error encountered while accessing output flow; aborting!"));
}
}
} else
outputValid = true;
if (this.inputPending != null) {
while (true) {
if (this.inputPendingSize == -1) {
if (this.inputPending.position () >= 4) {
this.inputPendingSize = this.inputPending.getInt (0) + 4;
if (this.inputPending.capacity () < this.inputPendingSize) {
if (this.inputPendingSize > this.maximumPacketSize)
throw (new IgnoredException (new BufferOverflowException (), "unexpected inbound packet size; aborting!"));
final ByteBuffer buffer = ByteBuffer.allocate (this.inputPendingSize);
this.inputPending.compact ();
buffer.put (this.inputPending);
this.inputPending = buffer;
}
}
}
if (this.inputPendingSize != -1) {
final ByteBuffer packet;
if (this.inputPending.position () == this.inputPendingSize) {
packet = this.inputPending;
this.inputPending = null;
this.inputPendingSize = -1;
} else if (this.inputPending.position () > this.inputPendingSize) {
this.inputPending.flip ();
packet = ByteBuffer.allocate (this.inputPendingSize);
final ByteBuffer inputPendingSlice = this.inputPending.asReadOnlyBuffer ();
inputPendingSlice.limit (this.inputPendingSize);
packet.put (inputPendingSlice);
this.inputPending.position (this.inputPendingSize);
this.inputPending.compact ();
this.inputPendingSize = -1;
} else
packet = null;
if (packet != null) {
packet.flip ();
if (!Threading.offer (this.inboundPackets, packet.asReadOnlyBuffer (), this.pollTimeout))
throw (new IgnoredException (new BufferOverflowException (), "unexpected queue overflow error encountered while enqueueing inbound packet; aborting!"));
}
}
if ((this.inputPending == null) || (this.inputPending.position () < 4) || ((this.inputPendingSize != -1) && (this.inputPendingSize > this.inputPending.position ())))
break;
}