package Tools;

import java.io.*;

/**
 * A class that nonintrusively records some section of an input stream
 * as it is read, so that it may be rewound and "reviewed" later. This
 * is less "invasive" than using a BufferedInputStream, which although
 * it can be rewound, will "oversuck" the underlying stream, so that
 * when you're done with the underlying stream, it's left in an
 * undetermined state.
 */
public class RecordingInputStream
	extends java.io.FilterInputStream {

	protected ByteArrayOutputStream recordingOutputStream = null;
	protected boolean recording = false;

	/**
	 * Start a new recording (clearing any previous recording).
	 */
	public void startRecording() {
		recording = true;
		recordingOutputStream = new ByteArrayOutputStream();
	}

	public void stopRecording() {
		recording = false;
	}

	public byte[] getRecordingAsBytes() {
		return recordingOutputStream.toByteArray();
	}

	public InputStream getRecordingAsStream() {
		return new ByteArrayInputStream(getRecordingAsBytes());
	}

	public RecordingInputStream(InputStream is) {
		super(is);
	}

	public int read()
		throws java.io.IOException {
		int rc = super.read();
		if (recording && rc>=0) {
			recordingOutputStream.write(rc);
		}
		return rc;
	}

	public int read(byte[] p0)
		throws java.io.IOException {
		return read(p0, 0, p0.length);
	}

	public int read(byte[] p0, int p1, int p2)
		throws java.io.IOException {
		int rc = super.read(p0, p1, p2);
		if (recording && rc>0) {
			recordingOutputStream.write(p0, p1, rc);
		}
		return rc;
	}

	/**
	 * Calling skip() while recording has an undefined impact on the
	 * recording. It might record the skipped bytes, or omit them from
	 * the recording, or make a recording of YMCA by the Village
	 * People.
	 */
	public long skip(long p0)
		throws java.io.IOException {
		// this method doesn't do anything; it's just here so the javadoc
		// will take. Sigh.
		return super.skip(p0);
	}

}
