org.jboss.resteasy.client.jaxrs.engines.SelfExpandingBufferredInputStream Maven / Gradle / Ivy
package org.jboss.resteasy.client.jaxrs.engines;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.jboss.resteasy.resteasy_jaxrs.i18n.Messages;
/**
* Extension of {@link BufferedInputStream} enforcing the contract where reset()
* always returns to the beginning of the stream, and the internal buffer
* expands automatically to the total length of content read from the underlying
* stream.
*
* @author ul8b
*/
public class SelfExpandingBufferredInputStream extends BufferedInputStream
{
private static int defaultBufferSize = 8192;
public SelfExpandingBufferredInputStream(final InputStream in)
{
super(in);
super.mark(defaultBufferSize);
}
public SelfExpandingBufferredInputStream(final InputStream in, final int size)
{
super(in, size);
super.mark(size);
}
/**
* Not supported. Mark position is always zero.
*/
@Override
public synchronized void mark(int readlimit)
{
throw new UnsupportedOperationException(Messages.MESSAGES.alwaysMarkedAtIndex0());
}
@Override
public synchronized int read() throws IOException
{
if (pos == marklimit)
{
expand();
}
return super.read();
}
@Override
public synchronized int read(byte[] b, int off, int len) throws IOException
{
while (pos + len > marklimit)
{
expand();
}
return super.read(b, off, len);
}
@Override
public synchronized int read(byte[] b) throws IOException
{
while (pos + b.length > marklimit)
{
expand();
}
return super.read(b);
}
/**
* Double the current buffer size limit. Reset to zero, then double the
* buffer size and restore last position in the buffer.
*
* @throws IOException
*/
private void expand() throws IOException
{
int lastPos = pos;
super.reset();
super.mark((marklimit < (Integer.MAX_VALUE - 8) / 2) ? (marklimit * 2) : (Integer.MAX_VALUE - 8));
pos = lastPos;
}
/**
* Return the current maximum size of the internal buffer. This is
* independent of how much data is actually contained within the buffer.
* @return internal buffer size
*/
public int getBufSize()
{
return buf.length;
}
public int getCount()
{
return count;
}
public int getPos()
{
return pos;
}
public int getMarkLimit()
{
return marklimit;
}
public int getMarkPos()
{
return markpos;
}
}