aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/core/src/main/java/org/spongycastle/util/io/BufferingOutputStream.java
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/spongycastle/core/src/main/java/org/spongycastle/util/io/BufferingOutputStream.java')
-rw-r--r--libraries/spongycastle/core/src/main/java/org/spongycastle/util/io/BufferingOutputStream.java108
1 files changed, 108 insertions, 0 deletions
diff --git a/libraries/spongycastle/core/src/main/java/org/spongycastle/util/io/BufferingOutputStream.java b/libraries/spongycastle/core/src/main/java/org/spongycastle/util/io/BufferingOutputStream.java
new file mode 100644
index 000000000..ae4abec41
--- /dev/null
+++ b/libraries/spongycastle/core/src/main/java/org/spongycastle/util/io/BufferingOutputStream.java
@@ -0,0 +1,108 @@
+package org.spongycastle.util.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.spongycastle.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();
+ }
+}