@Override public <T> T decode(BitBuffer bitbuffer, Class<T> classOfT, Annotation[] extraAnnotations) { UperEncoder.logger.debug("BYTE"); return (T) new Byte( (byte) UperEncoder.decodeConstrainedInt(bitbuffer, UperEncoder.newRange(0, 255, false))); }
@Override public <T> T decode(BitBuffer bitbuffer, Class<T> classOfT, Annotation[] extraAnnotations) { AnnotationStore annotations = new AnnotationStore(classOfT.getAnnotations(), extraAnnotations); if (!Asn1VarSizeBitstring.class.isAssignableFrom(classOfT)) { UperEncoder.logger.debug("Bitlist(fixed-size, all-named)"); FixedSize fixedSize = annotations.getAnnotation(FixedSize.class); if (fixedSize == null) { throw new UnsupportedOperationException( "bitstrings of non-fixed size that do not extend Asn1VarSizeBitstring are not supported yet"); } Asn1ContainerFieldSorter sorter = new Asn1ContainerFieldSorter(classOfT); if (fixedSize.value() != sorter.ordinaryFields.size()) { throw new IllegalArgumentException( "Fixed size annotation " + fixedSize.value() + " does not match the number of fields " + sorter.ordinaryFields.size() + " in " + classOfT.getName()); } if (UperEncoder.hasExtensionMarker(annotations)) { boolean extensionPresent = bitbuffer.get(); if (extensionPresent) { throw new UnsupportedOperationException( "extensions in fixed-size bitlist are not supported yet"); } } T result = UperEncoder.instantiate(classOfT); for (Field f : sorter.ordinaryFields) { boolean value = bitbuffer.get(); UperEncoder.logger.debug("Field {} set to {}", f.getName(), value); try { f.set(result, value); } catch (IllegalArgumentException | IllegalAccessException e) { throw new IllegalArgumentException("can't decode " + classOfT, e); } } return result; } else { UperEncoder.logger.debug("Bitlist(var-size)"); FixedSize fixedSize = annotations.getAnnotation(FixedSize.class); SizeRange sizeRange = annotations.getAnnotation(SizeRange.class); // We use reflection here to access protected method of Asn1VarSizeBitstring. // Alternative would be to mandate BitSet constructors for all subclasses of // Asn1VarSizeBitstring. Method setBitMethod; try { setBitMethod = Asn1VarSizeBitstring.class.getDeclaredMethod("setBit", int.class, boolean.class); setBitMethod.setAccessible(true); } catch (SecurityException | NoSuchMethodException e) { throw new AssertionError("Can't find/access setBit " + e); } long size = (fixedSize != null) ? fixedSize.value() : (sizeRange != null) ? UperEncoder.decodeConstrainedInt( bitbuffer, UperEncoder.intRangeFromSizeRange(sizeRange)) : badSize(classOfT); T result = UperEncoder.instantiate(classOfT); for (int i = 0; i < size; i++) { try { setBitMethod.invoke(result, i, bitbuffer.get()); } catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) { throw new IllegalArgumentException("Can't invoke setBit", e); } } return result; } }