    001package org.apache.commons.ssl.asn1;
    002
    003import java.io.ByteArrayOutputStream;
    004import java.io.IOException;
    005import java.util.Enumeration;
    006
    007/** A DER encoded set object */
    008public class DERSet
    009    extends ASN1Set {
    010    /** create an empty set */
    011    public DERSet() {
    012    }
    013
    014    /** @param obj - a single object that makes up the set. */
    015    public DERSet(
    016        DEREncodable obj) {
    017        this.addObject(obj);
    018    }
    019
    020    /** @param v - a vector of objects making up the set. */
    021    public DERSet(
    022        DEREncodableVector v) {
    023        this(v, true);
    024    }
    025
    026    /** create a set from an array of objects. */
    027    public DERSet(
    028        ASN1Encodable[] a) {
    029        for (int i = 0; i != a.length; i++) {
    030            this.addObject(a[i]);
    031        }
    032
    033        this.sort();
    034    }
    035
    036    /** @param v - a vector of objects making up the set. */
    037    DERSet(
    038        DEREncodableVector v,
    039        boolean needsSorting) {
    040        for (int i = 0; i != v.size(); i++) {
    041            this.addObject(v.get(i));
    042        }
    043
    044        if (needsSorting) {
    045            this.sort();
    046        }
    047    }
    048
    049    /*
    050     * A note on the implementation:
    051     * <p>
    052     * As DER requires the constructed, definite-length model to
    053     * be used for structured types, this varies slightly from the
    054     * ASN.1 descriptions given. Rather than just outputing SET,
    055     * we also have to specify CONSTRUCTED, and the objects length.
    056     */
    057    void encode(
    058        DEROutputStream out)
    059        throws IOException {
    060        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    061        DEROutputStream dOut = new DEROutputStream(bOut);
    062        Enumeration e = this.getObjects();
    063
    064        while (e.hasMoreElements()) {
    065            Object obj = e.nextElement();
    066
    067            dOut.writeObject(obj);
    068        }
    069
    070        dOut.close();
    071
    072        byte[] bytes = bOut.toByteArray();
    073
    074        out.writeEncoded(SET | CONSTRUCTED, bytes);
    075    }
    076}