org.etlunit.io.ByteArrayOutputStreamInputStream Maven / Gradle / Ivy
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