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 Carlstromimport org.bouncycastle.util.io.Streams;
8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromclass DefiniteLengthInputStream
10c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        extends LimitedInputStream
11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom{
12c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final byte[] EMPTY_BYTES = new byte[0];
13c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
14c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private final int _originalLength;
15c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private int _remaining;
16c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
17c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    DefiniteLengthInputStream(
18c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        InputStream in,
19c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        int         length)
20c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
216e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        super(in, length);
22c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
23c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (length < 0)
24c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
25c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new IllegalArgumentException("negative lengths not allowed");
26c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
27c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
28c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        this._originalLength = length;
29c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        this._remaining = length;
30c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
31c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (length == 0)
32c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
33c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            setParentEofDetect(true);
34c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
35c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
36c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
37c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    int getRemaining()
38c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
39c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return _remaining;
40c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
41c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
42c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public int read()
43c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException
44c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
45c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (_remaining == 0)
46c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
47c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return -1;
48c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
49c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
50c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        int b = _in.read();
51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
52c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (b < 0)
53c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
54c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
55c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
57c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (--_remaining == 0)
58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
59c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            setParentEofDetect(true);
60c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
61c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return b;
63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public int read(byte[] buf, int off, int len)
66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException
67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (_remaining == 0)
69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return -1;
71c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        int toRead = Math.min(len, _remaining);
74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        int numRead = _in.read(buf, off, toRead);
75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (numRead < 0)
77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
78c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
80c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
81c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if ((_remaining -= numRead) == 0)
82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
83c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            setParentEofDetect(true);
84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
85c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
86c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return numRead;
87c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
89c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    byte[] toByteArray()
90c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException
91c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
92c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (_remaining == 0)
93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
94c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return EMPTY_BYTES;
95c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        byte[] bytes = new byte[_remaining];
98c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if ((_remaining -= Streams.readFully(_in, bytes)) != 0)
99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
102c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        setParentEofDetect(true);
103c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return bytes;
104c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
105c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom}
106