
Parameterized Types
The compiler can parse parameterized type definitions and references as specified in the X.683 standard. These types allow dummy parameters to be declared that will be replaced with actual parameters when the type is referenced. This is similar to templates in C++.
A simple and common example of the use of parameterized types is for the declaration of an upper bound on a sized type as follows:
SizedOctetString{INTEGER:ub} ::= OCTET STRING (SIZE (1..ub))In this definition, `ub' would be replaced with an actual value when the type is referenced. For example, a sized octet string with an upper bound of 32 would be declared as follows:
OctetString32 ::= SizedOctetString{32}The compiler would handle this in the same way as if the original type was declared to be an octet string of size 1 to 32. That is, it will generate a C structure containing a static byte array of size 32 as follows:
typedef struct OctetString32 { ASN1UINT numocts; ASN1OCTET data[32]; } OctetString32;Another common example of parameterization is the substitution of a given type inside a common container type. For example, security specifications frequently contain a `signed' parameterized type that allows a digital signature to be applied to other types. An example of this would be as follows:
SIGNED { ToBeSigned } ::= SEQUENCE { toBeSigned ToBeSigned, algorithmOID OBJECT IDENTIFIER, paramS Params, signature BIT STRING }SignedName ::= SIGNED { Name }typedef struct SignedName { Name toBeSigned; ASN1OBJID algorithmOID; Params paramS; ASN1DynBitStr signature; } SignedName;When processing parameterized type definitions, the compiler will first look to see if the parameters are actually used in the final generated code. If not, they will simply be discarded and the parameterized type converted to a normal type reference. For example, when used with information objects, parameterized types are frequently used to pass information object set definitions to impose table constraints on the final type. Since table constraints do not affect the code that is generated by the compiler, the parameterized type definition is reduced to a normal type definition and references to it are handled in the same way as defined type references. This can lead to a significant reduction in generated code in cases where a parameterized type is referenced over and over again.
ProtocolIE-Field {RANAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE { id RANAP-PROTOCOL-IES.&id ({IEsSetParam}), criticality RANAP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}), value RANAP-PROTOCOL-IES.&Value ({IEsSetParam}{@id}) }In this case, IEsSetParam refers to an information object set specification that constrains the values that are allowed to be passed for any given instance of a type referencing a ProtocolIE-Field. The compiler does not add any extra code to check for these values, so the parameter can be discarded (note that this is not true if the -tables compiler option is specified). After processing the Information Object Class references within the construct (refer to the section on "Information Objects" for information on how this is done), the reduced definition for ProtocolIE-Field becomes the following:
ProtocolIE-Field ::= SEQUENCE { id ProtocolIE-ID, criticality Criticality, value ASN.1 OPEN TYPE }
Objective Systems, Inc.102 Pickering Way, Suite #506Exton, Pennsylvania 19341 http://www.obj-sys.com Phone: (484) 875-9841 Toll-free: (877) 307-6855 (US only) Fax: (484) 875-9830 info@obj-sys.com |