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