package org.bouncycastle.asn1.x509; import java.util.ArrayList; import java.util.BitSet; import org.bouncycastle.asn1.DERObjectIdentifier; // BEGIN android-note // This class was extracted from X509Name as a way to keep the element // list in a more controlled fashion. // END android-note /** * List of elements of an X509 name. Each element has a key, a value, and * an "added" flag. */ public class X509NameElementList { /** null-ok; key #0 */ private DERObjectIdentifier key0; /** null-ok; key #1 */ private DERObjectIdentifier key1; /** null-ok; key #2 */ private DERObjectIdentifier key2; /** null-ok; key #3 */ private DERObjectIdentifier key3; /** null-ok; value #0 */ private String value0; /** null-ok; value #1 */ private String value1; /** null-ok; value #2 */ private String value2; /** null-ok; value #3 */ private String value3; /** * null-ok; array of additional keys and values, alternating * key then value, etc. */ private ArrayList<Object> rest; /** bit vector for all the "added" bits */ private BitSet added = new BitSet(); /** >= 0; number of elements in the list */ private int size; // Note: Default public constructor. /** * Adds an element. The "added" flag is set to false for the element. * * @param key non-null; the key * @param value non-null; the value */ public void add(DERObjectIdentifier key, String value) { add(key, value, false); } /** * Adds an element. * * @param key non-null; the key * @param value non-null; the value * @param added the added bit */ public void add(DERObjectIdentifier key, String value, boolean added) { if (key == null) { throw new NullPointerException("key == null"); } if (value == null) { throw new NullPointerException("value == null"); } int sz = size; switch (sz) { case 0: { key0 = key; value0 = value; break; } case 1: { key1 = key; value1 = value; break; } case 2: { key2 = key; value2 = value; break; } case 3: { key3 = key; value3 = value; break; } case 4: { // Do initial allocation of rest. rest = new ArrayList<Object>(); // Fall through... } default: { rest.add(key); rest.add(value); break; } } if (added) { this.added.set(sz); } size = sz + 1; } /** * Sets the "added" flag on the most recently added element. */ public void setLastAddedFlag() { added.set(size - 1); } /** * Gets the number of elements in this instance. */ public int size() { return size; } /** * Gets the nth key. * * @param n index * @return non-null; the nth key */ public DERObjectIdentifier getKey(int n) { if ((n < 0) || (n >= size)) { throw new IndexOutOfBoundsException(Integer.toString(n)); } switch (n) { case 0: return key0; case 1: return key1; case 2: return key2; case 3: return key3; default: return (DERObjectIdentifier) rest.get((n - 4) * 2); } } /** * Gets the nth value. * * @param n index * @return non-null; the nth value */ public String getValue(int n) { if ((n < 0) || (n >= size)) { throw new IndexOutOfBoundsException(Integer.toString(n)); } switch (n) { case 0: return value0; case 1: return value1; case 2: return value2; case 3: return value3; default: return (String) rest.get(((n - 4) * 2) + 1); } } /** * Gets the nth added flag bit. * * @param n index * @return the nth added flag bit */ public boolean getAdded(int n) { if ((n < 0) || (n >= size)) { throw new IndexOutOfBoundsException(Integer.toString(n)); } return added.get(n); } /** * Constructs and returns a new instance which consists of the * elements of this one in reverse order * * @return non-null; the reversed instance */ public X509NameElementList reverse() { X509NameElementList result = new X509NameElementList(); for (int i = size - 1; i >= 0; i--) { result.add(getKey(i), getValue(i), getAdded(i)); } return result; } }