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