1 package org.bouncycastle.asn1.x509; 2 3 import java.util.ArrayList; 4 import java.util.BitSet; 5 import org.bouncycastle.asn1.DERObjectIdentifier; 6 7 // BEGIN android-note 8 // This class was extracted from X509Name as a way to keep the element 9 // list in a more controlled fashion. 10 // END android-note 11 12 /** 13 * List of elements of an X509 name. Each element has a key, a value, and 14 * an "added" flag. 15 */ 16 public class X509NameElementList { 17 /** null-ok; key #0 */ 18 private DERObjectIdentifier key0; 19 20 /** null-ok; key #1 */ 21 private DERObjectIdentifier key1; 22 23 /** null-ok; key #2 */ 24 private DERObjectIdentifier key2; 25 26 /** null-ok; key #3 */ 27 private DERObjectIdentifier key3; 28 29 /** null-ok; value #0 */ 30 private String value0; 31 32 /** null-ok; value #1 */ 33 private String value1; 34 35 /** null-ok; value #2 */ 36 private String value2; 37 38 /** null-ok; value #3 */ 39 private String value3; 40 41 /** 42 * null-ok; array of additional keys and values, alternating 43 * key then value, etc. 44 */ 45 private ArrayList<Object> rest; 46 47 /** bit vector for all the "added" bits */ 48 private BitSet added = new BitSet(); 49 50 /** >= 0; number of elements in the list */ 51 private int size; 52 53 // Note: Default public constructor. 54 55 /** 56 * Adds an element. The "added" flag is set to false for the element. 57 * 58 * @param key non-null; the key 59 * @param value non-null; the value 60 */ 61 public void add(DERObjectIdentifier key, String value) { 62 add(key, value, false); 63 } 64 65 /** 66 * Adds an element. 67 * 68 * @param key non-null; the key 69 * @param value non-null; the value 70 * @param added the added bit 71 */ 72 public void add(DERObjectIdentifier key, String value, boolean added) { 73 if (key == null) { 74 throw new NullPointerException("key == null"); 75 } 76 77 if (value == null) { 78 throw new NullPointerException("value == null"); 79 } 80 81 int sz = size; 82 83 switch (sz) { 84 case 0: { 85 key0 = key; 86 value0 = value; 87 break; 88 } 89 case 1: { 90 key1 = key; 91 value1 = value; 92 break; 93 } 94 case 2: { 95 key2 = key; 96 value2 = value; 97 break; 98 } 99 case 3: { 100 key3 = key; 101 value3 = value; 102 break; 103 } 104 case 4: { 105 // Do initial allocation of rest. 106 rest = new ArrayList<Object>(); 107 // Fall through... 108 } 109 default: { 110 rest.add(key); 111 rest.add(value); 112 break; 113 } 114 } 115 116 if (added) { 117 this.added.set(sz); 118 } 119 120 size = sz + 1; 121 } 122 123 /** 124 * Sets the "added" flag on the most recently added element. 125 */ 126 public void setLastAddedFlag() { 127 added.set(size - 1); 128 } 129 130 /** 131 * Gets the number of elements in this instance. 132 */ 133 public int size() { 134 return size; 135 } 136 137 /** 138 * Gets the nth key. 139 * 140 * @param n index 141 * @return non-null; the nth key 142 */ 143 public DERObjectIdentifier getKey(int n) { 144 if ((n < 0) || (n >= size)) { 145 throw new IndexOutOfBoundsException(Integer.toString(n)); 146 } 147 148 switch (n) { 149 case 0: return key0; 150 case 1: return key1; 151 case 2: return key2; 152 case 3: return key3; 153 default: return (DERObjectIdentifier) rest.get((n - 4) * 2); 154 } 155 } 156 157 /** 158 * Gets the nth value. 159 * 160 * @param n index 161 * @return non-null; the nth value 162 */ 163 public String getValue(int n) { 164 if ((n < 0) || (n >= size)) { 165 throw new IndexOutOfBoundsException(Integer.toString(n)); 166 } 167 168 switch (n) { 169 case 0: return value0; 170 case 1: return value1; 171 case 2: return value2; 172 case 3: return value3; 173 default: return (String) rest.get(((n - 4) * 2) + 1); 174 } 175 } 176 177 /** 178 * Gets the nth added flag bit. 179 * 180 * @param n index 181 * @return the nth added flag bit 182 */ 183 public boolean getAdded(int n) { 184 if ((n < 0) || (n >= size)) { 185 throw new IndexOutOfBoundsException(Integer.toString(n)); 186 } 187 188 return added.get(n); 189 } 190 191 /** 192 * Constructs and returns a new instance which consists of the 193 * elements of this one in reverse order 194 * 195 * @return non-null; the reversed instance 196 */ 197 public X509NameElementList reverse() { 198 X509NameElementList result = new X509NameElementList(); 199 200 for (int i = size - 1; i >= 0; i--) { 201 result.add(getKey(i), getValue(i), getAdded(i)); 202 } 203 204 return result; 205 } 206 } 207