1package org.bouncycastle.asn1;
2
3import java.io.IOException;
4import java.io.InputStream;
5import java.io.OutputStream;
6
7public class BERGenerator
8    extends ASN1Generator
9{
10    private boolean      _tagged = false;
11    private boolean      _isExplicit;
12    private int          _tagNo;
13
14    protected BERGenerator(
15        OutputStream out)
16    {
17        super(out);
18    }
19
20    public BERGenerator(
21        OutputStream out,
22        int tagNo,
23        boolean isExplicit)
24    {
25        super(out);
26
27        _tagged = true;
28        _isExplicit = isExplicit;
29        _tagNo = tagNo;
30    }
31
32    public OutputStream getRawOutputStream()
33    {
34        return _out;
35    }
36
37    private void writeHdr(
38        int tag)
39        throws IOException
40    {
41        _out.write(tag);
42        _out.write(0x80);
43    }
44
45    protected void writeBERHeader(
46        int tag)
47        throws IOException
48    {
49        if (_tagged)
50        {
51            int tagNum = _tagNo | BERTags.TAGGED;
52
53            if (_isExplicit)
54            {
55                writeHdr(tagNum | BERTags.CONSTRUCTED);
56                writeHdr(tag);
57            }
58            else
59            {
60                if ((tag & BERTags.CONSTRUCTED) != 0)
61                {
62                    writeHdr(tagNum | BERTags.CONSTRUCTED);
63                }
64                else
65                {
66                    writeHdr(tagNum);
67                }
68            }
69        }
70        else
71        {
72            writeHdr(tag);
73        }
74    }
75
76    protected void writeBERBody(
77        InputStream contentStream)
78        throws IOException
79    {
80        int ch;
81
82        while ((ch = contentStream.read()) >= 0)
83        {
84            _out.write(ch);
85        }
86    }
87
88    protected void writeBEREnd()
89        throws IOException
90    {
91        _out.write(0x00);
92        _out.write(0x00);
93
94        if (_tagged && _isExplicit)  // write extra end for tag header
95        {
96            _out.write(0x00);
97            _out.write(0x00);
98        }
99    }
100}
101