1package org.bouncycastle.asn1;
2
3import java.io.IOException;
4
5/**
6 * DER TaggedObject - in ASN.1 notation this is any object preceded by
7 * a [n] where n is some number - these are assumed to follow the construction
8 * rules (as with sequences).
9 */
10public class DERTaggedObject
11    extends ASN1TaggedObject
12{
13    private static final byte[] ZERO_BYTES = new byte[0];
14
15    /**
16     * @param tagNo the tag number for this object.
17     * @param obj the tagged object.
18     */
19    public DERTaggedObject(
20        int             tagNo,
21        DEREncodable    obj)
22    {
23        super(tagNo, obj);
24    }
25
26    /**
27     * @param explicit true if an explicitly tagged object.
28     * @param tagNo the tag number for this object.
29     * @param obj the tagged object.
30     */
31    public DERTaggedObject(
32        boolean         explicit,
33        int             tagNo,
34        DEREncodable    obj)
35    {
36        super(explicit, tagNo, obj);
37    }
38
39    /**
40     * create an implicitly tagged object that contains a zero
41     * length sequence.
42     */
43    public DERTaggedObject(
44        int             tagNo)
45    {
46        super(false, tagNo, new DERSequence());
47    }
48
49    void encode(
50        DEROutputStream  out)
51        throws IOException
52    {
53        if (!empty)
54        {
55            byte[] bytes = obj.getDERObject().getEncoded(DER);
56
57            if (explicit)
58            {
59                out.writeEncoded(CONSTRUCTED | TAGGED, tagNo, bytes);
60            }
61            else
62            {
63                //
64                // need to mark constructed types...
65                //
66                int flags;
67                if ((bytes[0] & CONSTRUCTED) != 0)
68                {
69                    flags = CONSTRUCTED | TAGGED;
70                }
71                else
72                {
73                    flags = TAGGED;
74                }
75
76                out.writeTag(flags, tagNo);
77                out.write(bytes, 1, bytes.length - 1);
78            }
79        }
80        else
81        {
82            out.writeEncoded(CONSTRUCTED | TAGGED, tagNo, ZERO_BYTES);
83        }
84    }
85}
86