1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.archivers.sevenz;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.nio.ByteBuffer;
24 import java.nio.channels.SeekableByteChannel;
25
26 final class BoundedSeekableByteChannelInputStream extends InputStream {
27 private static final int MAX_BUF_LEN = 8192;
28 private final ByteBuffer buffer;
29 private final SeekableByteChannel channel;
30 private long bytesRemaining;
31
32 BoundedSeekableByteChannelInputStream(final SeekableByteChannel channel, final long size) {
33 this.channel = channel;
34 this.bytesRemaining = size;
35 this.buffer = ByteBuffer.allocate(size < MAX_BUF_LEN && size > 0 ? (int) size : MAX_BUF_LEN);
36 }
37
38 @Override
39 public void close() {
40
41 }
42
43 @Override
44 public int read() throws IOException {
45 if (bytesRemaining > 0) {
46 --bytesRemaining;
47 final int read = read(1);
48 if (read < 0) {
49 return read;
50 }
51 return buffer.get() & 0xff;
52 }
53 return -1;
54 }
55
56
57
58
59
60
61
62
63
64
65
66
67 @Override
68 public int read(final byte[] b, final int off, final int len) throws IOException {
69 if (len == 0) {
70 return 0;
71 }
72 if (bytesRemaining <= 0) {
73 return -1;
74 }
75 int bytesToRead = len;
76 if (bytesToRead > bytesRemaining) {
77 bytesToRead = (int) bytesRemaining;
78 }
79 final int bytesRead;
80 final ByteBuffer buf;
81 if (bytesToRead <= buffer.capacity()) {
82 buf = buffer;
83 bytesRead = read(bytesToRead);
84 } else {
85 buf = ByteBuffer.allocate(bytesToRead);
86 bytesRead = channel.read(buf);
87 buf.flip();
88 }
89 if (bytesRead >= 0) {
90 buf.get(b, off, bytesRead);
91 bytesRemaining -= bytesRead;
92 }
93 return bytesRead;
94 }
95
96 private int read(final int len) throws IOException {
97 buffer.rewind().limit(len);
98 final int read = channel.read(buffer);
99 buffer.flip();
100 return read;
101 }
102 }