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