@Test public void testWriteBeyondFileSize() throws Exception { final ReadableByteChannel channel = new ReadableByteChannelMock( new String[] {"a"}, StandardCharsets.US_ASCII); final SessionInputBuffer inbuf = new SessionInputBufferImpl(1024, 256, 0, StandardCharsets.US_ASCII); final BasicHttpTransportMetrics metrics = new BasicHttpTransportMetrics(); final IdentityDecoder decoder = new IdentityDecoder( channel, inbuf, metrics); createTempFile(); final RandomAccessFile testfile = new RandomAccessFile(this.tmpfile, "rw"); try { Assert.assertEquals(0, testfile.length()); final FileChannel fchannel = testfile.getChannel(); try { decoder.transfer(fchannel, 5, 10); Assert.fail("expected IOException"); } catch(final IOException iox) {} } finally { testfile.close(); } }
@Override public long transfer( final FileChannel dst, final long position, final long count) throws IOException { if (dst == null) { return 0; } if (isCompleted()) { return 0; } long bytesRead; if (this.buffer.hasData()) { final int maxLen = this.buffer.length(); dst.position(position); bytesRead = this.buffer.read(dst, count < maxLen ? (int)count : maxLen); } else { if (this.channel.isOpen()) { if (position > dst.size()) { throw new IOException("Position past end of file [" + position + " > " + dst.size() + "]"); } bytesRead = dst.transferFrom(this.channel, position, count); if (count > 0 && bytesRead == 0) { bytesRead = this.buffer.fill(this.channel); } } else { bytesRead = -1; } if (bytesRead > 0) { this.metrics.incrementBytesTransferred(bytesRead); } } if (bytesRead == -1) { setCompleted(); } return bytesRead; }
IdentityDecoder extends AbstractContentDecoder implements FileContentDecoder { @Override public long transfer( final FileChannel dst, final long position, final long count) throws IOException { if (dst == null) { return 0; } if (isCompleted()) { return 0; } long bytesRead; if (this.buffer.hasData()) { final int maxLen = this.buffer.length(); dst.position(position); bytesRead = this.buffer.read(dst, count < maxLen ? (int)count : maxLen); } else { if (this.channel.isOpen()) { if (position > dst.size()) { throw new IOException("Position past end of file [" + position + " > " + dst.size() + "]"); } bytesRead = dst.transferFrom(this.channel, position, count); if (count > 0 && bytesRead == 0) { bytesRead = this.buffer.fill(this.channel); } } else { bytesRead = -1; } if (bytesRead > 0) { this.metrics.incrementBytesTransferred(bytesRead); } } if (bytesRead == -1) { setCompleted(); } return bytesRead; } }
IdentityDecoder extends AbstractContentDecoder implements FileContentDecoder { @Override public long transfer( final FileChannel dst, final long position, final long count) throws IOException { if (dst == null) { return 0; } if (isCompleted()) { return 0; } long bytesRead; if (this.buffer.hasData()) { final int maxLen = this.buffer.length(); dst.position(position); bytesRead = this.buffer.read(dst, count < maxLen ? (int)count : maxLen); } else { if (this.channel.isOpen()) { if (position > dst.size()) { throw new IOException("Position past end of file [" + position + " > " + dst.size() + "]"); } bytesRead = dst.transferFrom(this.channel, position, count); if (count > 0 && bytesRead == 0) { bytesRead = this.buffer.fill(this.channel); } } else { bytesRead = -1; } if (bytesRead > 0) { this.metrics.incrementBytesTransferred(bytesRead); } } if (bytesRead == -1) { setCompleted(); } return bytesRead; } IdentityDecoder(
            final ReadableByteChannel channel,
            final SessionInputBuffer buffer,
            final BasicHttpTransportMetrics metrics); }
IdentityDecoder extends AbstractContentDecoder implements FileContentDecoder { @Override public long transfer( final FileChannel dst, final long position, final long count) throws IOException { if (dst == null) { return 0; } if (isCompleted()) { return 0; } long bytesRead; if (this.buffer.hasData()) { final int maxLen = this.buffer.length(); dst.position(position); bytesRead = this.buffer.read(dst, count < maxLen ? (int)count : maxLen); } else { if (this.channel.isOpen()) { if (position > dst.size()) { throw new IOException("Position past end of file [" + position + " > " + dst.size() + "]"); } bytesRead = dst.transferFrom(this.channel, position, count); if (count > 0 && bytesRead == 0) { bytesRead = this.buffer.fill(this.channel); } } else { bytesRead = -1; } if (bytesRead > 0) { this.metrics.incrementBytesTransferred(bytesRead); } } if (bytesRead == -1) { setCompleted(); } return bytesRead; } IdentityDecoder(
            final ReadableByteChannel channel,
            final SessionInputBuffer buffer,
            final BasicHttpTransportMetrics metrics); @Override int read(final ByteBuffer dst); @Override long transfer(
            final FileChannel dst,
            final long position,
            final long count); @Override String toString(); }
IdentityDecoder extends AbstractContentDecoder implements FileContentDecoder { @Override public long transfer( final FileChannel dst, final long position, final long count) throws IOException { if (dst == null) { return 0; } if (isCompleted()) { return 0; } long bytesRead; if (this.buffer.hasData()) { final int maxLen = this.buffer.length(); dst.position(position); bytesRead = this.buffer.read(dst, count < maxLen ? (int)count : maxLen); } else { if (this.channel.isOpen()) { if (position > dst.size()) { throw new IOException("Position past end of file [" + position + " > " + dst.size() + "]"); } bytesRead = dst.transferFrom(this.channel, position, count); if (count > 0 && bytesRead == 0) { bytesRead = this.buffer.fill(this.channel); } } else { bytesRead = -1; } if (bytesRead > 0) { this.metrics.incrementBytesTransferred(bytesRead); } } if (bytesRead == -1) { setCompleted(); } return bytesRead; } IdentityDecoder(
            final ReadableByteChannel channel,
            final SessionInputBuffer buffer,
            final BasicHttpTransportMetrics metrics); @Override int read(final ByteBuffer dst); @Override long transfer(
            final FileChannel dst,
            final long position,
            final long count); @Override String toString();  }