1
2
3
4
5
6
7
8
9
10
11
12
13 package org.abstracthorizon.mercury.common.io;
14
15 import java.io.IOException;
16 import java.io.InputStream;
17
18
19
20
21
22
23
24 public class RangedInputStream extends InputStream {
25
26
27 protected InputStream is;
28
29
30 protected long from;
31
32
33 protected long to;
34
35
36 protected long left;
37
38
39 protected long marked;
40
41
42 protected long readlimit;
43
44
45 protected long readlimitCache;
46
47
48
49
50
51
52
53
54 public RangedInputStream(InputStream is, long from, long to) throws IOException {
55 this.is = is;
56 this.from = from;
57 this.to = to;
58 long l = is.skip(from);
59 if (l < from) {
60 left = 0;
61 } else {
62 left = to-from;
63 }
64 readlimit = -1;
65 readlimitCache = -1;
66 }
67
68 @Override
69 public int available() throws IOException {
70 int i = is.available();
71 if (i > left) {
72 i = (int)left;
73 }
74 return i;
75 }
76
77 @Override
78 public void close() throws IOException {
79 is.close();
80 }
81
82 @Override
83 public void mark(int readlimit) {
84 is.mark(readlimit);
85 this.readlimit = readlimit;
86 this.readlimitCache = readlimit;
87 marked = left;
88 }
89
90 @Override
91 public boolean markSupported() {
92 return is.markSupported();
93 }
94
95 @Override
96 public int read() throws IOException {
97 if (left == 0) {
98 return -1;
99 }
100 int i = is.read();
101 if (i >= 0) {
102 left = left-1;
103 if (readlimit >= 0) {
104 readlimit = readlimit-1;
105 if (readlimit < 0) {
106 readlimitCache = -1;
107 }
108 }
109 }
110 return i;
111 }
112
113 @Override
114 public int read(byte[] b) throws IOException {
115 if (left == 0) {
116 return -1;
117 }
118 if (left < b.length) {
119 return read(b, 0, (int)left);
120 }
121 int i = is.read(b);
122 if (i >= 0) {
123 left = left - i;
124 if (readlimit >= 0) {
125 readlimit = readlimit-i;
126 if (readlimit < 0) {
127 readlimitCache = -1;
128 }
129 }
130 } else {
131 left = 0;
132 }
133 return i;
134 }
135
136 @Override
137 public int read(byte[] b, int off, int len) throws IOException {
138 if (left == 0) {
139 return -1;
140 }
141 if (left < len) {
142 len = (int)left;
143 }
144 int i = is.read(b, off, len);
145 if (i >= 0) {
146 left = left - i;
147 if (readlimit >= 0) {
148 readlimit = readlimit-i;
149 if (readlimit < 0) {
150 readlimitCache = -1;
151 }
152 }
153 } else {
154 left = 0;
155 }
156 return i;
157 }
158
159 @Override
160 public void reset() throws IOException {
161 is.reset();
162 if (readlimit >= 0) {
163 left = marked;
164 readlimit = readlimitCache;
165 }
166 }
167
168 @Override
169 public long skip(long n) throws IOException {
170 if (left == 0) {
171 return 0;
172 }
173 if (n > left) {
174 n = left;
175 }
176 long i = is.skip(n);
177 left = left - i;
178 return i;
179 }
180 }