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