1package org.bouncycastle.asn1;
2
3import java.io.IOException;
4import java.util.Enumeration;
5
6/**
7 * BER TaggedObject - in ASN.1 nottation this is any object proceeded by
8 * a [n] where n is some number - these are assume 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.write(CONSTRUCTED | TAGGED | tagNo);
55            out.write(0x80);
56
57            if (!empty)
58            {
59                if (!explicit)
60                {
61                    if (obj instanceof ASN1OctetString)
62                    {
63                        Enumeration  e;
64
65                        if (obj instanceof BERConstructedOctetString)
66                        {
67                            e = ((BERConstructedOctetString)obj).getObjects();
68                        }
69                        else
70                        {
71                            ASN1OctetString             octs = (ASN1OctetString)obj;
72                            BERConstructedOctetString   berO = new BERConstructedOctetString(octs.getOctets());
73
74                            e = berO.getObjects();
75                        }
76
77                        while (e.hasMoreElements())
78                        {
79                            out.writeObject(e.nextElement());
80                        }
81                    }
82                    else if (obj instanceof ASN1Sequence)
83                    {
84                        Enumeration  e = ((ASN1Sequence)obj).getObjects();
85
86                        while (e.hasMoreElements())
87                        {
88                            out.writeObject(e.nextElement());
89                        }
90                    }
91                    else if (obj instanceof ASN1Set)
92                    {
93                        Enumeration  e = ((ASN1Set)obj).getObjects();
94
95                        while (e.hasMoreElements())
96                        {
97                            out.writeObject(e.nextElement());
98                        }
99                    }
100                    else
101                    {
102                        throw new RuntimeException("not implemented: " + obj.getClass().getName());
103                    }
104                }
105                else
106                {
107                    out.writeObject(obj);
108                }
109            }
110
111            out.write(0x00);
112            out.write(0x00);
113        }
114        else
115        {
116            super.encode(out);
117        }
118    }
119}
120