aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1/doc/src/asn1_spec.xmlsrc
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/asn1/doc/src/asn1_spec.xmlsrc
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/asn1/doc/src/asn1_spec.xmlsrc')
-rw-r--r--lib/asn1/doc/src/asn1_spec.xmlsrc824
1 files changed, 824 insertions, 0 deletions
diff --git a/lib/asn1/doc/src/asn1_spec.xmlsrc b/lib/asn1/doc/src/asn1_spec.xmlsrc
new file mode 100644
index 0000000000..8d61834da8
--- /dev/null
+++ b/lib/asn1/doc/src/asn1_spec.xmlsrc
@@ -0,0 +1,824 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2003</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Specialized Decodes</title>
+ <prepared>EAB/UAB/UKH/KD Bertil Karlsson</prepared>
+ <docno></docno>
+ <date>2003-04-24</date>
+ <rev>D</rev>
+ <file>asn1_spec.xml</file>
+ </header>
+ <marker id="SpecializedDecodes"></marker>
+ <p>When performance is of highest priority and one is interested in
+ a limited part of the ASN.1 encoded message, before one decide what
+ to do with the rest of it, one may want to decode only this small
+ part. The situation may be a server that has to decide to which
+ addressee it will send a message. The addressee may be interested in
+ the entire message, but the server may be a bottleneck that one want
+ to spare any unnecessary load. Instead of making two <em>complete decodes</em> (the normal case of decode), one in the server and one
+ in the addressee, it is only necessary to make one <em>specialized decode</em>(in the server) and another complete decode(in the
+ addressee). The following specialized decodes <em>exclusive decode</em> and <em>selected decode</em> support to solve this and
+ similar problems.
+ </p>
+ <p>So far this functionality is only provided when using the
+ optimized BER_BIN version, that is when compiling with the
+ options <c>ber_bin</c> and <c>optimize</c>. It does also work
+ using the <c>driver</c> option. We have no intent to make this
+ available on the default BER version, but maybe in the PER_BIN
+ version (<c>per_bin</c>).
+ </p>
+
+ <section>
+ <title>Exclusive Decode</title>
+ <p>The basic idea with exclusive
+ decode is that you specify which parts of the message you want to
+ exclude from being decoded. These parts remain encoded and are
+ returned in the value structure as binaries. They may be decoded
+ in turn by passing them to a certain <c>decode_part/2</c>
+ function. The performance gain is high when the message is large
+ and you can do an exclusive decode and later on one or several
+ decodes of the parts or a second complete decode instead of two or
+ more complete decodes.
+ </p>
+
+ <section>
+ <title>How To Make It Work</title>
+ <p>In order to make exclusive decode work you have to do the
+ following:
+ </p>
+ <list type="bulleted">
+ <item>First,decide the name of the function for the exclusive
+ decode.</item>
+ <item>Second, write instructions that must consist of the name
+ of the exclusive decode function, the name of the ASN.1
+ specification and a notation that tells which parts of the
+ message structure will be excluded from decode. These
+ instructions shall be included in a configuration
+ file. </item>
+ <item>Third, compile with the additional option
+ <c>asn1config</c>. The compiler searches for a configuration
+ file with the same name as the ASN.1 spec but with the
+ extension .asn1config. This configuration file is not the same
+ as used for compilation of a set of files. See section
+ <seealso marker="#UndecodedPart">Writing an Exclusive Decode Instruction.</seealso></item>
+ </list>
+ </section>
+
+ <section>
+ <title>User Interface</title>
+ <p>The run-time user interface for exclusive decode consists of
+ two different functions. First, the function for an exclusive
+ decode, whose name the user decides in the configuration
+ file. Second, the compiler generates a <c>decode_part/2</c>
+ function when exclusive decode is chosen. This function decodes
+ the parts that were left undecoded during the exclusive
+ decode. Both functions are described below.
+ </p>
+ <p>If the exclusive decode function has for example got the name
+ <c>decode_exclusive</c> and an ASN.1 encoded message
+ <c>Bin</c> shall be exclusive decoded, the call is:</p>
+ <pre>
+{ok,Excl_Message} = 'MyModule':decode_exclusive(Bin) </pre>
+ <marker id="UndecodedPart"></marker>
+ <p>The result <c>Excl_Message</c> has the same structure as an
+ complete decode would have, except for the parts of the top-type
+ that were not decoded. The undecoded parts will be on their place
+ in the structure on the format <c>{Type_Key,Undecoded_Value}</c>.
+ </p>
+ <p>Each undecoded part that shall be decoded must be fed into the <c>decode_part/2</c> function,like:</p>
+ <pre>
+{ok,Part_Message} = 'MyModule':decode_part(Type_Key,Undecoded_Value) </pre>
+ </section>
+
+ <section>
+ <marker id="Exclusive Instruction"></marker>
+ <title>Writing an Exclusive Decode Instruction</title>
+ <p>This instruction is written in the configuration file on the
+ format:</p>
+ <pre>
+
+Exclusive_Decode_Instruction = {exclusive_decode,{Module_Name,Decode_Instructions}}.
+
+Module_Name = atom()
+
+Decode_Instructions = [Decode_Instruction]+
+
+Decode_Instruction = {Exclusive_Decode_Function_Name,Type_List}
+
+Exclusive_Decode_Function_Name = atom()
+
+Type_List = [Top_Type,Element_List]
+
+Element_List = [Element]+
+
+Element = {Name,parts} |
+ {Name,undecoded} |
+ {Name,Element_List}
+
+Top_Type = atom()
+
+Name = atom()
+ </pre>
+ <p>Observe that the instruction must be a valid Erlang term ended
+ by a dot.
+ </p>
+ <p>In the <c>Type_List</c> the "path" from the top type to each
+ undecoded sub-components is described. The top type of the path is
+ an atom, the name of it. The action on each component/type that
+ follows will be described by one of <c>{Name,parts}, {Name,undecoded}, {Name,Element_List}</c></p>
+ <p>The use and effect of the actions are:
+ </p>
+ <list type="bulleted">
+ <item><c>{Name,undecoded}</c> Tells that the element will be
+ left undecoded during the exclusive decode. The type of Name may
+ be any ASN.1 type. The value of element Name will be returned as a
+ tuple,as mentioned <seealso marker="#UndecodedPart">above</seealso>, in the value structure of the top type.</item>
+ <item><c>{Name,parts}</c> The type of Name may be one of
+ SEQUENCE OF or SET OF. The action implies that the different
+ components of Name will be left undecoded. The value of Name
+ will be returned as a tuple, as <seealso marker="#UndecodedPart">above </seealso>, where the second element is a list of
+ binaries. That is because the representation of a SEQUENCE OF/
+ SET OF in Erlang is a list of its internal type. Any of the
+ elements of this list or the entire list can be decoded by the
+ <c>decode_part</c> function.</item>
+ <item><c>{Name,Element_List}</c>This action is used when one or
+ more of the sub-types of Name will be exclusive decoded.</item>
+ </list>
+ <p>Name in the actions above may be a component name of a
+ SEQUENCE or a SET or a name of an alternative in a CHOICE.
+ </p>
+ </section>
+
+ <section>
+ <title>Example</title>
+ <p>In the examples below we use the definitions from the following ASN.1 spec:</p>
+ <marker id="Asn1spec"></marker>
+ <codeinclude file="Seq.asn" tag="" type="none"></codeinclude>
+ <p>If <c>Button</c> is a top type and we want to exclude
+ component <c>number</c> from decode the Type_List in the
+ instruction in the configuration file will be
+ <c>['Button',[{number,undecoded}]]</c>. If we call the decode
+ function <c>decode_Button_exclusive</c> the Decode_Instruction
+ will be
+ <c>{decode_Button_exclusive,['Button',[{number,undecoded}]]}</c>.
+ </p>
+ <p>We also have another top type <c>Window</c> whose sub
+ component actions in type <c>Status</c> and the parts of component
+ <c>buttonList</c> shall be left undecoded. For this type we name
+ the function <c>decode__Window_exclusive</c>. The whole
+ Exclusive_Decode_Instruction configuration is as follows: </p>
+ <codeinclude file="Seq.asn1config" tag="" type="none"></codeinclude>
+ <p></p>
+ <image file="exclusive_Win_But.gif">
+ <icaption>Figure symbolizes the bytes of a Window:status message. The components buttonList and actions are excluded from decode. Only state and enabled are decoded when decode__Window_exclusive is called. </icaption>
+ </image>
+ <p></p>
+ <p>Compiling GUI.asn including the configuration file is done like:</p>
+ <pre>
+unix> erlc -bber_bin +optimize +asn1config GUI.asn
+
+erlang> asn1ct:compile('GUI',[ber_bin,optimize,asn1config]). </pre>
+ <p>The module can be used like:</p>
+ <pre>
+
+1> Button_Msg = {'Button',123,true}.
+{'Button',123,true}
+2> {ok,Button_Bytes} = 'GUI':encode('Button',Button_Msg).
+{ok,[&lt;&lt;48&gt;&gt;,
+ [6],
+ [&lt;&lt;128&gt;&gt;,
+ [1],
+ 123],
+ [&lt;&lt;129&gt;&gt;,
+ [1],
+ 255]]}
+3> {ok,Exclusive_Msg_Button} = 'GUI':decode_Button_exclusive(list_to_binary(Button_Bytes)).
+{ok,{'Button',{'Button_number',&lt;&lt;28,1,123&gt;&gt;},
+ true}}
+4> 'GUI':decode_part('Button_number',&lt;&lt;128,1,123&gt;&gt;).
+{ok,123}
+5> Window_Msg =
+{'Window',{status,{'Status',35,
+ [{'Button',3,true},
+ {'Button',4,false},
+ {'Button',5,true},
+ {'Button',6,true},
+ {'Button',7,false},
+ {'Button',8,true},
+ {'Button',9,true},
+ {'Button',10,false},
+ {'Button',11,true},
+ {'Button',12,true},
+ {'Button',13,false},
+ {'Button',14,true}],
+ false,
+ {possibleActions,[{'Action',16,{'Button',17,true}}]}}}}.
+{'Window',{status,{'Status',35,
+ [{'Button',3,true},
+ {'Button',4,false},
+ {'Button',5,true},
+ {'Button',6,true},
+ {'Button',7,false},
+ {'Button',8,true},
+ {'Button',9,true},
+ {'Button',10,false},
+ {'Button',11,true},
+ {'Button',12,true},
+ {'Button',13,false},
+ {'Button',14,true}],
+ false,
+ {possibleActions,[{'Action',16,{'Button',17,true}}]}}}}
+6> {ok,Window_Bytes}='GUI':encode('Window',Window_Msg).
+{ok,[&lt;&lt;161&gt;&gt;,
+ [127],
+ [&lt;&lt;128&gt;&gt;, ...
+
+
+8> {ok,{status,{'Status',Int,{Type_Key_SeqOf,Val_SEQOF},
+BoolOpt,{Type_Key_Choice,Val_Choice}}}}=
+'GUI':decode_Window_status_exclusive(list_to_binary(Window_Bytes)).
+{ok,{status,{'Status',35,
+ {'Status_buttonList',[&lt;&lt;48,6,128,1,3,129,1,255&gt;&gt;,
+ &lt;&lt;48,6,128,1,4,129,1,0&gt;&gt;,
+ &lt;&lt;48,6,128,1,5,129,1,255&gt;&gt;,
+ &lt;&lt;48,6,128,1,6,129,1,255&gt;&gt;,
+ &lt;&lt;48,6,128,1,7,129,1,0&gt;&gt;,
+ &lt;&lt;48,6,128,1,8,129,1,255&gt;&gt;,
+ &lt;&lt;48,6,128,1,9,129,1,255&gt;&gt;,
+ &lt;&lt;48,6,128,1,10,129,1,0&gt;&gt;,
+ &lt;&lt;48,6,128,1,11,129,1,255&gt;&gt;,
+ &lt;&lt;48,6,128,1,12,129,1,255&gt;&gt;,
+ &lt;&lt;48,6,128,1,13,129,1,0&gt;&gt;,
+ &lt;&lt;48,6,128,1,14,129,1,255&gt;&gt;]},
+ false,
+ {'Status_actions',
+&lt;&lt;163,21,160,19,48,17,2,1,16,160,12,172,10,171,8,48,6,128,1,...&gt;&gt;}}}}
+10> 'GUI':decode_part(Type_Key_SeqOf,Val_SEQOF).
+{ok,[{'Button',3,true},
+ {'Button',4,false},
+ {'Button',5,true},
+ {'Button',6,true},
+ {'Button',7,false},
+ {'Button',8,true},
+ {'Button',9,true},
+ {'Button',10,false},
+ {'Button',11,true},
+ {'Button',12,true},
+ {'Button',13,false},
+ {'Button',14,true}]}
+11> 'GUI':decode_part(Type_Key_SeqOf,hd(Val_SEQOF)).
+{ok,{'Button',3,true}}
+12> 'GUI':decode_part(Type_Key_Choice,Val_Choice).
+{ok,{possibleActions,[{'Action',16,{'Button',17,true}}]}}
+ </pre>
+ </section>
+ </section>
+
+ <section>
+ <title>Selective Decode</title>
+ <p>This specialized decode decodes one single subtype of a
+ constructed value. It is the fastest method to extract one sub
+ value. The typical use of this decode is when one want to
+ inspect, for instance a version number,to be able to decide what
+ to do with the entire value. The result is returned as
+ <c>{ok,Value}</c> or <c>{error,Reason}</c>.
+ </p>
+
+ <section>
+ <title>How To Make It Work</title>
+ <p>The following steps are necessary:
+ </p>
+ <list type="bulleted">
+ <item>Write instructions in the configuration
+ file. Including the name of a user function, the name of the ASN.1
+ specification and a notation that tells which part of the type
+ will be decoded. </item>
+ <item>Compile with the additional option
+ <c>asn1config</c>. The compiler searches for a configuration file
+ with the same name as the ASN.1 spec but with the extension
+ .asn1config. In the same file you can provide configuration specs
+ for exclusive decode as well. The generated Erlang module has the
+ usual functionality for encode/decode preserved and the
+ specialized decode functionality added. </item>
+ </list>
+ </section>
+
+ <section>
+ <title>User Interface</title>
+ <p>The only new user interface function is the one provided by the
+ user in the configuration file. You can invoke that function by
+ the <c>ModuleName:FunctionName</c> notation.
+ </p>
+ <p>So, if you have the following spec
+ <c>{selective_decode,{'ModuleName',[{selected_decode_Window,TypeList}]}}</c>
+ in the con-fig file, you do the selective decode by
+ <c>{ok,Result}='ModuleName':selected_decode_Window(EncodedBinary).</c></p>
+ </section>
+
+ <section>
+ <marker id="Selective Instruction"></marker>
+ <title>Writing a Selective Decode Instruction</title>
+ <p>It is possible to describe one or many selective decode
+ functions in a configuration file, you have to use the following
+ notation:</p>
+ <pre>
+Selective_Decode_Instruction = {selective_decode,{Module_Name,Decode_Instructions}}.
+
+Module_Name = atom()
+
+Decode_Instructions = [Decode_Instruction]+
+
+Decode_Instruction = {Selective_Decode_Function_Name,Type_List}
+
+Selective_Decode_Function_Name = atom()
+
+Type_List = [Top_Type|Element_List]
+
+Element_List = Name|List_Selector
+
+Name = atom()
+
+List_Selector = [integer()] </pre>
+ <p>Observe that the instruction must be a valid Erlang term ended
+ by a dot.
+ </p>
+ <p>The <c>Module_Name</c> is the same as the name of the ASN.1
+ spec, but without the extension. A <c>Decode_Instruction</c> is
+ a tuple with your chosen function name and the components from
+ the top type that leads to the single type you want to
+ decode. Notice that you have to choose a name of your function
+ that will not be the same as any of the generated functions. The
+ first element of the <c>Type_List</c> is the top type of the
+ encoded message. In the <c>Element_List</c> it is followed by
+ each of the component names that leads to selected type. Each of
+ the names in the <c>Element_List</c> must be constructed types
+ except the last name, which can be any type.
+ </p>
+ <p>The List_Selector makes it possible to choose one of the
+ encoded components in a SEQUENCE OF/ SET OF. It is also possible
+ to go further in that component and pick a sub type of that to
+ decode. So in the <c>Type_List</c>: <c>['Window',status,buttonList,[1],number]</c> the
+ component <c>buttonList</c> has to be a SEQUENCE OF or SET OF type. In
+ this example component <c>number</c> of the first of the encoded
+ elements in the SEQUENCE OF <c>buttonList</c> is selected. This apply on
+ the ASN.1 spec <seealso marker="#Asn1spec">above</seealso>.
+ </p>
+ </section>
+
+ <section>
+ <title>Another Example</title>
+ <p>In this example we use the same ASN.1 spec as <seealso marker="#Asn1spec">above</seealso>. A valid selective decode
+ instruction is:</p>
+ <pre>
+{selective_decode,
+ {'GUI',
+ [{selected_decode_Window1,
+ ['Window',status,buttonList,
+ [1],
+ number]},
+ {selected_decode_Action,
+ ['Action',handle,number]},
+ {selected_decode_Window2,
+ ['Window',
+ status,
+ actions,
+ possibleActions,
+ [1],
+ handle,number]}]}}.
+ </pre>
+ <p>The first <c>Decode_Instruction</c>,
+ <c>{selected_decode_Window1,['Window',status,buttonList,[1],number]}</c>
+ is commented in the previous section. The instruction
+ <c>{selected_decode_Action,['Action',handle,number]}</c> picks
+ the component <c>number</c> in the <c>handle</c> component of the type
+ <c>Action</c>. If we have the value <c>ValAction = {'Action',17,{'Button',4711,false}}</c> the internal value 4711
+ should be picked by <c>selected_decode_Action</c>. In an Erlang
+ terminal it looks like:</p>
+ <pre>
+ValAction = {'Action',17,{'Button',4711,false}}.
+{'Action',17,{'Button',4711,false}}
+7> {ok,Bytes}='GUI':encode('Action',ValAction).
+...
+8> BinBytes = list_to_binary(Bytes).
+&lt;&lt;48,18,2,1,17,160,13,172,11,171,9,48,7,128,2,18,103,129,1,0&gt;&gt;
+9> 'GUI':selected_decode_Action(BinBytes).
+{ok,4711}
+10> </pre>
+ <p>The third instruction,
+ <c>['Window',status,actions,possibleActions,[1],handle,number]</c>,
+ which is a little more complicated,</p>
+ <list type="bulleted">
+ <item>starts with type <em>Window</em>. </item>
+ <item>Picks component <em>status</em> of <c>Window</c> that is
+ of type <c>Status</c>.</item>
+ <item>Then takes component <em>actions</em> of type
+ <c>Status</c>.</item>
+ <item>Then <em>possibleActions</em> of the internal defined
+ CHOICE type.</item>
+ <item>Thereafter it goes into the first component of the
+ SEQUENCE OF by <em>[1]</em>. That component is of type
+ <c>Action</c>.</item>
+ <item>The instruction next picks component
+ <em>handle</em>.</item>
+ <item>And finally component <em>number</em> of the type
+ <c>Button</c>.</item>
+ </list>
+ <p>The following figures shows which components are in the
+ TypeList
+ <c>['Window',status,actions,possibleActions,[1],handle,number]</c>. And
+ which part of a message that will be decoded by
+ selected_decode_Window2.
+ </p>
+ <p></p>
+ <image file="selective_TypeList.gif">
+ <icaption>The elements specified in the config file for selective decode of a sub-value in a Window message</icaption>
+ </image>
+ <p></p>
+ <image file="selective_Window2.gif">
+ <icaption>Figure symbolizes the bytes of a Window:status message. Only the marked element is decoded when selected_decode_Window2 is called. </icaption>
+ </image>
+ <p>With the following example you can examine that both
+ <c>selected_decode_Window2</c> and
+ <c>selected_decode_Window1</c> decodes the intended sub-value
+ of the value <c>Val</c></p>
+ <pre>
+1> Val = {'Window',{status,{'Status',12,
+ [{'Button',13,true},
+ {'Button',14,false},
+ {'Button',15,true},
+ {'Button',16,false}],
+ true,
+ {possibleActions,[{'Action',17,{'Button',18,false}},
+ {'Action',19,{'Button',20,true}},
+ {'Action',21,{'Button',22,false}}]}}}}
+2> {ok,Bytes}='GUI':encode('Window',Val).
+...
+3> Bin = list_to_binary(Bytes).
+&lt;&lt;161,101,128,1,12,161,32,48,6,128,1,13,129,1,255,48,6,128,1,14,129,1,0,48,6,128,1,15,129,...&gt;&gt;
+4> 'GUI':selected_decode_Window1(Bin).
+{ok,13}
+5> 'GUI':selected_decode_Window2(Bin).
+{ok,18} </pre>
+ <p>Observe that the value feed into the selective decode
+ functions must be a binary.
+ </p>
+ </section>
+ </section>
+
+ <section>
+ <title>Performance</title>
+ <p>To give an indication on the possible performance gain using
+ the specialized decodes, some measures have been performed. The
+ relative figures in the outcome between selective, exclusive and
+ complete decode (the normal case) depends on the structure of
+ the type, the size of the message and on what level the
+ selective and exclusive decodes are specified.
+ </p>
+
+ <section>
+ <title>ASN.1 Specifications, Messages and Configuration</title>
+ <p>The specs <seealso marker="#Asn1spec">GUI</seealso> and
+ <url href="http://www.itu.int/ITU-T/asn1/database/itu-t/h/h248/2002/MEDIA-GATEWAY-CONTROL.html">MEDIA-GATEWAY-CONTROL</url>
+ was used in the test.
+ </p>
+ <p>For the GUI spec the configuration looked like:</p>
+ <pre>
+{selective_decode,
+ {'GUI',
+ [{selected_decode_Window1,
+ ['Window',
+ status,buttonList,
+ [1],
+ number]},
+ {selected_decode_Window2,
+ ['Window',
+ status,
+ actions,
+ possibleActions,
+ [1],
+ handle,number]}]}}.
+ {exclusive_decode,
+ {'GUI',
+ [{decode_Window_status_exclusive,
+ ['Window',
+ [{status,
+ [{buttonList,parts},
+ {actions,undecoded}]}]]}]}}.
+ </pre>
+ <p>The MEDIA-GATEWAY-CONTROL configuration was:</p>
+ <pre>
+{exclusive_decode,
+ {'MEDIA-GATEWAY-CONTROL',
+ [{decode_MegacoMessage_exclusive,
+ ['MegacoMessage',
+ [{authHeader,undecoded},
+ {mess,
+ [{mId,undecoded},
+ {messageBody,undecoded}]}]]}]}}.
+{selective_decode,
+ {'MEDIA-GATEWAY-CONTROL',
+ [{decode_MegacoMessage_selective,
+ ['MegacoMessage',mess,version]}]}}.
+ </pre>
+ <p>The corresponding values were:</p>
+ <pre>
+{'Window',{status,{'Status',12,
+ [{'Button',13,true},
+ {'Button',14,false},
+ {'Button',15,true},
+ {'Button',16,false},
+ {'Button',13,true},
+ {'Button',14,false},
+ {'Button',15,true},
+ {'Button',16,false},
+ {'Button',13,true},
+ {'Button',14,false},
+ {'Button',15,true},
+ {'Button',16,false}],
+ true,
+ {possibleActions,
+ [{'Action',17,{'Button',18,false}},
+ {'Action',19,{'Button',20,true}},
+ {'Action',21,{'Button',22,false}},
+ {'Action',17,{'Button',18,false}},
+ {'Action',19,{'Button',20,true}},
+ {'Action',21,{'Button',22,false}},
+ {'Action',17,{'Button',18,false}},
+ {'Action',19,{'Button',20,true}},
+ {'Action',21,{'Button',22,false}},
+ {'Action',17,{'Button',18,false}},
+ {'Action',19,{'Button',20,true}},
+ {'Action',21,{'Button',22,false}},
+ {'Action',17,{'Button',18,false}},
+ {'Action',19,{'Button',20,true}},
+ {'Action',21,{'Button',22,false}},
+ {'Action',17,{'Button',18,false}},
+ {'Action',19,{'Button',20,true}},
+ {'Action',21,{'Button',22,false}}]}}}}
+
+
+{'MegacoMessage',asn1_NOVALUE,
+ {'Message',1,
+ {ip4Address,
+ {'IP4Address',[125,125,125,111],55555}},
+ {transactions,
+ [{transactionReply,
+ {'TransactionReply',50007,asn1_NOVALUE,
+ {actionReplies,
+ [{'ActionReply',0,asn1_NOVALUE,asn1_NOVALUE,
+ [{auditValueReply,{auditResult,{'AuditResult',
+ {'TerminationID',[],[255,255,255]},
+ [{mediaDescriptor,
+ {'MediaDescriptor',asn1_NOVALUE,
+ {multiStream,
+ [{'StreamDescriptor',1,
+ {'StreamParms',
+ {'LocalControlDescriptor',
+ sendRecv,
+ asn1_NOVALUE,
+ asn1_NOVALUE,
+ [{'PropertyParm',
+ [0,11,0,7],
+ [[52,48]],
+ asn1_NOVALUE}]},
+ {'LocalRemoteDescriptor',
+ [[{'PropertyParm',
+ [0,0,176,1],
+ [[48]],
+ asn1_NOVALUE},
+ {'PropertyParm',
+ [0,0,176,8],
+ [[73,78,32,73,80,52,32,49,50,53,46,49,
+ 50,53,46,49,50,53,46,49,49,49]],
+ asn1_NOVALUE},
+ {'PropertyParm',
+ [0,0,176,15],
+ [[97,117,100,105,111,32,49,49,49,49,32,
+ 82,84,80,47,65,86,80,32,32,52]],
+ asn1_NOVALUE},
+ {'PropertyParm',
+ [0,0,176,12],
+ [[112,116,105,109,101,58,51,48]],
+ asn1_NOVALUE}]]},
+ {'LocalRemoteDescriptor',
+ [[{'PropertyParm',
+ [0,0,176,1],
+ [[48]],
+ asn1_NOVALUE},
+ {'PropertyParm',
+ [0,0,176,8],
+ [[73,78,32,73,80,52,32,49,50,52,46,49,50,
+ 52,46,49,50,52,46,50,50,50]],
+ asn1_NOVALUE},
+ {'PropertyParm',
+ [0,0,176,15],
+ [[97,117,100,105,111,32,50,50,50,50,32,82,
+ 84,80,47,65,86,80,32,32,52]],
+ asn1_NOVALUE},
+ {'PropertyParm',
+ [0,0,176,12],
+ [[112,116,105,109,101,58,51,48]],
+ asn1_NOVALUE}]]}}}]}}},
+ {packagesDescriptor,
+ [{'PackagesItem',[0,11],1},
+ {'PackagesItem',[0,11],1}]},
+ {statisticsDescriptor,
+ [{'StatisticsParameter',[0,12,0,4],[[49,50,48,48]]},
+ {'StatisticsParameter',[0,11,0,2],[[54,50,51,48,48]]},
+ {'StatisticsParameter',[0,12,0,5],[[55,48,48]]},
+ {'StatisticsParameter',[0,11,0,3],[[52,53,49,48,48]]},
+ {'StatisticsParameter',[0,12,0,6],[[48,46,50]]},
+ {'StatisticsParameter',[0,12,0,7],[[50,48]]},
+ {'StatisticsParameter',[0,12,0,8],[[52,48]]}]}]}}}]}]}}}]}}}
+ </pre>
+ <p>The size of the encoded values was 458 bytes for GUI and 464
+ bytes for MEDIA-GATEWAY-CONTROL.
+ </p>
+ </section>
+
+ <section>
+ <title>Results</title>
+ <p>The ASN.1 specs in the test are compiled with the options
+ <c>ber_bin, optimize, driver</c> and <c>asn1config</c>. If the
+ <c>driver</c> option had been omitted there should have been
+ higher values for <c>decode</c> and <c>decode_part</c>.
+ </p>
+ <p>The test program runs 10000 decodes on the value, resulting
+ in a printout with the elapsed time in microseconds for the
+ total number of decodes.
+ </p>
+ <table>
+ <row>
+ <cell align="left" valign="top"><em>Function</em></cell>
+ <cell align="left" valign="top"><em>Time</em>(microseconds)</cell>
+ <cell align="left" valign="top"><em>Kind of Decode</em></cell>
+ <cell align="left" valign="top"><em>ASN.1 spec</em></cell>
+ <cell align="left" valign="top"><em>% of time vs. complete decode</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>decode_MegacoMessage_selective/1</c></cell>
+ <cell align="left" valign="middle"><c>374045</c></cell>
+ <cell align="left" valign="middle"><c>selective</c></cell>
+ <cell align="left" valign="middle"><c>MEDIA-GATEWAY-CONTROL</c></cell>
+ <cell align="left" valign="middle"><em>8.3</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>decode_MegacoMessage_exclusive/1</c></cell>
+ <cell align="left" valign="middle"><c>621107</c></cell>
+ <cell align="left" valign="middle"><c>exclusive</c></cell>
+ <cell align="left" valign="middle"><c>MEDIA-GATEWAY-CONTROL</c></cell>
+ <cell align="left" valign="middle"><em>13.8</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>decode/2</c></cell>
+ <cell align="left" valign="middle"><c>4507457</c></cell>
+ <cell align="left" valign="middle"><c>complete</c></cell>
+ <cell align="left" valign="middle"><c>MEDIA-GATEWAY-CONTROL</c></cell>
+ <cell align="left" valign="middle"><em>100</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>selected_decode_Window1/1</c></cell>
+ <cell align="left" valign="middle"><c>449585</c></cell>
+ <cell align="left" valign="middle"><c>selective</c></cell>
+ <cell align="left" valign="middle"><c>GUI</c></cell>
+ <cell align="left" valign="middle"><em>7.6</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>selected_decode_Window2/1</c></cell>
+ <cell align="left" valign="middle"><c>890666</c></cell>
+ <cell align="left" valign="middle"><c>selective</c></cell>
+ <cell align="left" valign="middle"><c>GUI</c></cell>
+ <cell align="left" valign="middle"><em>15.1</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>decode_Window_status_exclusive/1</c></cell>
+ <cell align="left" valign="middle"><c>1251878</c></cell>
+ <cell align="left" valign="middle"><c>exclusive</c></cell>
+ <cell align="left" valign="middle"><c>GUI</c></cell>
+ <cell align="left" valign="middle"><em>21.3</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>decode/2</c></cell>
+ <cell align="left" valign="middle"><c>5889197</c></cell>
+ <cell align="left" valign="middle"><c>complete</c></cell>
+ <cell align="left" valign="middle"><c>GUI</c></cell>
+ <cell align="left" valign="middle"><em>100</em></cell>
+ </row>
+ <tcaption>Results of complete, exclusive and selective decode</tcaption>
+ </table>
+ <p>Another interesting question is what the relation is between
+ a complete decode, an exclusive decode followed by
+ <c>decode_part</c> of the excluded parts and a selective decode
+ followed by a complete decode. Some situations may be compared to
+ this simulation, e.g. inspect a sub-value and later on look at
+ the entire value. The following table shows figures from this
+ test. The number of loops and time unit is the same as in the
+ previous test.
+ </p>
+ <table>
+ <row>
+ <cell align="left" valign="top"><em>Actions</em></cell>
+ <cell align="left" valign="top"><em>Function</em>&nbsp;&nbsp;&nbsp;&nbsp;</cell>
+ <cell align="left" valign="top"><em>Time</em>(microseconds)</cell>
+ <cell align="left" valign="top"><em>ASN.1 spec</em></cell>
+ <cell align="left" valign="top"><em>% of time vs. complete decode</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>complete</c></cell>
+ <cell align="left" valign="middle"><c>decode/2</c></cell>
+ <cell align="left" valign="middle"><c>4507457</c></cell>
+ <cell align="left" valign="middle"><c>MEDIA-GATEWAY-CONTROL</c></cell>
+ <cell align="left" valign="middle"><em>100</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>selective and complete</c></cell>
+ <cell align="left" valign="middle"><c>decode_&shy;MegacoMessage_&shy;selective/1</c></cell>
+ <cell align="left" valign="middle"><c>4881502</c></cell>
+ <cell align="left" valign="middle"><c>MEDIA-GATEWAY-CONTROL</c></cell>
+ <cell align="left" valign="middle"><em>108.3</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>exclusive and decode_part</c></cell>
+ <cell align="left" valign="middle"><c>decode_&shy;MegacoMessage_&shy;exclusive/1</c></cell>
+ <cell align="left" valign="middle"><c>5481034</c></cell>
+ <cell align="left" valign="middle"><c>MEDIA-GATEWAY-CONTROL</c></cell>
+ <cell align="left" valign="middle"><em>112.3</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>complete</c></cell>
+ <cell align="left" valign="middle"><c>decode/2</c></cell>
+ <cell align="left" valign="middle"><c>5889197</c></cell>
+ <cell align="left" valign="middle"><c>GUI</c></cell>
+ <cell align="left" valign="middle"><em>100</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>selective and complete</c></cell>
+ <cell align="left" valign="middle"><c>selected_&shy;decode_&shy;Window1/1</c></cell>
+ <cell align="left" valign="middle"><c>6337636</c></cell>
+ <cell align="left" valign="middle"><c>GUI</c></cell>
+ <cell align="left" valign="middle"><em>107.6</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>selective and complete</c></cell>
+ <cell align="left" valign="middle"><c>selected_&shy;decode_&shy;Window2/1</c></cell>
+ <cell align="left" valign="middle"><c>6795319</c></cell>
+ <cell align="left" valign="middle"><c>GUI</c></cell>
+ <cell align="left" valign="middle"><em>115.4</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><c>exclusive and decode_part</c></cell>
+ <cell align="left" valign="middle"><c>decode_&shy;Window_&shy;status_&shy;exclusive/1</c></cell>
+ <cell align="left" valign="middle"><c>6249200</c></cell>
+ <cell align="left" valign="middle"><c>GUI</c></cell>
+ <cell align="left" valign="middle"><em>106.1</em></cell>
+ </row>
+ <tcaption>Results of complete, exclusive + decode_part and selective + complete decodes</tcaption>
+ </table>
+ <p>Other ASN.1 types and values can differ much from these
+ figures. Therefore it is important that you, in every case where
+ you intend to use either of these decodes, perform some tests
+ that shows if you will benefit your purpose.
+ </p>
+ </section>
+
+ <section>
+ <title>Comments</title>
+ <p>Generally speaking the gain of selective and exclusive decode
+ in advance of complete decode is greater the bigger value and the
+ less deep in the structure you have to decode. One should also
+ prefer selective decode instead of exclusive decode if you are
+ interested in just one single sub-value.</p>
+ <p>Another observation is that the exclusive decode followed by
+ decode_part decodes is very attractive if the parts will be sent
+ to different servers for decoding or if one in some cases not is
+ interested in all parts.</p>
+ <p>The fastest selective decode are when the decoded type is a
+ primitive type and not so deep in the structure of the top
+ type. The <c>selected_decode_Window2</c> decodes a big constructed
+ value, which explains why this operation is relatively slow.</p>
+ <p>It may vary from case to case which combination of
+ selective/complete decode or exclusive/part decode is the fastest.</p>
+ </section>
+ </section>
+</chapter>
+