blob: 9d5fe1423b13881adfb8ffe45a0eb7ab2298dea2 [file] [log] [blame]
package org.bouncycastle.util.io;
import java.io.IOException;
import java.io.OutputStream;
import org.bouncycastle.util.Arrays;
/**
* An output stream that buffers data to be feed into an encapsulated output stream.
* <p>
* The stream zeroes out the internal buffer on each flush.
* </p>
*/
public class BufferingOutputStream
extends OutputStream
{
private final OutputStream other;
private final byte[] buf;
private int bufOff;
/**
* Create a buffering stream with the default buffer size (4096).
*
* @param other output stream to be wrapped.
*/
public BufferingOutputStream(OutputStream other)
{
this.other = other;
this.buf = new byte[4096];
}
/**
* Create a buffering stream with a specified buffer size.
*
* @param other output stream to be wrapped.
* @param bufferSize size in bytes for internal buffer.
*/
public BufferingOutputStream(OutputStream other, int bufferSize)
{
this.other = other;
this.buf = new byte[bufferSize];
}
public void write(byte[] bytes, int offset, int len)
throws IOException
{
if (len < buf.length - bufOff)
{
System.arraycopy(bytes, offset, buf, bufOff, len);
bufOff += len;
}
else
{
int gap = buf.length - bufOff;
System.arraycopy(bytes, offset, buf, bufOff, gap);
bufOff += gap;
flush();
offset += gap;
len -= gap;
while (len >= buf.length)
{
other.write(bytes, offset, buf.length);
offset += buf.length;
len -= buf.length;
}
if (len > 0)
{
System.arraycopy(bytes, offset, buf, bufOff, len);
bufOff += len;
}
}
}
public void write(int b)
throws IOException
{
buf[bufOff++] = (byte)b;
if (bufOff == buf.length)
{
flush();
}
}
/**
* Flush the internal buffer to the encapsulated output stream. Zero the buffer contents when done.
*
* @throws IOException on error.
*/
public void flush()
throws IOException
{
other.write(buf, 0, bufOff);
bufOff = 0;
Arrays.fill(buf, (byte)0);
}
public void close()
throws IOException
{
flush();
other.close();
}
}