Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/net/www/MeteredStream.java
38830 views
/*1* Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.net.www;2627import java.net.URL;28import java.util.*;29import java.io.*;30import sun.net.ProgressSource;31import sun.net.www.http.ChunkedInputStream;323334public class MeteredStream extends FilterInputStream {3536// Instance variables.37/* if expected != -1, after we've read >= expected, we're "closed" and return -138* from subsequest read() 's39*/40protected boolean closed = false;41protected long expected;42protected long count = 0;43protected long markedCount = 0;44protected int markLimit = -1;45protected ProgressSource pi;4647public MeteredStream(InputStream is, ProgressSource pi, long expected)48{49super(is);5051this.pi = pi;52this.expected = expected;5354if (pi != null) {55pi.updateProgress(0, expected);56}57}5859private final void justRead(long n) throws IOException {60if (n == -1) {6162/*63* don't close automatically when mark is set and is valid;64* cannot reset() after close()65*/66if (!isMarked()) {67close();68}69return;70}7172count += n;7374/**75* If read beyond the markLimit, invalidate the mark76*/77if (count - markedCount > markLimit) {78markLimit = -1;79}8081if (pi != null)82pi.updateProgress(count, expected);8384if (isMarked()) {85return;86}8788// if expected length is known, we could determine if89// read overrun.90if (expected > 0) {91if (count >= expected) {92close();93}94}95}9697/**98* Returns true if the mark is valid, false otherwise99*/100private boolean isMarked() {101102if (markLimit < 0) {103return false;104}105106// mark is set, but is not valid anymore107if (count - markedCount > markLimit) {108return false;109}110111// mark still holds112return true;113}114115public synchronized int read() throws java.io.IOException {116if (closed) {117return -1;118}119int c = in.read();120if (c != -1) {121justRead(1);122} else {123justRead(c);124}125return c;126}127128public synchronized int read(byte b[], int off, int len)129throws java.io.IOException {130if (closed) {131return -1;132}133int n = in.read(b, off, len);134justRead(n);135return n;136}137138public synchronized long skip(long n) throws IOException {139140// REMIND: what does skip do on EOF????141if (closed) {142return 0;143}144145if (in instanceof ChunkedInputStream) {146n = in.skip(n);147}148else {149// just skip min(n, num_bytes_left)150long min = (n > expected - count) ? expected - count: n;151n = in.skip(min);152}153justRead(n);154return n;155}156157public void close() throws IOException {158if (closed) {159return;160}161if (pi != null)162pi.finishTracking();163164closed = true;165in.close();166}167168public synchronized int available() throws IOException {169return closed ? 0: in.available();170}171172public synchronized void mark(int readLimit) {173if (closed) {174return;175}176super.mark(readLimit);177178/*179* mark the count to restore upon reset180*/181markedCount = count;182markLimit = readLimit;183}184185public synchronized void reset() throws IOException {186if (closed) {187return;188}189190if (!isMarked()) {191throw new IOException ("Resetting to an invalid mark");192}193194count = markedCount;195super.reset();196}197198public boolean markSupported() {199if (closed) {200return false;201}202return super.markSupported();203}204205protected void finalize() throws Throwable {206try {207close();208if (pi != null)209pi.close();210}211finally {212// Call super class213super.finalize();214}215}216}217218219