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