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