1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.ByteArrayOutputStream;
4c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.IOException;
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Enumeration;
6db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstromimport java.util.Vector;
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamabstract public class ASN1Set
94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    extends ASN1Primitive
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private Vector set = new Vector();
124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private boolean isSorted = false;
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return an ASN1Set from the given object.
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the object we want converted.
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if the object cannot be converted.
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static ASN1Set getInstance(
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object  obj)
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj == null || obj instanceof ASN1Set)
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (ASN1Set)obj;
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (obj instanceof ASN1SetParser)
284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return ASN1Set.getInstance(((ASN1SetParser)obj).toASN1Primitive());
304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (obj instanceof byte[])
324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            try
344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                return ASN1Set.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            catch (IOException e)
384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                throw new IllegalArgumentException("failed to construct set from byte[]: " + e.getMessage());
404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (obj instanceof ASN1Encodable)
434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (primitive instanceof ASN1Set)
474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                return (ASN1Set)primitive;
494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
52c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Return an ASN1 set from a tagged object. There is a special
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * case here, if an object appears to have been explicitly tagged on
58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * reading but we were expecting it to be implicitly tagged in the
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * normal course of events it indicates that we lost the surrounding
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * set - so we need to add it back (this will happen if the tagged
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * object is a sequence that contains other sequences). If you are
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * dealing with implicitly tagged sets you really <b>should</b>
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * be using this method.
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the tagged object.
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param explicit true if the object is meant to be explicitly tagged
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *          false otherwise.
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if the tagged object cannot
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *          be converted.
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static ASN1Set getInstance(
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject    obj,
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean             explicit)
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (explicit)
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (!obj.isExplicit())
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                throw new IllegalArgumentException("object implicit - explicit expected.");
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (ASN1Set)obj.getObject();
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            //
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // constructed object which appears to be explicitly tagged
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // and it's really implicit means we have to add the
894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            // surrounding set.
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            //
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (obj.isExplicit())
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                if (obj instanceof BERTaggedObject)
944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    return new BERSet(obj.getObject());
964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                else
984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    return new DLSet(obj.getObject());
1004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (obj.getObject() instanceof ASN1Set)
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    return (ASN1Set)obj.getObject();
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                //
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                // in this case the parser returns a sequence, convert it
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                // into a set.
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                //
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (obj.getObject() instanceof ASN1Sequence)
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    ASN1Sequence s = (ASN1Sequence)obj.getObject();
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    if (obj instanceof BERTaggedObject)
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    {
1194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        return new BERSet(s.toArray());
1204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    }
1214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    else
1224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    {
1234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        return new DLSet(s.toArray());
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    }
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
129c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
1324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected ASN1Set()
1334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * create a sequence containing one object
1384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected ASN1Set(
1404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable obj)
1414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        set.addElement(obj);
1434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * create a sequence containing a vector of objects.
1474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected ASN1Set(
1494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1EncodableVector v,
1504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        boolean                  doSort)
1514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        for (int i = 0; i != v.size(); i++)
1534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            set.addElement(v.get(i));
1554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (doSort)
1584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.sort();
1604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * create a sequence containing a vector of objects.
1654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected ASN1Set(
1674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable[]   array,
1684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        boolean doSort)
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
1704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        for (int i = 0; i != array.length; i++)
1714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            set.addElement(array[i]);
1734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (doSort)
1764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.sort();
1784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
181db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public Enumeration getObjects()
182db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
183db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return set.elements();
184db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
185db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
186db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    /**
187db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * return the object at the set position indicated by index.
188db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     *
189db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * @param index the set number (starting at zero) of the object
190db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * @return the object at the set position indicated by index.
191db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     */
1924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Encodable getObjectAt(
193db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        int index)
194db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
1954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return (ASN1Encodable)set.elementAt(index);
196db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
197db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
198db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    /**
199db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * return the number of objects in this set.
200db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     *
201db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * @return the number of objects in this set.
202db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     */
203db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public int size()
204db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
205db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return set.size();
206db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
2086e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    public ASN1Encodable[] toArray()
2096e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    {
2106e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        ASN1Encodable[] values = new ASN1Encodable[this.size()];
2116e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2126e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        for (int i = 0; i != this.size(); i++)
2136e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        {
2144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            values[i] = this.getObjectAt(i);
2156e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        }
2166e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2176e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        return values;
2186e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    }
2196e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
220c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public ASN1SetParser parser()
221b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
222c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        final ASN1Set outer = this;
223c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
224c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return new ASN1SetParser()
225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
226c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            private final int max = size();
227b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
228c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            private int index;
229c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
2304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            public ASN1Encodable readObject() throws IOException
231c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
232c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (index == max)
233c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
234c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return null;
235c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
236c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
2374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ASN1Encodable obj = getObjectAt(index++);
238c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (obj instanceof ASN1Sequence)
239c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
240c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return ((ASN1Sequence)obj).parser();
241c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
242c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (obj instanceof ASN1Set)
243c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
244c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return ((ASN1Set)obj).parser();
245c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
246c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
247c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return obj;
248c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
249c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
2504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            public ASN1Primitive getLoadedObject()
2516e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            {
2526e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                return outer;
2536e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            }
2546e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            public ASN1Primitive toASN1Primitive()
256c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
257c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return outer;
258c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
259c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        };
260c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
261c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
262db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public int hashCode()
263db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
264db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        Enumeration             e = this.getObjects();
265db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        int                     hashCode = size();
266db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
267db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        while (e.hasMoreElements())
268db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        {
269db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            Object o = getNext(e);
270db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            hashCode *= 17;
271db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
272db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            hashCode ^= o.hashCode();
273db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        }
274db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
275db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return hashCode;
276db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
277c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
2784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    ASN1Primitive toDERObject()
2794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
2804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (isSorted)
2814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Set derSet = new DERSet();
2834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            derSet.set = this.set;
2854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return derSet;
2874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else
2894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            Vector v = new Vector();
2914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            for (int i = 0; i != set.size(); i++)
2934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
2944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                v.addElement(set.elementAt(i));
2954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
2964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Set derSet = new DERSet();
2984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            derSet.set = v;
3004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            derSet.sort();
3024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return derSet;
3044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    ASN1Primitive toDLObject()
3084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Set derSet = new DLSet();
3104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        derSet.set = this.set;
3124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return derSet;
3144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
316c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    boolean asn1Equals(
3174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Primitive o)
318c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
319c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (!(o instanceof ASN1Set))
320b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
321b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
322b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
323b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
324c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ASN1Set   other = (ASN1Set)o;
325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (this.size() != other.size())
327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
328b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
330b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Enumeration s1 = this.getObjects();
332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Enumeration s2 = other.getObjects();
333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        while (s1.hasMoreElements())
335b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
3364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Encodable obj1 = getNext(s1);
3374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Encodable obj2 = getNext(s2);
3386e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
3394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Primitive o1 = obj1.toASN1Primitive();
3404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Primitive o2 = obj2.toASN1Primitive();
341c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
3426e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            if (o1 == o2 || o1.equals(o2))
343b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
344c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                continue;
345b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
346c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
347c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return false;
348b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
350b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return true;
351b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private ASN1Encodable getNext(Enumeration e)
3546e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    {
3554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
3566e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
3576e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        // unfortunately null was allowed as a substitute for DER null
3586e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        if (encObj == null)
3596e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        {
3606e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            return DERNull.INSTANCE;
3616e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        }
3626e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
3636e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        return encObj;
3646e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    }
3656e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
366db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    /**
367db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * return true if a <= b (arrays are assumed padded with zeros).
368db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     */
369db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    private boolean lessThanOrEqual(
370db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom         byte[] a,
371db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom         byte[] b)
372db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
373db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        int len = Math.min(a.length, b.length);
374db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        for (int i = 0; i != len; ++i)
375db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        {
376db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            if (a[i] != b[i])
377db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            {
378db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom                return (a[i] & 0xff) < (b[i] & 0xff);
379db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            }
380db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        }
381db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return len == a.length;
382db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
383b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
384c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private byte[] getEncoded(
3854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable obj)
386c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
387c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
388c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ASN1OutputStream        aOut = new ASN1OutputStream(bOut);
389c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
390c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        try
391c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
392c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            aOut.writeObject(obj);
393c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
394c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        catch (IOException e)
395c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
396c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new IllegalArgumentException("cannot encode object added to SET");
397c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
398c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
399c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return bOut.toByteArray();
400c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
401c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
402db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    protected void sort()
403db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
4044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (!isSorted)
405db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        {
4064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            isSorted = true;
4074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (set.size() > 1)
408db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            {
4094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                boolean    swapped = true;
4104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                int        lastSwap = set.size() - 1;
411db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                while (swapped)
413db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom                {
4144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    int    index = 0;
4154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    int    swapIndex = 0;
4164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    byte[] a = getEncoded((ASN1Encodable)set.elementAt(0));
417db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    swapped = false;
4194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    while (index != lastSwap)
421db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom                    {
4224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        byte[] b = getEncoded((ASN1Encodable)set.elementAt(index + 1));
423db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        if (lessThanOrEqual(a, b))
4254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        {
4264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            a = b;
4274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        }
4284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        else
4294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        {
4304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            Object  o = set.elementAt(index);
431db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            set.setElementAt(set.elementAt(index + 1), index);
4334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            set.setElementAt(o, index + 1);
4344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            swapped = true;
4364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            swapIndex = index;
4374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        }
4384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        index++;
440db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom                    }
441db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    lastSwap = swapIndex;
443db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom                }
444db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            }
445db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        }
446db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
447db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    boolean isConstructed()
449db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
4504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return true;
451db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
452db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    abstract void encode(ASN1OutputStream out)
454db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            throws IOException;
455db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
456db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public String toString()
457db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
4584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return set.toString();
459db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
460b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
461