initial checkin
[org.ibex.nanogoat.git] / src / org / bouncycastle / asn1 / ASN1Set.java
1 package org.bouncycastle.asn1;
2
3 import java.io.*;
4 import java.util.*;
5
6 abstract public class ASN1Set
7     extends DERObject
8 {
9     protected Vector set = new Vector();
10
11     /**
12      * return an ASN1Set from the given object.
13      *
14      * @param obj the object we want converted.
15      * @exception IllegalArgumentException if the object cannot be converted.
16      */
17     public static ASN1Set getInstance(
18         Object  obj)
19     {
20         if (obj == null || obj instanceof ASN1Set)
21         {
22             return (ASN1Set)obj;
23         }
24
25         throw new IllegalArgumentException("unknown object in getInstance");
26     }
27
28     /**
29      * Return an ASN1 set from a tagged object. There is a special
30      * case here, if an object appears to have been explicitly tagged on 
31      * reading but we were expecting it to be implictly tagged in the 
32      * normal course of events it indicates that we lost the surrounding
33      * set - so we need to add it back (this will happen if the tagged
34      * object is a sequence that contains other sequences). If you are
35      * dealing with implicitly tagged sets you really <b>should</b>
36      * be using this method.
37      *
38      * @param obj the tagged object.
39      * @param explicit true if the object is meant to be explicitly tagged
40      *          false otherwise.
41      * @exception IllegalArgumentException if the tagged object cannot
42      *          be converted.
43      */
44     public static ASN1Set getInstance(
45         ASN1TaggedObject    obj,
46         boolean             explicit)
47     {
48         if (explicit)
49         {
50             if (!obj.isExplicit())
51             {
52                 throw new IllegalArgumentException("object implicit - explicit expected.");
53             }
54
55             return (ASN1Set)obj.getObject();
56         }
57         else
58         {
59             //
60             // constructed object which appears to be explicitly tagged
61             // and it's really implicit means we have to add the
62             // surrounding sequence.
63             //
64             if (obj.isExplicit())
65             {
66                 ASN1Set    set = new DERSet(obj.getObject());
67
68                 return set;
69             }
70             else
71             {
72                 //
73                 // in this case the parser returns a sequence, convert it
74                 // into a set.
75                 //
76                 DEREncodableVector  v = new DEREncodableVector();
77
78                 if (obj.getObject() instanceof ASN1Sequence)
79                 {
80                     ASN1Sequence s = (ASN1Sequence)obj.getObject();
81                     Enumeration e = s.getObjects();
82
83                     while (e.hasMoreElements())
84                     {
85                         v.add((DEREncodable)e.nextElement());
86                     }
87
88                     return new DERSet(v);
89                 }
90             }
91         }
92
93         throw new IllegalArgumentException(
94                     "unknown object in getInstanceFromTagged");
95     }
96
97     public ASN1Set()
98     {
99     }
100
101     public Enumeration getObjects()
102     {
103         return set.elements();
104     }
105
106     /**
107      * return the object at the set postion indicated by index.
108      *
109      * @param the set number (starting at zero) of the object
110      * @return the object at the set postion indicated by index.
111      */
112     public DEREncodable getObjectAt(
113         int index)
114     {
115         return (DEREncodable)set.elementAt(index);
116     }
117
118     /**
119      * return the number of objects in this set.
120      *
121      * @return the number of objects in this set.
122      */
123     public int size()
124     {
125         return set.size();
126     }
127
128     public int hashCode()
129     {
130         Enumeration             e = this.getObjects();
131         int                     hashCode = 0;
132
133         while (e.hasMoreElements())
134         {
135             hashCode ^= e.nextElement().hashCode();
136         }
137
138         return hashCode;
139     }
140
141     public boolean equals(
142         Object  o)
143     {
144         if (o == null || !(o instanceof ASN1Set))
145         {
146             return false;
147         }
148
149         ASN1Set   other = (ASN1Set)o;
150
151         if (this.size() != other.size())
152         {
153             return false;
154         }
155
156         Enumeration s1 = this.getObjects();
157         Enumeration s2 = other.getObjects();
158
159         while (s1.hasMoreElements())
160         {
161             if (!s1.nextElement().equals(s2.nextElement()))
162             {
163                 return false;
164             }
165         }
166
167         return true;
168     }
169
170     protected void addObject(
171         DEREncodable obj)
172     {
173         set.addElement(obj);
174     }
175
176     abstract void encode(DEROutputStream out)
177             throws IOException;
178 }