2003/02/12 06:21:04
[org.ibex.core.git] / src / org / bouncycastle / asn1 / ASN1Sequence.java
diff --git a/src/org/bouncycastle/asn1/ASN1Sequence.java b/src/org/bouncycastle/asn1/ASN1Sequence.java
new file mode 100644 (file)
index 0000000..5362f34
--- /dev/null
@@ -0,0 +1,173 @@
+package org.bouncycastle.asn1;
+
+import java.io.*;
+import java.util.*;
+
+public abstract class ASN1Sequence
+    extends DERObject
+{
+    private Vector seq = new Vector();
+
+    /**
+     * return an ASN1Sequence from the given object.
+     *
+     * @param obj the object we want converted.
+     * @exception IllegalArgumentException if the object cannot be converted.
+     */
+    public static ASN1Sequence getInstance(
+        Object  obj)
+    {
+        if (obj == null || obj instanceof ASN1Sequence)
+        {
+            return (ASN1Sequence)obj;
+        }
+
+        throw new IllegalArgumentException("unknown object in getInstance");
+    }
+
+    /**
+     * Return an ASN1 sequence 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
+     * sequence - 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 sequences 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 ASN1Sequence getInstance(
+        ASN1TaggedObject    obj,
+        boolean             explicit)
+    {
+        if (explicit)
+        {
+            if (!obj.isExplicit())
+            {
+                throw new IllegalArgumentException("object implicit - explicit expected.");
+            }
+
+            return (ASN1Sequence)obj.getObject();
+        }
+        else
+        {
+            //
+            // constructed object which appears to be explicitly tagged
+            // when it should be implicit means we have to add the
+            // surrounding sequence.
+            //
+            if (obj.isExplicit())
+            {
+                ASN1Sequence    seq;
+
+                if (obj instanceof BERTaggedObject)
+                {
+                    seq = new BERConstructedSequence();
+                }
+                else
+                {
+                    seq = new DERConstructedSequence();
+                }
+
+                seq.addObject(obj.getObject());
+
+                return seq;
+            }
+            else
+            {
+                ASN1Sequence    seq;
+
+                if (obj.getObject() instanceof ASN1Sequence)
+                {
+                    return (ASN1Sequence)obj.getObject();
+                }
+            }
+        }
+
+        throw new IllegalArgumentException(
+                "unknown object in getInstanceFromTagged");
+    }
+
+    public Enumeration getObjects()
+    {
+        return seq.elements();
+    }
+
+    /**
+     * return the object at the sequence postion indicated by index.
+     *
+     * @param the sequence number (starting at zero) of the object
+     * @return the object at the sequence postion indicated by index.
+     */
+    public DEREncodable getObjectAt(
+        int index)
+    {
+        return (DEREncodable)seq.elementAt(index);
+    }
+
+    /**
+     * return the number of objects in this sequence.
+     *
+     * @return the number of objects in this sequence.
+     */
+    public int size()
+    {
+        return seq.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 ASN1Sequence))
+        {
+            return false;
+        }
+
+        ASN1Sequence   other = (ASN1Sequence)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)
+    {
+        seq.addElement(obj);
+    }
+
+    abstract void encode(DEROutputStream out)
+        throws IOException;
+}