1package org.bouncycastle.asn1;
2
3import java.io.IOException;
4import java.util.Enumeration;
5
6/**
7 * BER TaggedObject - in ASN.1 notation this is any object preceded by
8 * a [n] where n is some number - these are assumed to follow the construction
9 * rules (as with sequences).
10 */
11public class BERTaggedObject
12    extends DERTaggedObject
13{
14    /**
15     * @param tagNo the tag number for this object.
16     * @param obj the tagged object.
17     */
18    public BERTaggedObject(
19        int             tagNo,
20        DEREncodable    obj)
21    {
22        super(tagNo, obj);
23    }
24
25    /**
26     * @param explicit true if an explicitly tagged object.
27     * @param tagNo the tag number for this object.
28     * @param obj the tagged object.
29     */
30    public BERTaggedObject(
31        boolean         explicit,
32        int             tagNo,
33        DEREncodable    obj)
34    {
35        super(explicit, tagNo, obj);
36    }
37
38    /**
39     * create an implicitly tagged object that contains a zero
40     * length sequence.
41     */
42    public BERTaggedObject(
43        int             tagNo)
44    {
45        super(false, tagNo, new BERSequence());
46    }
47
48    void encode(
49        DEROutputStream  out)
50        throws IOException
51    {
52        if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
53        {
54            out.writeTag(CONSTRUCTED | TAGGED, tagNo);
55            out.write(0x80);
56
57            if (!empty)
58            {
59                if (!explicit)
60                {
61                    Enumeration e;
62                    if (obj instanceof ASN1OctetString)
63                    {
64                        if (obj instanceof BERConstructedOctetString)
65                        {
66                            e = ((BERConstructedOctetString)obj).getObjects();
67                        }
68                        else
69                        {
70                            ASN1OctetString             octs = (ASN1OctetString)obj;
71                            BERConstructedOctetString   berO = new BERConstructedOctetString(octs.getOctets());
72                            e = berO.getObjects();
73                        }
74                    }
75                    else if (obj instanceof ASN1Sequence)
76                    {
77                        e = ((ASN1Sequence)obj).getObjects();
78                    }
79                    else if (obj instanceof ASN1Set)
80                    {
81                        e = ((ASN1Set)obj).getObjects();
82                    }
83                    else
84                    {
85                        throw new RuntimeException("not implemented: " + obj.getClass().getName());
86                    }
87
88                    while (e.hasMoreElements())
89                    {
90                        out.writeObject(e.nextElement());
91                    }
92                }
93                else
94                {
95                    out.writeObject(obj);
96                }
97            }
98
99            out.write(0x00);
100            out.write(0x00);
101        }
102        else
103        {
104            super.encode(out);
105        }
106    }
107}
108