示例#1
0
 @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;
 }
 @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;
   }
 }