Initial commit
[yaz4j-moved-to-github.git] / dependencies / yaz-2.1.28 / doc / odr.use.html
1 <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>2. Using ODR</title><meta name="generator" content="DocBook XSL Stylesheets V1.70.1"><link rel="start" href="index.html" title="YAZ User's Guide and Reference"><link rel="up" href="odr.html" title="Chapter 9. The ODR Module"><link rel="prev" href="odr.html" title="Chapter 9. The ODR Module"><link rel="next" href="odr.programming.html" title="3. Programming with ODR"></head><body><link rel="stylesheet" type="text/css" href="common/style1.css"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">2. Using ODR</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="odr.html">Prev</a> </td><th width="60%" align="center">Chapter 9. The ODR Module</th><td width="20%" align="right"> <a accesskey="n" href="odr.programming.html">Next</a></td></tr></table><hr></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="odr.use"></a>2. Using ODR</h2></div></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2601431"></a>2.1. ODR Streams</h3></div></div></div><p>
2      Conceptually, the ODR stream is the source of encoded data in the
3      decoding mode; when encoding, it is the receptacle for the encoded
4      data. Before you can use an ODR stream it must be allocated. This is
5      done with the function
6     </p><pre class="synopsis">
7      ODR odr_createmem(int direction);
8     </pre><p>
9      The <code class="function">odr_createmem()</code> function takes as argument one
10      of three manifest constants: <code class="literal">ODR_ENCODE</code>,
11      <code class="literal">ODR_DECODE</code>, or <code class="literal">ODR_PRINT</code>.
12      An <acronym class="acronym">ODR</acronym> stream can be in only one mode - it is not possible to change
13      its mode once it's selected. Typically, your program will allocate
14      at least two ODR streams - one for decoding, and one for encoding.
15     </p><p>
16      When you're done with the stream, you can use
17     </p><pre class="synopsis">
18      void odr_destroy(ODR o);
19     </pre><p>
20      to release the resources allocated for the stream.
21     </p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2601499"></a>2.2. Memory Management</h3></div></div></div><p>
22      Two forms of memory management take place in the <acronym class="acronym">ODR</acronym> system. The first
23      one, which has to do with allocating little bits of memory (sometimes
24      quite large bits of memory, actually) when a protocol package is
25      decoded, and turned into a complex of interlinked structures. This
26      section deals with this system, and how you can use it for your own
27      purposes. The next section deals with the memory management which is
28      required when encoding data - to make sure that a large enough buffer is
29      available to hold the fully encoded PDU.
30     </p><p>
31      The <acronym class="acronym">ODR</acronym> module has its own memory management system, which is
32      used whenever memory is required. Specifically, it is used to allocate
33      space for data when decoding incoming PDUs. You can use the memory
34      system for your own purposes, by using the function
35     </p><pre class="synopsis">
36      void *odr_malloc(ODR o, int size);
37     </pre><p>
38      You can't use the normal <code class="function">free(2)</code> routine to free
39      memory allocated by this function, and <acronym class="acronym">ODR</acronym> doesn't provide a parallel
40      function. Instead, you can call
41     </p><pre class="synopsis">
42      void odr_reset(ODR o, int size);
43     </pre><p>
44      when you are done with the
45      memory: Everything allocated since the last call to
46      <code class="function">odr_reset()</code> is released.
47      The <code class="function">odr_reset()</code> call is also required to clear
48      up an error condition on a stream.
49     </p><p>
50      The function
51     </p><pre class="synopsis">
52      int odr_total(ODR o);
53     </pre><p>
54      returns the number of bytes allocated on the stream since the last call to
55      <code class="function">odr_reset()</code>.
56     </p><p>
57      The memory subsystem of <acronym class="acronym">ODR</acronym> is fairly efficient at allocating and
58      releasing little bits of memory. Rather than managing the individual,
59      small bits of space, the system maintains a free-list of larger chunks
60      of memory, which are handed out in small bits. This scheme is
61      generally known as a <span class="emphasis"><em>nibble memory</em></span> system.
62      It is very useful for maintaining short-lived constructions such
63      as protocol PDUs.
64     </p><p>
65      If you want to retain a bit of memory beyond the next call to
66      <code class="function">odr_reset()</code>, you can use the function
67     </p><pre class="synopsis">
68      ODR_MEM odr_extract_mem(ODR o);
69     </pre><p>
70      This function will give you control of the memory recently allocated
71      on the ODR stream. The memory will live (past calls to
72      <code class="function">odr_reset()</code>), until you call the function
73     </p><pre class="synopsis">
74      void odr_release_mem(ODR_MEM p);
75     </pre><p>
76      The opaque <code class="literal">ODR_MEM</code> handle has no other purpose than
77      referencing the memory block for you until you want to release it.
78     </p><p>
79      You can use <code class="function">odr_extract_mem()</code> repeatedly between
80      allocating data, to retain individual control of separate chunks of data.
81     </p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2601680"></a>2.3. Encoding and Decoding Data</h3></div></div></div><p>
82      When encoding data, the ODR stream will write the encoded octet string
83      in an internal buffer. To retrieve the data, use the function
84     </p><pre class="synopsis">
85      char *odr_getbuf(ODR o, int *len, int *size);
86     </pre><p>
87      The integer pointed to by len is set to the length of the encoded
88      data, and a pointer to that data is returned. <code class="literal">*size</code>
89      is set to the size of the buffer (unless <code class="literal">size</code> is null,
90      signaling that you are not interested in the size). The next call to
91      a primitive function using the same <acronym class="acronym">ODR</acronym> stream will overwrite the
92      data, unless a different buffer has been supplied using the call
93     </p><pre class="synopsis">
94      void odr_setbuf(ODR o, char *buf, int len, int can_grow);
95     </pre><p>
96      which sets the encoding (or decoding) buffer used by
97      <code class="literal">o</code> to <code class="literal">buf</code>, using the length
98      <code class="literal">len</code>.
99      Before a call to an encoding function, you can use
100      <code class="function">odr_setbuf()</code> to provide the stream with an encoding
101      buffer of sufficient size (length). The <code class="literal">can_grow</code>
102      parameter tells the encoding <acronym class="acronym">ODR</acronym> stream whether it is allowed to use
103      <code class="function">realloc(2)</code> to increase the size of the buffer when
104      necessary. The default condition of a new encoding stream is equivalent
105      to the results of calling
106     </p><pre class="synopsis">
107      odr_setbuf(stream, 0, 0, 1);
108     </pre><p>
109      In this case, the stream will allocate and reallocate memory as
110      necessary. The stream reallocates memory by repeatedly doubling the
111      size of the buffer - the result is that the buffer will typically
112      reach its maximum, working size with only a small number of reallocation
113      operations. The memory is freed by the stream when the latter is destroyed,
114      unless it was assigned by the user with the <code class="literal">can_grow</code>
115      parameter set to zero (in this case, you are expected to retain
116      control of the memory yourself).
117     </p><p>
118      To assume full control of an encoded buffer, you must first call
119      <code class="function">odr_getbuf()</code> to fetch the buffer and its length.
120      Next, you should call <code class="function">odr_setbuf()</code> to provide a
121      different buffer (or a null pointer) to the stream. In the simplest
122      case, you will reuse the same buffer over and over again, and you
123      will just need to call <code class="function">odr_getbuf()</code> after each
124      encoding operation to get the length and address of the buffer.
125      Note that the stream may reallocate the buffer during an encoding
126      operation, so it is necessary to retrieve the correct address after
127      each encoding operation.
128     </p><p>
129      It is important to realize that the ODR stream will not release this
130      memory when you call <code class="function">odr_reset()</code>: It will
131      merely update its internal pointers to prepare for the encoding of a
132      new data value.
133      When the stream is released by the <code class="function">odr_destroy()</code>
134      function, the memory given to it by <code class="function">odr_setbuf</code> will
135      be released <span class="emphasis"><em>only</em></span> if the <code class="literal">can_grow</code>
136      parameter to <code class="function">odr_setbuf()</code> was nonzero. The
137      <code class="literal">can_grow</code> parameter, in other words, is a way of
138      signaling who is to own the buffer, you or the ODR stream. If you never call
139      <code class="function">odr_setbuf()</code> on your encoding stream, which is
140      typically the case, the buffer allocated by the stream will belong to
141      the stream by default.
142     </p><p>
143      When you wish to decode data, you should first call
144      <code class="function">odr_setbuf()</code>, to tell the decoding stream
145      where to find the encoded data, and how long the buffer is
146      (the <code class="literal">can_grow</code> parameter is ignored by a decoding
147      stream). After this, you can call the function corresponding to the
148      data you wish to decode (eg, <code class="function">odr_integer()</code> odr
149      <code class="function">z_APDU()</code>).
150     </p><div class="example"><a name="id2601357"></a><p class="title"><b>Example 9.1. Encoding and decoding functions</b></p><div class="example-contents"><pre class="synopsis">
151       int odr_integer(ODR o, int **p, int optional, const char *name);
152       
153       int z_APDU(ODR o, Z_APDU **p, int optional, const char *name);
154      </pre></div></div><br class="example-break"><p>
155      If the data is absent (or doesn't match the tag corresponding to
156      the type), the return value will be either 0 or 1 depending on the
157      <code class="literal">optional</code> flag. If <code class="literal">optional</code>
158      is 0 and the data is absent, an error flag will be raised in the
159      stream, and you'll need to call <code class="function">odr_reset()</code> before
160      you can use the stream again. If <code class="literal">optional</code> is
161      nonzero, the pointer <span class="emphasis"><em>pointed</em></span> to/ by
162      <code class="literal">p</code> will be set to the null value, and the function
163      will return 1.
164      The <code class="literal">name</code> argument is used to pretty-print the
165      tag in question. It may be set to <code class="literal">NULL</code> if
166      pretty-printing is not desired.
167     </p><p>
168      If the data value is found where it's expected, the pointer
169      <span class="emphasis"><em>pointed to</em></span> by the <code class="literal">p</code> argument
170      will be set to point to the decoded type.
171      The space for the type will be allocated and owned by the <acronym class="acronym">ODR</acronym>
172      stream, and it will live until you call
173      <code class="function">odr_reset()</code> on the stream. You cannot use
174      <code class="function">free(2)</code> to release the memory.
175      You can decode several data elements (by repeated calls to
176      <code class="function">odr_setbuf()</code> and your decoding function), and
177      new memory will be allocated each time. When you do call 
178      <code class="function">odr_reset()</code>, everything decoded since the
179      last call to <code class="function">odr_reset()</code> will be released.
180     </p><div class="example"><a name="id2602189"></a><p class="title"><b>Example 9.2. Encoding and decoding of an integer</b></p><div class="example-contents"><p>
181       The use of the double indirection can be a little confusing at first
182       (its purpose will become clear later on, hopefully),
183       so an example is in order. We'll encode an integer value, and
184       immediately decode it again using a different stream. A useless, but
185       informative operation.
186      </p><pre class="programlisting">
187 void do_nothing_useful(int value)
188 {
189     ODR encode, decode;
190     int *valp, *resvalp;
191     char *bufferp;
192     int len;
193      
194     /* allocate streams */
195     if (!(encode = odr_createmem(ODR_ENCODE)))
196         return;
197     if (!(decode = odr_createmem(ODR_DECODE)))
198         return;
199
200     valp = &amp;amp;value;
201     if (odr_integer(encode, &amp;amp;valp, 0, 0) == 0)
202     {
203         printf("encoding went bad\n");
204         return;
205     }
206     bufferp = odr_getbuf(encode, &amp;amp;len);
207     printf("length of encoded data is &amp;percnt;d\n", len);
208
209     /* now let's decode the thing again */
210     odr_setbuf(decode, bufferp, len);
211     if (odr_integer(decode, &amp;amp;resvalp, 0, 0) == 0)
212     {
213         printf("decoding went bad\n");
214         return;
215     }
216     printf("the value is &amp;percnt;d\n", *resvalp);
217
218     /* clean up */
219     odr_destroy(encode);
220     odr_destroy(decode);
221 }
222
223      </pre><p>
224       This looks like a lot of work, offhand. In practice, the <acronym class="acronym">ODR</acronym> streams
225       will typically be allocated once, in the beginning of your program
226       (or at the beginning of a new network session), and the encoding
227       and decoding will only take place in a few, isolated places in your
228       program, so the overhead is quite manageable.
229      </p></div></div><br class="example-break"></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2602222"></a>2.4. Printing</h3></div></div></div><p>
230      When an ODR stream is created of type <code class="literal">ODR_PRINT</code>
231      the ODR module will print the contents of a PDU in a readable format.
232      By default output is written to the <code class="literal">stderr</code> stream.
233      This behavior can be changed, however, by calling the function
234      </p><pre class="synopsis">
235       odr_setprint(ODR o, FILE *file);
236      </pre><p>
237      before encoders or decoders are being invoked.
238      It is also possible to direct the output to a buffer (of indeed
239      another file), by using the more generic mechanism:
240      </p><pre class="synopsis">
241       void odr_set_stream(ODR o, void *handle,
242                          void (*stream_write)(ODR o, void *handle, int type,
243                                               const char *buf, int len),
244                          void (*stream_close)(void *handle));
245      </pre><p>
246      Here the user provides an opaque handle and two handlers,
247      <em class="replaceable"><code>stream_write</code></em> for writing,
248      and <em class="replaceable"><code>stream_close</code></em> which is supposed
249      to close/free resources associated with handle. 
250      The <em class="replaceable"><code>stream_close</code></em> handler is optional and
251      if NULL for the function is provided, it will not be invoked.
252      The <em class="replaceable"><code>stream_write</code></em> takes the ODR handle
253      as parameter, the user defined handle, a type 
254      <code class="literal">ODR_OCTETSTRING</code>, <code class="literal">ODR_VISIBLESTRING</code>
255      which indicates the type of contents is being written.
256     </p><p>
257      Another utility useful for diagnostics (error handling) or as
258      part of the printing facilities is:
259      </p><pre class="synopsis">
260       const char **odr_get_element_path(ODR o);
261      </pre><p>
262      which returns a list of current elements that ODR deals with at the 
263      moment. For the returned array, say <code class="literal">ar</code>, 
264      <code class="literal">ar[0]</code> is the top level element,
265      <code class="literal">ar[n]</code> is the last. The last element has the
266      property that <code class="literal">ar[n+1] == NULL</code>.
267     </p><div class="example"><a name="id2602368"></a><p class="title"><b>Example 9.3. Element Path for record</b></p><div class="example-contents"><p>
268       For a database record part of a PresentResponse the
269       array returned by <code class="function">odr_get_element</code>
270       is <code class="literal">presentResponse</code>, <code class="literal">databaseOrSurDiagnostics</code>, <code class="literal">?</code>, <code class="literal">record</code>, <code class="literal">?</code>, <code class="literal">databaseRecord</code> . The question mark appears due to 
271       unnamed constructions.
272      </p></div></div><br class="example-break"></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2602422"></a>2.5. Diagnostics</h3></div></div></div><p>
273      The encoding/decoding functions all return 0 when an error occurs.
274      Until you call <code class="function">odr_reset()</code>, you cannot use the
275      stream again, and any function called will immediately return 0.
276     </p><p>
277      To provide information to the programmer or administrator, the function
278     </p><pre class="synopsis">
279      void odr_perror(ODR o, char *message);
280     </pre><p>
281      is provided, which prints the <code class="literal">message</code> argument to
282      <code class="literal">stderr</code> along with an error message from the stream.
283     </p><p>
284      You can also use the function
285     </p><pre class="synopsis">
286      int odr_geterror(ODR o);
287     </pre><p>
288      to get the current error number from the screen. The number will be
289      one of these constants:
290     </p><div class="table"><a name="id2602483"></a><p class="title"><b>Table 9.1. ODR Error codes</b></p><div class="table-contents"><table summary="ODR Error codes" border="1"><colgroup><col><col></colgroup><thead><tr><th>code</th><th>Description</th></tr></thead><tbody><tr><td>OMEMORY</td><td>Memory allocation failed.</td></tr><tr><td>OSYSERR</td><td>A system- or library call has failed.
291          The standard diagnostic variable <code class="literal">errno</code> should be
292          examined to determine the actual error.</td></tr><tr><td>OSPACE</td><td>No more space for encoding.
293          This will only occur when the user has explicitly provided a
294          buffer for an encoding stream without allowing the system to
295          allocate more space.</td></tr><tr><td>OREQUIRED</td><td>This is a common protocol error; A
296          required data element was missing during encoding or decoding.</td></tr><tr><td>OUNEXPECTED</td><td>An unexpected data element was
297          found during decoding.</td></tr><tr><td>OOTHER</td><td>Other error. This is typically an
298          indication of misuse of the <acronym class="acronym">ODR</acronym> system by the programmer, and also
299          that the diagnostic system isn't as good as it should be, yet.</td></tr></tbody></table></div></div><br class="table-break"><p>
300      The character string array
301     </p><pre class="synopsis">
302      char *odr_errlist[]
303     </pre><p>
304      can be indexed by the error code to obtain a human-readable
305      representation of the problem.
306     </p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2602602"></a>2.6. Summary and Synopsis</h3></div></div></div><pre class="synopsis">
307      #include &lt;odr.h&gt;
308
309      ODR odr_createmem(int direction);
310
311      void odr_destroy(ODR o);
312
313      void odr_reset(ODR o);
314
315      char *odr_getbuf(ODR o, int *len);
316
317      void odr_setbuf(ODR o, char *buf, int len);
318
319      void *odr_malloc(ODR o, int size);
320
321      ODR_MEM odr_extract_mem(ODR o);
322
323      void odr_release_mem(ODR_MEM r);
324
325      int odr_geterror(ODR o);
326
327      void odr_perror(char *message);
328
329      extern char *odr_errlist[];
330     </pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="odr.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="odr.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="odr.programming.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 9. The ODR Module </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 3. Programming with ODR</td></tr></table></div></body></html>