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