package org.bouncycastle.asn1;

import java.io.IOException;
import java.io.OutputStream;

/**
 * A generator for indefinite-length OCTET STRINGs
 */
public class BEROctetStringGenerator
    extends BERGenerator
{
    /**
     * Use the passed in stream as the target for the generator, writing out the header tag
     * for a constructed OCTET STRING.
     *
     * @param out target stream
     * @throws IOException if the target stream cannot be written to.
     */
    public BEROctetStringGenerator(OutputStream out) 
        throws IOException
    {
        super(out);
        
        writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
    }

    /**
     * Use the passed in stream as the target for the generator, writing out the header tag
     * for a tagged constructed OCTET STRING (possibly implicit).
     *
     * @param out target stream
     * @param tagNo the tag number to introduce
     * @param isExplicit true if this is an explicitly tagged object, false otherwise.
     * @throws IOException if the target stream cannot be written to.
     */
    public BEROctetStringGenerator(
        OutputStream out,
        int tagNo,
        boolean isExplicit) 
        throws IOException
    {
        super(out, tagNo, isExplicit);
        
        writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
    }

    /**
     * Return a stream representing the content target for this OCTET STRING
     *
     * @return an OutputStream which chunks data in blocks of 1000 (CER limit).
     */
    public OutputStream getOctetOutputStream()
    {
        return getOctetOutputStream(new byte[1000]); // limit for CER encoding.
    }

    /**
     * Return a stream representing the content target for this OCTET STRING
     *
     * @param buf the buffer to use for chunking the data.
     * @return an OutputStream which chunks data in blocks of buf length.
     */
    public OutputStream getOctetOutputStream(
        byte[] buf)
    {
        return new BufferedBEROctetStream(buf);
    }
   
    private class BufferedBEROctetStream
        extends OutputStream
    {
        private byte[] _buf;
        private int    _off;
        private DEROutputStream _derOut;

        BufferedBEROctetStream(
            byte[] buf)
        {
            _buf = buf;
            _off = 0;
            _derOut = new DEROutputStream(_out);
        }
        
        public void write(
            int b)
            throws IOException
        {
            _buf[_off++] = (byte)b;

            if (_off == _buf.length)
            {
                DEROctetString.encode(_derOut, _buf);
                _off = 0;
            }
        }

        public void write(byte[] b, int off, int len) throws IOException
        {
            while (len > 0)
            {
                int numToCopy = Math.min(len, _buf.length - _off);
                System.arraycopy(b, off, _buf, _off, numToCopy);

                _off += numToCopy;
                if (_off < _buf.length)
                {
                    break;
                }

                DEROctetString.encode(_derOut, _buf);
                _off = 0;

                off += numToCopy;
                len -= numToCopy;
            }
        }

        public void close() 
            throws IOException
        {
            if (_off != 0)
            {
                byte[] bytes = new byte[_off];
                System.arraycopy(_buf, 0, bytes, 0, _off);
                
                DEROctetString.encode(_derOut, bytes);
            }
            
             writeBEREnd();
        }
    }
}
