Add wrbuf_sha1_puts
[yaz-moved-to-github.git] / doc / odr.xml
index 2824d6c..6438e6f 100644 (file)
@@ -1,6 +1,5 @@
-<!-- $Id: odr.xml,v 1.12 2004-03-19 21:12:13 adam Exp $ -->
  <chapter id="odr"><title>The ODR Module</title>
-  
+
   <sect1 id="odr.introduction"><title>Introduction</title>
 
    <para>
@@ -39,7 +38,7 @@
   </sect1>
   <sect1 id="odr.use"><title>Using ODR</title>
 
-   <sect2><title>ODR Streams</title>
+   <sect2 id="odr.streams"><title>ODR Streams</title>
 
     <para>
      Conceptually, the ODR stream is the source of encoded data in the
@@ -74,7 +73,7 @@
     </para>
    </sect2>
 
-   <sect2><title id="memory">Memory Management</title>
+   <sect2 id="odr.memory.management"><title id="memory">Memory Management</title>
 
     <para>
      Two forms of memory management take place in the &odr; system. The first
@@ -95,7 +94,7 @@
     </para>
 
     <synopsis>
-     void *odr_malloc(ODR o, int size);
+     void *odr_malloc(ODR o, size_t size);
     </synopsis>
 
     <para>
     </para>
 
     <synopsis>
-     void odr_reset(ODR o, int size);
+     void odr_reset(ODR o);
     </synopsis>
 
     <para>
     </para>
 
     <synopsis>
-     int odr_total(ODR o);
+     size_t odr_total(ODR o);
     </synopsis>
 
     <para>
     </para>
 
    </sect2>
-   <sect2><title>Encoding and Decoding Data</title>
+   <sect2 id="odr.encoding.and.decoding"><title>Encoding and Decoding Data</title>
 
     <para>
      When encoding data, the ODR stream will write the encoded octet string
      data you wish to decode (eg, <function>odr_integer()</function> odr
      <function>z_APDU()</function>).
     </para>
-    
-    <example><title>Encoding and decoding functions</title>
+
+    <example id="example.odr.encoding.and.decoding.functions">
+     <title>Encoding and decoding functions</title>
      <synopsis>
-      int odr_integer(ODR o, int **p, int optional, const char *name);
-      
+      int odr_integer(ODR o, Odr_int **p, int optional, const char *name);
+
       int z_APDU(ODR o, Z_APDU **p, int optional, const char *name);
      </synopsis>
     </example>
      <function>free(2)</function> to release the memory.
      You can decode several data elements (by repeated calls to
      <function>odr_setbuf()</function> and your decoding function), and
-     new memory will be allocated each time. When you do call 
+     new memory will be allocated each time. When you do call
      <function>odr_reset()</function>, everything decoded since the
      last call to <function>odr_reset()</function> will be released.
     </para>
 
-    <example><title>Encoding and decoding of an integer</title>
+    <example id="example.odr.encoding.of.integer">
+     <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),
       informative operation.
      </para>
      <programlisting><![CDATA[
-void do_nothing_useful(int value)
+void do_nothing_useful(Odr_int value)
 {
     ODR encode, decode;
-    int *valp, *resvalp;
+    Odr_int *valp, *resvalp;
     char *bufferp;
     int len;
-     
+
     /* allocate streams */
     if (!(encode = odr_createmem(ODR_ENCODE)))
         return;
     if (!(decode = odr_createmem(ODR_DECODE)))
         return;
 
-    valp = &amp;value;
-    if (odr_integer(encode, &amp;valp, 0, 0) == 0)
+    valp = &value;
+    if (odr_integer(encode, &valp, 0, 0) == 0)
     {
         printf("encoding went bad\n");
         return;
     }
-    bufferp = odr_getbuf(encode, &amp;len);
-    printf("length of encoded data is &percnt;d\n", len);
+    bufferp = odr_getbuf(encode, &len, 0);
+    printf("length of encoded data is %d\n", len);
 
     /* now let's decode the thing again */
-    odr_setbuf(decode, bufferp, len);
-    if (odr_integer(decode, &amp;resvalp, 0, 0) == 0)
+    odr_setbuf(decode, bufferp, len, 0);
+    if (odr_integer(decode, &resvalp, 0, 0) == 0)
     {
         printf("decoding went bad\n");
         return;
     }
-    printf("the value is &percnt;d\n", *resvalp);
+    /* ODR_INT_PRINTF format for printf (such as %d) */
+    printf("the value is " ODR_INT_PRINTF "\n", *resvalp);
 
     /* clean up */
     odr_destroy(encode);
@@ -352,10 +354,61 @@ void do_nothing_useful(int value)
       program, so the overhead is quite manageable.
      </para>
     </example>
-    
+
    </sect2>
 
-   <sect2><title>Diagnostics</title>
+   <sect2 id="odr.printing"><title>Printing</title>
+    <para>
+     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>
+     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 id="example.odr.element.path.record">
+     <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 id="odr.diagnostics"><title>Diagnostics</title>
 
     <para>
      The encoding/decoding functions all return 0 when an error occurs.
@@ -389,7 +442,8 @@ void do_nothing_useful(int value)
      one of these constants:
     </para>
 
-    <table frame="top"><title>ODR Error codes</title>
+    <table frame="top" id="odr.error.codes">
+     <title>ODR Error codes</title>
      <tgroup cols="2">
       <thead>
        <row>
@@ -438,7 +492,7 @@ void do_nothing_useful(int value)
     </para>
 
     <synopsis>
-     char *odr_errlist&lsqb;&rsqb;
+     char *odr_errlist[]
     </synopsis>
 
     <para>
@@ -447,10 +501,11 @@ void do_nothing_useful(int value)
     </para>
 
    </sect2>
-   <sect2><title>Summary and Synopsis</title>
+   <sect2 id="odr.summary.and.synopsis">
+    <title>Summary and Synopsis</title>
 
     <synopsis>
-     #include &lt;odr.h>
+     #include &lt;yaz/odr.h>
 
      ODR odr_createmem(int direction);
 
@@ -458,19 +513,17 @@ void do_nothing_useful(int value)
 
      void odr_reset(ODR o);
 
-     char *odr_getbuf(ODR o, int *len);
+     char *odr_getbuf(ODR o, int *len, int *size);
 
-     void odr_setbuf(ODR o, char *buf, int len);
+     void odr_setbuf(ODR o, char *buf, int len, int can_grow);
 
      void *odr_malloc(ODR o, int size);
 
-     ODR_MEM odr_extract_mem(ODR o);
-
-     void odr_release_mem(ODR_MEM r);
+     NMEM odr_extract_mem(ODR o);
 
      int odr_geterror(ODR o);
 
-     void odr_perror(char *message);
+     void odr_perror(ODR o, const char *message);
 
      extern char *odr_errlist[];
     </synopsis>
@@ -489,12 +542,12 @@ void do_nothing_useful(int value)
    <tip>
     <para>
      There is an ASN.1 tutorial available at
-     <ulink url="http://asn1.elibel.tm.fr/en/introduction/">this site</ulink>.
-     This site also has standards for ASN.1 (X.680) and BER (X.690) 
-     <ulink url="http://asn1.elibel.tm.fr/en/standards/">online</ulink>.
+     <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>
     The ODR interface is based loosely on that of the Sun Microsystems
     XDR routines.
@@ -507,9 +560,9 @@ void do_nothing_useful(int value)
     definition for a type once - and you have the functionality of encoding,
     decoding (and pretty-printing) all in one unit.
     The resulting C source code is quite compact, and is a pretty
-    straightforward representation of the source ASN.1 specification. 
+    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.
@@ -517,14 +570,15 @@ void do_nothing_useful(int value)
     SEQUENCE members which don't exist in XDR.
    </para>
 
-   <sect2><title>The Primitive ASN.1 Types</title>
+   <sect2 id="odr.primitive.asn1.types">
+    <title>The Primitive ASN.1 Types</title>
 
     <para>
      ASN.1 defines a number of primitive types (many of which correspond
      roughly to primitive types in structured programming languages, such as C).
     </para>
 
-    <sect3><title>INTEGER</title>
+    <sect3 id="odr.integer"><title>INTEGER</title>
 
      <para>
       The &odr; function for encoding or decoding (or printing) the ASN.1
@@ -532,13 +586,13 @@ void do_nothing_useful(int value)
      </para>
 
      <synopsis>
-      int odr_integer(ODR o, int **p, int optional, const char *name);
+      int odr_integer(ODR o, Odr_int **p, int optional, const char *name);
      </synopsis>
 
      <para>
-      (we don't allow values that can't be contained in a C integer.)
+      The <literal>Odr_int</literal> is just a simple 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;
@@ -582,24 +636,24 @@ void do_nothing_useful(int value)
       similar manners:
      </para>
     </sect3>
-    <sect3><title>BOOLEAN</title>
+    <sect3 id="odr.boolean"><title>BOOLEAN</title>
 
      <synopsis>
-int odr_bool(ODR o, bool_t **p, int optional, const char *name);
+int odr_bool(ODR o, Odr_bool **p, int optional, const char *name);
      </synopsis>
 
     </sect3>
-    <sect3><title>REAL</title>
+    <sect3 id="odr.real"><title>REAL</title>
 
      <para>
       Not defined.
      </para>
 
     </sect3>
-    <sect3><title>NULL</title>
+    <sect3 id="odr.null"><title>NULL</title>
 
      <synopsis>
-int odr_null(ODR o, bool_t **p, int optional, const char *name);
+int odr_null(ODR o, Odr_null **p, int optional, const char *name);
      </synopsis>
 
      <para>
@@ -609,14 +663,13 @@ int odr_null(ODR o, bool_t **p, int optional, const char *name);
      </para>
 
     </sect3>
-    <sect3><title>OCTET STRING</title>
+    <sect3 id="odr.octet.string"><title>OCTET STRING</title>
 
      <synopsis>
 typedef struct odr_oct
 {
     unsigned char *buf;
     int len;
-    int size;
 } Odr_oct;
 
 int odr_octetstring(ODR o, Odr_oct **p, int optional,
@@ -626,8 +679,7 @@ int odr_octetstring(ODR o, Odr_oct **p, int optional,
      <para>
       The <literal>buf</literal> field should point to the character array
       that holds the octetstring. The <literal>len</literal> field holds the
-      actual length, while the <literal>size</literal> field gives the size
-      of the allocated array (not of interest to you, in most cases).
+      actual length.
       The character array need not be null terminated.
      </para>
 
@@ -656,7 +708,7 @@ int odr_visiblestring(ODR o, char **p, int optional,
      </synopsis>
 
     </sect3>
-    <sect3><title>BIT STRING</title>
+    <sect3 id="odr.bit.string"><title>BIT STRING</title>
 
      <synopsis>
 int odr_bitstring(ODR o, Odr_bitmask **p, int optional,
@@ -694,7 +746,7 @@ int ODR_MASK_GET(Odr_bitmask *b, int bitno);
      </para>
     </sect3>
 
-    <sect3><title>OBJECT IDENTIFIER</title>
+    <sect3 id="odr.object.identifier"><title>OBJECT IDENTIFIER</title>
 
      <synopsis>
 int odr_oid(ODR o, Odr_oid **p, int optional, const char *name);
@@ -703,19 +755,19 @@ int odr_oid(ODR o, Odr_oid **p, int optional, const char *name);
      <para>
       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 <literal>short</literal> type).
       We suggest that you use the OID database module (see
-      <xref linkend="asn.oid"/>) to handle object identifiers
+      <xref linkend="tools.oid.database"/>) to handle object identifiers
       in your application.
      </para>
 
     </sect3>
    </sect2>
-   <sect2 id="tag.prim"><title>Tagging Primitive Types</title>
+   <sect2 id="odr.tagging.primitive.types"><title>Tagging Primitive Types</title> <!-- tag.prim -->
 
     <para>
      The simplest way of tagging a type is to use the
-     <function>odr_implicit_tag()</function> or 
+     <function>odr_implicit_tag()</function> or
      <function>odr_explicit_tag()</function> macros:
     </para>
 
@@ -733,7 +785,7 @@ int odr_explicit_tag(ODR o, Odr_fun fun, int class, int tag,
     </para>
 
     <screen>
-     MyInt ::= &lsqb;210&rsqb; IMPLICIT INTEGER
+     MyInt ::= [210] IMPLICIT INTEGER
     </screen>
 
     <para>
@@ -741,7 +793,7 @@ int odr_explicit_tag(ODR o, Odr_fun fun, int class, int tag,
     </para>
 
     <screen>
-int myInt(ODR o, int **p, int optional, const char *name)
+int myInt(ODR o, Odr_int **p, int optional, const char *name)
 {
     return odr_implicit_tag(o, odr_integer, p,
                            ODR_CONTEXT, 210, optional, name);
@@ -762,7 +814,7 @@ int myInt(ODR o, int **p, int optional, const char *name)
     </para>
 
    </sect2>
-   <sect2><title>Constructed Types</title>
+   <sect2 id="odr.constructed.types"><title>Constructed Types</title>
 
     <para>
      Constructed types are created by combining primitive types. The
@@ -813,10 +865,10 @@ MySequence ::= SEQUENCE {
     <screen>
 typedef struct MySequence
 {
-    int *intval;
-    bool_t *boolval;
+    Odr_int *intval;
+    Odr_bool *boolval;
 } MySequence;
-     
+
 int mySequence(ODR o, MySequence **p, int optional, const char *name)
 {
     if (odr_sequence_begin(o, p, sizeof(**p), name) == 0)
@@ -849,23 +901,25 @@ int mySequence(ODR o, MySequence **p, int optional, const char *name)
     </para>
 
    </sect2>
-   <sect2><title>Tagging Constructed Types</title>
+   <sect2 id="odr.tagging.constructed.types">
+    <title>Tagging Constructed Types</title>
 
     <note>
      <para>
-      See <xref linkend="tag.prim"/> for information on how to tag
+      See <xref linkend="odr.tagging.primitive.types"/> for information on how to tag
       the primitive types, as well as types that are already defined.
      </para>
     </note>
 
-    <sect3><title>Implicit Tagging</title>
+    <sect3 id="odr.implicit.tagging">
+     <title>Implicit Tagging</title>
 
      <para>
       Assume the type above had been defined as
      </para>
 
      <screen>
-MySequence ::= &lsqb;10&rsqb; IMPLICIT SEQUENCE {
+MySequence ::= [10] IMPLICIT SEQUENCE {
       intval INTEGER,
       boolval BOOLEAN OPTIONAL
 }
@@ -906,7 +960,7 @@ int mySequence(ODR o, MySequence **p, int optional, const char *name)
      </para>
     </sect3>
 
-    <sect3><title>Explicit Tagging</title>
+    <sect3 id="odr.explicit.tagging"><title>Explicit Tagging</title>
 
      <para>
       Explicit tagging of constructed types is a little more complicated,
@@ -918,7 +972,7 @@ int mySequence(ODR o, MySequence **p, int optional, const char *name)
      </para>
 
      <screen>
-MySequence ::= &lsqb;10&rsqb; IMPLICIT SEQUENCE {
+MySequence ::= [10] IMPLICIT SEQUENCE {
    intval INTEGER,
    boolval BOOLEAN OPTIONAL
 }
@@ -981,7 +1035,7 @@ int mySequence(ODR o, MySequence **p, int optional, const char *name)
 
     </sect3>
    </sect2>
-   <sect2><title>SEQUENCE OF</title>
+   <sect2 id="odr.sequence.of"><title>SEQUENCE OF</title>
 
     <para>
      To handle sequences (arrays) of a specific type, the function
@@ -1015,7 +1069,7 @@ MyArray ::= SEQUENCE OF INTEGER
 typedef struct MyArray
 {
     int num_elements;
-    int **elements;
+    Odr_int **elements;
 } MyArray;
     </screen>
 
@@ -1037,7 +1091,7 @@ int myArray(ODR o, MyArray **p, int optional, const char *name)
     </screen>
 
    </sect2>
-   <sect2><title>CHOICE Types</title>
+   <sect2 id="odr.choice.types"><title>CHOICE Types</title>
 
     <para>
      The choice type is used fairly often in some ASN.1 definitions, so
@@ -1049,7 +1103,7 @@ int myArray(ODR o, MyArray **p, int optional, const char *name)
     </para>
 
     <synopsis>
-int odr_choice(ODR o, Odr_arm arm&lsqb;&rsqb;, void *p, void *whichp,
+int odr_choice(ODR o, Odr_arm arm[], void *p, void *whichp,
                const char *name);
     </synopsis>
 
@@ -1094,7 +1148,7 @@ typedef struct odr_arm
 
      <varlistentry><term>which</term>
       <listitem><para>The value of the discriminator that corresponds to
-       this CHOICE element. Typically, it will be a &num;defined constant, or
+       this CHOICE element. Typically, it will be a #defined constant, or
        an enum member.</para></listitem>
      </varlistentry>
 
@@ -1119,7 +1173,7 @@ typedef struct odr_arm
     <screen>
 MyChoice ::= CHOICE {
     untagged INTEGER,
-    tagged   &lsqb;99&rsqb; IMPLICIT INTEGER,
+    tagged   [99] IMPLICIT INTEGER,
     other    BOOLEAN
 }
     </screen>
@@ -1139,9 +1193,9 @@ typedef struct MyChoice
     } which;
     union
     {
-        int *untagged;
-        int *tagged;
-        bool_t *other;
+        Odr_int *untagged;
+        Odr_int *tagged;
+        Odr_bool *other;
     } u;
 };
     </screen>
@@ -1153,7 +1207,7 @@ typedef struct MyChoice
     <screen>
 int myChoice(ODR o, MyChoice **p, int optional, const char *name)
 {
-    static Odr_arm arm&lsqb;&rsqb; =
+    static Odr_arm arm[] =
     {
       {-1, -1, -1, MyChoice_untagged, odr_integer, "untagged"},
       {ODR_IMPLICIT, ODR_CONTEXT, 99, MyChoice_tagged, odr_integer,