Deferred Decoding and Partial Decoding

Another way to improve decoding performance of large messages is through the use of either deferred decoding or partial decoding. This allows for the selective decoding of only parts of a message in a single decode function call. This can significantly reduce decoding time because large parts of messages can be skipped.

Deferred decoding can be done on elements defined within a SEQUENCE, SET or CHOICE construct. It is done by designating an element to be an open type by using the <isOpenType/> configuration setting. This setting causes the ASN1C compiler to insert an Asn1OpenType placeholder in place of the type that would have normally been used for the element. The data in its original encoded form will be stored in the open type container when the message is decoded. The data within the open type container can be fully decoded later by using the normally-generated decode function generated by the ASN1C compiler. (This stands in contrast to C and C++ code generation, which requires a special decode function for this purpose.)

Partial decoding is similar to deferred decoding, except that where deferred decoding captures the encoded data for later decoding, partial decoding skips over it and discards the encoded data. Since the encoded data is not retained, partial decoding uses less memory. Partial decoding is done by designating an element to be skipped using the <skip/> configuration setting. This setting causes the ASN1C compiler to generate decoders that simply skip over that element.

In following example, decoding of the element id is deferred, while details is skipped:

Identifier ::= SEQUENCE {
   id INTEGER,
   oid OBJECT IDENTIFIER,
   details DetailedStuff
}

The following configuration file is required to indicate the element id is to be processed as an open type (i.e. that it will be decoded later) and that element details should be skipped:

<asn1config>
   <module>
      <name>modulename</name>
      <production>
         <name>Identifier</name>
         <element>
            <name>id</name>
            <isOpenType/>
         <element/>
         <element>
            <name>details</name>
            <skip/>
         <element/>
      <production/>
   <module/>
<asn1config/>

In the generated code, the element id type will be replaced with an open type (Asn1OpenType), and the type will be decoded as such. When the top-level decoding has finished, the element may be decoded by taking the open type value (id.value) and using it as a source for a new Asn1BerDecodeBuffer. The element can then be decoded by creating a new object for the element (in this case, a new instance of Asn1ObjectIdentifier) and calling its decode method. The element details will simply be skipped.