    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}