FileDocCategorySizeDatePackage
CountingInputStream.javaAPI DocJaudiotagger 2.0.42729Wed Mar 30 16:11:50 BST 2011org.jaudiotagger.audio.asf.io

CountingInputStream.java

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;
    }

}