package net.gcdc.asn1.uper; import java.lang.annotation.Annotation; import java.math.BigInteger; import net.gcdc.asn1.datatypes.Asn1BigInteger; import net.gcdc.asn1.datatypes.IntRange; class BigIntCoder implements Encoder, Decoder { @Override public <T> boolean canDecode(Class<T> classOfT, Annotation[] extraAnnotations) { return Asn1BigInteger.class.isAssignableFrom(classOfT); } @Override public <T> T decode(BitBuffer bitbuffer, Class<T> classOfT, Annotation[] extraAnnotations) { AnnotationStore annotations = new AnnotationStore(classOfT.getAnnotations(), extraAnnotations); UperEncoder.logger.debug("BIG INT"); IntRange intRange = annotations.getAnnotation(IntRange.class); if (intRange != null) { throw new UnsupportedOperationException( "Big int with range is not supported yet"); } int lengthInOctets = (int) UperEncoder.decodeLengthDeterminant(bitbuffer); BitBuffer valueBits = ByteBitBuffer.allocate(lengthInOctets * 8); for (int i = 0; i < lengthInOctets * 8; i++) { valueBits.put(bitbuffer.get()); } valueBits.flip(); BigInteger resultValue = new BigInteger(+1, valueBits.array()); UperEncoder.logger.debug("big int Decoded as {}", resultValue); return UperEncoder.instantiate(classOfT, resultValue); } @Override public <T> boolean canEncode(T obj, Annotation[] extraAnnotations) { return obj instanceof Asn1BigInteger; } @Override public <T> void encode(BitBuffer bitbuffer, T obj, Annotation[] extraAnnotations) throws Asn1EncodingException { Class<?> type = obj.getClass(); AnnotationStore annotations = new AnnotationStore(type.getAnnotations(), extraAnnotations); IntRange range = annotations.getAnnotation(IntRange.class); if (range != null) { throw new UnsupportedOperationException( "Asn1 BigInteger with range is not supported yet"); } byte[] array = ((Asn1BigInteger) obj).value().toByteArray(); int lengthInOctets = array.length; int position1 = bitbuffer.position(); try { UperEncoder.encodeLengthDeterminant(bitbuffer, lengthInOctets); } catch (Asn1EncodingException e) { throw new Asn1EncodingException(" length determinant of " + type.getName(), e); } int position2 = bitbuffer.position(); for (byte b : array) { bitbuffer.putByte(b); } UperEncoder.logger.debug("Big Int({}): len {}, val {}", obj, bitbuffer.toBooleanString(position1, position2 - position1), bitbuffer.toBooleanStringFromPosition(position2)); return; } }