Remove unneeded comma after enum list
[yaz-moved-to-github.git] / doc / odr.xml
index 820fa26..6a135e9 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Id: odr.xml,v 1.8 2002-09-03 09:50:34 adam Exp $ -->
+<!-- $Id: odr.xml,v 1.18 2006-04-25 11:25:08 marc Exp $ -->
  <chapter id="odr"><title>The ODR Module</title>
   
   <sect1 id="odr.introduction"><title>Introduction</title>
  <chapter id="odr"><title>The ODR Module</title>
   
   <sect1 id="odr.introduction"><title>Introduction</title>
    <para>
     If you are only interested in writing a Z39.50 implementation based on
     the PDUs that are already provided with &yaz;, you only need to concern
    <para>
     If you are only interested in writing a Z39.50 implementation based on
     the PDUs that are already provided with &yaz;, you only need to concern
-    yourself with the section on managing ODR streams (section
-    <link linkend="odr-use">Using ODR</link>). Only if you need to
+    yourself with the section on managing ODR streams
+    (<xref linkend="odr.use"/>). Only if you need to
     implement ASN.1 beyond that which has been provided, should you
     worry about the second half of the documentation
     implement ASN.1 beyond that which has been provided, should you
     worry about the second half of the documentation
-    (section <link linkend="odr-prog">Programming with ODR</link>).
+    (<xref linkend="odr.programming"/>).
     If you use one of the higher-level interfaces, you can skip this
     section entirely.
    </para>
 
    <para>
     This is important, so we'll repeat it for emphasis: <emphasis>You do
     If you use one of the higher-level interfaces, you can skip this
     section entirely.
    </para>
 
    <para>
     This is important, so we'll repeat it for emphasis: <emphasis>You do
-    not need to read section <link linkend="odr-prog">Programming with
-    ODR</link> to implement Z39.50 with &yaz;.</emphasis>
+     not need to read <xref linkend="odr.programming"/>
+     to implement Z39.50 with &yaz;.</emphasis>
    </para>
 
    <para>
    </para>
 
    <para>
@@ -37,7 +37,7 @@
    </para>
 
   </sect1>
    </para>
 
   </sect1>
-  <sect1 id="odr.use"><title id="odr-use">Using ODR</title>
+  <sect1 id="odr.use"><title>Using ODR</title>
 
    <sect2><title>ODR Streams</title>
 
 
    <sect2><title>ODR Streams</title>
 
      data you wish to decode (eg, <function>odr_integer()</function> odr
      <function>z_APDU()</function>).
     </para>
      data you wish to decode (eg, <function>odr_integer()</function> odr
      <function>z_APDU()</function>).
     </para>
-
-    <para>
-     Examples of encoding/decoding functions:
-    </para>
-
-    <synopsis>
-     int odr_integer(ODR o, int **p, int optional, const char *name);
-
-     int z_APDU(ODR o, Z_APDU **p, int optional, const char *name);
-    </synopsis>
+    
+    <example><title>Encoding and decoding functions</title>
+     <synopsis>
+      int odr_integer(ODR o, int **p, int optional, const char *name);
+      
+      int z_APDU(ODR o, Z_APDU **p, int optional, const char *name);
+     </synopsis>
+    </example>
 
     <para>
      If the data is absent (or doesn't match the tag corresponding to
 
     <para>
      If the data is absent (or doesn't match the tag corresponding to
      last call to <function>odr_reset()</function> will be released.
     </para>
 
      last call to <function>odr_reset()</function> will be released.
     </para>
 
-    <para>
-     The use of the double indirection can be a little confusing at first
-     (its purpose will become clear later on, hopefully),
-     so an example is in order. We'll encode an integer value, and
-     immediately decode it again using a different stream. A useless, but
-     informative operation.
-    </para>
-
-    <programlisting>
-
+    <example><title>Encoding and decoding of an integer</title>
+     <para>
+      The use of the double indirection can be a little confusing at first
+      (its purpose will become clear later on, hopefully),
+      so an example is in order. We'll encode an integer value, and
+      immediately decode it again using a different stream. A useless, but
+      informative operation.
+     </para>
+     <programlisting><![CDATA[
 void do_nothing_useful(int value)
 {
     ODR encode, decode;
 void do_nothing_useful(int value)
 {
     ODR encode, decode;
@@ -345,18 +342,70 @@ void do_nothing_useful(int value)
     odr_destroy(encode);
     odr_destroy(decode);
 }
     odr_destroy(encode);
     odr_destroy(decode);
 }
-    </programlisting>
+]]>
+     </programlisting>
+     <para>
+      This looks like a lot of work, offhand. In practice, the &odr; streams
+      will typically be allocated once, in the beginning of your program
+      (or at the beginning of a new network session), and the encoding
+      and decoding will only take place in a few, isolated places in your
+      program, so the overhead is quite manageable.
+     </para>
+    </example>
+    
+   </sect2>
 
 
+   <sect2><title>Printing</title>
     <para>
     <para>
-     This looks like a lot of work, offhand. In practice, the &odr; streams
-     will typically be allocated once, in the beginning of your program
-     (or at the beginning of a new network session), and the encoding
-     and decoding will only take place in a few, isolated places in your
-     program, so the overhead is quite manageable.
+     When an ODR stream is created of type <literal>ODR_PRINT</literal>
+     the ODR module will print the contents of a PDU in a readable format.
+     By default output is written to the <literal>stderr</literal> stream.
+     This behavior can be changed, however, by calling the function
+     <synopsis>
+      odr_setprint(ODR o, FILE *file);
+     </synopsis>
+     before encoders or decoders are being invoked.
+     It is also possible to direct the output to a buffer (of indeed
+     another file), by using the more generic mechanism:
+     <synopsis>
+      void odr_set_stream(ODR o, void *handle,
+                         void (*stream_write)(ODR o, void *handle, int type,
+                                              const char *buf, int len),
+                         void (*stream_close)(void *handle));
+     </synopsis>
+     Here the user provides an opaque handle and two handlers,
+     <replaceable>stream_write</replaceable> for writing,
+     and <replaceable>stream_close</replaceable> which is supposed
+     to close/free resources associated with handle. 
+     The <replaceable>stream_close</replaceable> handler is optional and
+     if NULL for the function is provided, it will not be invoked.
+     The <replaceable>stream_write</replaceable> takes the ODR handle
+     as parameter, the user defined handle, a type 
+     <literal>ODR_OCTETSTRING</literal>, <literal>ODR_VISIBLESTRING</literal>
+     which indicates the type of contents is being written.
     </para>
     </para>
-
+    <para>
+     Another utility useful for diagnostics (error handling) or as
+     part of the printing facilities is:
+     <synopsis>
+      const char **odr_get_element_path(ODR o);
+     </synopsis>
+     which returns a list of current elements that ODR deals with at the 
+     moment. For the returned array, say <literal>ar</literal>, 
+     <literal>ar[0]</literal> is the top level element,
+     <literal>ar[n]</literal> is the last. The last element has the
+     property that <literal>ar[n+1] == NULL</literal>.
+    </para>
+    <example>
+     <title>Element Path for record</title>
+     <para>
+      For a database record part of a PresentResponse the
+      array returned by <function>odr_get_element</function>
+      is <literal>presentResponse</literal>, <literal>databaseOrSurDiagnostics</literal>, <literal>?</literal>, <literal>record</literal>, <literal>?</literal>, <literal>databaseRecord</literal> . The question mark appears due to 
+      unnamed constructions.
+     </para>
+     </example>
    </sect2>
    </sect2>
-
    <sect2><title>Diagnostics</title>
 
     <para>
    <sect2><title>Diagnostics</title>
 
     <para>
@@ -480,7 +529,7 @@ void do_nothing_useful(int value)
    </sect2>
   </sect1>
 
    </sect2>
   </sect1>
 
-  <sect1 id="odr.programming"><title id="odr-prog">Programming with ODR</title>
+  <sect1 id="odr.programming"><title>Programming with ODR</title>
 
    <para>
     The API of &odr; is designed to reflect the structure of ASN.1, rather
 
    <para>
     The API of &odr; is designed to reflect the structure of ASN.1, rather
@@ -488,9 +537,18 @@ void do_nothing_useful(int value)
     other external forms.
    </para>
 
     other external forms.
    </para>
 
+   <tip>
+    <para>
+     There is an ASN.1 tutorial available at
+     <ulink url="&url.asn.1.tutorial;">this site</ulink>.
+     This site also has standards for ASN.1 (X.680) and BER (X.690) 
+     <ulink url="&url.asn.1.standards;">online</ulink>.
+    </para>
+   </tip>
+   
    <para>
    <para>
-    The interface is based loosely on that of the Sun Microsystems XDR
-    routines.
+    The ODR interface is based loosely on that of the Sun Microsystems
+    XDR routines.
     Specifically, each function which corresponds to an ASN.1 primitive
     type has a dual function. Depending on the settings of the ODR
     stream which is supplied as a parameter, the function may be used
     Specifically, each function which corresponds to an ASN.1 primitive
     type has a dual function. Depending on the settings of the ODR
     stream which is supplied as a parameter, the function may be used
@@ -502,7 +560,7 @@ void do_nothing_useful(int value)
     The resulting C source code is quite compact, and is a pretty
     straightforward representation of the source ASN.1 specification. 
    </para>
     The resulting C source code is quite compact, and is a pretty
     straightforward representation of the source ASN.1 specification. 
    </para>
-
+   
    <para>
     In many cases, the model of the XDR functions works quite well in this
     role.
    <para>
     In many cases, the model of the XDR functions works quite well in this
     role.
@@ -525,13 +583,13 @@ void do_nothing_useful(int value)
      </para>
 
      <synopsis>
      </para>
 
      <synopsis>
-int odr_integer(ODR o, int **p, int optional, const char *name);
+      int odr_integer(ODR o, int **p, int optional, const char *name);
      </synopsis>
 
      <para>
       (we don't allow values that can't be contained in a C integer.)
      </para>
      </synopsis>
 
      <para>
       (we don't allow values that can't be contained in a C integer.)
      </para>
-
+     
      <para>
       This form is typical of the primitive &odr; functions. They are named
       after the type of data that they encode or decode. They take an &odr;
      <para>
       This form is typical of the primitive &odr; functions. They are named
       after the type of data that they encode or decode. They take an &odr;
@@ -697,14 +755,14 @@ int odr_oid(ODR o, Odr_oid **p, int optional, const char *name);
       The C OID representation is simply an array of integers, terminated by
       the value -1 (the <literal>Odr_oid</literal> type is synonymous with
       the <literal>int</literal> type).
       The C OID representation is simply an array of integers, terminated by
       the value -1 (the <literal>Odr_oid</literal> type is synonymous with
       the <literal>int</literal> type).
-      We suggest that you use the OID database module (see section
-      <link linkend="oid">Object Identifiers</link>) to handle object identifiers
+      We suggest that you use the OID database module (see
+      <xref linkend="asn.oid"/>) to handle object identifiers
       in your application.
      </para>
 
     </sect3>
    </sect2>
       in your application.
      </para>
 
     </sect3>
    </sect2>
-   <sect2><title id="tag-prim">Tagging Primitive Types</title>
+   <sect2 id="tag.prim"><title>Tagging Primitive Types</title>
 
     <para>
      The simplest way of tagging a type is to use the
 
     <para>
      The simplest way of tagging a type is to use the
@@ -744,8 +802,8 @@ int myInt(ODR o, int **p, int optional, const char *name)
     <para>
      The function <function>myInt()</function> can then be used like any of
      the primitive functions provided by &odr;. Note that the behavior of
     <para>
      The function <function>myInt()</function> can then be used like any of
      the primitive functions provided by &odr;. Note that the behavior of
-     <function>odr_explicit()</function>
-     and <function>odr_implicit()</function> macros
+     <function>odr_explicit_tag()</function>
+     and <function>odr_implicit_tag()</function> macros
      act exactly the same as the functions they are applied to - they
      respond to error conditions, etc, in the same manner - they
      simply have three extra parameters. The class parameter may
      act exactly the same as the functions they are applied to - they
      respond to error conditions, etc, in the same manner - they
      simply have three extra parameters. The class parameter may
@@ -826,7 +884,8 @@ int mySequence(ODR o, MySequence **p, int optional, const char *name)
      Note the 1 in the call to <function>odr_bool()</function>, to mark
      that the sequence member is optional.
      If either of the member types had been tagged, the macros
      Note the 1 in the call to <function>odr_bool()</function>, to mark
      that the sequence member is optional.
      If either of the member types had been tagged, the macros
-     <function>odr_implicit()</function> or <function>odr_explicit()</function>
+     <function>odr_implicit_tag()</function> or
+     <function>odr_explicit_tag()</function>
      could have been used.
      The new function can be used exactly like the standard functions provided
      with &odr;. It will encode, decode or pretty-print a data value of the
      could have been used.
      The new function can be used exactly like the standard functions provided
      with &odr;. It will encode, decode or pretty-print a data value of the
@@ -845,9 +904,8 @@ int mySequence(ODR o, MySequence **p, int optional, const char *name)
 
     <note>
      <para>
 
     <note>
      <para>
-      See section <link linkend="tag-prim">Tagging Primitive types</link>
-      for information on how to tag the primitive types, as well as types
-      that are already defined.
+      See <xref linkend="tag.prim"/> for information on how to tag
+      the primitive types, as well as types that are already defined.
      </para>
     </note>
 
      </para>
     </note>
 
@@ -874,7 +932,7 @@ int odr_implicit_settag(ODR o, int class, int tag);
 
      <para>
       which overrides the tag of the type immediately following it. The
 
      <para>
       which overrides the tag of the type immediately following it. The
-      macro <function>odr_implicit()</function> works by calling
+      macro <function>odr_implicit_tag()</function> works by calling
       <function>odr_implicit_settag()</function> immediately
       before calling the function pointer argument.
       Your type function could look like this:
       <function>odr_implicit_settag()</function> immediately
       before calling the function pointer argument.
       Your type function could look like this:
@@ -964,7 +1022,7 @@ int mySequence(ODR o, MySequence **p, int optional, const char *name)
       interface) is less than the time that would be required to develop a
       better interface. Nevertheless, it is far from satisfying, and it's a
       point that will be worked on in the future. One option for you would
       interface) is less than the time that would be required to develop a
       better interface. Nevertheless, it is far from satisfying, and it's a
       point that will be worked on in the future. One option for you would
-      be to simply apply the <function>odr_explicit()</function> macro to
+      be to simply apply the <function>odr_explicit_tag()</function> macro to
       the first function, and not
       have to worry about <function>odr_constructed_*</function> yourself.
       Incidentally, as you might have guessed, the
       the first function, and not
       have to worry about <function>odr_constructed_*</function> yourself.
       Incidentally, as you might have guessed, the