2003/02/12 06:21:04
[org.ibex.core.git] / src / org / bouncycastle / asn1 / ASN1Set.java
diff --git a/src/org/bouncycastle/asn1/ASN1Set.java b/src/org/bouncycastle/asn1/ASN1Set.java
new file mode 100644 (file)
index 0000000..adb1b10
--- /dev/null
@@ -0,0 +1,178 @@
+package org.bouncycastle.asn1;
+
+import java.io.*;
+import java.util.*;
+
+abstract public class ASN1Set
+    extends DERObject
+{
+    protected Vector set = new Vector();
+
+    /**
+     * return an ASN1Set from the given object.
+     *
+     * @param obj the object we want converted.
+     * @exception IllegalArgumentException if the object cannot be converted.
+     */
+    public static ASN1Set getInstance(
+        Object  obj)
+    {
+        if (obj == null || obj instanceof ASN1Set)
+        {
+            return (ASN1Set)obj;
+        }
+
+        throw new IllegalArgumentException("unknown object in getInstance");
+    }
+
+    /**
+     * Return an ASN1 set from a tagged object. There is a special
+     * case here, if an object appears to have been explicitly tagged on 
+     * reading but we were expecting it to be implictly tagged in the 
+     * normal course of events it indicates that we lost the surrounding
+     * set - so we need to add it back (this will happen if the tagged
+     * object is a sequence that contains other sequences). If you are
+     * dealing with implicitly tagged sets you really <b>should</b>
+     * be using this method.
+     *
+     * @param obj the tagged object.
+     * @param explicit true if the object is meant to be explicitly tagged
+     *          false otherwise.
+     * @exception IllegalArgumentException if the tagged object cannot
+     *          be converted.
+     */
+    public static ASN1Set getInstance(
+        ASN1TaggedObject    obj,
+        boolean             explicit)
+    {
+        if (explicit)
+        {
+            if (!obj.isExplicit())
+            {
+                throw new IllegalArgumentException("object implicit - explicit expected.");
+            }
+
+            return (ASN1Set)obj.getObject();
+        }
+        else
+        {
+            //
+            // constructed object which appears to be explicitly tagged
+            // and it's really implicit means we have to add the
+            // surrounding sequence.
+            //
+            if (obj.isExplicit())
+            {
+                ASN1Set    set = new DERSet(obj.getObject());
+
+                return set;
+            }
+            else
+            {
+                //
+                // in this case the parser returns a sequence, convert it
+                // into a set.
+                //
+                DEREncodableVector  v = new DEREncodableVector();
+
+                if (obj.getObject() instanceof ASN1Sequence)
+                {
+                    ASN1Sequence s = (ASN1Sequence)obj.getObject();
+                    Enumeration e = s.getObjects();
+
+                    while (e.hasMoreElements())
+                    {
+                        v.add((DEREncodable)e.nextElement());
+                    }
+
+                    return new DERSet(v);
+                }
+            }
+        }
+
+        throw new IllegalArgumentException(
+                    "unknown object in getInstanceFromTagged");
+    }
+
+    public ASN1Set()
+    {
+    }
+
+    public Enumeration getObjects()
+    {
+        return set.elements();
+    }
+
+    /**
+     * return the object at the set postion indicated by index.
+     *
+     * @param the set number (starting at zero) of the object
+     * @return the object at the set postion indicated by index.
+     */
+    public DEREncodable getObjectAt(
+        int index)
+    {
+        return (DEREncodable)set.elementAt(index);
+    }
+
+    /**
+     * return the number of objects in this set.
+     *
+     * @return the number of objects in this set.
+     */
+    public int size()
+    {
+        return set.size();
+    }
+
+    public int hashCode()
+    {
+        Enumeration             e = this.getObjects();
+        int                     hashCode = 0;
+
+        while (e.hasMoreElements())
+        {
+            hashCode ^= e.nextElement().hashCode();
+        }
+
+        return hashCode;
+    }
+
+    public boolean equals(
+        Object  o)
+    {
+        if (o == null || !(o instanceof ASN1Set))
+        {
+            return false;
+        }
+
+        ASN1Set   other = (ASN1Set)o;
+
+        if (this.size() != other.size())
+        {
+            return false;
+        }
+
+        Enumeration s1 = this.getObjects();
+        Enumeration s2 = other.getObjects();
+
+        while (s1.hasMoreElements())
+        {
+            if (!s1.nextElement().equals(s2.nextElement()))
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    protected void addObject(
+        DEREncodable obj)
+    {
+        set.addElement(obj);
+    }
+
+    abstract void encode(DEROutputStream out)
+            throws IOException;
+}