/** * @return a byte array with the content of this {@link DataInfo} * @param consume whether to consume the content */ public byte[] asBytes(boolean consume) { ByteBuffer buffer = asByteBuffer(consume); byte[] result = new byte[buffer.remaining()]; buffer.get(result); return result; }
@Override protected void consume(DataInfo item, int length) { item.consume(length); }
/** * <p>Reads and consumes the content bytes of this {@link DataInfo} into the given {@link ByteBuffer}.</p> * * @param output the {@link ByteBuffer} to copy the bytes into * @return the number of bytes copied * @see #consume(int) */ public int consumeInto(ByteBuffer output) { int read = readInto(output); consume(read); return read; }
/** * @return a {@link ByteBuffer} with the content of this {@link DataInfo} * @param consume whether to consume the content */ public ByteBuffer asByteBuffer(boolean consume) { ByteBuffer buffer = allocate(available()); if (consume) consumeInto(buffer); else readInto(buffer); buffer.flip(); return buffer; }
private void data(final Stream stream, final DataInfo serverDataInfo) { final ByteBufferDataInfo clientDataInfo = new ByteBufferDataInfo(serverDataInfo.asByteBuffer(false), serverDataInfo.isClose()) { @Override public void consume(int delta) { super.consume(delta); serverDataInfo.consume(delta); } }; receiverStream.data(clientDataInfo, new Callback() //TODO: timeout??? { @Override public void succeeded() { if (LOG.isDebugEnabled()) LOG.debug("P -> C {} from {} to {}", clientDataInfo, stream, receiverStream); } @Override public void failed(Throwable x) { LOG.debug(x); rst(receiverStream); } }); } }
dataInfo.consume(dataInfo.length()); logger.debug("Consumed {} content bytes, queue size {}", dataInfo.consumed(), dataInfos.size()); dataInfo = null; buffer = null; ByteBuffer byteBuffer = dataInfo.asByteBuffer(false); buffer = byteBuffer.isDirect() ? new DirectNIOBuffer(byteBuffer, false) : new IndirectNIOBuffer(byteBuffer, false);
/** * <p>Consumes the given number of bytes from this {@link DataInfo}.</p> * * @param delta the number of bytes consumed */ public void consume(int delta) { if (delta < 0) throw new IllegalArgumentException(); int read = length() - available(); int newConsumed = consumed() + delta; // if (newConsumed > read) // throw new IllegalStateException("Consuming without reading: consumed " + newConsumed + " but only read " + read); consumed.addAndGet(delta); }
@Override public void succeeded() { 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. flush(this, flusher.prepend(this)); } else { super.succeeded(); stream.updateCloseState(dataInfo.isClose(), true); if (stream.isClosed()) removeStream(stream); } }
LOG.debug("HTTP > {} bytes of content", dataInfo.length()); ByteBuffer copyByteBuffer = dataInfo.asByteBuffer(false); ByteBufferDataInfo copyDataInfo = new ByteBufferDataInfo(copyByteBuffer, dataInfo.isClose())
ByteBufferDataInfo copyDataInfo = new ByteBufferDataInfo(dataInfo.asByteBuffer(false), dataInfo.isClose(), dataInfo.isCompress())
@Override public void onData(final Stream stream, final DataInfo dataInfo) { logger.debug("S -> P {} on {}", dataInfo, stream); if (replyInfo != null) { if (dataInfo.isClose()) replyInfo.getHeaders().put("content-length", String.valueOf(dataInfo.available())); reply(stream); } data(stream, dataInfo); }
/** * @return the close and compress flags as integer * @see #FLAG_CLOSE */ public byte getFlags() { return isClose() ? FLAG_CLOSE : 0; }
@Override public void onDataConsumed(ISession session, IStream stream, DataInfo dataInfo, int delta) { // This is the algorithm for flow control. // This method may be called multiple times with delta=1, but we only send a window // update when the whole dataInfo has been consumed. // Other policies may be to send window updates when consumed() is greater than // a certain threshold, etc. but for now the policy is not pluggable for simplicity. // Note that the frequency of window updates depends on the read buffer, that // should not be too smaller than the window size to avoid frequent window updates. // Therefore, a pluggable policy should be able to modify the read buffer capacity. int length = dataInfo.length(); if (dataInfo.consumed() == length && !stream.isClosed() && length > 0) { WindowUpdateFrame windowUpdateFrame = new WindowUpdateFrame(session.getVersion(), stream.getId(), length); session.control(stream, windowUpdateFrame, 0, TimeUnit.MILLISECONDS, Callback.Adapter.INSTANCE); } } }
@Override public void run() { logger.debug("HTTP > {} bytes of content", dataInfo.length()); if (state == State.HEADERS) { updateState(State.HEADERS_COMPLETE); handle(); } updateState(State.CONTENT); handle(); } });
@Override protected int remaining(DataInfo item) { return item.available(); }
@Override protected int get(DataInfo item, byte[] buffer, int offset, int length) { return item.readInto(buffer, offset, length); }
/** * * @param charset the charset used to convert the bytes * @param consume whether to consume the content * @return a String with the content of this {@link DataInfo} */ public String asString(String charset, boolean consume) { return asString(Charset.forName(charset), consume); }