This blog introduces a new feature for asn1c's Java and C# code generation called "lazy open type decoding".  I should note that this feature allows you to implement "lazy" decoding of open types in the sense that it lets you decode open types only when you actually want to, but the responsibility for decoding then shifts from asn1c-generated code to your own code; in other words, this is not lazy decoding in the sense of "automatically decode open types only when I need you to".  What you really have is a runtime choice between automatic and manual decoding of open types.

In ASN.1, information objects provide a way to specify and constrain open types.  As a quick example, you may have the following ASN.1.

ATTRIBUTE ::= CLASS {
   &Type,
   &id      OBJECT IDENTIFIER UNIQUE
}
WITH SYNTAX {
   WITH SYNTAX &Type ID &id
}

Attribute ::= SEQUENCE {
   type-id   ATTRIBUTE.&id ({SupportedAttributes}),
   value     ATTRIBUTE.&Type  ({SupportedAttributes}{@type})
}

...

In this example, Attribute.value is an open type.  The table constraints are used to constrain Attribute.value based on the value of type-id.

With these constraints, asn1c is able to produce code that automatically decodes the value of Attribute.value, using the correct actual type.  Such code is produced using the "-tables" command-line option.  Without the -tables option, you would need to manually encode and decode the actual type for Attribute.value.

Using -tables makes working with open types easier.  However, for performance reasons, perhaps you don't want every open type automatically decoded.  One solution is to simply not use "-tables" and in many cases, that may be just the thing to do.  If, however, you need to make the choice between manual and automatic open type decoding at runtime, you can now do that too.

As of version 6.4.4, an undocumented "-lazytables" option has been added.  This generates slightly different code which supports runtime enabling/disabling of open type decoding.  In version 6.5, "-lazytables" will not be present; its behavior will be the standard behavior.  The only reason we used a command line option in 6.4.4 was to avoid the risk of unforeseen backward incompatibilities.  So, if you are using asn1c 6.4.4, you begin by generating your code using the "-lazytables" option (also still specify "-tables").

In your code, you can invoke buffer.setLazyOpenTypeDecode(true) on your decode buffer to disable automatic decoding of open types.  You may then write code following this pattern:

buffer.setLazyOpenTypeDecode(true);
pdu.decode(buffer);
...

//navigate to the open type and determine the actual type
...

//Create a new buffer on the open type data or else use  Asn1PerDecodeBuffer.setBuffer.
//In this example, attribute would be an instance of Java class Attribute, generated
//for ASN.1 type Attribute from the previous example.  The actual Java type for
//attribute.value will be Asn1OpenType, and attribute.value.value contains the
//encoding of the actual ASN.1 type.
//Note that you may or may not use lazy open type decoding on this buffer.
Asn1PerDecodeBuffer buffer = new Asn1PerDecodeBuffer(((Asn1OpenType)attribute.value).value, aligned);

//Create object of the correct actual type and decode it.
//You may replace the Asn1OpenType object if you wish, as is done here.
attribute.value = new ActualType();
attribute.value.decode(innerBuffer);

Of course, if you had not invoked buffer.setLazyOpenTypeDecode(true), then your open type would automatically have been decoded, and the actual Java type of attribute.value, instead of Asn1OpenType, would have been ActualType (assuming ActualType represented the actual ASN.1 type, according to the table constraints).


Published

Category

ASN1C