package org.jaudiotagger.audio.asf.io; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; /** * This implementation of {@link FilterInputStream} counts each read byte.<br> * So at each time, with {@link #getReadCount()} one can determine how many * bytes have been read, by this classes read and skip methods (mark and reset * are also taken into account).<br> * * @author Christian Laireiter */ class CountingInputStream extends FilterInputStream { /** * If {@link #mark(int)} has been called, the current value of * {@link #readCount} is stored, in order to reset it upon {@link #reset()}. */ private long markPos; /** * The amount of read or skipped bytes. */ private long readCount; /** * Creates an instance, which delegates the commands to the given stream. * * @param stream * stream to actually work with. */ public CountingInputStream(final InputStream stream) { super(stream); this.markPos = 0; this.readCount = 0; } /** * Counts the given amount of bytes. * * @param amountRead * number of bytes to increase. */ private synchronized void bytesRead(final long amountRead) { if (amountRead >= 0) { this.readCount += amountRead; } } /** * @return the readCount */ public synchronized long getReadCount() { return this.readCount; } /** * {@inheritDoc} */ @Override public synchronized void mark(final int readlimit) { super.mark(readlimit); this.markPos = this.readCount; } /** * {@inheritDoc} */ @Override public int read() throws IOException { final int result = super.read(); bytesRead(1); return result; } /** * {@inheritDoc} */ @Override public int read(final byte[] destination, final int off, final int len) throws IOException { final int result = super.read(destination, off, len); bytesRead(result); return result; } /** * {@inheritDoc} */ @Override public synchronized void reset() throws IOException { super.reset(); synchronized (this) { this.readCount = this.markPos; } } /** * {@inheritDoc} */ @Override public long skip(final long amount) throws IOException { final long skipped = super.skip(amount); bytesRead(skipped); return skipped; } }