001    package org.apache.commons.ssl.asn1;
002    
003    import java.io.IOException;
004    import java.io.InputStream;
005    
006    class ConstructedOctetStream
007        extends InputStream {
008        private final ASN1ObjectParser _parser;
009    
010        private boolean _first = true;
011        private InputStream _currentStream;
012    
013        ConstructedOctetStream(
014            ASN1ObjectParser parser) {
015            _parser = parser;
016        }
017    
018        public int read(byte[] b, int off, int len) throws IOException {
019            if (_currentStream == null) {
020                if (!_first) {
021                    return -1;
022                }
023    
024                ASN1OctetStringParser s = (ASN1OctetStringParser) _parser.readObject();
025    
026                if (s == null) {
027                    return -1;
028                }
029    
030                _first = false;
031                _currentStream = s.getOctetStream();
032            }
033    
034            int totalRead = 0;
035    
036            for (; ;) {
037                int numRead = _currentStream.read(b, off + totalRead, len - totalRead);
038    
039                if (numRead >= 0) {
040                    totalRead += numRead;
041    
042                    if (totalRead == len) {
043                        return totalRead;
044                    }
045                } else {
046                    ASN1OctetStringParser aos = (ASN1OctetStringParser) _parser.readObject();
047    
048                    if (aos == null) {
049                        _currentStream = null;
050                        return totalRead < 1 ? -1 : totalRead;
051                    }
052    
053                    _currentStream = aos.getOctetStream();
054                }
055            }
056        }
057    
058        public int read()
059            throws IOException {
060            if (_currentStream == null) {
061                if (!_first) {
062                    return -1;
063                }
064    
065                ASN1OctetStringParser s = (ASN1OctetStringParser) _parser.readObject();
066    
067                if (s == null) {
068                    return -1;
069                }
070    
071                _first = false;
072                _currentStream = s.getOctetStream();
073            }
074    
075            for (; ;) {
076                int b = _currentStream.read();
077    
078                if (b >= 0) {
079                    return b;
080                }
081    
082                ASN1OctetStringParser s = (ASN1OctetStringParser) _parser.readObject();
083    
084                if (s == null) {
085                    _currentStream = null;
086                    return -1;
087                }
088    
089                _currentStream = s.getOctetStream();
090            }
091        }
092    }