...
By creating a constructed external format definition, that is, where the external record definition consists of sub-externals.
By extending the
target_internal
with first level temporary fields which will hold the values of the nested fields to be encoded.By creating a new UDR which is populated with values from the incoming nested UDR.
Constructed Internal
It is possible to encode to a constructed sequential external, that is, an external sequential definition containing other externals to represent the nested fields. The disadvantage with this approach is that it is not possible to mix different level fields in the produced output record.
external
Name the fields in the outgoing external exactly as in the incoming ASN.1 structure. This allows the use of automatic mapping.
Code Block |
---|
asn_block { exchangeRec DEFINITIONS IMPLICIT TAGS ::= BEGIN main_udr ::= SEQUENCE { duration [ APPLICATION 1 ] INTEGER OPTIONAL, calledNumber [ APPLICATION 2 ] INTEGER OPTIONAL, callingNumber subUDR1 } subUDR1 ::= [ APPLICATION 3 ] SEQUENCE { category [ APPLICATION 4 ] INTEGER OPTIONAL, adressString subUDR2 } subUDR2 ::= [ APPLICATION 5 ] SEQUENCE { number [ APPLICATION 6 ] INTEGER OPTIONAL, ton [ APPLICATION 7 ] INTEGER OPTIONAL, npi [ APPLICATION 8 ] INTEGER OPTIONAL } END }; //------------------------------------------------------- external out { ascii duration : static_size(2); ascii calledNumber : static_size(8); subUDR1 callingNumber : static_size(8); }; external subUDR1 { ascii category : static_size(2); subUDR2 adressString : static_size(6); }; external subUDR2 { ascii number : static_size(2); ascii ton : static_size(2); ascii npi : static_size(2); }; |
in-map and out_map
Automatic mapping considers sub-UDRs as well.
Code Block |
---|
in_map inM : external( main_udr ), target_internal( myTI ) { automatic; }; out_map outM : internal( myTI ), external( out ) { automatic; }; |
decoder and encoder
Code Block |
---|
decoder myDec : in_map( inM ); encoder myEnc : out_map( outM ); |
Extending the target_internal
Create an internal
which will hold the nested fields to be mapped to the sequential format. Define a target_internal
holding both the asn_block
and the internal
. The values of the nested fields of the target_internal
are copied to the fields added with the internal format specification, using APL code.
...
Code Block |
---|
consume { if ( udrIsPresent( input.callingNumber.adressString ) ) { input.category_i = input.callingNumber.category; input.number_i = input.callingNumber.adressString.number; input.ton_i = input.callingNumber.adressString.ton; input.npi_i = input.callingNumber.adressString.npi; } udrRoute( input ); } |
Creating a New UDR
Create an internal
for the sequential format, however do not add it to the incoming ASN.1 structure's target_internal
. Instead for each incoming UDR, create a new UDR and copy the field values from the ASN.1 UDR. The ASN.1 UDR can then be discarded, routing the new internal further.
...
Code Block |
---|
exRec.exchangeRec_Int outUDR = udrCreate( exRec.exchangeRec_Int ); consume { outUDR.duration_i = input.duration; outUDR.calledNumber_i = input.calledNumber; if ( udrIsPresent( input.callingNumber.adressString ) ) { outUDR.category_i = input.callingNumber.category; outUDR.number_i = input.callingNumber.adressString.number; outUDR.ton_i = input.callingNumber.adressString.ton; outUDR.npi_i = input.callingNumber.adressString.npi; } udrRoute( outUDR ); } |
external
The ASN.1 definition can be copied directly into an Ultra asn_block
definition. An external
for the sequential outgoing UDRs is created.
...
Code Block |
---|
asn_block { : main_udr : }; // The same field names as in the internal format are used // to be able to use automatic mapping. external exchangeRecSEQ ascii duration_i ascii calledNumber_i ascii category_i ascii number_i ascii ton_i ascii npi_i }; |
internal
An internal
, containing fields matching the external field names, is created in order to hold the values to be encoded.
Code Block |
---|
internal exchangeRec_Int { int duration_i : optional; string calledNumber_i : optional; int category_i : optional; string number_i : optional; string ton_i : optional; string npi_i : optional; }; |
in_map and out_map
The incoming external
is turned into a target_internal
, without adding any fields. The internal
is mapped to the sequential external format.
Code Block |
---|
in_map exchangeRecord_MAP_IN_II: external(main_udr), target_internal(exRec_TI){ automatic; }; out_map exchangeRecord_MAP_OUT: external(exchangeRecSEQ), internal(exchangeRec_Int) { automatic; }; |
decoder and encoder
Code Block |
---|
decoder exchangeRec: in_map(exchangeRecord_MAP_IN); encoder exchangeRecSEQ: out_map(exchangeRecord_MAP_OUT); |
...