    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}