Using partial decoding can change how types are generated in addition to changing what functions are generated.
When -noencode
is not used, types are
generated normally, to support the complete generation of encoders.
If, however, the -noencode
option is used, then
the partial decode configuration determines how types are generated:
they may be fully generated, partially generated,
or discarded; which case applies depends on
what values the partial decode functions will need to return.
If you target an element, that element's type will be fully generated (i.e. generated normally), allowing the partial decode function to return the complete value for that element. All types referenced by that type will also be fully generated, since those types conceptually form a part of the targeted element's value.
You can force a type to be fully generated by adding it
to the types
list of an <include>
configuration element (refer to the section on configuration files).
If you do this, it isn't necessary to also add types that your
partial decoding configuration would require to be fully generated;
those types will be automatically included.
If you target a group of elements, the enclosing SEQUENCE
or SET
type will be partially generated
(unless it must be fully generated, according to the above
rules). In this case, the generated type will include just the
fields corresponding to the targeted elements. If you target
different groups of elements in the same enclosing SEQUENCE
or SET
, the generated type will include fields
for all of the elements that were targeted in one or more of the
groups.
To illustrate this, consider the group target example
referenced above. The Name
type is defined as
Name ::= SEQUENCE { givenName VisibleString, initial VisibleString, familyName VisibleString }
and we targeted just two of the three elements (givenName
and
familyName
). As a result, the type was
partially generated:
typedef struct Name { const char* givenName; const char* familyName; } Name;
Any type that is neither fully generated nor partially generated will not be generated at all. Such a type might still have corresponding functions generated.
To illustrate, in both of our examples, PersonnelRecord
is not a part of the values we targeted, nor did we target any
group of elements in that type. Therefore, PersonnelRecord
is discarded. If you look at the generated header file for the
aforementioned samples, you will find we don't generate that type.
Three kinds of PER decode functions may be generated:
normal decode functions
partial decode functions
skip functions
All fully generated types will have a normal decode function generated.
For some types, no function will need to be generated. Types that are discarded and which require neither a partial decode function nor a skip function will have no generated functions.
The next two sections cover partial decode and skip functions.
A partial decode function will be generated for each partial decode target you configure. Partial decode function names have the following format:
asn1PPD_<outermost_type>_<suffix>
The suffix is a unique suffix, indicating the element or
elements being targeted. The suffix may be longer or shorter, as
needed, to uniquely identify which of the outermost type's configured
targets it relates to. For groups, the suffix will be based on the
type name of the enclosing SEQUENCE
or
SET
. You can control the suffix by providing a
name when configuring the target in the configuration file. The
behavior of this partial decode function is to decode a value of the
given outermost type, and return just the targeted value(s).
Other partial decode functions will also be generated to support the top-level partial decode functions just described. Each of these functions is responsible for returning the same value(s), but will decode a type nested inside the outermost type. The name for such a function will be based on the type it actually decodes, rather than the outermost type for which partial decoding was configured. For these supplemental partial decode functions, the suffix part of the function name is not configurable, but you will not use these supplemental functions directly anyway.
The value returned by a partial decode function is
dynamically allocated (or is a list of dynamically allocated
values). You are responsible for freeing the memory associated
with those values. If you are generating code using the C++
standard libary option (-cpp11
), it's important
to follow the memory management guidelines discussed for that option.
Otherwise, make use of the generated free functions or rtxMemFree
to free the memory. If the partial decode function returns a list,
here are some additional rules to keep in mind:
If you are using -cpp11
,
the objects in the list may contain standard library objects
(e.g. std::string
). If so, you will need
to interate through the list and follow the memory management
rules related to using that option. The remaining points
in this list do not apply to you.
rtxDListFreeAll
can be used
to free all of the memory associated with the list and its
contents. However, this cannot be used if the objects in the
list contain pointers to dynamically allocated memory.
If the objects in the list have an associated
asn1Free_*
function, you should iterate
through the list and use it (or else, see the next option).
You can use rtxMemFree
to free all memory allocated with the current
OSCTXT
context object in one shot.
A skip function may be generated when a type will need to be
skipped over (sometimes, a separate function is not required). This
happens during partial decoding, when the decoder needs to parse
through an encoded value that it isn't interested in, in order to
reach the encoded values that it is interested
in. The job of the skip function is simply to get past the value of
the corresponding type. Skip function names are of the form
asn1PDSkip_<typename>
. You will not directly
invoke the skip functions.
In our examples, the target path passes through
PersonnelRecord.children
, which means our
partial decode function must skip over the sibling elements,
such as PersonnelRecord.name
of type
Name
. Therefore, we generate function
asn1PDSkip_Name
.
The partial decode feature affects C++ Control Class generation. The C++ Control Class will include partial decode helper methods for any partial decode functions that are generated for the associated type. If the outermost type, the one the control class is being generated for, is fully generated, the partial decode methods will simply be added to what is normally generated. However, if the type is not fully generated, then the C++ control class will be generated without a msgData field (it won't contain a value of the type) and without most of the other methods it would normally have (those which would operate on msgData); it will, however, have the partial decode helper methods.