package org.apache.haox.asn1.type; import org.apache.haox.asn1.EncodingOption; import org.apache.haox.asn1.LimitedByteBuffer; import org.apache.haox.asn1.TagClass; import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.nio.ByteBuffer; /** * For tagging any Asn1Type with a tagNo */ public class Asn1Tagging<T extends Asn1Type> extends AbstractAsn1Type<T> { public Asn1Tagging(boolean isAppSpecific) { this(-1, null, isAppSpecific); } public Asn1Tagging(int tagNo, T value, boolean isAppSpecific) { super(isAppSpecific ? TagClass.APPLICATION : TagClass.CONTEXT_SPECIFIC, tagNo, value); setEncodingOption(EncodingOption.EXPLICIT); if (value == null) { initValue(); } } @Override protected int encodingBodyLength() { AbstractAsn1Type value = (AbstractAsn1Type) getValue(); if (encodingOption.isExplicit()) { return value.encodingLength(); } else if (encodingOption.isImplicit()) { return value.encodingBodyLength(); } else { throw new RuntimeException("Invalid util option, only allowing explicit/implicit"); } } @Override public boolean isConstructed() { if (encodingOption.isExplicit()) { return true; } else if (encodingOption.isImplicit()) { AbstractAsn1Type value = (AbstractAsn1Type) getValue(); return value.isConstructed(); } return false; } @Override protected void encodeBody(ByteBuffer buffer) { AbstractAsn1Type value = (AbstractAsn1Type) getValue(); if (encodingOption.isExplicit()) { value.encode(buffer); } else if (encodingOption.isImplicit()) { value.encodeBody(buffer); } else { throw new RuntimeException("Invalid util option, only allowing explicit/implicit"); } } @Override protected void decodeBody(LimitedByteBuffer content) throws IOException { AbstractAsn1Type value = (AbstractAsn1Type) getValue(); if (encodingOption.isExplicit()) { value.decode(content); } else if (encodingOption.isImplicit()) { value.decodeBody(content); } else { throw new RuntimeException("Invalid util option, only allowing explicit/implicit"); } } private void initValue() { Class<? extends Asn1Type> valueType = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; AbstractAsn1Type value = null; try { value = (AbstractAsn1Type) valueType.newInstance(); } catch (Exception e) { throw new RuntimeException("Failed to create tagged value", e); } setValue((T) value); } }