-<!-- $Id: odr.xml,v 1.7 2001-10-26 20:13:44 adam Exp $ -->
+<!-- $Id: odr.xml,v 1.10 2003-11-03 10:45:05 adam Exp $ -->
<chapter id="odr"><title>The ODR Module</title>
<sect1 id="odr.introduction"><title>Introduction</title>
<para>
The memory subsystem of &odr; is fairly efficient at allocating and
releasing little bits of memory. Rather than managing the individual,
- small bits of space, the system maintains a freelist of larger chunks
+ small bits of space, the system maintains a free-list of larger chunks
of memory, which are handed out in small bits. This scheme is
generally known as a <emphasis>nibble memory</emphasis> system.
It is very useful for maintaining short-lived constructions such
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
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;
odr_destroy(encode);
odr_destroy(decode);
}
- </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>
-
+]]>
+ </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>Diagnostics</title>
other external forms.
</para>
+ <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>.
+ </para>
+ </tip>
+
<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
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>
<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>
-
+
<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;
</synopsis>
<para>
- The functions are modelled after the manipulation functions that
+ The functions are modeled after the manipulation functions that
accompany the <literal>fd_set</literal> type used by the
<function>select(2)</function> call.
<literal>ODR_MASK_ZERO</literal> should always be called first on a
<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
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
<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:
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