// package net.sf.zipme; import java.io.IOException; import java.io.InputStream; /** * InputStream that computes a checksum of the data being read using a * supplied Checksum object. * @see Checksum * @author Tom Tromey * @date May 17, 1999 */ public class CheckedInputStream extends InputStream { /** * This is the subordinate <code>InputStream</code> to which method calls * are redirected */ protected InputStream in; /** * Creates a new CheckInputStream on top of the supplied OutputStream * using the supplied Checksum. */ public CheckedInputStream( InputStream in, Checksum sum){ this.in=in; this.sum=sum; } /** * Returns the Checksum object used. To get the data checksum computed so * far call <code>getChecksum.getValue()</code>. */ public Checksum getChecksum(){ return sum; } /** * Reads one byte, updates the checksum and returns the read byte * (or -1 when the end of file was reached). */ public int read() throws IOException { int x=in.read(); if (x != -1) sum.update(x); return x; } /** * Calls the <code>read(byte[], int, int)</code> overloaded method. * Note that * this method does not redirect its call directly to a corresponding * method in <code>in</code>. This allows subclasses to override only the * three argument version of <code>read</code>. * @param buf The buffer to read bytes into * @return The value retured from <code>in.read(byte[], int, int)</code> * @exception IOException If an error occurs */ public int read( byte[] buf) throws IOException { return read(buf,0,buf.length); } /** * Reads at most len bytes in the supplied buffer and updates the checksum * with it. Returns the number of bytes actually read or -1 when the end * of file was reached. */ public int read( byte[] buf, int off, int len) throws IOException { int r=in.read(buf,off,len); if (r != -1) sum.update(buf,off,r); return r; } /** * Skips n bytes by reading them in a temporary buffer and updating the * the checksum with that buffer. Returns the actual number of bytes skiped * which can be less then requested when the end of file is reached. */ public long skip( long n) throws IOException { if (n == 0) return 0; int min=(int)Math.min(n,1024); byte[] buf=new byte[min]; long s=0; while (n > 0) { int r=in.read(buf,0,min); if (r == -1) break; n-=r; s+=r; min=(int)Math.min(n,1024); sum.update(buf,0,r); } return s; } /** * Calls the <code>in.mark(int)</code> method. * @param readlimit The parameter passed to <code>in.mark(int)</code> */ public void mark( int readlimit){ in.mark(readlimit); } /** * Calls the <code>in.markSupported()</code> method. * @return <code>true</code> if mark/reset is supported, <code>false</code> * otherwise */ public boolean markSupported(){ return in.markSupported(); } /** * Calls the <code>in.reset()</code> method. * @exception IOException If an error occurs */ public void reset() throws IOException { in.reset(); } /** * Calls the <code>in.available()</code> method. * @return The value returned from <code>in.available()</code> * @exception IOException If an error occurs */ public int available() throws IOException { return in.available(); } /** * This method closes the input stream by closing the input stream that * this object is filtering. Future attempts to access this stream may * throw an exception. * @exception IOException If an error occurs */ public void close() throws IOException { in.close(); } /** * The checksum object. */ private Checksum sum; }