001package org.apache.commons.ssl.asn1;
002
003import java.io.IOException;
004import java.io.InputStream;
005
006class 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}