001package org.apache.commons.ssl.org.bouncycastle.asn1;
002
003import java.io.IOException;
004import java.io.OutputStream;
005
006public class BEROctetStringGenerator
007    extends BERGenerator
008{
009    public BEROctetStringGenerator(OutputStream out) 
010        throws IOException
011    {
012        super(out);
013        
014        writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
015    }
016
017    public BEROctetStringGenerator(
018        OutputStream out,
019        int tagNo,
020        boolean isExplicit) 
021        throws IOException
022    {
023        super(out, tagNo, isExplicit);
024        
025        writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
026    }
027    
028    public OutputStream getOctetOutputStream()
029    {
030        return getOctetOutputStream(new byte[1000]); // limit for CER encoding.
031    }
032
033    public OutputStream getOctetOutputStream(
034        byte[] buf)
035    {
036        return new BufferedBEROctetStream(buf);
037    }
038   
039    private class BufferedBEROctetStream
040        extends OutputStream
041    {
042        private byte[] _buf;
043        private int    _off;
044        private DEROutputStream _derOut;
045
046        BufferedBEROctetStream(
047            byte[] buf)
048        {
049            _buf = buf;
050            _off = 0;
051            _derOut = new DEROutputStream(_out);
052        }
053        
054        public void write(
055            int b)
056            throws IOException
057        {
058            _buf[_off++] = (byte)b;
059
060            if (_off == _buf.length)
061            {
062                DEROctetString.encode(_derOut, _buf);
063                _off = 0;
064            }
065        }
066
067        public void write(byte[] b, int off, int len) throws IOException
068        {
069            while (len > 0)
070            {
071                int numToCopy = Math.min(len, _buf.length - _off);
072                System.arraycopy(b, off, _buf, _off, numToCopy);
073
074                _off += numToCopy;
075                if (_off < _buf.length)
076                {
077                    break;
078                }
079
080                DEROctetString.encode(_derOut, _buf);
081                _off = 0;
082
083                off += numToCopy;
084                len -= numToCopy;
085            }
086        }
087
088        public void close() 
089            throws IOException
090        {
091            if (_off != 0)
092            {
093                byte[] bytes = new byte[_off];
094                System.arraycopy(_buf, 0, bytes, 0, _off);
095                
096                DEROctetString.encode(_derOut, bytes);
097            }
098            
099             writeBEREnd();
100        }
101    }
102}