001package org.apache.commons.ssl.org.bouncycastle.asn1;
002
003import java.io.IOException;
004import java.util.Enumeration;
005
006public class DERSequence
007    extends ASN1Sequence
008{
009    private int bodyLength = -1;
010
011    /**
012     * create an empty sequence
013     */
014    public DERSequence()
015    {
016    }
017
018    /**
019     * create a sequence containing one object
020     */
021    public DERSequence(
022        ASN1Encodable obj)
023    {
024        super(obj);
025    }
026
027    /**
028     * create a sequence containing a vector of objects.
029     */
030    public DERSequence(
031        ASN1EncodableVector v)
032    {
033        super(v);
034    }
035
036    /**
037     * create a sequence containing an array of objects.
038     */
039    public DERSequence(
040        ASN1Encodable[]   array)
041    {
042        super(array);
043    }
044
045    private int getBodyLength()
046        throws IOException
047    {
048        if (bodyLength < 0)
049        {
050            int length = 0;
051
052            for (Enumeration e = this.getObjects(); e.hasMoreElements();)
053            {
054                Object    obj = e.nextElement();
055
056                length += ((ASN1Encodable)obj).toASN1Primitive().toDERObject().encodedLength();
057            }
058
059            bodyLength = length;
060        }
061
062        return bodyLength;
063    }
064
065    int encodedLength()
066        throws IOException
067    {
068        int length = getBodyLength();
069
070        return 1 + StreamUtil.calculateBodyLength(length) + length;
071    }
072
073    /*
074     * A note on the implementation:
075     * <p>
076     * As DER requires the constructed, definite-length model to
077     * be used for structured types, this varies slightly from the
078     * ASN.1 descriptions given. Rather than just outputting SEQUENCE,
079     * we also have to specify CONSTRUCTED, and the objects length.
080     */
081    void encode(
082        ASN1OutputStream out)
083        throws IOException
084    {
085        ASN1OutputStream        dOut = out.getDERSubStream();
086        int                     length = getBodyLength();
087
088        out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
089        out.writeLength(length);
090
091        for (Enumeration e = this.getObjects(); e.hasMoreElements();)
092        {
093            Object    obj = e.nextElement();
094
095            dOut.writeObject((ASN1Encodable)obj);
096        }
097    }
098}