001package org.apache.commons.ssl.org.bouncycastle.asn1; 002 003import java.io.IOException; 004 005/** 006 * Definite Length TaggedObject - in ASN.1 notation this is any object preceded by 007 * a [n] where n is some number - these are assumed to follow the construction 008 * rules (as with sequences). 009 */ 010public class DLTaggedObject 011 extends ASN1TaggedObject 012{ 013 private static final byte[] ZERO_BYTES = new byte[0]; 014 015 /** 016 * @param explicit true if an explicitly tagged object. 017 * @param tagNo the tag number for this object. 018 * @param obj the tagged object. 019 */ 020 public DLTaggedObject( 021 boolean explicit, 022 int tagNo, 023 ASN1Encodable obj) 024 { 025 super(explicit, tagNo, obj); 026 } 027 028 boolean isConstructed() 029 { 030 if (!empty) 031 { 032 if (explicit) 033 { 034 return true; 035 } 036 else 037 { 038 ASN1Primitive primitive = obj.toASN1Primitive().toDLObject(); 039 040 return primitive.isConstructed(); 041 } 042 } 043 else 044 { 045 return true; 046 } 047 } 048 049 int encodedLength() 050 throws IOException 051 { 052 if (!empty) 053 { 054 int length = obj.toASN1Primitive().toDLObject().encodedLength(); 055 056 if (explicit) 057 { 058 return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length; 059 } 060 else 061 { 062 // header length already in calculation 063 length = length - 1; 064 065 return StreamUtil.calculateTagLength(tagNo) + length; 066 } 067 } 068 else 069 { 070 return StreamUtil.calculateTagLength(tagNo) + 1; 071 } 072 } 073 074 void encode( 075 ASN1OutputStream out) 076 throws IOException 077 { 078 if (!empty) 079 { 080 ASN1Primitive primitive = obj.toASN1Primitive().toDLObject(); 081 082 if (explicit) 083 { 084 out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo); 085 out.writeLength(primitive.encodedLength()); 086 out.writeObject(primitive); 087 } 088 else 089 { 090 // 091 // need to mark constructed types... 092 // 093 int flags; 094 if (primitive.isConstructed()) 095 { 096 flags = BERTags.CONSTRUCTED | BERTags.TAGGED; 097 } 098 else 099 { 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}