Use example element. Pointer to BER/ASN.1 standards/tutorial
[yaz-moved-to-github.git] / doc / odr.xml
1 <!-- $Id: odr.xml,v 1.10 2003-11-03 10:45:05 adam Exp $ -->
2  <chapter id="odr"><title>The ODR Module</title>
3   
4   <sect1 id="odr.introduction"><title>Introduction</title>
5
6    <para>
7      &odr; is the BER-encoding/decoding subsystem of &yaz;. Care as been taken
8     to isolate &odr; from the rest of the package - specifically from the
9     transport interface. &odr; may be used in any context where basic
10     ASN.1/BER representations are used.
11    </para>
12
13    <para>
14     If you are only interested in writing a Z39.50 implementation based on
15     the PDUs that are already provided with &yaz;, you only need to concern
16     yourself with the section on managing ODR streams (section
17     <link linkend="odr-use">Using ODR</link>). Only if you need to
18     implement ASN.1 beyond that which has been provided, should you
19     worry about the second half of the documentation
20     (section <link linkend="odr-prog">Programming with ODR</link>).
21     If you use one of the higher-level interfaces, you can skip this
22     section entirely.
23    </para>
24
25    <para>
26     This is important, so we'll repeat it for emphasis: <emphasis>You do
27     not need to read section <link linkend="odr-prog">Programming with
28     ODR</link> to implement Z39.50 with &yaz;.</emphasis>
29    </para>
30
31    <para>
32     If you need a part of the protocol that isn't already in &yaz;, you
33     should contact the authors before going to work on it yourself: We
34     might already be working on it. Conversely, if you implement a useful
35     part of the protocol before us, we'd be happy to include it in a
36     future release.
37    </para>
38
39   </sect1>
40   <sect1 id="odr.use"><title id="odr-use">Using ODR</title>
41
42    <sect2><title>ODR Streams</title>
43
44     <para>
45      Conceptually, the ODR stream is the source of encoded data in the
46      decoding mode; when encoding, it is the receptacle for the encoded
47      data. Before you can use an ODR stream it must be allocated. This is
48      done with the function
49     </para>
50
51     <synopsis>
52      ODR odr_createmem(int direction);
53     </synopsis>
54
55     <para>
56      The <function>odr_createmem()</function> function takes as argument one
57      of three manifest constants: <literal>ODR_ENCODE</literal>,
58      <literal>ODR_DECODE</literal>, or <literal>ODR_PRINT</literal>.
59      An &odr; stream can be in only one mode - it is not possible to change
60      its mode once it's selected. Typically, your program will allocate
61      at least two ODR streams - one for decoding, and one for encoding.
62     </para>
63
64     <para>
65      When you're done with the stream, you can use
66     </para>
67
68     <synopsis>
69      void odr_destroy(ODR o);
70     </synopsis>
71
72     <para>
73      to release the resources allocated for the stream.
74     </para>
75    </sect2>
76
77    <sect2><title id="memory">Memory Management</title>
78
79     <para>
80      Two forms of memory management take place in the &odr; system. The first
81      one, which has to do with allocating little bits of memory (sometimes
82      quite large bits of memory, actually) when a protocol package is
83      decoded, and turned into a complex of interlinked structures. This
84      section deals with this system, and how you can use it for your own
85      purposes. The next section deals with the memory management which is
86      required when encoding data - to make sure that a large enough buffer is
87      available to hold the fully encoded PDU.
88     </para>
89
90     <para>
91      The &odr; module has its own memory management system, which is
92      used whenever memory is required. Specifically, it is used to allocate
93      space for data when decoding incoming PDUs. You can use the memory
94      system for your own purposes, by using the function
95     </para>
96
97     <synopsis>
98      void *odr_malloc(ODR o, int size);
99     </synopsis>
100
101     <para>
102      You can't use the normal <function>free(2)</function> routine to free
103      memory allocated by this function, and &odr; doesn't provide a parallel
104      function. Instead, you can call
105     </para>
106
107     <synopsis>
108      void odr_reset(ODR o, int size);
109     </synopsis>
110
111     <para>
112      when you are done with the
113      memory: Everything allocated since the last call to
114      <function>odr_reset()</function> is released.
115      The <function>odr_reset()</function> call is also required to clear
116      up an error condition on a stream.
117     </para>
118
119     <para>
120      The function
121     </para>
122
123     <synopsis>
124      int odr_total(ODR o);
125     </synopsis>
126
127     <para>
128      returns the number of bytes allocated on the stream since the last call to
129      <function>odr_reset()</function>.
130     </para>
131
132     <para>
133      The memory subsystem of &odr; is fairly efficient at allocating and
134      releasing little bits of memory. Rather than managing the individual,
135      small bits of space, the system maintains a free-list of larger chunks
136      of memory, which are handed out in small bits. This scheme is
137      generally known as a <emphasis>nibble memory</emphasis> system.
138      It is very useful for maintaining short-lived constructions such
139      as protocol PDUs.
140     </para>
141
142     <para>
143      If you want to retain a bit of memory beyond the next call to
144      <function>odr_reset()</function>, you can use the function
145     </para>
146
147     <synopsis>
148      ODR_MEM odr_extract_mem(ODR o);
149     </synopsis>
150
151     <para>
152      This function will give you control of the memory recently allocated
153      on the ODR stream. The memory will live (past calls to
154      <function>odr_reset()</function>), until you call the function
155     </para>
156
157     <synopsis>
158      void odr_release_mem(ODR_MEM p);
159     </synopsis>
160
161     <para>
162      The opaque <literal>ODR_MEM</literal> handle has no other purpose than
163      referencing the memory block for you until you want to release it.
164     </para>
165
166     <para>
167      You can use <function>odr_extract_mem()</function> repeatedly between
168      allocating data, to retain individual control of separate chunks of data.
169     </para>
170
171    </sect2>
172    <sect2><title>Encoding and Decoding Data</title>
173
174     <para>
175      When encoding data, the ODR stream will write the encoded octet string
176      in an internal buffer. To retrieve the data, use the function
177     </para>
178
179     <synopsis>
180      char *odr_getbuf(ODR o, int *len, int *size);
181     </synopsis>
182
183     <para>
184      The integer pointed to by len is set to the length of the encoded
185      data, and a pointer to that data is returned. <literal>*size</literal>
186      is set to the size of the buffer (unless <literal>size</literal> is null,
187      signaling that you are not interested in the size). The next call to
188      a primitive function using the same &odr; stream will overwrite the
189      data, unless a different buffer has been supplied using the call
190     </para>
191
192     <synopsis>
193      void odr_setbuf(ODR o, char *buf, int len, int can_grow);
194     </synopsis>
195
196     <para>
197      which sets the encoding (or decoding) buffer used by
198      <literal>o</literal> to <literal>buf</literal>, using the length
199      <literal>len</literal>.
200      Before a call to an encoding function, you can use
201      <function>odr_setbuf()</function> to provide the stream with an encoding
202      buffer of sufficient size (length). The <literal>can_grow</literal>
203      parameter tells the encoding &odr; stream whether it is allowed to use
204      <function>realloc(2)</function> to increase the size of the buffer when
205      necessary. The default condition of a new encoding stream is equivalent
206      to the results of calling
207     </para>
208
209     <synopsis>
210      odr_setbuf(stream, 0, 0, 1);
211     </synopsis>
212
213     <para>
214      In this case, the stream will allocate and reallocate memory as
215      necessary. The stream reallocates memory by repeatedly doubling the
216      size of the buffer - the result is that the buffer will typically
217      reach its maximum, working size with only a small number of reallocation
218      operations. The memory is freed by the stream when the latter is destroyed,
219      unless it was assigned by the user with the <literal>can_grow</literal>
220      parameter set to zero (in this case, you are expected to retain
221      control of the memory yourself).
222     </para>
223
224     <para>
225      To assume full control of an encoded buffer, you must first call
226      <function>odr_getbuf()</function> to fetch the buffer and its length.
227      Next, you should call <function>odr_setbuf()</function> to provide a
228      different buffer (or a null pointer) to the stream. In the simplest
229      case, you will reuse the same buffer over and over again, and you
230      will just need to call <function>odr_getbuf()</function> after each
231      encoding operation to get the length and address of the buffer.
232      Note that the stream may reallocate the buffer during an encoding
233      operation, so it is necessary to retrieve the correct address after
234      each encoding operation.
235     </para>
236
237     <para>
238      It is important to realize that the ODR stream will not release this
239      memory when you call <function>odr_reset()</function>: It will
240      merely update its internal pointers to prepare for the encoding of a
241      new data value.
242      When the stream is released by the <function>odr_destroy()</function>
243      function, the memory given to it by <function>odr_setbuf</function> will
244      be released <emphasis>only</emphasis> if the <literal>can_grow</literal>
245      parameter to <function>odr_setbuf()</function> was nonzero. The
246      <literal>can_grow</literal> parameter, in other words, is a way of
247      signaling who is to own the buffer, you or the ODR stream. If you never call
248      <function>odr_setbuf()</function> on your encoding stream, which is
249      typically the case, the buffer allocated by the stream will belong to
250      the stream by default.
251     </para>
252
253     <para>
254      When you wish to decode data, you should first call
255      <function>odr_setbuf()</function>, to tell the decoding stream
256      where to find the encoded data, and how long the buffer is
257      (the <literal>can_grow</literal> parameter is ignored by a decoding
258      stream). After this, you can call the function corresponding to the
259      data you wish to decode (eg, <function>odr_integer()</function> odr
260      <function>z_APDU()</function>).
261     </para>
262     
263     <example><title>Encoding and decoding functions</title>
264      <synopsis>
265       int odr_integer(ODR o, int **p, int optional, const char *name);
266       
267       int z_APDU(ODR o, Z_APDU **p, int optional, const char *name);
268      </synopsis>
269     </example>
270
271     <para>
272      If the data is absent (or doesn't match the tag corresponding to
273      the type), the return value will be either 0 or 1 depending on the
274      <literal>optional</literal> flag. If <literal>optional</literal>
275      is 0 and the data is absent, an error flag will be raised in the
276      stream, and you'll need to call <function>odr_reset()</function> before
277      you can use the stream again. If <literal>optional</literal> is
278      nonzero, the pointer <emphasis>pointed</emphasis> to/ by
279      <literal>p</literal> will be set to the null value, and the function
280      will return 1.
281      The <literal>name</literal> argument is used to pretty-print the
282      tag in question. It may be set to <literal>NULL</literal> if
283      pretty-printing is not desired.
284     </para>
285
286     <para>
287      If the data value is found where it's expected, the pointer
288      <emphasis>pointed to</emphasis> by the <literal>p</literal> argument
289      will be set to point to the decoded type.
290      The space for the type will be allocated and owned by the &odr;
291      stream, and it will live until you call
292      <function>odr_reset()</function> on the stream. You cannot use
293      <function>free(2)</function> to release the memory.
294      You can decode several data elements (by repeated calls to
295      <function>odr_setbuf()</function> and your decoding function), and
296      new memory will be allocated each time. When you do call 
297      <function>odr_reset()</function>, everything decoded since the
298      last call to <function>odr_reset()</function> will be released.
299     </para>
300
301     <example><title>Encoding and decoding of an integer</title>
302      <para>
303       The use of the double indirection can be a little confusing at first
304       (its purpose will become clear later on, hopefully),
305       so an example is in order. We'll encode an integer value, and
306       immediately decode it again using a different stream. A useless, but
307       informative operation.
308      </para>
309      <programlisting><![CDATA[
310 void do_nothing_useful(int value)
311 {
312     ODR encode, decode;
313     int *valp, *resvalp;
314     char *bufferp;
315     int len;
316      
317     /* allocate streams */
318     if (!(encode = odr_createmem(ODR_ENCODE)))
319         return;
320     if (!(decode = odr_createmem(ODR_DECODE)))
321         return;
322
323     valp = &amp;value;
324     if (odr_integer(encode, &amp;valp, 0, 0) == 0)
325     {
326         printf("encoding went bad\n");
327         return;
328     }
329     bufferp = odr_getbuf(encode, &amp;len);
330     printf("length of encoded data is &percnt;d\n", len);
331
332     /* now let's decode the thing again */
333     odr_setbuf(decode, bufferp, len);
334     if (odr_integer(decode, &amp;resvalp, 0, 0) == 0)
335     {
336         printf("decoding went bad\n");
337         return;
338     }
339     printf("the value is &percnt;d\n", *resvalp);
340
341     /* clean up */
342     odr_destroy(encode);
343     odr_destroy(decode);
344 }
345 ]]>
346      </programlisting>
347      <para>
348       This looks like a lot of work, offhand. In practice, the &odr; streams
349       will typically be allocated once, in the beginning of your program
350       (or at the beginning of a new network session), and the encoding
351       and decoding will only take place in a few, isolated places in your
352       program, so the overhead is quite manageable.
353      </para>
354     </example>
355     
356    </sect2>
357
358    <sect2><title>Diagnostics</title>
359
360     <para>
361      The encoding/decoding functions all return 0 when an error occurs.
362      Until you call <function>odr_reset()</function>, you cannot use the
363      stream again, and any function called will immediately return 0.
364     </para>
365
366     <para>
367      To provide information to the programmer or administrator, the function
368     </para>
369
370     <synopsis>
371      void odr_perror(ODR o, char *message);
372     </synopsis>
373
374     <para>
375      is provided, which prints the <literal>message</literal> argument to
376      <literal>stderr</literal> along with an error message from the stream.
377     </para>
378
379     <para>
380      You can also use the function
381     </para>
382
383     <synopsis>
384      int odr_geterror(ODR o);
385     </synopsis>
386
387     <para>
388      to get the current error number from the screen. The number will be
389      one of these constants:
390     </para>
391
392     <table frame="top"><title>ODR Error codes</title>
393      <tgroup cols="2">
394       <thead>
395        <row>
396         <entry>code</entry>
397         <entry>Description</entry>
398        </row>
399       </thead>
400       <tbody>
401        <row>
402         <entry>OMEMORY</entry><entry>Memory allocation failed.</entry>
403        </row>
404
405        <row>
406         <entry>OSYSERR</entry><entry>A system- or library call has failed.
407          The standard diagnostic variable <literal>errno</literal> should be
408          examined to determine the actual error.</entry>
409        </row>
410
411        <row>
412         <entry>OSPACE</entry><entry>No more space for encoding.
413          This will only occur when the user has explicitly provided a
414          buffer for an encoding stream without allowing the system to
415          allocate more space.</entry>
416        </row>
417
418        <row>
419         <entry>OREQUIRED</entry><entry>This is a common protocol error; A
420          required data element was missing during encoding or decoding.</entry>
421        </row>
422
423        <row>
424         <entry>OUNEXPECTED</entry><entry>An unexpected data element was
425          found during decoding.</entry>
426        </row>
427
428        <row><entry>OOTHER</entry><entry>Other error. This is typically an
429          indication of misuse of the &odr; system by the programmer, and also
430          that the diagnostic system isn't as good as it should be, yet.</entry>
431        </row>
432       </tbody>
433      </tgroup>
434     </table>
435
436     <para>
437      The character string array
438     </para>
439
440     <synopsis>
441      char *odr_errlist&lsqb;&rsqb;
442     </synopsis>
443
444     <para>
445      can be indexed by the error code to obtain a human-readable
446      representation of the problem.
447     </para>
448
449    </sect2>
450    <sect2><title>Summary and Synopsis</title>
451
452     <synopsis>
453      #include &lt;odr.h>
454
455      ODR odr_createmem(int direction);
456
457      void odr_destroy(ODR o);
458
459      void odr_reset(ODR o);
460
461      char *odr_getbuf(ODR o, int *len);
462
463      void odr_setbuf(ODR o, char *buf, int len);
464
465      void *odr_malloc(ODR o, int size);
466
467      ODR_MEM odr_extract_mem(ODR o);
468
469      void odr_release_mem(ODR_MEM r);
470
471      int odr_geterror(ODR o);
472
473      void odr_perror(char *message);
474
475      extern char *odr_errlist[];
476     </synopsis>
477
478    </sect2>
479   </sect1>
480
481   <sect1 id="odr.programming"><title id="odr-prog">Programming with ODR</title>
482
483    <para>
484     The API of &odr; is designed to reflect the structure of ASN.1, rather
485     than BER itself. Future releases may be able to represent data in
486     other external forms.
487    </para>
488
489    <tip>
490     <para>
491      There is an ASN.1 tutorial available at
492      <ulink url="http://asn1.elibel.tm.fr/en/introduction/">this site</ulink>.
493      This site also has standards for ASN.1 (X.680) and BER (X.690) 
494      <ulink url="http://asn1.elibel.tm.fr/en/standards/">online</ulink>.
495     </para>
496    </tip>
497    
498    <para>
499     The ODR interface is based loosely on that of the Sun Microsystems
500     XDR routines.
501     Specifically, each function which corresponds to an ASN.1 primitive
502     type has a dual function. Depending on the settings of the ODR
503     stream which is supplied as a parameter, the function may be used
504     either to encode or decode data. The functions that can be built
505     using these primitive functions, to represent more complex data types,
506     share this quality. The result is that you only have to enter the
507     definition for a type once - and you have the functionality of encoding,
508     decoding (and pretty-printing) all in one unit.
509     The resulting C source code is quite compact, and is a pretty
510     straightforward representation of the source ASN.1 specification. 
511    </para>
512    
513    <para>
514     In many cases, the model of the XDR functions works quite well in this
515     role.
516     In others, it is less elegant. Most of the hassle comes from the optional
517     SEQUENCE members which don't exist in XDR.
518    </para>
519
520    <sect2><title>The Primitive ASN.1 Types</title>
521
522     <para>
523      ASN.1 defines a number of primitive types (many of which correspond
524      roughly to primitive types in structured programming languages, such as C).
525     </para>
526
527     <sect3><title>INTEGER</title>
528
529      <para>
530       The &odr; function for encoding or decoding (or printing) the ASN.1
531       INTEGER type looks like this:
532      </para>
533
534      <synopsis>
535       int odr_integer(ODR o, int **p, int optional, const char *name);
536      </synopsis>
537
538      <para>
539       (we don't allow values that can't be contained in a C integer.)
540      </para>
541      
542      <para>
543       This form is typical of the primitive &odr; functions. They are named
544       after the type of data that they encode or decode. They take an &odr;
545       stream, an indirect reference to the type in question, and an
546       <literal>optional</literal> flag (corresponding to the OPTIONAL keyword
547       of ASN.1) as parameters. They all return an integer value of either one
548       or zero.
549       When you use the primitive functions to construct encoders for complex
550       types of your own, you should follow this model as well. This
551       ensures that your new types can be reused as elements in yet more
552       complex types.
553      </para>
554
555      <para>
556       The <literal>o</literal> parameter should obviously refer to a properly
557       initialized &odr; stream of the right type (encoding/decoding/printing)
558       for the operation that you wish to perform.
559      </para>
560
561      <para>
562       When encoding or printing, the function first looks at
563       <literal>* p</literal>. If <literal>* p</literal> (the pointer pointed
564       to by <literal>p</literal>) is a null pointer, this is taken to mean that
565       the data element is absent. If the <literal>optional</literal> parameter
566       is nonzero, the function will return one (signifying success) without
567       any further processing. If the <literal>optional</literal> is zero, an
568       internal error flag is set in the &odr; stream, and the function will
569       return 0. No further operations can be carried out on the stream without
570       a call to the function <function>odr_reset()</function>.
571      </para>
572
573      <para>
574       If <literal>*p</literal> is not a null pointer, it is expected to
575       point to an instance of the data type. The data will be subjected to
576       the encoding rules, and the result will be placed in the buffer held
577       by the &odr; stream.
578      </para>
579
580      <para>
581       The other ASN.1 primitives have similar functions that operate in
582       similar manners:
583      </para>
584     </sect3>
585     <sect3><title>BOOLEAN</title>
586
587      <synopsis>
588 int odr_bool(ODR o, bool_t **p, int optional, const char *name);
589      </synopsis>
590
591     </sect3>
592     <sect3><title>REAL</title>
593
594      <para>
595       Not defined.
596      </para>
597
598     </sect3>
599     <sect3><title>NULL</title>
600
601      <synopsis>
602 int odr_null(ODR o, bool_t **p, int optional, const char *name);
603      </synopsis>
604
605      <para>
606       In this case, the value of **p is not important. If <literal>*p</literal>
607       is different from the null pointer, the null value is present, otherwise
608       it's absent.
609      </para>
610
611     </sect3>
612     <sect3><title>OCTET STRING</title>
613
614      <synopsis>
615 typedef struct odr_oct
616 {
617     unsigned char *buf;
618     int len;
619     int size;
620 } Odr_oct;
621
622 int odr_octetstring(ODR o, Odr_oct **p, int optional,
623                     const char *name);
624      </synopsis>
625
626      <para>
627       The <literal>buf</literal> field should point to the character array
628       that holds the octetstring. The <literal>len</literal> field holds the
629       actual length, while the <literal>size</literal> field gives the size
630       of the allocated array (not of interest to you, in most cases).
631       The character array need not be null terminated.
632      </para>
633
634      <para>
635       To make things a little easier, an alternative is given for string
636       types that are not expected to contain embedded NULL characters (eg.
637       VisibleString):
638      </para>
639
640      <synopsis>
641       int odr_cstring(ODR o, char **p, int optional, const char *name);
642      </synopsis>
643
644      <para>
645       Which encoded or decodes between OCTETSTRING representations and
646       null-terminates C strings.
647      </para>
648
649      <para>
650       Functions are provided for the derived string types, eg:
651      </para>
652
653      <synopsis>
654 int odr_visiblestring(ODR o, char **p, int optional,
655                       const char *name);
656      </synopsis>
657
658     </sect3>
659     <sect3><title>BIT STRING</title>
660
661      <synopsis>
662 int odr_bitstring(ODR o, Odr_bitmask **p, int optional,
663                   const char *name);
664      </synopsis>
665
666      <para>
667       The opaque type <literal>Odr_bitmask</literal> is only suitable for
668       holding relatively brief bit strings, eg. for options fields, etc.
669       The constant <literal>ODR_BITMASK_SIZE</literal> multiplied by 8
670       gives the maximum possible number of bits.
671      </para>
672
673      <para>
674       A set of macros are provided for manipulating the
675       <literal>Odr_bitmask</literal> type:
676      </para>
677
678      <synopsis>
679 void ODR_MASK_ZERO(Odr_bitmask *b);
680
681 void ODR_MASK_SET(Odr_bitmask *b, int bitno);
682
683 void ODR_MASK_CLEAR(Odr_bitmask *b, int bitno);
684
685 int ODR_MASK_GET(Odr_bitmask *b, int bitno);
686      </synopsis>
687
688      <para>
689       The functions are modeled after the manipulation functions that
690       accompany the <literal>fd_set</literal> type used by the
691       <function>select(2)</function> call.
692       <literal>ODR_MASK_ZERO</literal> should always be called first on a
693       new bitmask, to initialize the bits to zero.
694      </para>
695     </sect3>
696
697     <sect3><title>OBJECT IDENTIFIER</title>
698
699      <synopsis>
700 int odr_oid(ODR o, Odr_oid **p, int optional, const char *name);
701      </synopsis>
702
703      <para>
704       The C OID representation is simply an array of integers, terminated by
705       the value -1 (the <literal>Odr_oid</literal> type is synonymous with
706       the <literal>int</literal> type).
707       We suggest that you use the OID database module (see section
708       <link linkend="oid">Object Identifiers</link>) to handle object identifiers
709       in your application.
710      </para>
711
712     </sect3>
713    </sect2>
714    <sect2><title id="tag-prim">Tagging Primitive Types</title>
715
716     <para>
717      The simplest way of tagging a type is to use the
718      <function>odr_implicit_tag()</function> or 
719      <function>odr_explicit_tag()</function> macros:
720     </para>
721
722     <synopsis>
723 int odr_implicit_tag(ODR o, Odr_fun fun, int class, int tag,
724                      int optional, const char *name);
725
726 int odr_explicit_tag(ODR o, Odr_fun fun, int class, int tag,
727                      int optional, const char *name);
728     </synopsis>
729
730     <para>
731      To create a type derived from the integer type by implicit tagging, you
732      might write:
733     </para>
734
735     <screen>
736      MyInt ::= &lsqb;210&rsqb; IMPLICIT INTEGER
737     </screen>
738
739     <para>
740      In the &odr; system, this would be written like:
741     </para>
742
743     <screen>
744 int myInt(ODR o, int **p, int optional, const char *name)
745 {
746     return odr_implicit_tag(o, odr_integer, p,
747                             ODR_CONTEXT, 210, optional, name);
748 }
749     </screen>
750
751     <para>
752      The function <function>myInt()</function> can then be used like any of
753      the primitive functions provided by &odr;. Note that the behavior of
754      <function>odr_explicit_tag()</function>
755      and <function>odr_implicit_tag()</function> macros
756      act exactly the same as the functions they are applied to - they
757      respond to error conditions, etc, in the same manner - they
758      simply have three extra parameters. The class parameter may
759      take one of the values: <literal>ODR_CONTEXT</literal>,
760      <literal>ODR_PRIVATE</literal>, <literal>ODR_UNIVERSAL</literal>, or
761      <literal>/ODR_APPLICATION</literal>.
762     </para>
763
764    </sect2>
765    <sect2><title>Constructed Types</title>
766
767     <para>
768      Constructed types are created by combining primitive types. The
769       &odr; system only implements the SEQUENCE and SEQUENCE OF constructions
770      (although adding the rest of the container types should be simple
771      enough, if the need arises).
772     </para>
773
774     <para>
775      For implementing SEQUENCEs, the functions
776     </para>
777
778     <synopsis>
779 int odr_sequence_begin(ODR o, void *p, int size, const char *name);
780 int odr_sequence_end(ODR o);
781     </synopsis>
782
783     <para>
784      are provided.
785     </para>
786
787     <para>
788      The <function>odr_sequence_begin()</function> function should be
789      called in the beginning of a function that implements a SEQUENCE type.
790      Its parameters are the &odr; stream, a pointer (to a pointer to the type
791      you're implementing), and the <literal>size</literal> of the type
792      (typically a C structure). On encoding, it returns 1 if
793      <literal>* p</literal> is a null pointer. The <literal>size</literal>
794      parameter is ignored. On decoding, it returns 1 if the type is found in
795      the data stream. <literal>size</literal> bytes of memory are allocated,
796      and <literal>*p</literal> is set to point to this space.
797      <function>odr_sequence_end()</function> is called at the end of the
798      complex function. Assume that a type is defined like this:
799     </para>
800
801     <screen>
802 MySequence ::= SEQUENCE {
803      intval INTEGER,
804      boolval BOOLEAN OPTIONAL
805 }
806     </screen>
807
808     <para>
809      The corresponding &odr; encoder/decoder function and the associated data
810      structures could be written like this:
811     </para>
812
813     <screen>
814 typedef struct MySequence
815 {
816     int *intval;
817     bool_t *boolval;
818 } MySequence;
819      
820 int mySequence(ODR o, MySequence **p, int optional, const char *name)
821 {
822     if (odr_sequence_begin(o, p, sizeof(**p), name) == 0)
823         return optional &amp;&amp; odr_ok(o);
824     return
825         odr_integer(o, &amp;(*p)->intval, 0, "intval") &amp;&amp;
826         odr_bool(o, &amp;(*p)->boolval, 1, "boolval") &amp;&amp;
827         odr_sequence_end(o);
828 }
829
830     </screen>
831
832     <para>
833      Note the 1 in the call to <function>odr_bool()</function>, to mark
834      that the sequence member is optional.
835      If either of the member types had been tagged, the macros
836      <function>odr_implicit_tag()</function> or
837      <function>odr_explicit_tag()</function>
838      could have been used.
839      The new function can be used exactly like the standard functions provided
840      with &odr;. It will encode, decode or pretty-print a data value of the
841      <literal>MySequence</literal> type. We like to name types with an
842      initial capital, as done in ASN.1 definitions, and to name the
843      corresponding function with the first character of the name in lower case.
844      You could, of course, name your structures, types, and functions any way
845      you please - as long as you're consistent, and your code is easily readable.
846      <literal>odr_ok</literal> is just that - a predicate that returns the
847      state of the stream. It is used to ensure that the behavior of the new
848      type is compatible with the interface of the primitive types.
849     </para>
850
851    </sect2>
852    <sect2><title>Tagging Constructed Types</title>
853
854     <note>
855      <para>
856       See section <link linkend="tag-prim">Tagging Primitive types</link>
857       for information on how to tag the primitive types, as well as types
858       that are already defined.
859      </para>
860     </note>
861
862     <sect3><title>Implicit Tagging</title>
863
864      <para>
865       Assume the type above had been defined as
866      </para>
867
868      <screen>
869 MySequence ::= &lsqb;10&rsqb; IMPLICIT SEQUENCE {
870       intval INTEGER,
871       boolval BOOLEAN OPTIONAL
872 }
873      </screen>
874
875      <para>
876       You would implement this in &odr; by calling the function
877      </para>
878
879      <synopsis>
880 int odr_implicit_settag(ODR o, int class, int tag);
881      </synopsis>
882
883      <para>
884       which overrides the tag of the type immediately following it. The
885       macro <function>odr_implicit_tag()</function> works by calling
886       <function>odr_implicit_settag()</function> immediately
887       before calling the function pointer argument.
888       Your type function could look like this:
889      </para>
890
891      <screen>
892 int mySequence(ODR o, MySequence **p, int optional, const char *name)
893 {
894     if (odr_implicit_settag(o, ODR_CONTEXT, 10) == 0 ||
895         odr_sequence_begin(o, p, sizeof(**p), name) == 0)
896         return optional &amp;&amp; odr_ok(o);
897     return
898         odr_integer(o, &amp;(*p)->intval, 0, "intval") &amp;&amp;
899         odr_bool(o, &amp;(*p)->boolval, 1, "boolval") &amp;&amp;
900         odr_sequence_end(o);
901 }
902      </screen>
903
904      <para>
905       The definition of the structure <literal>MySequence</literal> would be
906       the same.
907      </para>
908     </sect3>
909
910     <sect3><title>Explicit Tagging</title>
911
912      <para>
913       Explicit tagging of constructed types is a little more complicated,
914       since you are in effect adding a level of construction to the data.
915      </para>
916
917      <para>
918       Assume the definition:
919      </para>
920
921      <screen>
922 MySequence ::= &lsqb;10&rsqb; IMPLICIT SEQUENCE {
923    intval INTEGER,
924    boolval BOOLEAN OPTIONAL
925 }
926      </screen>
927
928      <para>
929       Since the new type has an extra level of construction, two new functions
930       are needed to encapsulate the base type:
931      </para>
932
933      <synopsis>
934 int odr_constructed_begin(ODR o, void *p, int class, int tag,
935                           const char *name);
936
937 int odr_constructed_end(ODR o);
938      </synopsis>
939
940      <para>
941       Assume that the IMPLICIT in the type definition above were replaced
942       with EXPLICIT (or that the IMPLICIT keyword were simply deleted, which
943       would be equivalent). The structure definition would look the same,
944       but the function would look like this:
945      </para>
946
947      <screen>
948 int mySequence(ODR o, MySequence **p, int optional, const char *name)
949 {
950     if (odr_constructed_begin(o, p, ODR_CONTEXT, 10, name) == 0)
951         return optional &amp;&amp; odr_ok(o);
952     if (o->direction == ODR_DECODE)
953         *p = odr_malloc(o, sizeof(**p));
954     if (odr_sequence_begin(o, p, sizeof(**p), 0) == 0)
955     {
956         *p = 0; /* this is almost certainly a protocol error */
957         return 0;
958     }
959     return
960         odr_integer(o, &amp;(*p)->intval, 0, "intval") &amp;&amp;
961         odr_bool(o, &amp;(*p)->boolval, 1, "boolval") &amp;&amp;
962         odr_sequence_end(o) &amp;&amp;
963         odr_constructed_end(o);
964 }
965      </screen>
966
967      <para>
968       Notice that the interface here gets kind of nasty. The reason is
969       simple: Explicitly tagged, constructed types are fairly rare in
970       the protocols that we care about, so the
971       esthetic annoyance (not to mention the dangers of a cluttered
972       interface) is less than the time that would be required to develop a
973       better interface. Nevertheless, it is far from satisfying, and it's a
974       point that will be worked on in the future. One option for you would
975       be to simply apply the <function>odr_explicit_tag()</function> macro to
976       the first function, and not
977       have to worry about <function>odr_constructed_*</function> yourself.
978       Incidentally, as you might have guessed, the
979       <function>odr_sequence_</function> functions are themselves
980       implemented using the <function>/odr_constructed_</function> functions.
981      </para>
982
983     </sect3>
984    </sect2>
985    <sect2><title>SEQUENCE OF</title>
986
987     <para>
988      To handle sequences (arrays) of a specific type, the function
989     </para>
990
991     <synopsis>
992 int odr_sequence_of(ODR o, int (*fun)(ODR o, void *p, int optional),
993                     void *p, int *num, const char *name);
994     </synopsis>
995
996     <para>
997      The <literal>fun</literal> parameter is a pointer to the decoder/encoder
998      function of the type. <literal>p</literal> is a pointer to an array of
999      pointers to your type. <literal>num</literal> is the number of elements
1000      in the array.
1001     </para>
1002
1003     <para>
1004      Assume a type
1005     </para>
1006
1007     <screen>
1008 MyArray ::= SEQUENCE OF INTEGER
1009     </screen>
1010
1011     <para>
1012      The C representation might be
1013     </para>
1014
1015     <screen>
1016 typedef struct MyArray
1017 {
1018     int num_elements;
1019     int **elements;
1020 } MyArray;
1021     </screen>
1022
1023     <para>
1024      And the function might look like
1025     </para>
1026
1027     <screen>
1028 int myArray(ODR o, MyArray **p, int optional, const char *name)
1029 {
1030     if (o->direction == ODR_DECODE)
1031         *p = odr_malloc(o, sizeof(**p));
1032     if (odr_sequence_of(o, odr_integer, &amp;(*p)->elements,
1033         &amp;(*p)->num_elements, name))
1034         return 1;
1035     *p = 0;
1036         return optional &amp;&amp; odr_ok(o);
1037 }
1038     </screen>
1039
1040    </sect2>
1041    <sect2><title>CHOICE Types</title>
1042
1043     <para>
1044      The choice type is used fairly often in some ASN.1 definitions, so
1045      some work has gone into streamlining its interface.
1046     </para>
1047
1048     <para>
1049      CHOICE types are handled by the function:
1050     </para>
1051
1052     <synopsis>
1053 int odr_choice(ODR o, Odr_arm arm&lsqb;&rsqb;, void *p, void *whichp,
1054                const char *name);
1055     </synopsis>
1056
1057     <para>
1058      The <literal>arm</literal> array is used to describe each of the possible
1059      types that the CHOICE type may assume. Internally in your application,
1060      the CHOICE type is represented as a discriminated union. That is, a
1061      C union accompanied by an integer (or enum) identifying the active
1062      'arm' of the union.
1063      <literal>whichp</literal> is a pointer to the union discriminator.
1064      When encoding, it is examined to determine the current type.
1065      When decoding, it is set to reference the type that was found in
1066      the input stream.
1067     </para>
1068
1069     <para>
1070      The Odr_arm type is defined thus:
1071     </para>
1072
1073     <screen>
1074 typedef struct odr_arm
1075 {
1076     int tagmode;
1077     int class;
1078     int tag;
1079     int which;
1080     Odr_fun fun;
1081     char *name;
1082 } Odr_arm;
1083     </screen>
1084
1085     <para>
1086      The interpretation of the fields are:
1087     </para>
1088
1089     <variablelist>
1090      <varlistentry><term>tagmode</term>
1091       <listitem><para>Either <literal>ODR_IMPLICIT</literal>,
1092         <literal>ODR_EXPLICIT</literal>, or <literal>ODR_NONE</literal> (-1)
1093         to mark no tagging.</para></listitem>
1094      </varlistentry>
1095
1096      <varlistentry><term>which</term>
1097       <listitem><para>The value of the discriminator that corresponds to
1098         this CHOICE element. Typically, it will be a &num;defined constant, or
1099         an enum member.</para></listitem>
1100      </varlistentry>
1101
1102      <varlistentry><term>fun</term>
1103       <listitem><para>A pointer to a function that implements the type of
1104         the CHOICE member. It may be either a standard &odr; type or a type
1105         defined by yourself.</para></listitem>
1106      </varlistentry>
1107
1108      <varlistentry><term>name</term>
1109       <listitem><para>Name of tag.</para></listitem>
1110      </varlistentry>
1111     </variablelist>
1112
1113     <para>
1114      A handy way to prepare the array for use by the
1115      <function>odr_choice()</function> function is to
1116      define it as a static, initialized array in the beginning of your
1117      decoding/encoding function. Assume the type definition:
1118     </para>
1119
1120     <screen>
1121 MyChoice ::= CHOICE {
1122     untagged INTEGER,
1123     tagged   &lsqb;99&rsqb; IMPLICIT INTEGER,
1124     other    BOOLEAN
1125 }
1126     </screen>
1127
1128     <para>
1129      Your C type might look like
1130     </para>
1131
1132     <screen>
1133 typedef struct MyChoice
1134 {
1135     enum
1136     {
1137         MyChoice_untagged,
1138         MyChoice_tagged,
1139         MyChoice_other
1140     } which;
1141     union
1142     {
1143         int *untagged;
1144         int *tagged;
1145         bool_t *other;
1146     } u;
1147 };
1148     </screen>
1149
1150     <para>
1151      And your function could look like this:
1152     </para>
1153
1154     <screen>
1155 int myChoice(ODR o, MyChoice **p, int optional, const char *name)
1156 {
1157     static Odr_arm arm&lsqb;&rsqb; =
1158     {
1159       {-1, -1, -1, MyChoice_untagged, odr_integer, "untagged"},
1160       {ODR_IMPLICIT, ODR_CONTEXT, 99, MyChoice_tagged, odr_integer,
1161       "tagged"},
1162       {-1, -1, -1, MyChoice_other, odr_boolean, "other"},
1163       {-1, -1, -1, -1, 0}
1164     };
1165
1166     if (o->direction == ODR_DECODE)
1167         *p = odr_malloc(o, sizeof(**p);
1168     else if (!*p)
1169         return optional &amp;&amp; odr_ok(o);
1170
1171     if (odr_choice(o, arm, &amp;(*p)->u, &amp;(*p)->which), name)
1172         return 1;
1173     *p = 0;
1174         return optional &amp;&amp; odr_ok(o);
1175 }
1176     </screen>
1177
1178     <para>
1179      In some cases (say, a non-optional choice which is a member of a
1180      sequence), you can "embed" the union and its discriminator in the
1181      structure belonging to the enclosing type, and you won't need to
1182      fiddle with memory allocation to create a separate structure to
1183      wrap the discriminator and union.
1184     </para>
1185
1186     <para>
1187      The corresponding function is somewhat nicer in the Sun XDR interface.
1188      Most of the complexity of this interface comes from the possibility of
1189      declaring sequence elements (including CHOICEs) optional.
1190     </para>
1191
1192     <para>
1193      The ASN.1 specifications naturally requires that each member of a
1194      CHOICE have a distinct tag, so they can be told apart on decoding.
1195      Sometimes it can be useful to define a CHOICE that has multiple types
1196      that share the same tag. You'll need some other mechanism, perhaps
1197      keyed to the context of the CHOICE type. In effect, we would like to
1198      introduce a level of context-sensitiveness to our ASN.1 specification.
1199      When encoding an internal representation, we have no problem, as long
1200      as each CHOICE member has a distinct discriminator value. For
1201      decoding, we need a way to tell the choice function to look for a
1202      specific arm of the table. The function
1203     </para>
1204
1205     <synopsis>
1206 void odr_choice_bias(ODR o, int what);
1207     </synopsis>
1208
1209     <para>
1210      provides this functionality. When called, it leaves a notice for the next
1211      call to <function>odr_choice()</function> to be called on the decoding
1212      stream <literal>o</literal> that only the <literal>arm</literal> entry with
1213      a <literal>which</literal> field equal to <literal>what</literal>
1214      should be tried.
1215     </para>
1216
1217     <para>
1218      The most important application (perhaps the only one, really) is in
1219      the definition of application-specific EXTERNAL encoders/decoders
1220      which will automatically decode an ANY member given the direct or
1221      indirect reference.
1222     </para>
1223
1224    </sect2>
1225   </sect1>
1226
1227   <sect1 id="odr.debugging"><title>Debugging</title>
1228
1229    <para>
1230     The protocol modules are suffering somewhat from a lack of diagnostic
1231     tools at the moment. Specifically ways to pretty-print PDUs that
1232     aren't recognized by the system. We'll include something to this end
1233     in a not-too-distant release. In the meantime, what we do when we get
1234     packages we don't understand is to compile the ODR module with
1235     <literal>ODR_DEBUG</literal> defined. This causes the module to dump tracing
1236     information as it processes data units. With this output and the
1237     protocol specification (Z39.50), it is generally fairly easy to see
1238     what goes wrong.
1239    </para>
1240   </sect1>
1241  </chapter>
1242  <!-- Keep this comment at the end of the file
1243  Local variables:
1244  mode: sgml
1245  sgml-omittag:t
1246  sgml-shorttag:t
1247  sgml-minimize-attributes:nil
1248  sgml-always-quote-attributes:t
1249  sgml-indent-step:1
1250  sgml-indent-data:t
1251  sgml-parent-document: "yaz.xml"
1252  sgml-local-catalogs: nil
1253  sgml-namecase-general:t
1254  End:
1255  -->