@Override public void data(DataInfo dataInfo, Callback handler) { try { // Data buffer must be copied, as the ByteBuffer is pooled ByteBuffer byteBuffer = dataInfo.asByteBuffer(false); send(null, byteBuffer, dataInfo.isClose()); if (dataInfo.isClose()) completed(); handler.succeeded(); } catch (IOException x) { handler.failed(x); } }
@Override public void complete() { bufferPool.release(buffer); IStream stream = getStream(); dataInfo.consume(size); flowControlStrategy.updateWindow(StandardSession.this, stream, -size); if (dataInfo.available() > 0) { // We have written a frame out of this DataInfo, but there is more to write. // We need to keep the correct ordering of frames, to avoid that another // DataInfo for the same stream is written before this one is finished. prepend(this); flush(); } else { super.complete(); stream.updateCloseState(dataInfo.isClose(), true); if (stream.isClosed()) removeStream(stream); } }
@Override public void onData(Stream stream, DataInfo dataInfo) { HttpExchange exchange = getHttpExchange(); if (exchange == null) return; try { int length = dataInfo.length(); // TODO: avoid data copy here boolean process = responseContent(exchange, dataInfo.asByteBuffer(false)); dataInfo.consume(length); if (process) { if (dataInfo.isClose()) { responseSuccess(exchange); } } } catch (Exception x) { responseFailure(x); } }
@Override public ByteBuffer getByteBuffer() { try { IStream stream = getStream(); int windowSize = stream.getWindowSize(); if (windowSize <= 0) return null; size = dataInfo.available(); if (size > windowSize) size = windowSize; buffer = generator.data(stream.getId(), size, dataInfo); return buffer; } catch (Throwable x) { fail(x); return null; } }
@Override public String toString() { return String.format( "DATA bytes @%x available=%d consumed=%d on %s", dataInfo.hashCode(), dataInfo.available(), dataInfo.consumed(), getStream()); }