1package org.bouncycastle.asn1;
2
3import java.io.IOException;
4import java.util.Enumeration;
5
6public class DERSequence
7    extends ASN1Sequence
8{
9    private int bodyLength = -1;
10
11    /**
12     * create an empty sequence
13     */
14    public DERSequence()
15    {
16    }
17
18    /**
19     * create a sequence containing one object
20     * @param obj the object to go in the sequence.
21     */
22    public DERSequence(
23        ASN1Encodable obj)
24    {
25        super(obj);
26    }
27
28    /**
29     * create a sequence containing a vector of objects.
30     * @param v the vector of objects to make up the sequence.
31     */
32    public DERSequence(
33        ASN1EncodableVector v)
34    {
35        super(v);
36    }
37
38    /**
39     * create a sequence containing an array of objects.
40     * @param array the array of objects to make up the sequence.
41     */
42    public DERSequence(
43        ASN1Encodable[]   array)
44    {
45        super(array);
46    }
47
48    private int getBodyLength()
49        throws IOException
50    {
51        if (bodyLength < 0)
52        {
53            int length = 0;
54
55            for (Enumeration e = this.getObjects(); e.hasMoreElements();)
56            {
57                Object    obj = e.nextElement();
58
59                length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength();
60            }
61
62            bodyLength = length;
63        }
64
65        return bodyLength;
66    }
67
68    int encodedLength()
69        throws IOException
70    {
71        int length = getBodyLength();
72
73        return 1 + StreamUtil.calculateBodyLength(length) + length;
74    }
75
76    /*
77     * A note on the implementation:
78     * <p>
79     * As DER requires the constructed, definite-length model to
80     * be used for structured types, this varies slightly from the
81     * ASN.1 descriptions given. Rather than just outputting SEQUENCE,
82     * we also have to specify CONSTRUCTED, and the objects length.
83     */
84    void encode(
85        ASN1OutputStream out)
86        throws IOException
87    {
88        ASN1OutputStream        dOut = out.getDERSubStream();
89        int                     length = getBodyLength();
90
91        out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
92        out.writeLength(length);
93
94        for (Enumeration e = this.getObjects(); e.hasMoreElements();)
95        {
96            Object    obj = e.nextElement();
97
98            dOut.writeObject((ASN1Encodable)obj);
99        }
100    }
101}
102