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

org.etlunit.io.ByteArrayOutputStreamInputStream Maven / Gradle / Ivy

There is a newer version: 1.6.9
Show newest version
package org.etlunit.io;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.Semaphore;

public class ByteArrayOutputStreamInputStream extends InputStream
{
	private final ClosableByteArrayOutputStream bout;
	private final Semaphore lock;

	private byte[] READ_ONE_BUFFER = new byte[1];

	private byte[] readBuffer = new byte[8192];
	private int beginOffset;
	private int endOffset;

	public ByteArrayOutputStreamInputStream(ClosableByteArrayOutputStream bout, Semaphore lock)
	{
		this.bout = bout;
		this.lock = lock;
	}

	@Override
	public int read() throws IOException
	{
		int len = read(READ_ONE_BUFFER);

		if (len == -1)
		{
			return len;
		}

		return READ_ONE_BUFFER[0] & 0xff;
	}

	@Override
	public int read(byte[] b) throws IOException
	{
		return read(b, 0, b.length);
	}

	@Override
	public int read(byte[] b, int off, int len) throws IOException
	{
		lock.acquireUninterruptibly();

		try
		{
			// load up the waiting buffer
			refill();

			// check if we are closed
			if (endOffset == beginOffset && bout.isClosed())
			{
				return -1;
			}

			int lengthAvail = Math.min(len, (endOffset - beginOffset));

			System.arraycopy(readBuffer, beginOffset, b, off, lengthAvail);

			beginOffset += lengthAvail;

			return lengthAvail;
		}
		finally
		{
			lock.release();
		}
	}

	private void refill()
	{
		if (bout.size() != 0)
		{
			byte[] lastReadBuffer = bout.toByteArray();
			bout.reset();

			if (endOffset == beginOffset && readBuffer.length >= lastReadBuffer.length)
			{
				// reset to zero
				beginOffset = 0;

				//copy over verbatim
				System.arraycopy(lastReadBuffer, 0, readBuffer, 0, lastReadBuffer.length);

				endOffset = lastReadBuffer.length;
			}
			else if ((readBuffer.length - endOffset) >= lastReadBuffer.length)
			{
				// append
				System.arraycopy(lastReadBuffer, 0, readBuffer, endOffset, lastReadBuffer.length);

				endOffset += lastReadBuffer.length;
			}
			else
			{
				// need to create a new array to hold the capacity and merge the contents over
				byte[]
						newReadBuffer =
						new byte[lastReadBuffer.length + (endOffset - beginOffset) + ((int) (readBuffer.length * 0.2d))];

				// copy old
				System.arraycopy(readBuffer, beginOffset, newReadBuffer, 0, (endOffset - beginOffset));
				System.arraycopy(lastReadBuffer, 0, newReadBuffer, (endOffset - beginOffset), lastReadBuffer.length);

				readBuffer = newReadBuffer;

				endOffset = lastReadBuffer.length + (endOffset - beginOffset);
				beginOffset = 0;
			}
		}
	}

	@Override
	public int available() throws IOException
	{
		lock.acquireUninterruptibly();

		try
		{
			return bout.size() + (endOffset - beginOffset);
		}
		finally
		{
			lock.release();
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy