All Downloads are FREE. Search and download functionalities are using the official Maven repository.

panda.io.stream.NullInputStream Maven / Gradle / Ivy

Go to download

Panda Core is the core module of Panda Framework, it contains commonly used utility classes similar to apache-commons.

There is a newer version: 1.8.0
Show newest version
package panda.io.stream;

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;

/**
 * A functional, light weight {@link InputStream} that emulates a stream of a specified size.
 * 

* This implementation provides a light weight object for testing with an {@link InputStream} where * the contents don't matter. *

* One use case would be for testing the handling of large {@link InputStream} as it can emulate * that scenario without the overhead of actually processing large numbers of bytes - significantly * speeding up test execution times. *

* This implementation returns zero from the method that reads a byte and leaves the array unchanged * in the read methods that are passed a byte array. If alternative data is required the * processByte() and processBytes() methods can be implemented to generate * data, for example: * *

 * public class TestInputStream extends NullInputStream {
 * 	public TestInputStream(int size) {
 * 		super(size);
 * 	}
 * 
 * 	protected int processByte() {
 *          return ... // return required value here
 *      }
 * 
 * 	protected void processBytes(byte[] bytes, int offset, int length) {
 *          for (int i = offset; i < length; i++) {
 *              bytes[i] = ... // set array value here
 *          }
 *      }
 * }
 * 
 * 
*/ public class NullInputStream extends InputStream { private final long size; private long position; private long mark = -1; private long readlimit; private boolean eof; private final boolean throwEofException; private final boolean markSupported; /** * Create an {@link InputStream} that emulates a specified size which supports marking and does * not throw EOFException. * * @param size The size of the input stream to emulate. */ public NullInputStream(final long size) { this(size, true, false); } /** * Create an {@link InputStream} that emulates a specified size with option settings. * * @param size The size of the input stream to emulate. * @param markSupported Whether this instance will support the mark() * functionality. * @param throwEofException Whether this implementation will throw an {@link EOFException} or * return -1 when the end of file is reached. */ public NullInputStream(final long size, final boolean markSupported, final boolean throwEofException) { this.size = size; this.markSupported = markSupported; this.throwEofException = throwEofException; } /** * Return the current position. * * @return the current position. */ public long getPosition() { return position; } /** * Return the size this {@link InputStream} emulates. * * @return The size of the input stream to emulate. */ public long getSize() { return size; } /** * Return the number of bytes that can be read. * * @return The number of bytes that can be read. */ @Override public int available() { final long avail = size - position; if (avail <= 0) { return 0; } else if (avail > Integer.MAX_VALUE) { return Integer.MAX_VALUE; } else { return (int)avail; } } /** * Close this input stream - resets the internal state to the initial values. * * @throws IOException If an error occurs. */ @Override public void close() throws IOException { eof = false; position = 0; mark = -1; } /** * Mark the current position. * * @param readlimit The number of bytes before this marked position is invalid. * @throws UnsupportedOperationException if mark is not supported. */ @Override public synchronized void mark(final int readlimit) { if (!markSupported) { throw new UnsupportedOperationException("Mark not supported"); } mark = position; this.readlimit = readlimit; } /** * Indicates whether mark is supported. * * @return Whether mark is supported or not. */ @Override public boolean markSupported() { return markSupported; } /** * Read a byte. * * @return Either The byte value returned by processByte() or -1 if * the end of file has been reached and throwEofException is set to * {@code false}. * @throws EOFException if the end of file is reached and throwEofException is set * to {@code true}. * @throws IOException if trying to read past the end of file. */ @Override public int read() throws IOException { if (eof) { throw new IOException("Read after end of file"); } if (position == size) { return doEndOfFile(); } position++; return processByte(); } /** * Read some bytes into the specified array. * * @param bytes The byte array to read into * @return The number of bytes read or -1 if the end of file has been reached and * throwEofException is set to {@code false}. * @throws EOFException if the end of file is reached and throwEofException is set * to {@code true}. * @throws IOException if trying to read past the end of file. */ @Override public int read(final byte[] bytes) throws IOException { return read(bytes, 0, bytes.length); } /** * Read the specified number bytes into an array. * * @param bytes The byte array to read into. * @param offset The offset to start reading bytes into. * @param length The number of bytes to read. * @return The number of bytes read or -1 if the end of file has been reached and * throwEofException is set to {@code false}. * @throws EOFException if the end of file is reached and throwEofException is set * to {@code true}. * @throws IOException if trying to read past the end of file. */ @Override public int read(final byte[] bytes, final int offset, final int length) throws IOException { if (eof) { throw new IOException("Read after end of file"); } if (position == size) { return doEndOfFile(); } position += length; int returnLength = length; if (position > size) { returnLength = length - (int)(position - size); position = size; } processBytes(bytes, offset, returnLength); return returnLength; } /** * Reset the stream to the point when mark was last called. * * @throws UnsupportedOperationException if mark is not supported. * @throws IOException If no position has been marked or the read limit has been exceed since * the last position was marked. */ @Override public synchronized void reset() throws IOException { if (!markSupported) { throw new UnsupportedOperationException("Mark not supported"); } if (mark < 0) { throw new IOException("No position has been marked"); } if (position > mark + readlimit) { throw new IOException("Marked position [" + mark + "] is no longer valid - passed the read limit [" + readlimit + "]"); } position = mark; eof = false; } /** * Skip a specified number of bytes. * * @param numberOfBytes The number of bytes to skip. * @return The number of bytes skipped or -1 if the end of file has been reached * and throwEofException is set to {@code false}. * @throws EOFException if the end of file is reached and throwEofException is set * to {@code true}. * @throws IOException if trying to read past the end of file. */ @Override public long skip(final long numberOfBytes) throws IOException { if (eof) { throw new IOException("Skip after end of file"); } if (position == size) { return doEndOfFile(); } position += numberOfBytes; long returnLength = numberOfBytes; if (position > size) { returnLength = numberOfBytes - (position - size); position = size; } return returnLength; } /** * Return a byte value for the read() method. *

* This implementation returns zero. * * @return This implementation always returns zero. */ protected int processByte() { // do nothing - overridable by subclass return 0; } /** * Process the bytes for the read(byte[], offset, length) method. *

* This implementation leaves the byte array unchanged. * * @param bytes The byte array * @param offset The offset to start at. * @param length The number of bytes. */ protected void processBytes(final byte[] bytes, final int offset, final int length) { // do nothing - overridable by subclass } /** * Handle End of File. * * @return -1 if throwEofException is set to {@code false} * @throws EOFException if throwEofException is set to {@code true}. */ private int doEndOfFile() throws EOFException { eof = true; if (throwEofException) { throw new EOFException(); } return -1; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy