Avoid redundant YAZ includes.
[yaz4j-moved-to-github.git] / dependencies / yaz-2.1.28 / doc / odr.programming.html
1 <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>3. Programming with ODR</title><meta name="generator" content="DocBook XSL Stylesheets V1.70.1"><link rel="start" href="index.html" title="YAZ User's Guide and Reference"><link rel="up" href="odr.html" title="Chapter 9. The ODR Module"><link rel="prev" href="odr.use.html" title="2. Using ODR"><link rel="next" href="odr.debugging.html" title="4. Debugging"></head><body><link rel="stylesheet" type="text/css" href="common/style1.css"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">3. Programming with ODR</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="odr.use.html">Prev</a> </td><th width="60%" align="center">Chapter 9. The ODR Module</th><td width="20%" align="right"> <a accesskey="n" href="odr.debugging.html">Next</a></td></tr></table><hr></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="odr.programming"></a>3. Programming with ODR</h2></div></div></div><p>
2     The API of <acronym class="acronym">ODR</acronym> is designed to reflect the structure of ASN.1, rather
3     than BER itself. Future releases may be able to represent data in
4     other external forms.
5    </p><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Tip</h3><p>
6      There is an ASN.1 tutorial available at
7      <a href="http://asn1.elibel.tm.fr/en/introduction/" target="_top">this site</a>.
8      This site also has standards for ASN.1 (X.680) and BER (X.690) 
9      <a href="http://asn1.elibel.tm.fr/en/standards/" target="_top">online</a>.
10     </p></div><p>
11     The ODR interface is based loosely on that of the Sun Microsystems
12     XDR routines.
13     Specifically, each function which corresponds to an ASN.1 primitive
14     type has a dual function. Depending on the settings of the ODR
15     stream which is supplied as a parameter, the function may be used
16     either to encode or decode data. The functions that can be built
17     using these primitive functions, to represent more complex data types,
18     share this quality. The result is that you only have to enter the
19     definition for a type once - and you have the functionality of encoding,
20     decoding (and pretty-printing) all in one unit.
21     The resulting C source code is quite compact, and is a pretty
22     straightforward representation of the source ASN.1 specification. 
23    </p><p>
24     In many cases, the model of the XDR functions works quite well in this
25     role.
26     In others, it is less elegant. Most of the hassle comes from the optional
27     SEQUENCE members which don't exist in XDR.
28    </p><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2602706"></a>3.1. The Primitive ASN.1 Types</h3></div></div></div><p>
29      ASN.1 defines a number of primitive types (many of which correspond
30      roughly to primitive types in structured programming languages, such as C).
31     </p><div class="sect3" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="id2602716"></a>3.1.1. INTEGER</h4></div></div></div><p>
32       The <acronym class="acronym">ODR</acronym> function for encoding or decoding (or printing) the ASN.1
33       INTEGER type looks like this:
34      </p><pre class="synopsis">
35       int odr_integer(ODR o, int **p, int optional, const char *name);
36      </pre><p>
37       (we don't allow values that can't be contained in a C integer.)
38      </p><p>
39       This form is typical of the primitive <acronym class="acronym">ODR</acronym> functions. They are named
40       after the type of data that they encode or decode. They take an <acronym class="acronym">ODR</acronym>
41       stream, an indirect reference to the type in question, and an
42       <code class="literal">optional</code> flag (corresponding to the OPTIONAL keyword
43       of ASN.1) as parameters. They all return an integer value of either one
44       or zero.
45       When you use the primitive functions to construct encoders for complex
46       types of your own, you should follow this model as well. This
47       ensures that your new types can be reused as elements in yet more
48       complex types.
49      </p><p>
50       The <code class="literal">o</code> parameter should obviously refer to a properly
51       initialized <acronym class="acronym">ODR</acronym> stream of the right type (encoding/decoding/printing)
52       for the operation that you wish to perform.
53      </p><p>
54       When encoding or printing, the function first looks at
55       <code class="literal">* p</code>. If <code class="literal">* p</code> (the pointer pointed
56       to by <code class="literal">p</code>) is a null pointer, this is taken to mean that
57       the data element is absent. If the <code class="literal">optional</code> parameter
58       is nonzero, the function will return one (signifying success) without
59       any further processing. If the <code class="literal">optional</code> is zero, an
60       internal error flag is set in the <acronym class="acronym">ODR</acronym> stream, and the function will
61       return 0. No further operations can be carried out on the stream without
62       a call to the function <code class="function">odr_reset()</code>.
63      </p><p>
64       If <code class="literal">*p</code> is not a null pointer, it is expected to
65       point to an instance of the data type. The data will be subjected to
66       the encoding rules, and the result will be placed in the buffer held
67       by the <acronym class="acronym">ODR</acronym> stream.
68      </p><p>
69       The other ASN.1 primitives have similar functions that operate in
70       similar manners:
71      </p></div><div class="sect3" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="id2602856"></a>3.1.2. BOOLEAN</h4></div></div></div><pre class="synopsis">
72 int odr_bool(ODR o, bool_t **p, int optional, const char *name);
73      </pre></div><div class="sect3" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="id2602868"></a>3.1.3. REAL</h4></div></div></div><p>
74       Not defined.
75      </p></div><div class="sect3" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="id2602878"></a>3.1.4. NULL</h4></div></div></div><pre class="synopsis">
76 int odr_null(ODR o, bool_t **p, int optional, const char *name);
77      </pre><p>
78       In this case, the value of **p is not important. If <code class="literal">*p</code>
79       is different from the null pointer, the null value is present, otherwise
80       it's absent.
81      </p></div><div class="sect3" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="id2602902"></a>3.1.5. OCTET STRING</h4></div></div></div><pre class="synopsis">
82 typedef struct odr_oct
83 {
84     unsigned char *buf;
85     int len;
86     int size;
87 } Odr_oct;
88
89 int odr_octetstring(ODR o, Odr_oct **p, int optional,
90                     const char *name);
91      </pre><p>
92       The <code class="literal">buf</code> field should point to the character array
93       that holds the octetstring. The <code class="literal">len</code> field holds the
94       actual length, while the <code class="literal">size</code> field gives the size
95       of the allocated array (not of interest to you, in most cases).
96       The character array need not be null terminated.
97      </p><p>
98       To make things a little easier, an alternative is given for string
99       types that are not expected to contain embedded NULL characters (eg.
100       VisibleString):
101      </p><pre class="synopsis">
102       int odr_cstring(ODR o, char **p, int optional, const char *name);
103      </pre><p>
104       Which encoded or decodes between OCTETSTRING representations and
105       null-terminates C strings.
106      </p><p>
107       Functions are provided for the derived string types, eg:
108      </p><pre class="synopsis">
109 int odr_visiblestring(ODR o, char **p, int optional,
110                       const char *name);
111      </pre></div><div class="sect3" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="id2602972"></a>3.1.6. BIT STRING</h4></div></div></div><pre class="synopsis">
112 int odr_bitstring(ODR o, Odr_bitmask **p, int optional,
113                   const char *name);
114      </pre><p>
115       The opaque type <code class="literal">Odr_bitmask</code> is only suitable for
116       holding relatively brief bit strings, eg. for options fields, etc.
117       The constant <code class="literal">ODR_BITMASK_SIZE</code> multiplied by 8
118       gives the maximum possible number of bits.
119      </p><p>
120       A set of macros are provided for manipulating the
121       <code class="literal">Odr_bitmask</code> type:
122      </p><pre class="synopsis">
123 void ODR_MASK_ZERO(Odr_bitmask *b);
124
125 void ODR_MASK_SET(Odr_bitmask *b, int bitno);
126
127 void ODR_MASK_CLEAR(Odr_bitmask *b, int bitno);
128
129 int ODR_MASK_GET(Odr_bitmask *b, int bitno);
130      </pre><p>
131       The functions are modeled after the manipulation functions that
132       accompany the <code class="literal">fd_set</code> type used by the
133       <code class="function">select(2)</code> call.
134       <code class="literal">ODR_MASK_ZERO</code> should always be called first on a
135       new bitmask, to initialize the bits to zero.
136      </p></div><div class="sect3" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="id2603048"></a>3.1.7. OBJECT IDENTIFIER</h4></div></div></div><pre class="synopsis">
137 int odr_oid(ODR o, Odr_oid **p, int optional, const char *name);
138      </pre><p>
139       The C OID representation is simply an array of integers, terminated by
140       the value -1 (the <code class="literal">Odr_oid</code> type is synonymous with
141       the <code class="literal">int</code> type).
142       We suggest that you use the OID database module (see
143       <a href="asn.oid.html" title="3. Object Identifiers">Section 3, &#8220;Object Identifiers&#8221;</a>) to handle object identifiers
144       in your application.
145      </p></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="tag.prim"></a>3.2. Tagging Primitive Types</h3></div></div></div><p>
146      The simplest way of tagging a type is to use the
147      <code class="function">odr_implicit_tag()</code> or 
148      <code class="function">odr_explicit_tag()</code> macros:
149     </p><pre class="synopsis">
150 int odr_implicit_tag(ODR o, Odr_fun fun, int class, int tag,
151                      int optional, const char *name);
152
153 int odr_explicit_tag(ODR o, Odr_fun fun, int class, int tag,
154                      int optional, const char *name);
155     </pre><p>
156      To create a type derived from the integer type by implicit tagging, you
157      might write:
158     </p><pre class="screen">
159      MyInt ::= [210] IMPLICIT INTEGER
160     </pre><p>
161      In the <acronym class="acronym">ODR</acronym> system, this would be written like:
162     </p><pre class="screen">
163 int myInt(ODR o, int **p, int optional, const char *name)
164 {
165     return odr_implicit_tag(o, odr_integer, p,
166                             ODR_CONTEXT, 210, optional, name);
167 }
168     </pre><p>
169      The function <code class="function">myInt()</code> can then be used like any of
170      the primitive functions provided by <acronym class="acronym">ODR</acronym>. Note that the behavior of
171      <code class="function">odr_explicit_tag()</code>
172      and <code class="function">odr_implicit_tag()</code> macros
173      act exactly the same as the functions they are applied to - they
174      respond to error conditions, etc, in the same manner - they
175      simply have three extra parameters. The class parameter may
176      take one of the values: <code class="literal">ODR_CONTEXT</code>,
177      <code class="literal">ODR_PRIVATE</code>, <code class="literal">ODR_UNIVERSAL</code>, or
178      <code class="literal">/ODR_APPLICATION</code>.
179     </p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2603205"></a>3.3. Constructed Types</h3></div></div></div><p>
180      Constructed types are created by combining primitive types. The
181       <acronym class="acronym">ODR</acronym> system only implements the SEQUENCE and SEQUENCE OF constructions
182      (although adding the rest of the container types should be simple
183      enough, if the need arises).
184     </p><p>
185      For implementing SEQUENCEs, the functions
186     </p><pre class="synopsis">
187 int odr_sequence_begin(ODR o, void *p, int size, const char *name);
188 int odr_sequence_end(ODR o);
189     </pre><p>
190      are provided.
191     </p><p>
192      The <code class="function">odr_sequence_begin()</code> function should be
193      called in the beginning of a function that implements a SEQUENCE type.
194      Its parameters are the <acronym class="acronym">ODR</acronym> stream, a pointer (to a pointer to the type
195      you're implementing), and the <code class="literal">size</code> of the type
196      (typically a C structure). On encoding, it returns 1 if
197      <code class="literal">* p</code> is a null pointer. The <code class="literal">size</code>
198      parameter is ignored. On decoding, it returns 1 if the type is found in
199      the data stream. <code class="literal">size</code> bytes of memory are allocated,
200      and <code class="literal">*p</code> is set to point to this space.
201      <code class="function">odr_sequence_end()</code> is called at the end of the
202      complex function. Assume that a type is defined like this:
203     </p><pre class="screen">
204 MySequence ::= SEQUENCE {
205      intval INTEGER,
206      boolval BOOLEAN OPTIONAL
207 }
208     </pre><p>
209      The corresponding <acronym class="acronym">ODR</acronym> encoder/decoder function and the associated data
210      structures could be written like this:
211     </p><pre class="screen">
212 typedef struct MySequence
213 {
214     int *intval;
215     bool_t *boolval;
216 } MySequence;
217      
218 int mySequence(ODR o, MySequence **p, int optional, const char *name)
219 {
220     if (odr_sequence_begin(o, p, sizeof(**p), name) == 0)
221         return optional &amp;&amp; odr_ok(o);
222     return
223         odr_integer(o, &amp;(*p)-&gt;intval, 0, "intval") &amp;&amp;
224         odr_bool(o, &amp;(*p)-&gt;boolval, 1, "boolval") &amp;&amp;
225         odr_sequence_end(o);
226 }
227
228     </pre><p>
229      Note the 1 in the call to <code class="function">odr_bool()</code>, to mark
230      that the sequence member is optional.
231      If either of the member types had been tagged, the macros
232      <code class="function">odr_implicit_tag()</code> or
233      <code class="function">odr_explicit_tag()</code>
234      could have been used.
235      The new function can be used exactly like the standard functions provided
236      with <acronym class="acronym">ODR</acronym>. It will encode, decode or pretty-print a data value of the
237      <code class="literal">MySequence</code> type. We like to name types with an
238      initial capital, as done in ASN.1 definitions, and to name the
239      corresponding function with the first character of the name in lower case.
240      You could, of course, name your structures, types, and functions any way
241      you please - as long as you're consistent, and your code is easily readable.
242      <code class="literal">odr_ok</code> is just that - a predicate that returns the
243      state of the stream. It is used to ensure that the behavior of the new
244      type is compatible with the interface of the primitive types.
245     </p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2603377"></a>3.4. Tagging Constructed Types</h3></div></div></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
246       See <a href="odr.programming.html#tag.prim" title="3.2. Tagging Primitive Types">Section 3.2, &#8220;Tagging Primitive Types&#8221;</a> for information on how to tag
247       the primitive types, as well as types that are already defined.
248      </p></div><div class="sect3" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="id2603396"></a>3.4.1. Implicit Tagging</h4></div></div></div><p>
249       Assume the type above had been defined as
250      </p><pre class="screen">
251 MySequence ::= [10] IMPLICIT SEQUENCE {
252       intval INTEGER,
253       boolval BOOLEAN OPTIONAL
254 }
255      </pre><p>
256       You would implement this in <acronym class="acronym">ODR</acronym> by calling the function
257      </p><pre class="synopsis">
258 int odr_implicit_settag(ODR o, int class, int tag);
259      </pre><p>
260       which overrides the tag of the type immediately following it. The
261       macro <code class="function">odr_implicit_tag()</code> works by calling
262       <code class="function">odr_implicit_settag()</code> immediately
263       before calling the function pointer argument.
264       Your type function could look like this:
265      </p><pre class="screen">
266 int mySequence(ODR o, MySequence **p, int optional, const char *name)
267 {
268     if (odr_implicit_settag(o, ODR_CONTEXT, 10) == 0 ||
269         odr_sequence_begin(o, p, sizeof(**p), name) == 0)
270         return optional &amp;&amp; odr_ok(o);
271     return
272         odr_integer(o, &amp;(*p)-&gt;intval, 0, "intval") &amp;&amp;
273         odr_bool(o, &amp;(*p)-&gt;boolval, 1, "boolval") &amp;&amp;
274         odr_sequence_end(o);
275 }
276      </pre><p>
277       The definition of the structure <code class="literal">MySequence</code> would be
278       the same.
279      </p></div><div class="sect3" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="id2603470"></a>3.4.2. Explicit Tagging</h4></div></div></div><p>
280       Explicit tagging of constructed types is a little more complicated,
281       since you are in effect adding a level of construction to the data.
282      </p><p>
283       Assume the definition:
284      </p><pre class="screen">
285 MySequence ::= [10] IMPLICIT SEQUENCE {
286    intval INTEGER,
287    boolval BOOLEAN OPTIONAL
288 }
289      </pre><p>
290       Since the new type has an extra level of construction, two new functions
291       are needed to encapsulate the base type:
292      </p><pre class="synopsis">
293 int odr_constructed_begin(ODR o, void *p, int class, int tag,
294                           const char *name);
295
296 int odr_constructed_end(ODR o);
297      </pre><p>
298       Assume that the IMPLICIT in the type definition above were replaced
299       with EXPLICIT (or that the IMPLICIT keyword were simply deleted, which
300       would be equivalent). The structure definition would look the same,
301       but the function would look like this:
302      </p><pre class="screen">
303 int mySequence(ODR o, MySequence **p, int optional, const char *name)
304 {
305     if (odr_constructed_begin(o, p, ODR_CONTEXT, 10, name) == 0)
306         return optional &amp;&amp; odr_ok(o);
307     if (o-&gt;direction == ODR_DECODE)
308         *p = odr_malloc(o, sizeof(**p));
309     if (odr_sequence_begin(o, p, sizeof(**p), 0) == 0)
310     {
311         *p = 0; /* this is almost certainly a protocol error */
312         return 0;
313     }
314     return
315         odr_integer(o, &amp;(*p)-&gt;intval, 0, "intval") &amp;&amp;
316         odr_bool(o, &amp;(*p)-&gt;boolval, 1, "boolval") &amp;&amp;
317         odr_sequence_end(o) &amp;&amp;
318         odr_constructed_end(o);
319 }
320      </pre><p>
321       Notice that the interface here gets kind of nasty. The reason is
322       simple: Explicitly tagged, constructed types are fairly rare in
323       the protocols that we care about, so the
324       esthetic annoyance (not to mention the dangers of a cluttered
325       interface) is less than the time that would be required to develop a
326       better interface. Nevertheless, it is far from satisfying, and it's a
327       point that will be worked on in the future. One option for you would
328       be to simply apply the <code class="function">odr_explicit_tag()</code> macro to
329       the first function, and not
330       have to worry about <code class="function">odr_constructed_*</code> yourself.
331       Incidentally, as you might have guessed, the
332       <code class="function">odr_sequence_</code> functions are themselves
333       implemented using the <code class="function">/odr_constructed_</code> functions.
334      </p></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2603581"></a>3.5. SEQUENCE OF</h3></div></div></div><p>
335      To handle sequences (arrays) of a specific type, the function
336     </p><pre class="synopsis">
337 int odr_sequence_of(ODR o, int (*fun)(ODR o, void *p, int optional),
338                     void *p, int *num, const char *name);
339     </pre><p>
340      The <code class="literal">fun</code> parameter is a pointer to the decoder/encoder
341      function of the type. <code class="literal">p</code> is a pointer to an array of
342      pointers to your type. <code class="literal">num</code> is the number of elements
343      in the array.
344     </p><p>
345      Assume a type
346     </p><pre class="screen">
347 MyArray ::= SEQUENCE OF INTEGER
348     </pre><p>
349      The C representation might be
350     </p><pre class="screen">
351 typedef struct MyArray
352 {
353     int num_elements;
354     int **elements;
355 } MyArray;
356     </pre><p>
357      And the function might look like
358     </p><pre class="screen">
359 int myArray(ODR o, MyArray **p, int optional, const char *name)
360 {
361     if (o-&gt;direction == ODR_DECODE)
362         *p = odr_malloc(o, sizeof(**p));
363     if (odr_sequence_of(o, odr_integer, &amp;(*p)-&gt;elements,
364         &amp;(*p)-&gt;num_elements, name))
365         return 1;
366     *p = 0;
367         return optional &amp;&amp; odr_ok(o);
368 }
369     </pre></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2603660"></a>3.6. CHOICE Types</h3></div></div></div><p>
370      The choice type is used fairly often in some ASN.1 definitions, so
371      some work has gone into streamlining its interface.
372     </p><p>
373      CHOICE types are handled by the function:
374     </p><pre class="synopsis">
375 int odr_choice(ODR o, Odr_arm arm[], void *p, void *whichp,
376                const char *name);
377     </pre><p>
378      The <code class="literal">arm</code> array is used to describe each of the possible
379      types that the CHOICE type may assume. Internally in your application,
380      the CHOICE type is represented as a discriminated union. That is, a
381      C union accompanied by an integer (or enum) identifying the active
382      'arm' of the union.
383      <code class="literal">whichp</code> is a pointer to the union discriminator.
384      When encoding, it is examined to determine the current type.
385      When decoding, it is set to reference the type that was found in
386      the input stream.
387     </p><p>
388      The Odr_arm type is defined thus:
389     </p><pre class="screen">
390 typedef struct odr_arm
391 {
392     int tagmode;
393     int class;
394     int tag;
395     int which;
396     Odr_fun fun;
397     char *name;
398 } Odr_arm;
399     </pre><p>
400      The interpretation of the fields are:
401     </p><div class="variablelist"><dl><dt><span class="term">tagmode</span></dt><dd><p>Either <code class="literal">ODR_IMPLICIT</code>,
402         <code class="literal">ODR_EXPLICIT</code>, or <code class="literal">ODR_NONE</code> (-1)
403         to mark no tagging.</p></dd><dt><span class="term">which</span></dt><dd><p>The value of the discriminator that corresponds to
404         this CHOICE element. Typically, it will be a #defined constant, or
405         an enum member.</p></dd><dt><span class="term">fun</span></dt><dd><p>A pointer to a function that implements the type of
406         the CHOICE member. It may be either a standard <acronym class="acronym">ODR</acronym> type or a type
407         defined by yourself.</p></dd><dt><span class="term">name</span></dt><dd><p>Name of tag.</p></dd></dl></div><p>
408      A handy way to prepare the array for use by the
409      <code class="function">odr_choice()</code> function is to
410      define it as a static, initialized array in the beginning of your
411      decoding/encoding function. Assume the type definition:
412     </p><pre class="screen">
413 MyChoice ::= CHOICE {
414     untagged INTEGER,
415     tagged   [99] IMPLICIT INTEGER,
416     other    BOOLEAN
417 }
418     </pre><p>
419      Your C type might look like
420     </p><pre class="screen">
421 typedef struct MyChoice
422 {
423     enum
424     {
425         MyChoice_untagged,
426         MyChoice_tagged,
427         MyChoice_other
428     } which;
429     union
430     {
431         int *untagged;
432         int *tagged;
433         bool_t *other;
434     } u;
435 };
436     </pre><p>
437      And your function could look like this:
438     </p><pre class="screen">
439 int myChoice(ODR o, MyChoice **p, int optional, const char *name)
440 {
441     static Odr_arm arm[] =
442     {
443       {-1, -1, -1, MyChoice_untagged, odr_integer, "untagged"},
444       {ODR_IMPLICIT, ODR_CONTEXT, 99, MyChoice_tagged, odr_integer,
445       "tagged"},
446       {-1, -1, -1, MyChoice_other, odr_boolean, "other"},
447       {-1, -1, -1, -1, 0}
448     };
449
450     if (o-&gt;direction == ODR_DECODE)
451         *p = odr_malloc(o, sizeof(**p);
452     else if (!*p)
453         return optional &amp;&amp; odr_ok(o);
454
455     if (odr_choice(o, arm, &amp;(*p)-&gt;u, &amp;(*p)-&gt;which), name)
456         return 1;
457     *p = 0;
458         return optional &amp;&amp; odr_ok(o);
459 }
460     </pre><p>
461      In some cases (say, a non-optional choice which is a member of a
462      sequence), you can "embed" the union and its discriminator in the
463      structure belonging to the enclosing type, and you won't need to
464      fiddle with memory allocation to create a separate structure to
465      wrap the discriminator and union.
466     </p><p>
467      The corresponding function is somewhat nicer in the Sun XDR interface.
468      Most of the complexity of this interface comes from the possibility of
469      declaring sequence elements (including CHOICEs) optional.
470     </p><p>
471      The ASN.1 specifications naturally requires that each member of a
472      CHOICE have a distinct tag, so they can be told apart on decoding.
473      Sometimes it can be useful to define a CHOICE that has multiple types
474      that share the same tag. You'll need some other mechanism, perhaps
475      keyed to the context of the CHOICE type. In effect, we would like to
476      introduce a level of context-sensitiveness to our ASN.1 specification.
477      When encoding an internal representation, we have no problem, as long
478      as each CHOICE member has a distinct discriminator value. For
479      decoding, we need a way to tell the choice function to look for a
480      specific arm of the table. The function
481     </p><pre class="synopsis">
482 void odr_choice_bias(ODR o, int what);
483     </pre><p>
484      provides this functionality. When called, it leaves a notice for the next
485      call to <code class="function">odr_choice()</code> to be called on the decoding
486      stream <code class="literal">o</code> that only the <code class="literal">arm</code> entry with
487      a <code class="literal">which</code> field equal to <code class="literal">what</code>
488      should be tried.
489     </p><p>
490      The most important application (perhaps the only one, really) is in
491      the definition of application-specific EXTERNAL encoders/decoders
492      which will automatically decode an ANY member given the direct or
493      indirect reference.
494     </p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="odr.use.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="odr.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="odr.debugging.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2. Using ODR </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 4. Debugging</td></tr></table></div></body></html>