@Override public <T> T decode(BitBuffer bitbuffer, Class<T> classOfT, Annotation[] extraAnnotations) { AnnotationStore annotations = new AnnotationStore(classOfT.getAnnotations(), extraAnnotations); UperEncoder.logger.debug("SEQUENCE"); T result = UperEncoder.instantiate(classOfT); Asn1ContainerFieldSorter sorter = new Asn1ContainerFieldSorter(classOfT); boolean extensionPresent = false; if (UperEncoder.hasExtensionMarker(annotations)) { extensionPresent = bitbuffer.get(); UperEncoder.logger.debug( "with extension marker, extension {}", extensionPresent ? "present!" : "absent"); } // Bitmask for optional fields. Deque<Boolean> optionalFieldsMask = new ArrayDeque<>(sorter.optionalOrdinaryFields.size()); for (Field f : sorter.optionalOrdinaryFields) { optionalFieldsMask.add(bitbuffer.get()); UperEncoder.logger.debug( "with optional field {} {}", f.getName(), optionalFieldsMask.getLast() ? "present" : "absent"); } // All ordinary fields (fields within extension root). for (Field f : sorter.ordinaryFields) { if (!UperEncoder.isTestInstrumentation(f) && (UperEncoder.isMandatory(f) || (UperEncoder.isOptional(f) && optionalFieldsMask.pop()))) { UperEncoder.logger.debug("Field : {}", f.getName()); try { f.set(result, UperEncoder.decode2(bitbuffer, f.getType(), f.getAnnotations())); } catch (IllegalAccessException e) { throw new IllegalArgumentException( "can't access 'set method' for field " + f + " of class " + classOfT + " " + e, e); } } } // Extension fields. if (UperEncoder.hasExtensionMarker(annotations) && extensionPresent) { // Number of extensions. int numExtensions = (int) UperEncoder.decodeLengthOfBitmask(bitbuffer); UperEncoder.logger.debug("sequence has {} extension(s)", numExtensions); // Bitmask for extensions. boolean[] bitmaskValueIsPresent = new boolean[numExtensions]; for (int i = 0; i < numExtensions; i++) { bitmaskValueIsPresent[i] = bitbuffer.get(); UperEncoder.logger.debug( "extension {} is {}", i, bitmaskValueIsPresent[i] ? "present" : "absent"); } // Values. UperEncoder.logger.debug("decoding extensions values..."); for (int i = 0; i < numExtensions; i++) { UperEncoder.logger.debug( "sequence extension {} {}", i, bitmaskValueIsPresent[i] ? "present" : "absent"); if (bitmaskValueIsPresent[i]) { UperEncoder.logger.debug("decoding extension {}...", i); Field field = sorter.extensionFields.size() > i ? sorter.extensionFields.get(i) : null; Class<?> classOfElement = field != null ? field.getType() : null; try { Object decodedValue = UperEncoder.decodeAsOpenType(bitbuffer, classOfElement, field.getAnnotations()); if (field != null) { field.set(result, decodedValue); } } catch (IllegalArgumentException | IllegalAccessException e) { throw new IllegalArgumentException("can't decode " + classOfT, e); } } } } sorter.revertAccess(); return result; }