The compiler generates parser functions. These functions have the following signature:
int asn1PP_&type> (OSCTXT* pctxt, ASN1RawEventResp parseIndicator);
Your program will begin by calling one of these parser functions
and passing ASN1RER_PARSE
. The parser function will parse the ASN.1
value and fire events by invoking your event handlers.
The interface supports three events:
component
actual-type
component-end
The component event fires when a component is ready to be parsed. You receive the numeric identifier for the component (componentID), and a flag (nestedValues) which indicates whether component events may fire for child components. You may respond with:
ASN1RER_CONSUMED
: This indicates that
you have consumed the value yourself. The parser will
continue as if it had parsed the value. You will not receive
a component-end event for this component.
ASN1RER_PARSE
: This indicates that you
want the parser to parse the component's value, continuing to
fire events for child components, if applicable. If
nestedValues
is true, component events
will fire for any child components present, followed by a
component-end event when the end of the current component is
reached. If nestedValues
is false, there
are no child components to receive events for, and you will
not receive a component-end event for this component.
ASN1RER_QUIET_PARSE
: This indicates that
you want the parser to handle parsing the component's value
without firing any events for any child components. You will
not receive a component-end event for this component. Return
this value when you are neither interested in a component's
value nor in any of its sub-values, in order to let the parser
move past the value as efficiently as possible.
The actual-type event fires when an open type is ready to be parsed.
It notifies you of the actual type, allowing you to make type-specific
decisions. This event only is only fired when -table-unions
is used (otherwise, the parser does not attempt to determine the actual type).
You receive the numeric identifier for the actual type (actualTypeID),
and a length. If the actual type is unknown, the actualTypeID
will be 0. If an open type is encoded with fragmentation and -perindef
was not used, an error will be returned. Otherwise, the length will
represent the defragmented length of the actual type encoding, and the
context will hold a defragmented version of the encoding. Thus, your
event handler does not need to worry about fragmentation.
The actual-type event is always preceded by a component event with
nestedValues
equal to true. If you respond to the
component event with ASN1RER_CONSUMED
or
ASN1RER_QUIET_PARSE
, the actual-type event will not
fire. If you are not interested in receiving events for the open type
value, responding to the component event with
ASN1RER_QUIET_PARSE
lets the parser skip past the
open type value in the most efficient way.
You may respond to the actual-type event with:
ASN1RER_CONSUMED
: This indicates that
you have consumed the actual type value yourself. In this
case, the component-end event will not fire for the component.
When the actual type is unknown (actualTypeID
equals 0), you will need the length parameter
(len
) in order to know how much data to
consume.
ASN1RER_PARSE
: This indicates that you
want the parser to parse the actual type. When the end of the
open type value is reached, so is the end of the component
value, and the component-end event will fire.
ASN1RER_QUIET_PARSE
: This indicates that
you want the parser to handle parsing the actual type, but you
don't want to receive events for any child components. The
component-end event will not fire for the open type component.
Implementing a handler for the actual-type event is optional. If
you do not implement a handler, the behavior is the same as if you
did and returned ASN1RER_PARSE
for every event.
The component-end event indicates that the end of a component value
has been reached. You receive the numeric component identifier, the
same as with the component event. As mentioned above, whether or not
you receive this event depends on the nestedValues
parameter of the component event, as well as how you respond to the
component and/or actual-type events. Basically, if the event is not
needed in order for you to know that you won't receive further events
for the component, then the event is not fired.
Implementing a handler for the component-end event is optional.