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 org.apache.haox.asn1.UniversalTag; import java.io.IOException; import java.nio.ByteBuffer; public abstract class Asn1Simple<T> extends AbstractAsn1Type<T> { private byte[] bytes; public Asn1Simple(UniversalTag tagNo) { this(tagNo, null); } public Asn1Simple(UniversalTag tagNo, T value) { super(TagClass.UNIVERSAL, tagNo.getValue(), value); setEncodingOption(EncodingOption.PRIMITIVE); } protected byte[] getBytes() { return bytes; } protected void setBytes(byte[] bytes) { this.bytes = bytes; } @Override public void encode(ByteBuffer buffer) { encodeTag(buffer, tagFlags(), tagNo()); int bodyLen = encodingBodyLength(); encodeLength(buffer, bodyLen); if (bodyLen > 0) { buffer.put(encodeBody()); } } protected byte[] encodeBody() { if (bytes == null) { toBytes(); } return bytes; } @Override protected void encodeBody(ByteBuffer buffer) { buffer.put(encodeBody()); } @Override protected int encodingBodyLength() { if (getValue() == null) { return 0; } if (bytes == null) { toBytes(); } return bytes.length; } @Override protected void decodeBody(LimitedByteBuffer content) throws IOException { byte[] leftBytes = content.readAllLeftBytes(); if (leftBytes.length > 0) { setBytes(leftBytes); toValue(); } } @Override public boolean isConstructed() { return false; } protected void toValue() throws IOException {} protected void toBytes() {} public static boolean isSimple(int tagNo) { return isSimple(UniversalTag.fromValue(tagNo)); } public static boolean isSimple(UniversalTag tagNo) { switch (tagNo) { case BIT_STRING: case BMP_STRING: case BOOLEAN: case ENUMERATED: case GENERALIZED_TIME: case GENERAL_STRING: case IA5_STRING: case INTEGER: case NULL: case NUMERIC_STRING: case OBJECT_IDENTIFIER: case OCTET_STRING: case PRINTABLE_STRING: case T61_STRING: case UNIVERSAL_STRING: case UTC_TIME: case UTF8_STRING: case VISIBLE_STRING: return true; default: return false; } } public static Asn1Type createSimple(int tagNo) { if (! isSimple(tagNo)) { throw new IllegalArgumentException("Not simple type, tag: " + tagNo); } return createSimple(UniversalTag.fromValue(tagNo)); } public static Asn1Type createSimple(UniversalTag tagNo) { if (! isSimple(tagNo)) { throw new IllegalArgumentException("Not simple type, tag: " + tagNo); } switch (tagNo) { case BIT_STRING: return new Asn1BitString(); case BMP_STRING: return new Asn1BmpString(); case BOOLEAN: return new Asn1Boolean(); case ENUMERATED: return null; case GENERALIZED_TIME: return new Asn1GeneralizedTime(); case GENERAL_STRING: return new Asn1GeneralString(); case IA5_STRING: return new Asn1IA5String(); case INTEGER: return new Asn1Integer(); case NULL: return new Asn1Null(); case NUMERIC_STRING: return new Asn1NumericsString(); case OBJECT_IDENTIFIER: return new Asn1ObjectIdentifier(); case OCTET_STRING: return new Asn1OctetString(); case PRINTABLE_STRING: return new Asn1PrintableString(); case T61_STRING: return new Asn1T61String(); case UNIVERSAL_STRING: return new Asn1UniversalString(); case UTC_TIME: return new Asn1UtcTime(); case UTF8_STRING: return new Asn1Utf8String(); case VISIBLE_STRING: return new Asn1VisibleString(); default: throw new IllegalArgumentException("Unexpected tag " + tagNo.getValue()); } } }