001package org.apache.commons.ssl.asn1;
002
003import java.io.IOException;
004import java.util.Enumeration;
005
006/**
007 * BER TaggedObject - in ASN.1 nottation this is any object proceeded by
008 * a [n] where n is some number - these are assume to follow the construction
009 * rules (as with sequences).
010 */
011public class BERTaggedObject
012    extends DERTaggedObject {
013    /**
014     * @param tagNo the tag number for this object.
015     * @param obj   the tagged object.
016     */
017    public BERTaggedObject(
018        int tagNo,
019        DEREncodable obj) {
020        super(tagNo, obj);
021    }
022
023    /**
024     * @param explicit true if an explicitly tagged object.
025     * @param tagNo    the tag number for this object.
026     * @param obj      the tagged object.
027     */
028    public BERTaggedObject(
029        boolean explicit,
030        int tagNo,
031        DEREncodable obj) {
032        super(explicit, tagNo, obj);
033    }
034
035    /**
036     * create an implicitly tagged object that contains a zero
037     * length sequence.
038     */
039    public BERTaggedObject(
040        int tagNo) {
041        super(false, tagNo, new BERSequence());
042    }
043
044    void encode(
045        DEROutputStream out)
046        throws IOException {
047        if (out instanceof ASN1OutputStream || out instanceof BEROutputStream) {
048            out.write(CONSTRUCTED | TAGGED | tagNo);
049            out.write(0x80);
050
051            if (!empty) {
052                if (!explicit) {
053                    if (obj instanceof ASN1OctetString) {
054                        Enumeration e;
055
056                        if (obj instanceof BERConstructedOctetString) {
057                            e = ((BERConstructedOctetString) obj).getObjects();
058                        } else {
059                            ASN1OctetString octs = (ASN1OctetString) obj;
060                            BERConstructedOctetString berO = new BERConstructedOctetString(octs.getOctets());
061
062                            e = berO.getObjects();
063                        }
064
065                        while (e.hasMoreElements()) {
066                            out.writeObject(e.nextElement());
067                        }
068                    } else if (obj instanceof ASN1Sequence) {
069                        Enumeration e = ((ASN1Sequence) obj).getObjects();
070
071                        while (e.hasMoreElements()) {
072                            out.writeObject(e.nextElement());
073                        }
074                    } else if (obj instanceof ASN1Set) {
075                        Enumeration e = ((ASN1Set) obj).getObjects();
076
077                        while (e.hasMoreElements()) {
078                            out.writeObject(e.nextElement());
079                        }
080                    } else {
081                        throw new RuntimeException("not implemented: " + obj.getClass().getName());
082                    }
083                } else {
084                    out.writeObject(obj);
085                }
086            }
087
088            out.write(0x00);
089            out.write(0x00);
090        } else {
091            super.encode(out);
092        }
093    }
094}