    001package org.apache.commons.ssl.asn1;
    002
    003import java.io.ByteArrayOutputStream;
    004import java.io.IOException;
    005
    006/**
    007 * DER 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 DERTaggedObject
    012    extends ASN1TaggedObject {
    013    /**
    014     * @param tagNo the tag number for this object.
    015     * @param obj   the tagged object.
    016     */
    017    public DERTaggedObject(
    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 DERTaggedObject(
    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 DERTaggedObject(
    040        int tagNo) {
    041        super(false, tagNo, new DERSequence());
    042    }
    043
    044    void encode(
    045        DEROutputStream out)
    046        throws IOException {
    047        if (!empty) {
    048            ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    049            DEROutputStream dOut = new DEROutputStream(bOut);
    050
    051            dOut.writeObject(obj);
    052            dOut.close();
    053
    054            byte[] bytes = bOut.toByteArray();
    055
    056            if (explicit) {
    057                out.writeEncoded(CONSTRUCTED | TAGGED | tagNo, bytes);
    058            } else {
    059                //
    060                // need to mark constructed types...
    061                //
    062                if ((bytes[0] & CONSTRUCTED) != 0) {
    063                    bytes[0] = (byte) (CONSTRUCTED | TAGGED | tagNo);
    064                } else {
    065                    bytes[0] = (byte) (TAGGED | tagNo);
    066                }
    067
    068                out.write(bytes);
    069            }
    070        } else {
    071            out.writeEncoded(CONSTRUCTED | TAGGED | tagNo, new byte[0]);
    072        }
    073    }
    074}