1c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrompackage org.bouncycastle.asn1;
2c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.EOFException;
4c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.IOException;
5c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.InputStream;
6c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
7c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromclass IndefiniteLengthInputStream
8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    extends LimitedInputStream
9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom{
10c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private int _b1;
11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private int _b2;
12c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private boolean _eofReached = false;
13c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private boolean _eofOn00 = true;
14c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
15c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    IndefiniteLengthInputStream(
166e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        InputStream in,
176e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        int         limit)
18c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException
19c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
206e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        super(in, limit);
21c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
22c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        _b1 = in.read();
23c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        _b2 = in.read();
24c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
25c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (_b2 < 0)
26c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
27c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            // Corrupted stream
28c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new EOFException();
29c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
30c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
31c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        checkForEof();
32c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
33c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
34c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    void setEofOn00(
35c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        boolean eofOn00)
36c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
37c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        _eofOn00 = eofOn00;
38c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        checkForEof();
39c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
40c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
41c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private boolean checkForEof()
42c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
43c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (!_eofReached && _eofOn00 && (_b1 == 0x00 && _b2 == 0x00))
44c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
45c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            _eofReached = true;
46c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            setParentEofDetect(true);
47c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
48c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return _eofReached;
49c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
50c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public int read(byte[] b, int off, int len)
52c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException
53c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
54c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        // Only use this optimisation if we aren't checking for 00
55c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (_eofOn00 || len < 3)
56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
57c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return super.read(b, off, len);
58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
59c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
60c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (_eofReached)
61c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return -1;
63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        int numRead = _in.read(b, off + 2, len - 2);
66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (numRead < 0)
68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            // Corrupted stream
70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new EOFException();
71c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        b[off] = (byte)_b1;
74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        b[off + 1] = (byte)_b2;
75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        _b1 = _in.read();
77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        _b2 = _in.read();
78c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (_b2 < 0)
80c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
81c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            // Corrupted stream
82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new EOFException();
83c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
85c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return numRead + 2;
86c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
87c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public int read()
89c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException
90c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
91c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (checkForEof())
92c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return -1;
94c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
95c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        int b = _in.read();
97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
98c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (b < 0)
99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            // Corrupted stream
101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new EOFException();
102c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
103c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
104c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        int v = _b1;
105c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
106c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        _b1 = _b2;
107c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        _b2 = b;
108c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
109c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return v;
110c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
111c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom}
112