/** * Attempts to read a buffered message from the underlying connection. This is more efficient than * attempting to actually read from the underlying connection for each message, when ends up * making a final "empty" read from the non-blocking connection, rather than simply consuming all * buffered data. * * <p>TODO: It would be ideal if there was a way to consume data as we go, instead of buffering it * all then consuming it. However, this only matters for streams of medium-sized messages with a * huge backlog, which should be rare? The C++ implementation has a similar issue. * * @param builder message builder to be parsed * @return true if a message was read, false if there is not enough buffered data to read a * message. */ public boolean readBufferedMessage(MessageLite.Builder builder) { try { if (nextMessageLength == -1) { if (connection.available() < 4) { return false; } input.setLimit(4); nextMessageLength = codedInput.readRawLittleEndian32(); } assert nextMessageLength >= 0; if (connection.available() < nextMessageLength) { assert 0 <= connection.available() && connection.available() < nextMessageLength; return false; } // Parse the response for the next RPC // TODO: Add .available() to CodedInputStream to avoid many copies to internal buffer? // or make CodedInputStream wrap a non-blocking interface like C++? input.setLimit(nextMessageLength); builder.mergeFrom(codedInput); assert codedInput.isAtEnd(); codedInput.resetSizeCounter(); nextMessageLength = -1; return true; } catch (IOException e) { throw new RuntimeException(e); } }
public ProtoConnection(NonBlockingConnection connection) { this.connection = connection; input = connection.getInputStream(); output = connection.getOutputStream(); codedInput = CodedInputStream.newInstance(input); codedOutput = CodedOutputStream.newInstance(output); }
public boolean tryWrite(MessageLite message) { try { codedOutput.writeRawLittleEndian32(message.getSerializedSize()); message.writeTo(codedOutput); // writes to the underlying output stream codedOutput.flush(); return connection.tryFlush(); } catch (IOException e) { throw new RuntimeException(e); } }
/** * See {@link NIOReadStream#readAllAvailable()}. * * @see NIOReadStream#readAllAvailable() */ public boolean readAllAvailable() { return connection.readAllAvailable(); }
public void close() { connection.close(); }
public boolean writeAvailable() { return connection.writeAvailable(); }
public SelectableChannel getChannel() { return connection.getChannel(); }