001package org.apache.commons.ssl.asn1;
002
003import java.io.IOException;
004import java.io.InputStream;
005
006class IndefiniteLengthInputStream
007    extends LimitedInputStream {
008    private int _b1;
009    private int _b2;
010    private boolean _eofReached = false;
011    private boolean _eofOn00 = true;
012
013    IndefiniteLengthInputStream(
014        InputStream in)
015        throws IOException {
016        super(in);
017
018        _b1 = in.read();
019        _b2 = in.read();
020        _eofReached = (_b2 < 0);
021    }
022
023    void setEofOn00(
024        boolean eofOn00) {
025        _eofOn00 = eofOn00;
026    }
027
028    boolean checkForEof() {
029        if (_eofOn00 && (_b1 == 0x00 && _b2 == 0x00)) {
030            _eofReached = true;
031            setParentEofDetect(true);
032        }
033        return _eofReached;
034    }
035
036    public int read(byte[] b, int off, int len)
037        throws IOException {
038        // Only use this optimisation if we aren't checking for 00
039        if (_eofOn00 || len < 3) {
040            return super.read(b, off, len);
041        }
042
043        if (_eofReached) {
044            return -1;
045        }
046
047        int numRead = _in.read(b, off + 2, len - 2);
048
049        if (numRead < 0) {
050//          throw new EOFException();
051            _eofReached = true;
052            return -1;
053        }
054
055        b[off] = (byte) _b1;
056        b[off + 1] = (byte) _b2;
057
058        _b1 = _in.read();
059        _b2 = _in.read();
060
061        if (_b2 < 0) {
062            // Corrupted stream
063//            throw new EOFException();
064            _eofReached = true;
065            // Just fall thru...
066        }
067
068        return numRead + 2;
069    }
070
071    public int read()
072        throws IOException {
073        if (checkForEof()) {
074            return -1;
075        }
076
077        int b = _in.read();
078
079        //
080        // strictly speaking we should return b1 and b2, but if this happens the stream
081        // is corrupted so we are already in trouble.
082        //
083        if (b < 0) {
084            // Corrupted stream
085//            throw new EOFException();
086            _eofReached = true;
087
088            return -1;
089        }
090
091        int v = _b1;
092
093        _b1 = _b2;
094        _b2 = b;
095
096        return v;
097    }
098}