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