| package org.bouncycastle.asn1; |
| |
| import java.io.IOException; |
| import java.util.Enumeration; |
| // BEGIN android-removed |
| // import java.util.Vector; |
| // END android-removed |
| |
| // BEGIN android-note |
| // Changed inheritence of class. |
| // END android-note |
| |
| public abstract class ASN1Sequence |
| extends ASN1Collection |
| { |
| // BEGIN android-removed |
| // private Vector seq = new Vector(); |
| // END android-removed |
| |
| /** |
| * 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: " + obj.getClass().getName()); |
| } |
| |
| /** |
| * 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 implicitly 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()) |
| { |
| if (obj instanceof BERTaggedObject) |
| { |
| return new BERSequence(obj.getObject()); |
| } |
| else |
| { |
| return new DERSequence(obj.getObject()); |
| } |
| } |
| else |
| { |
| if (obj.getObject() instanceof ASN1Sequence) |
| { |
| return (ASN1Sequence)obj.getObject(); |
| } |
| } |
| } |
| |
| throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName()); |
| } |
| |
| // BEGIN android-removed |
| // public Enumeration getObjects() |
| // { |
| // return seq.elements(); |
| // } |
| // END android-removed |
| |
| public ASN1SequenceParser parser() |
| { |
| final ASN1Sequence outer = this; |
| |
| return new ASN1SequenceParser() |
| { |
| private final int max = size(); |
| |
| private int index; |
| |
| public DEREncodable readObject() throws IOException |
| { |
| if (index == max) |
| { |
| return null; |
| } |
| |
| DEREncodable obj = getObjectAt(index++); |
| if (obj instanceof ASN1Sequence) |
| { |
| return ((ASN1Sequence)obj).parser(); |
| } |
| if (obj instanceof ASN1Set) |
| { |
| return ((ASN1Set)obj).parser(); |
| } |
| |
| return obj; |
| } |
| |
| public DERObject getDERObject() |
| { |
| return outer; |
| } |
| }; |
| } |
| |
| // BEGIN android-removed |
| // /** |
| // * return the object at the sequence position indicated by index. |
| // * |
| // * @param index the sequence number (starting at zero) of the object |
| // * @return the object at the sequence position 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 = size(); |
| // |
| // while (e.hasMoreElements()) |
| // { |
| // Object o = e.nextElement(); |
| // hashCode *= 17; |
| // if (o != null) |
| // { |
| // hashCode ^= o.hashCode(); |
| // } |
| // } |
| // |
| // return hashCode; |
| // } |
| // END android-removed |
| |
| boolean asn1Equals( |
| DERObject o) |
| { |
| if (!(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()) |
| { |
| DERObject o1 = ((DEREncodable)s1.nextElement()).getDERObject(); |
| DERObject o2 = ((DEREncodable)s2.nextElement()).getDERObject(); |
| |
| if (o1 == o2 || (o1 != null && o1.equals(o2))) |
| { |
| continue; |
| } |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| // BEGIN android-removed |
| //protected void addObject( |
| // DEREncodable obj) |
| //{ |
| // seq.addElement(obj); |
| //} |
| |
| //abstract void encode(DEROutputStream out) |
| // throws IOException; |
| |
| //public String toString() |
| //{ |
| // return seq.toString(); |
| //} |
| // END android-removed |
| } |