@Test public void testCodingEmptyBuffer() throws Exception { final WritableByteChannelMock channel = new WritableByteChannelMock(64); final SessionOutputBuffer outbuf = new SessionOutputBufferImpl(1024, 128); final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics(); final LengthDelimitedEncoder encoder = new LengthDelimitedEncoder( channel, outbuf, metrics, 16); encoder.write(CodecTestUtils.wrap("stuff;")); final ByteBuffer empty = ByteBuffer.allocate(100); empty.flip(); encoder.write(empty); encoder.write(null); encoder.write(CodecTestUtils.wrap("more stuff")); final String s = channel.dump(StandardCharsets.US_ASCII); Assert.assertTrue(encoder.isCompleted()); Assert.assertEquals("stuff;more stuff", s); }
@Override public int write(final ByteBuffer src) throws IOException { if (src == null) { return 0; } assertNotCompleted(); int total = 0; while (src.hasRemaining() && this.remaining > 0) { if (this.buffer.hasData() || this.fragHint > 0) { final int chunk = nextChunk(src); if (chunk <= this.fragHint) { final int capacity = this.fragHint - this.buffer.length(); if (capacity > 0) { final int limit = Math.min(capacity, chunk); final int bytesWritten = writeToBuffer(src, limit); this.remaining -= bytesWritten; total += bytesWritten; } } } if (this.buffer.hasData()) { final int chunk = nextChunk(src); if (this.buffer.length() >= this.fragHint || chunk > 0) { final int bytesWritten = flushToChannel(); if (bytesWritten == 0) { break; } } } if (!this.buffer.hasData()) { final int chunk = nextChunk(src); if (chunk > this.fragHint) { final int bytesWritten = writeToChannel(src, chunk); this.remaining -= bytesWritten; total += bytesWritten; if (bytesWritten == 0) { break; } } } } if (this.remaining <= 0) { super.complete(null); } return total; }
LengthDelimitedEncoder extends AbstractContentEncoder implements FileContentEncoder { @Override public int write(final ByteBuffer src) throws IOException { if (src == null) { return 0; } assertNotCompleted(); int total = 0; while (src.hasRemaining() && this.remaining > 0) { if (this.buffer.hasData() || this.fragHint > 0) { final int chunk = nextChunk(src); if (chunk <= this.fragHint) { final int capacity = this.fragHint - this.buffer.length(); if (capacity > 0) { final int limit = Math.min(capacity, chunk); final int bytesWritten = writeToBuffer(src, limit); this.remaining -= bytesWritten; total += bytesWritten; } } } if (this.buffer.hasData()) { final int chunk = nextChunk(src); if (this.buffer.length() >= this.fragHint || chunk > 0) { final int bytesWritten = flushToChannel(); if (bytesWritten == 0) { break; } } } if (!this.buffer.hasData()) { final int chunk = nextChunk(src); if (chunk > this.fragHint) { final int bytesWritten = writeToChannel(src, chunk); this.remaining -= bytesWritten; total += bytesWritten; if (bytesWritten == 0) { break; } } } } if (this.remaining <= 0) { super.complete(null); } return total; } }
LengthDelimitedEncoder extends AbstractContentEncoder implements FileContentEncoder { @Override public int write(final ByteBuffer src) throws IOException { if (src == null) { return 0; } assertNotCompleted(); int total = 0; while (src.hasRemaining() && this.remaining > 0) { if (this.buffer.hasData() || this.fragHint > 0) { final int chunk = nextChunk(src); if (chunk <= this.fragHint) { final int capacity = this.fragHint - this.buffer.length(); if (capacity > 0) { final int limit = Math.min(capacity, chunk); final int bytesWritten = writeToBuffer(src, limit); this.remaining -= bytesWritten; total += bytesWritten; } } } if (this.buffer.hasData()) { final int chunk = nextChunk(src); if (this.buffer.length() >= this.fragHint || chunk > 0) { final int bytesWritten = flushToChannel(); if (bytesWritten == 0) { break; } } } if (!this.buffer.hasData()) { final int chunk = nextChunk(src); if (chunk > this.fragHint) { final int bytesWritten = writeToChannel(src, chunk); this.remaining -= bytesWritten; total += bytesWritten; if (bytesWritten == 0) { break; } } } } if (this.remaining <= 0) { super.complete(null); } return total; } LengthDelimitedEncoder(
            final WritableByteChannel channel,
            final SessionOutputBuffer buffer,
            final BasicHttpTransportMetrics metrics,
            final long contentLength,
            final int chunkSizeHint);  LengthDelimitedEncoder(
            final WritableByteChannel channel,
            final SessionOutputBuffer buffer,
            final BasicHttpTransportMetrics metrics,
            final long contentLength); }
LengthDelimitedEncoder extends AbstractContentEncoder implements FileContentEncoder { @Override public int write(final ByteBuffer src) throws IOException { if (src == null) { return 0; } assertNotCompleted(); int total = 0; while (src.hasRemaining() && this.remaining > 0) { if (this.buffer.hasData() || this.fragHint > 0) { final int chunk = nextChunk(src); if (chunk <= this.fragHint) { final int capacity = this.fragHint - this.buffer.length(); if (capacity > 0) { final int limit = Math.min(capacity, chunk); final int bytesWritten = writeToBuffer(src, limit); this.remaining -= bytesWritten; total += bytesWritten; } } } if (this.buffer.hasData()) { final int chunk = nextChunk(src); if (this.buffer.length() >= this.fragHint || chunk > 0) { final int bytesWritten = flushToChannel(); if (bytesWritten == 0) { break; } } } if (!this.buffer.hasData()) { final int chunk = nextChunk(src); if (chunk > this.fragHint) { final int bytesWritten = writeToChannel(src, chunk); this.remaining -= bytesWritten; total += bytesWritten; if (bytesWritten == 0) { break; } } } } if (this.remaining <= 0) { super.complete(null); } return total; } LengthDelimitedEncoder(
            final WritableByteChannel channel,
            final SessionOutputBuffer buffer,
            final BasicHttpTransportMetrics metrics,
            final long contentLength,
            final int chunkSizeHint);  LengthDelimitedEncoder(
            final WritableByteChannel channel,
            final SessionOutputBuffer buffer,
            final BasicHttpTransportMetrics metrics,
            final long contentLength); @Override int write(final ByteBuffer src); @Override long transfer(
            final FileChannel src,
            final long position,
            final long count); @Override String toString(); }
LengthDelimitedEncoder extends AbstractContentEncoder implements FileContentEncoder { @Override public int write(final ByteBuffer src) throws IOException { if (src == null) { return 0; } assertNotCompleted(); int total = 0; while (src.hasRemaining() && this.remaining > 0) { if (this.buffer.hasData() || this.fragHint > 0) { final int chunk = nextChunk(src); if (chunk <= this.fragHint) { final int capacity = this.fragHint - this.buffer.length(); if (capacity > 0) { final int limit = Math.min(capacity, chunk); final int bytesWritten = writeToBuffer(src, limit); this.remaining -= bytesWritten; total += bytesWritten; } } } if (this.buffer.hasData()) { final int chunk = nextChunk(src); if (this.buffer.length() >= this.fragHint || chunk > 0) { final int bytesWritten = flushToChannel(); if (bytesWritten == 0) { break; } } } if (!this.buffer.hasData()) { final int chunk = nextChunk(src); if (chunk > this.fragHint) { final int bytesWritten = writeToChannel(src, chunk); this.remaining -= bytesWritten; total += bytesWritten; if (bytesWritten == 0) { break; } } } } if (this.remaining <= 0) { super.complete(null); } return total; } LengthDelimitedEncoder(
            final WritableByteChannel channel,
            final SessionOutputBuffer buffer,
            final BasicHttpTransportMetrics metrics,
            final long contentLength,
            final int chunkSizeHint);  LengthDelimitedEncoder(
            final WritableByteChannel channel,
            final SessionOutputBuffer buffer,
            final BasicHttpTransportMetrics metrics,
            final long contentLength); @Override int write(final ByteBuffer src); @Override long transfer(
            final FileChannel src,
            final long position,
            final long count); @Override String toString();  }