1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.io.hfile;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22
23 import org.apache.hadoop.classification.InterfaceAudience;
24 import org.apache.hadoop.fs.FSDataInputStream;
25
26
27
28
29
30
31
32
33 @InterfaceAudience.Private
34 class BoundedRangeFileInputStream extends InputStream {
35
36 private FSDataInputStream in;
37 private long pos;
38 private long end;
39 private long mark;
40 private final byte[] oneByte = new byte[1];
41 private final boolean pread;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public BoundedRangeFileInputStream(FSDataInputStream in, long offset,
58 long length, final boolean pread) {
59 if (offset < 0 || length < 0) {
60 throw new IndexOutOfBoundsException("Invalid offset/length: " + offset
61 + "/" + length);
62 }
63
64 this.in = in;
65 this.pos = offset;
66 this.end = offset + length;
67 this.mark = -1;
68 this.pread = pread;
69 }
70
71 @Override
72 public int available() throws IOException {
73 int avail = in.available();
74 if (pos + avail > end) {
75 avail = (int) (end - pos);
76 }
77
78 return avail;
79 }
80
81 @Override
82 public int read() throws IOException {
83 int ret = read(oneByte);
84 if (ret == 1) return oneByte[0] & 0xff;
85 return -1;
86 }
87
88 @Override
89 public int read(byte[] b) throws IOException {
90 return read(b, 0, b.length);
91 }
92
93 @Override
94 public int read(byte[] b, int off, int len) throws IOException {
95 if ((off | len | (off + len) | (b.length - (off + len))) < 0) {
96 throw new IndexOutOfBoundsException();
97 }
98
99 int n = (int) Math.min(Integer.MAX_VALUE, Math.min(len, (end - pos)));
100 if (n == 0) return -1;
101 int ret = 0;
102 if (this.pread) {
103 ret = in.read(pos, b, off, n);
104 } else {
105 synchronized (in) {
106 in.seek(pos);
107 ret = in.read(b, off, n);
108 }
109 }
110 if (ret < 0) {
111 end = pos;
112 return -1;
113 }
114 pos += ret;
115 return ret;
116 }
117
118 @Override
119
120
121
122 public long skip(long n) throws IOException {
123 long len = Math.min(n, end - pos);
124 pos += len;
125 return len;
126 }
127
128 @Override
129 public void mark(int readlimit) {
130 mark = pos;
131 }
132
133 @Override
134 public void reset() throws IOException {
135 if (mark < 0) throw new IOException("Resetting to invalid mark");
136 pos = mark;
137 }
138
139 @Override
140 public boolean markSupported() {
141 return true;
142 }
143
144 @Override
145 public void close() {
146
147 in = null;
148 pos = end;
149 mark = -1;
150 }
151 }