1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.io;
19
20 import java.io.FilterInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23
24 import org.apache.hadoop.hbase.classification.InterfaceAudience;
25
26 import static com.google.common.base.Preconditions.checkArgument;
27 import static com.google.common.base.Preconditions.checkNotNull;
28
29
30
31
32
33
34 @InterfaceAudience.Private
35 public final class LimitInputStream extends FilterInputStream {
36 private long left;
37 private long mark = -1;
38
39 public LimitInputStream(InputStream in, long limit) {
40 super(in);
41 checkNotNull(in);
42 checkArgument(limit >= 0, "limit must be non-negative");
43 left = limit;
44 }
45
46 @Override
47 public int available() throws IOException {
48 return (int) Math.min(in.available(), left);
49 }
50
51
52 @Override
53 public synchronized void mark(int readLimit) {
54 in.mark(readLimit);
55 mark = left;
56 }
57
58 @Override
59 public int read() throws IOException {
60 if (left == 0) {
61 return -1;
62 }
63
64 int result = in.read();
65 if (result != -1) {
66 --left;
67 }
68 return result;
69 }
70
71 @Override
72 public int read(byte[] b, int off, int len) throws IOException {
73 if (left == 0) {
74 return -1;
75 }
76
77 len = (int) Math.min(len, left);
78 int result = in.read(b, off, len);
79 if (result != -1) {
80 left -= result;
81 }
82 return result;
83 }
84
85 @Override
86 public synchronized void reset() throws IOException {
87 if (!in.markSupported()) {
88 throw new IOException("Mark not supported");
89 }
90 if (mark == -1) {
91 throw new IOException("Mark not set");
92 }
93
94 in.reset();
95 left = mark;
96 }
97
98 @Override
99 public long skip(long n) throws IOException {
100 n = Math.min(n, left);
101 long skipped = in.skip(n);
102 left -= skipped;
103 return skipped;
104 }
105 }