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