001    package org.apache.commons.ssl.asn1;
002    
003    import java.io.ByteArrayOutputStream;
004    import java.io.IOException;
005    import java.util.Enumeration;
006    
007    /** A DER encoded set object */
008    public 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    }