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