Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/net/www/MeteredStream.java
41159 views
1
/*
2
* Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.net.www;
27
28
import java.io.*;
29
import java.util.concurrent.locks.ReentrantLock;
30
import sun.net.ProgressSource;
31
import sun.net.www.http.ChunkedInputStream;
32
33
34
public class MeteredStream extends FilterInputStream {
35
36
// Instance variables.
37
/* if expected != -1, after we've read >= expected, we're "closed" and return -1
38
* from subsequest read() 's
39
*/
40
protected boolean closed = false;
41
protected long expected;
42
protected long count = 0;
43
protected long markedCount = 0;
44
protected int markLimit = -1;
45
protected ProgressSource pi;
46
private final ReentrantLock readLock = new ReentrantLock();
47
48
public MeteredStream(InputStream is, ProgressSource pi, long expected)
49
{
50
super(is);
51
52
this.pi = pi;
53
this.expected = expected;
54
55
if (pi != null) {
56
pi.updateProgress(0, expected);
57
}
58
}
59
60
private final void justRead(long n) throws IOException {
61
assert isLockHeldByCurrentThread();
62
63
if (n == -1) {
64
65
/*
66
* don't close automatically when mark is set and is valid;
67
* cannot reset() after close()
68
*/
69
if (!isMarked()) {
70
close();
71
}
72
return;
73
}
74
75
count += n;
76
77
/**
78
* If read beyond the markLimit, invalidate the mark
79
*/
80
if (count - markedCount > markLimit) {
81
markLimit = -1;
82
}
83
84
if (pi != null)
85
pi.updateProgress(count, expected);
86
87
if (isMarked()) {
88
return;
89
}
90
91
// if expected length is known, we could determine if
92
// read overrun.
93
if (expected > 0) {
94
if (count >= expected) {
95
close();
96
}
97
}
98
}
99
100
/**
101
* Returns true if the mark is valid, false otherwise
102
*/
103
private boolean isMarked() {
104
assert isLockHeldByCurrentThread();
105
106
if (markLimit < 0) {
107
return false;
108
}
109
110
// mark is set, but is not valid anymore
111
if (count - markedCount > markLimit) {
112
return false;
113
}
114
115
// mark still holds
116
return true;
117
}
118
119
public int read() throws java.io.IOException {
120
lock();
121
try {
122
if (closed) return -1;
123
int c = in.read();
124
if (c != -1) {
125
justRead(1);
126
} else {
127
justRead(c);
128
}
129
return c;
130
} finally {
131
unlock();
132
}
133
}
134
135
public int read(byte b[], int off, int len)
136
throws java.io.IOException {
137
lock();
138
try {
139
if (closed) return -1;
140
141
int n = in.read(b, off, len);
142
justRead(n);
143
return n;
144
} finally {
145
unlock();
146
}
147
}
148
149
public long skip(long n) throws IOException {
150
lock();
151
try {
152
// REMIND: what does skip do on EOF????
153
if (closed) return 0;
154
155
if (in instanceof ChunkedInputStream) {
156
n = in.skip(n);
157
} else {
158
// just skip min(n, num_bytes_left)
159
long min = (n > expected - count) ? expected - count : n;
160
n = in.skip(min);
161
}
162
justRead(n);
163
return n;
164
} finally {
165
unlock();
166
}
167
}
168
169
public void close() throws IOException {
170
lock();
171
try {
172
if (closed) return;
173
if (pi != null)
174
pi.finishTracking();
175
176
closed = true;
177
in.close();
178
} finally {
179
unlock();
180
}
181
}
182
183
public int available() throws IOException {
184
lock();
185
try {
186
return closed ? 0 : in.available();
187
} finally {
188
unlock();
189
}
190
}
191
192
public void mark(int readLimit) {
193
lock();
194
try {
195
if (closed) return;
196
super.mark(readLimit);
197
198
/*
199
* mark the count to restore upon reset
200
*/
201
markedCount = count;
202
markLimit = readLimit;
203
} finally {
204
unlock();
205
}
206
}
207
208
public void reset() throws IOException {
209
lock();
210
try {
211
if (closed) return;
212
if (!isMarked()) {
213
throw new IOException("Resetting to an invalid mark");
214
}
215
216
count = markedCount;
217
super.reset();
218
} finally {
219
unlock();
220
}
221
}
222
223
public boolean markSupported() {
224
lock();
225
try {
226
if (closed) return false;
227
return super.markSupported();
228
} finally {
229
unlock();
230
}
231
}
232
233
public final void lock() {
234
readLock.lock();
235
}
236
237
public final void unlock() {
238
readLock.unlock();
239
}
240
241
public final boolean isLockHeldByCurrentThread() {
242
return readLock.isHeldByCurrentThread();
243
}
244
245
@SuppressWarnings("deprecation")
246
protected void finalize() throws Throwable {
247
try {
248
close();
249
if (pi != null)
250
pi.close();
251
}
252
finally {
253
// Call super class
254
super.finalize();
255
}
256
}
257
}
258
259