/*
 * Written by Dawid Kurzyniec and released to the public domain, as explained
 * at http://creativecommons.org/licenses/publicdomain
 */

package edu.emory.mathcs.util.security.io;

import java.io.ByteArrayOutputStream;
import java.util.*;
import java.io.*;

/**
 * Variant of ByteArrayOutputStream that ensures that all data is cleared
 * from temporary arrays before they are unreferenced. Hence, this class can
 * be safely used to convert sensitive information into byte arrays, provided
 * that it is {@link #close closed} after use.
 *
 * @author Dawid Kurzyniec
 * @version 1.0
 */
public final class SecureByteArrayOutputStream extends ByteArrayOutputStream {

    public SecureByteArrayOutputStream() {
        super();
    }

    public SecureByteArrayOutputStream(int size) {
        super(size);
    }

    public synchronized void write(int b) {
        byte[] buf = this.buf;
        super.write(b);
        if (buf != this.buf) {
            Arrays.fill(buf, (byte)0);
        }
    }

    public synchronized void write(byte b[], int off, int len) {
        byte[] buf = this.buf;
        super.write(b, off, len);
        if (buf != this.buf) {
            Arrays.fill(buf, (byte)0);
        }
    }

    /**
     * Resets the <code>count</code> field of this byte array output
     * stream to zero and clears up the entire buffer with zeros, so that all
     * currently accumulated output in the
     * ouput stream is discarded. The output stream can be used again,
     * reusing the already allocated buffer space.
     *
     * @see     java.io.ByteArrayInputStream#count
     */
    public synchronized void reset() {
        count = 0;
        Arrays.fill(buf, (byte)0);
    }

    /**
     * Closing a <tt>SecureByteArrayOutputStream</tt> causes it to be {@link #reset},
     * that is, all data is discarded.
     * <p>
     *
     */
    public void close() throws IOException {
        reset();
    }

}