1c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrompackage org.bouncycastle.asn1;
2c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.IOException;
44c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.InputStream;
5c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
6c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromclass ConstructedOctetStream
7c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    extends InputStream
8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom{
9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private final ASN1StreamParser _parser;
10c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private boolean                _first = true;
12c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private InputStream            _currentStream;
13c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
14c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    ConstructedOctetStream(
15c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ASN1StreamParser parser)
16c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
17c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        _parser = parser;
18c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
19c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
20c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public int read(byte[] b, int off, int len) throws IOException
21c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
22c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (_currentStream == null)
23c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
24c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (!_first)
25c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
26c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return -1;
27c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
28c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
29c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
30c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
31c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (s == null)
32c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
33c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return -1;
34c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
35c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
36c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            _first = false;
37c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            _currentStream = s.getOctetStream();
38c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
39c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
40c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        int totalRead = 0;
41c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
42c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        for (;;)
43c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
44c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            int numRead = _currentStream.read(b, off + totalRead, len - totalRead);
45c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
46c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (numRead >= 0)
47c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
48c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                totalRead += numRead;
49c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
50c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (totalRead == len)
51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
52c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return totalRead;
53c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
54c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
55c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            else
56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
57c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                ASN1OctetStringParser aos = (ASN1OctetStringParser)_parser.readObject();
58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
59c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (aos == null)
60c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
61c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    _currentStream = null;
62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return totalRead < 1 ? -1 : totalRead;
63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                _currentStream = aos.getOctetStream();
66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public int read()
71c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException
72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (_currentStream == null)
74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (!_first)
76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return -1;
78c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
80c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
81c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (s == null)
83c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return -1;
85c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
86c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
87c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            _first = false;
88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            _currentStream = s.getOctetStream();
89c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
90c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
91c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        for (;;)
92c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            int b = _currentStream.read();
94c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
95c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (b >= 0)
96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return b;
98c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
102c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (s == null)
103c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
104c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                _currentStream = null;
105c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return -1;
106c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
107c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
108c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            _currentStream = s.getOctetStream();
109c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
110c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
111c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom}
112