1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.bouncycastle.asn1;
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.ByteArrayOutputStream;
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException;
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Enumeration;
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ConcurrentModificationException;
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// BEGIN android-note
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is a new class that was synthesized from ASN1Sequence and
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ASN1Set, but with extra smarts about efficiently storing its
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * elements.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// END android-note
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Base class for collection-like <code>DERObject</code>s. Instances
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of this class will keep up to four elements directly, resorting to
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an external collection only if more elements than that need to be
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * stored.
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic abstract class ASN1Collection
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    extends DERObject
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** &gt;= 0; size of the collection */
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int size;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; element #0 */
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private DEREncodable obj0;
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; element #1 */
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private DEREncodable obj1;
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; element #2 */
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private DEREncodable obj2;
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; element #3 */
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private DEREncodable obj3;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; elements #4 and higher */
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private DEREncodable[] rest;
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the object at the postion indicated by index.
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param index the index (starting at zero) of the object
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the object at the postion indicated by index
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final DEREncodable getObjectAt(int index) {
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((index < 0) || (index >= size)) {
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IndexOutOfBoundsException(Integer.toString(index));
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (index) {
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0: return obj0;
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1: return obj1;
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 2: return obj2;
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 3: return obj3;
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            default: return rest[index - 4];
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the number of objects in this instance.
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of objects in this instance
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int size() {
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return size;
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int hashCode() {
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Enumeration e = this.getObjects();
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int hashCode = 0;
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (e.hasMoreElements()) {
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Object o = e.nextElement();
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (o != null) {
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                hashCode ^= o.hashCode();
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return hashCode;
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds a new element to this instance.
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param obj non-null; the instance to add
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void addObject(DEREncodable obj) {
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (obj == null) {
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("obj == null");
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz = size;
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (sz) {
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0: obj0 = obj; break;
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1: obj1 = obj; break;
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 2: obj2 = obj; break;
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 3: obj3 = obj; break;
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 4: {
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Initial allocation of rest.
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                rest = new DEREncodable[5];
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                rest[0] = obj;
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            default: {
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int index = sz - 4;
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (index >= rest.length) {
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // Grow rest.
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    DEREncodable[] newRest = new DEREncodable[index * 2 + 10];
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    System.arraycopy(rest, 0, newRest, 0, rest.length);
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    rest = newRest;
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                rest[index] = obj;
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        size++;
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the element at a given index (used by {@link #sort}).
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param obj non-null; the object to set
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param index &gt;= 0; the index
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void setObjectAt(DEREncodable obj, int index) {
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (index) {
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0: obj0 = obj; break;
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1: obj1 = obj; break;
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 2: obj2 = obj; break;
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 3: obj3 = obj; break;
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            default: {
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                rest[index - 4] = obj;
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Encodes this instance to the given stream.
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param out non-null; stream to encode to
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*package*/ abstract void encode(DEROutputStream out) throws IOException;
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets an enumeration of all the objects in this collection.
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return non-null; the enumeration
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final Enumeration getObjects() {
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new ASN1CollectionEnumeration();
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Associated enumeration class.
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private class ASN1CollectionEnumeration implements Enumeration {
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** original size; used for modification detection */
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final int origSize = size;
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** &gt;= 0; current cursor */
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private int at = 0;
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** {@inheritDoc} */
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public boolean hasMoreElements() {
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (size != origSize) {
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new ConcurrentModificationException();
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return at < origSize;
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** {@inheritDoc} */
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public Object nextElement() {
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (size != origSize) {
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new ConcurrentModificationException();
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            switch (at++) {
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case 0: return obj0;
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case 1: return obj1;
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case 2: return obj2;
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case 3: return obj3;
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                default: return rest[at - 5];
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sorts the elements in this instance.
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void sort() {
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (size <= 1) {
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean swapped = true;
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // TODO: This is bubble sort. Probably not the best choice.
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (swapped) {
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int index = 0;
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            byte[] a = getEncoded(getObjectAt(0));
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            swapped = false;
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            while (index != size - 1) {
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int nextIndex = index + 1;
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                byte[] b = getEncoded(getObjectAt(nextIndex));
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (lessThanOrEqual(a, b)) {
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    a = b;
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else {
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    DEREncodable o = getObjectAt(index);
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    setObjectAt(getObjectAt(nextIndex), index);
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    setObjectAt(o, nextIndex);
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    swapped = true;
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                index++;
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns true if a <= b (arrays are assumed padded with zeros).
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static boolean lessThanOrEqual(byte[] a, byte[] b) {
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (a.length <= b.length) {
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i != a.length; i++) {
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int l = a[i] & 0xff;
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int r = b[i] & 0xff;
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (r > l) {
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return true;
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else if (l > r) {
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return false;
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i != b.length; i++) {
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 int l = a[i] & 0xff;
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 int r = b[i] & 0xff;
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 if (r > l) {
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     return true;
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 } else if (l > r) {
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     return false;
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 }
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             }
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             return false;
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         }
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the encoded form of an object.
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param obj non-null; object to encode
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return non-null; the encoded form
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static byte[] getEncoded(DEREncodable obj) {
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ASN1OutputStream aOut = new ASN1OutputStream(bOut);
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            aOut.writeObject(obj);
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (IOException e) {
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "cannot encode object added to collection");
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return bOut.toByteArray();
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final String toString() {
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StringBuilder sb = new StringBuilder();
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sb.append('[');
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < size; i++) {
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (i != 0) sb.append(", ");
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append(getObjectAt(i));
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sb.append(']');
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return sb.toString();
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
299