Home | History | Annotate | Download | only in asn1
      1 package org.bouncycastle.asn1;
      2 
      3 import java.io.IOException;
      4 
      5 /**
      6  * Definite Length TaggedObject - in ASN.1 notation this is any object preceded by
      7  * a [n] where n is some number - these are assumed to follow the construction
      8  * rules (as with sequences).
      9  */
     10 public class DLTaggedObject
     11     extends ASN1TaggedObject
     12 {
     13     private static final byte[] ZERO_BYTES = new byte[0];
     14 
     15     /**
     16      * @param explicit true if an explicitly tagged object.
     17      * @param tagNo the tag number for this object.
     18      * @param obj the tagged object.
     19      */
     20     public DLTaggedObject(
     21         boolean explicit,
     22         int tagNo,
     23         ASN1Encodable obj)
     24     {
     25         super(explicit, tagNo, obj);
     26     }
     27 
     28     boolean isConstructed()
     29     {
     30         if (!empty)
     31         {
     32             if (explicit)
     33             {
     34                 return true;
     35             }
     36             else
     37             {
     38                 ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
     39 
     40                 return primitive.isConstructed();
     41             }
     42         }
     43         else
     44         {
     45             return true;
     46         }
     47     }
     48 
     49     int encodedLength()
     50         throws IOException
     51     {
     52         if (!empty)
     53         {
     54             int length = obj.toASN1Primitive().toDLObject().encodedLength();
     55 
     56             if (explicit)
     57             {
     58                 return  StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
     59             }
     60             else
     61             {
     62                 // header length already in calculation
     63                 length = length - 1;
     64 
     65                 return StreamUtil.calculateTagLength(tagNo) + length;
     66             }
     67         }
     68         else
     69         {
     70             return StreamUtil.calculateTagLength(tagNo) + 1;
     71         }
     72     }
     73 
     74     void encode(
     75         ASN1OutputStream out)
     76         throws IOException
     77     {
     78         if (!empty)
     79         {
     80             ASN1Primitive primitive = obj.toASN1Primitive().toDLObject();
     81 
     82             if (explicit)
     83             {
     84                 out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
     85                 out.writeLength(primitive.encodedLength());
     86                 out.writeObject(primitive);
     87             }
     88             else
     89             {
     90                 //
     91                 // need to mark constructed types...
     92                 //
     93                 int flags;
     94                 if (primitive.isConstructed())
     95                 {
     96                     flags = BERTags.CONSTRUCTED | BERTags.TAGGED;
     97                 }
     98                 else
     99                 {
    100                     flags = BERTags.TAGGED;
    101                 }
    102 
    103                 out.writeTag(flags, tagNo);
    104                 out.writeImplicitObject(primitive);
    105             }
    106         }
    107         else
    108         {
    109             out.writeEncoded(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo, ZERO_BYTES);
    110         }
    111     }
    112 }
    113