External { public void decode(AsnInputStream ais) throws AsnException { this.oid = false; this.integer = false; this.objDescriptor = false; this.oidValue = null; this.indirectReference = 0; this.objDescriptorValue = null; this.asn = false; this.octet = false; this.arbitrary = false; this.data = null; this.bitDataString = null; try { AsnInputStream localAsnIS = ais.readSequenceStream(); while( true ) { if (localAsnIS.available() == 0) break; int tag = localAsnIS.readTag(); if (localAsnIS.getTagClass() == Tag.CLASS_UNIVERSAL) { switch(tag) { case Tag.INTEGER: this.indirectReference = localAsnIS.readInteger(); this.setInteger(true); break; case Tag.OBJECT_IDENTIFIER: this.oidValue = localAsnIS.readObjectIdentifier(); this.setOid(true); break; case Tag.OBJECT_DESCRIPTOR: this.objDescriptorValue = localAsnIS.readGraphicString(); this.setObjDescriptor(true); break; default: throw new AsnException("Error while decoding External: Unrecognized tag value=" + tag + ", tagClass=" + localAsnIS.getTagClass()); } } else if (localAsnIS.getTagClass() == Tag.CLASS_CONTEXT_SPECIFIC) { switch(tag) { case External._TAG_ASN: this.data = localAsnIS.readSequence(); this.setAsn(true); break; case External._TAG_OCTET_ALIGNED: this.setEncodeType(localAsnIS.readOctetString()); setOctet(true); break; case External._TAG_ARBITRARY: this.setEncodeBitStringType(localAsnIS.readBitString()); setArbitrary(true); break; default: throw new AsnException("Error while decoding External: Unrecognized tag value=" + tag + ", tagClass=" + localAsnIS.getTagClass()); } if (localAsnIS.available() != 0) throw new AsnException("Error while decoding External: data field must be the last"); } else { throw new AsnException("Error while decoding External: Unrecognized tag value=" + tag + ", tagClass=" + localAsnIS.getTagClass()); } } } catch (IOException e) { throw new AsnException("IOException while decoding External: " + e.getMessage(), e); } }  void decode(AsnInputStream ais); void encode(AsnOutputStream aos); void encode(AsnOutputStream aos, int tagClass, int tag); byte[] getEncodeType(); void setEncodeType(byte[] data); BitSetStrictLength getEncodeBitStringType(); void setEncodeBitStringType(BitSetStrictLength data); boolean isOid(); void setOid(boolean oid); boolean isInteger(); void setInteger(boolean integer); boolean isObjDescriptor(); void setObjDescriptor(boolean objDescriptor); long[] getOidValue(); void setOidValue(long[] oidValue); long getIndirectReference(); void setIndirectReference(long indirectReference); String getObjDescriptorValue(); void setObjDescriptorValue(String objDescriptorValue); boolean isAsn(); void setAsn(boolean asn); boolean isOctet(); void setOctet(boolean octet); boolean isArbitrary(); void setArbitrary(boolean arbitrary);  }
@Test public void testDecode() throws Exception { byte[] data = new byte[] { 0x28, 0x23, 0x06, 0x07, 0x04, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, (byte) 0xa0, 0x18, (byte) 0xa0, (byte) 0x80, (byte) 0x80, 0x09, (byte) 0x96, 0x02, 0x24, (byte) 0x80, 0x03, 0x00, (byte) 0x80, 0x00, (byte) 0xf2, (byte) 0x81, 0x07, (byte) 0x91, 0x13, 0x26, (byte) 0x98, (byte) 0x86, 0x03, (byte) 0xf0, 0x00, 0x00 }; AsnInputStream asin = new AsnInputStream(data); int tag = asin.readTag(); assertTrue(External._TAG_IMPLICIT_SEQUENCE == tag); External external = new External(); external.decode(asin); assertTrue(external.isOid()); assertTrue(Arrays.equals(new long[] { 0, 4, 0, 0, 1, 1, 1, 1 }, external.getOidValue())); assertFalse(external.isInteger()); assertTrue(external.isAsn()); assertTrue(Arrays.equals(new byte[] { (byte) 0xa0, (byte) 0x80, (byte) 0x80, 0x09, (byte) 0x96, 0x02, 0x24, (byte) 0x80, 0x03, 0x00, (byte) 0x80, 0x00, (byte) 0xf2, (byte) 0x81, 0x07, (byte) 0x91, 0x13, 0x26, (byte) 0x98, (byte) 0x86, 0x03, (byte) 0xf0, 0x00, 0x00 }, external.getEncodeType())); }