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