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