Milán Major

netscape-revival

1 branch
Code

sun-java/classsrc/sun/net/www/MeteredStream.java

/*
 * @(#)MeteredStream.java	1.13 95/02/07 Chris Warth
 *
 * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and without
 * fee is hereby granted provided that this copyright notice
 * appears in all copies. Please refer to the file "copyright.html"
 * for further important copyright and licensing information.
 *
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */

package sun.net.www;

import java.net.URL;
import java.util.*;
import java.io.*;
import sun.net.ProgressData;

public 
class MeteredStream extends FilterInputStream 
{
    // Class variables.
    private static int	total_need;	
    private static int	total_read;	
    private static int	total_connections = 0;

    // Instance variables.
    int expected;
    int	count = 0;
    public URL url = null;
   
    private synchronized static void globalJustRead(int n) {
	total_read += n;
    }

    private synchronized static void updateExpected(int est) {
	total_need += est;
    }

    private synchronized static void addConnection(MeteredStream s) {
	total_connections += 1;
    }

    private synchronized static void removeConnection(MeteredStream s) {
	total_connections -= 1;
	total_read -= s.expected;
	total_need -= s.expected;
    }

    /*
     * Provide read-only access the static variables of interest to
     * observers.  It is expected that these methods are accessed
     * with the static monitor locked.  This is usually the case
     * because the notification to observers happens through the
     * synchronized method checkUpdate().
     */
    public static synchronized 
    ProgressReport checkProgress(ProgressReport pr) {
	return pr.set(total_read, total_need, total_connections);
    }

    public MeteredStream(InputStream is, int estimate, URL u) {
	this(is, estimate);
	this.url = u;
    }

    public MeteredStream(InputStream is, int estimate) {
	super(is);
	updateExpected(estimate);
	expected = estimate;
	addConnection(this);
    }

    private final void justRead(int n) {
	if (count + n > expected) {
	    n = expected - count;
	}
	count += n;
	globalJustRead(n);
	ProgressData.pdata.update(url, count, expected);
    }


    public int read() throws java.io.IOException {
	int c = super.read();
	if (c != -1) {
	    justRead(1);
	}
	return c;
    }

    /*
    public int read(byte b[]) 
	This routine is implemented in terms of read(byte b[], int off, int len)
	so we don't need to override it here.
    */

    public int read(byte b[], int off, int len) throws java.io.IOException {
	int n = super.read(b, off, len);
	if (n != -1) {
	    justRead(n);
	}
	return n;
    }
    
    public long skip(long n) throws IOException {
	n = super.skip(n);
	if (n != -1) {
	    justRead((int)n);
	}
	return n;
    }

    boolean closed = false;

    public void close() throws IOException {
	super.close();
	if (!closed) {
	    closed = true;
	    justRead(expected - count);
	    removeConnection(this);
	}
	ProgressData.pdata.unregister(url);
    }

    protected void finalize() {
	if (!closed) {
	    closed = true;
	    justRead(expected - count);
	    removeConnection(this);
	}
	ProgressData.pdata.unregister(url);
    }
}