/* ProgressInputStream.java * * created: Mon Sep 20 1999 * * This file is part of Artemis * * Copyright (C) 1999 Genome Research Limited * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/util/ProgressInputStream.java,v 1.1 2004-06-09 09:53:08 tjc Exp $ */ package uk.ac.sanger.artemis.util; import java.io.*; /** * This is a FileInputStream which has the readLine () and close () methods * overridden to show the progress in a Label component. * * @author Kim Rutherford * @version $Id: ProgressInputStream.java,v 1.1 2004-06-09 09:53:08 tjc Exp $ **/ public class ProgressInputStream extends FilterInputStream { /** * Creates an InputStream to read from the specified InputStream object and * show the progress in a Label as it goes. * @param input_stream the InputStream to be read from * @param listener InputStreamProgressEvent objects will be sent to this * listener as progress on reading is made. * @exception IOException if an I/O error occurs. **/ public ProgressInputStream (final InputStream input_stream, final InputStreamProgressListenerVector listeners) { super (input_stream); this.listeners = listeners; } /** * Reads up to b.length bytes of data from this input * stream into an array of bytes. This method blocks until some input * is available. * * @param b the buffer into which the data is read. * @return the total number of bytes read into the buffer, or * -1 if there is no more data because the end of * the file has been reached. * @exception IOException if an I/O error occurs. */ public int read(byte b[]) throws IOException { final int result = super.read (b); if (result > 0) { byte_count += b.length; maybeFireEvent (); } else { if (result == -1) { final InputStreamProgressEvent event = new InputStreamProgressEvent (InputStreamProgressEvent.EOF); fireEvent (event); } } return result; } /** * Reads up to len bytes of data from this input stream * into an array of bytes. This method blocks until some input is * available. * * @param b the buffer into which the data is read. * @param off the start offset of the data. * @param len the maximum number of bytes read. * @return the total number of bytes read into the buffer, or * -1 if there is no more data because the end of * the file has been reached. * @exception IOException if an I/O error occurs. */ public int read(byte b[], int off, int len) throws IOException { final int result = super.read (b, off, len); if (result > 0) { byte_count += b.length; maybeFireEvent (); } else { if (result == -1) { final InputStreamProgressEvent event = new InputStreamProgressEvent (InputStreamProgressEvent.EOF); fireEvent (event); } } return result; } /** * Close this file input stream and release any system resources associated * with the stream. * * @exception IOException if an I/O error occurs. **/ public void close () throws IOException { super.close (); final InputStreamProgressEvent event = new InputStreamProgressEvent (InputStreamProgressEvent.EOF); fireEvent (event); } /** * If we haven't sent a InputStreamProgressEvent to the listener recently, * then send one. **/ private void maybeFireEvent () { if (byte_count > 50000) { // do some rounding (we divide by 2 because chars are twice the size // of bytes) final int char_count = (byte_count / 10000) * 10000; if (last_count + 10000 < char_count) { fireEvent (new InputStreamProgressEvent (char_count)); last_count = char_count; } } } /** * Send the event to all the listeners. **/ private void fireEvent (final InputStreamProgressEvent event) { if (listeners != null) { for (int i = 0 ; i < listeners.size () ; ++i) { listeners.elementAt (i).progressMade (event); } } } /** * InputStreamProgressEvents are sent to these object. **/ private final InputStreamProgressListenerVector listeners; /** * The number of bytes that have been read so far. **/ private int byte_count = 0; /** * This is the char count that was sent to the listener last time. **/ private int last_count = 0; }