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