Add ZOOM_connection_diagset()
[yaz-moved-to-github.git] / doc / zoom.xml
1 <!--
2 ### Still to document:
3 ZOOM_connection_errcode(c)
4 ZOOM_connection_errmsg(c)
5 ZOOM_connection_addinfo(c)
6 ZOOM_connection_addinfo(c)
7 ZOOM_connection_diagset(c);
8 ZOOM_diag_str(error)
9 ZOOM_resultset_record_immediate(s, pos)
10 ZOOM_resultset_cache_reset(r)
11 ZOOM_resultset_sort(r, sort_type, sort_spec)
12 ZOOM_resultset_sort1(r, sort_type, sort_spec)
13 ZOOM_options_set_callback(opt, function, handle)
14 ZOOM_options_create_with_parent2(parent1, parent2)
15 ZOOM_options_getl(opt, name, len)
16 ZOOM_options_setl(opt, name, value, len)
17 ZOOM_options_get_bool(opt, name, defa)
18 ZOOM_options_get_int(opt, name, defa)
19 ZOOM_options_set_int(opt, name, value)
20 -->
21 <!-- $Id: zoom.xml,v 1.44 2005-11-16 16:04:19 mike Exp $ -->
22  <chapter id="zoom"><title>ZOOM</title>
23   <para>
24     &zoom; is an acronym for 'Z39.50 Object-Orientation Model' and is
25    an initiative started by Mike Taylor (Mike is from the UK, which
26    explains the peculiar name of the model). The goal of &zoom; is to
27    provide a common Z39.50 client API not bound to a particular
28    programming language or toolkit.
29   </para>
30
31   <note>
32    <para>
33     A recent addition to &yaz; is SRW support. You can now make
34     SRW ZOOM connections by specifying scheme <literal>http://</literal>
35     for the hostname for a connection.
36    </para>
37   </note>
38
39   <para>
40    The lack of a simple Z39.50 client API for &yaz; has become more
41    and more apparent over time. So when the first &zoom; specification
42    became available,
43    an implementation for &yaz; was quickly developed. For the first time, it is
44    now as easy (or easier!) to develop clients than servers with &yaz;. This
45    chapter describes the &zoom; C binding. Before going further, please
46    reconsider whether C is the right programming language for the job.
47    There are other language bindings available for &yaz;, and still
48    more
49    are in active development. See the
50    <ulink url="http://zoom.z3950.org/">ZOOM web-site</ulink> for
51    more information.
52   </para>
53   
54   <para>
55    In order to fully understand this chapter you should read and
56    try the example programs <literal>zoomtst1.c</literal>,
57    <literal>zoomtst2.c</literal>, .. in the <literal>zoom</literal>
58    directory.
59   </para>
60   
61   <para>
62    The C language misses features found in object oriented languages
63    such as C++, Java, etc. For example, you'll have to manually,
64    destroy all objects you create, even though you may think of them as
65    temporary. Most objects has a <literal>_create</literal> - and a
66    <literal>_destroy</literal> variant.
67    All objects are in fact pointers to internal stuff, but you don't see
68    that because of typedefs. All destroy methods should gracefully ignore a
69    <literal>NULL</literal> pointer.
70   </para>
71   <para>
72    In each of the sections below you'll find a sub section called
73    protocol behavior, that describes how the API maps to the Z39.50
74    protocol.
75   </para>
76   <sect1 id="zoom.connections"><title>Connections</title>
77    
78    <para>The Connection object is a session with a target.
79    </para>
80    <synopsis>
81     #include &lt;yaz/zoom.h>
82     
83     ZOOM_connection ZOOM_connection_new (const char *host, int portnum);
84     
85     ZOOM_connection ZOOM_connection_create (ZOOM_options options);
86     
87     void ZOOM_connection_connect(ZOOM_connection c, const char *host,
88                                  int portnum);
89     void ZOOM_connection_destroy (ZOOM_connection c);
90    </synopsis>
91    <para>
92     Connection objects are created with either function
93     <function>ZOOM_connection_new</function> or 
94     <function>ZOOM_connection_create</function>.
95     The former creates and automatically attempts to establish a network
96     connection with the target. The latter doesn't establish
97     a connection immediately, thus allowing you to specify options
98     before establishing network connection using the function
99     <function>ZOOM_connection_connect</function>. 
100     If the port number, <literal>portnum</literal>, is zero, the
101     <literal>host</literal> is consulted for a port specification.
102     If no port is given, 210 is used. A colon denotes the beginning of
103     a port number in the host string. If the host string includes a
104     slash, the following part specifies a database for the connection.
105    </para>
106    <para>
107     You can prefix the host with a scheme followed by colon. The
108     default scheme is <literal>tcp</literal> (Z39.50 protocol).
109     The scheme <literal>http</literal> selects SRW over HTTP.
110    </para>
111    <para>
112     Connection objects should be destroyed using the function
113     <function>ZOOM_connection_destroy</function>.
114    </para>
115    <synopsis>
116     void ZOOM_connection_option_set(ZOOM_connection c,
117                                     const char *key, const char *val);
118
119     void ZOOM_connection_option_setl(ZOOM_connection c,
120                                      const char *key,
121                                      const char *val, int len);
122
123     const char *ZOOM_connection_option_get(ZOOM_connection c,
124                                            const char *key);
125     const char *ZOOM_connection_option_getl(ZOOM_connection c,
126                                             const char *key,
127                                             int *lenp);
128    </synopsis>
129    <para>
130     The functions <function>ZOOM_connection_option_set</function> and
131     <function>ZOOM_connection_option_setl</function> allows you to
132     set an option given by <parameter>key</parameter> to the value
133     <parameter>value</parameter> for the connection. 
134     For <function>ZOOM_connection_option_set</function>, the
135     value is assumed to be a 0-terminated string. Function
136     <function>ZOOM_connection_option_setl</function> specifies a
137     value of a certain size (len).
138    </para>
139    <para>
140     Functions <function>ZOOM_connection_option_get</function> and
141     <function>ZOOM_connection_option_getl</function> returns
142     the value for an option given by <parameter>key</parameter>.
143    </para>
144    <table frame="top"><title>ZOOM Connection Options</title>
145     <tgroup cols="3">
146      <colspec colwidth="4*" colname="name"></colspec>
147      <colspec colwidth="7*" colname="description"></colspec>
148      <colspec colwidth="3*" colname="default"></colspec>
149      <thead>
150       <row>
151        <entry>Option</entry>
152        <entry>Description</entry>
153        <entry>Default</entry>
154       </row>
155      </thead>
156      <tbody>
157       <row><entry>
158         implementationName</entry><entry>Name of Your client
159        </entry><entry>none</entry></row>
160       <row><entry>
161         user</entry><entry>Authentication user name
162        </entry><entry>none</entry></row>
163       <row><entry>
164         group</entry><entry>Authentication group name
165        </entry><entry>none</entry></row>
166       <row><entry>
167         password</entry><entry>Authentication password.
168        </entry><entry>none</entry></row>
169       <row><entry>
170         host</entry><entry>Target host. This setting is "read-only".
171         It's automatically set internally when connecting to a target.
172        </entry><entry>none</entry></row>
173       <row><entry>
174         proxy</entry><entry>Proxy host
175        </entry><entry>none</entry></row>
176       <row><entry>
177         async</entry><entry>If true (1) the connection operates in 
178         asynchronous operation which means that all calls are non-blocking
179         except
180         <link linkend="zoom.events"><function>ZOOM_event</function></link>.
181        </entry><entry>0</entry></row>
182       <row><entry>
183         maximumRecordSize</entry><entry> Maximum size of single record.
184        </entry><entry>1 MB</entry></row>
185       <row><entry>
186         preferredMessageSize</entry><entry> Maximum size of multiple records.
187        </entry><entry>1 MB</entry></row>
188       <row><entry>
189         lang</entry><entry> Language for negotiation.
190        </entry><entry>none</entry></row>
191       <row><entry>
192         charset</entry><entry> Character set for negotiation.
193        </entry><entry>none</entry></row>
194       <row><entry>
195         serverImplementationId</entry><entry>
196         Implementation ID of server.  (The old targetImplementationId
197         option is also supported for the benefit of old applications.)
198        </entry><entry>none</entry></row>
199       <row><entry>
200         targetImplementationName</entry><entry>
201         Implementation Name of server.  (The old
202         targetImplementationName option is also supported for the
203         benefit of old applications.)
204        </entry><entry>none</entry></row>
205       <row><entry>
206         serverImplementationVersion</entry><entry>
207         Implementation Version of server.  (the old
208         targetImplementationVersion option is also supported for the
209         benefit of old applications.)
210        </entry><entry>none</entry></row>
211       <row><entry>
212         databaseName</entry><entry>One or more database names
213         separated by character plus (<literal>+</literal>), which to
214         be used by subsequent search requests on this Connection.
215        </entry><entry>Default</entry></row>
216       <row><entry>
217         piggyback</entry><entry>True (1) if piggyback should be
218         used in searches; false (0) if not.
219        </entry><entry>1</entry></row>
220       <row><entry>
221         smallSetUpperBound</entry><entry>If hits is less than or equal to this
222         value, then target will return all records using small element set name
223        </entry><entry>0</entry></row>
224       <row><entry>
225         largeSetLowerBound</entry><entry>If hits is greater than this
226         value, the target will return no records.
227        </entry><entry>1</entry></row>
228       <row><entry>
229         mediumSetPresentNumber</entry><entry>This value represents
230         the number of records to be returned as part of a search when when
231         hits is less than or equal to large set lower bound and if hits
232         is greater than small set upper bound.
233        </entry><entry>0</entry></row>
234       <row><entry>
235         smallSetElementSetName</entry><entry>
236         The element set name to be used for small result sets.
237        </entry><entry>none</entry></row>
238       <row><entry>
239         mediumSetElementSetName</entry><entry>
240         The element set name to be for medium-sized result sets.
241        </entry><entry>none</entry></row>
242      </tbody>
243     </tgroup>
244    </table>
245    <para>
246     If either option <literal>lang</literal> or <literal>charset</literal>
247     is set, then 
248     <ulink url="http://lcweb.loc.gov/z3950/agency/defns/charneg-3.html">
249      Character Set and Language Negotiation</ulink> is in effect.
250    </para>
251    <synopsis>
252      int ZOOM_connection_error (ZOOM_connection c, const char **cp,
253                                 const char **addinfo);
254      int ZOOM_connection_error_x (ZOOM_connection c, const char **cp,
255                                   const char **addinfo, const char **dset);
256    </synopsis>
257    <para>
258     Function <function>ZOOM_connection_error</function> checks for
259     errors for the last operation(s) performed. The function returns
260     zero if no errors occurred; non-zero otherwise indicating the error.
261     Pointers <parameter>cp</parameter> and <parameter>addinfo</parameter>
262     holds messages for the error and additional-info if passed as
263     non-<literal>NULL</literal>. Function
264     <function>ZOOM_connection_error_x</function> is an extended version
265     of <function>ZOOM_connection_error</function> that is capable of
266     returning name of diagnostic set in <parameter>dset</parameter>.
267    </para>
268    <sect2><title>Z39.50 Protocol behavior</title>
269     <para>
270      The calls <function>ZOOM_connection_new</function> and
271      <function>ZOOM_connection_connect</function> establishes a TCP/IP
272       connection and sends an Initialize Request to the target if
273       possible. In addition, the calls waits for an Initialize Response
274       from the target and the result is inspected (OK or rejected).
275     </para>
276     <para>
277      If <literal>proxy</literal> is set then the client will establish
278      a TCP/IP connection with the peer as specified by the
279      <literal>proxy</literal> host and the hostname as part of the
280      connect calls will be set as part of the Initialize Request.
281      The proxy server will then "forward" the PDU's transparently
282      to the target behind the proxy.
283     </para>
284     <para>
285      For the authentication parameters, if option <literal>user</literal>
286      is set and both options <literal>group</literal> and
287      <literal>pass</literal> are unset, then Open style
288      authentication is used (Version 2/3) in which case the username
289      is usually followed by a slash, then by a password.
290      If either <literal>group</literal>
291      or <literal>pass</literal> is set then idPass authentication
292      (Version 3 only) is used. If none of the options are set, no
293      authentication parameters are set as part of the Initialize Request
294      (obviously).
295     </para>
296     <para>
297      When option <literal>async</literal> is 1, it really means that
298      all network operations are postponed (and queued) until the
299      function <literal>ZOOM_event</literal> is invoked. When doing so
300      it doesn't make sense to check for errors after
301      <literal>ZOOM_connection_new</literal> is called since that
302      operation "connecting - and init" is still incomplete and the
303      API cannot tell the outcome (yet).
304     </para>
305     </sect2>
306    <sect2><title>SRW Protocol behavior</title>
307     <para>
308      The SRW protocol doesn't feature an Inititialize Request, so
309      the connection phase merely establishes a TCP/IP connection
310      with the SOAP service.
311     </para>
312     <para>Most of the ZOOM connection options do not
313      affect SRW and they are ignored. However, future versions
314      of &yaz; might honor <literal>implementationName</literal> and
315      put that as part of User-Agent header for HTTP requests.
316      </para>
317     <para>
318      The <literal>charset</literal> is used in the Content-Type header
319      of HTTP requests.
320     </para>
321    </sect2>
322   </sect1>
323   <sect1 id="zoom.query"><title>Queries</title>
324    <para>
325     Query objects represents queries.
326    </para>
327    <synopsis>
328      ZOOM_query ZOOM_query_create(void);
329
330      void ZOOM_query_destroy(ZOOM_query q);
331
332      int ZOOM_query_prefix(ZOOM_query q, const char *str);
333
334      int ZOOM_query_cql(ZOOM_query s, const char *str);
335
336      int ZOOM_query_sortby(ZOOM_query q, const char *criteria);
337    </synopsis>
338    <para>
339     Create query objects using <function>ZOOM_query_create</function>
340     and destroy them by calling <function>ZOOM_query_destroy</function>.
341     RPN-queries can be specified in <link linkend="PQF">PQF</link>
342     notation by using the
343     function <function>ZOOM_query_prefix</function>.
344     The <function>ZOOM_query_cql</function> specifies a CQL
345     query to be sent to the server/target.
346     More query types will be added in future versions of &yaz;, such as
347     <link linkend="CCL">CCL</link> to RPN-mapping, native CCL query,
348     etc. In addition to a search, a sort criteria may be set. Function
349     <function>ZOOM_query_sortby</function> specifies a 
350     sort criteria using the same string notation for sort as offered by
351     the <link linkend="sortspec">YAZ client</link>.
352    </para>
353    <sect2><title>Protocol behavior</title>
354     <para>
355      The query object is just an interface for the member Query
356      in the SearchRequest. The sortby-function is an interface to the
357      sortSequence member of the SortRequest.
358     </para>
359    </sect2>
360   </sect1>
361   <sect1 id="zoom.resultsets"><title>Result sets</title>
362    <para>
363     The result set object is a container for records returned from
364     a target.
365    </para>
366    <synopsis>
367      ZOOM_resultset ZOOM_connection_search(ZOOM_connection,
368                                            ZOOM_query q);
369
370      ZOOM_resultset ZOOM_connection_search_pqf(ZOOM_connection c,
371                                                const char *q);
372
373      void ZOOM_resultset_destroy(ZOOM_resultset r);
374    </synopsis>
375    <para>
376     Function <function>ZOOM_connection_search</function> creates
377      a result set given a connection and query.
378     Destroy a result set by calling
379     <function>ZOOM_resultset_destroy</function>.
380     Simple clients may using PQF only may use function
381     <function>ZOOM_connection_search_pqf</function> in which case
382     creating query objects is not necessary.
383    </para>
384    <synopsis>
385      void ZOOM_resultset_option_set (ZOOM_resultset r,
386                                       const char *key,
387                                       const char *val);
388
389      const char *ZOOM_resultset_option_get (ZOOM_resultset r,
390                                              const char *key);
391
392      size_t ZOOM_resultset_size (ZOOM_resultset r);
393    </synopsis>
394    <para>
395     Functions <function>ZOOM_resultset_options_set</function> and
396     <function>ZOOM_resultset_get</function> sets and gets an option
397     for a result set similar to <function>ZOOM_connection_option_get</function>
398     and <function>ZOOM_connection_option_set</function>.
399    </para>
400    <para>
401     The number of hits also called result-count is returned by
402     function <function>ZOOM_resultset_size</function>.
403    </para>
404    <table frame="top"><title>ZOOM Result set Options</title>
405     <tgroup cols="3">
406      <colspec colwidth="4*" colname="name"></colspec>
407      <colspec colwidth="7*" colname="description"></colspec>
408      <colspec colwidth="2*" colname="default"></colspec>
409      <thead>
410       <row>
411        <entry>Option</entry>
412        <entry>Description</entry>
413        <entry>Default</entry>
414       </row>
415      </thead>
416      <tbody>
417       <row><entry>
418         start</entry><entry>Offset of first record to be 
419         retrieved from target. First record has offset 0 unlike the
420         protocol specifications where first record has position 1.
421        </entry><entry>0</entry></row>
422       <row><entry>
423         count</entry><entry>Number of records to be retrieved.
424        </entry><entry>0</entry></row>
425       <row><entry>
426         presentChunk</entry><entry>The number of records to be
427         requested from the server in each chunk (present requst).  The
428         value 0 means to request all the records in a single chunk.
429         (The old <literal>step</literal>
430         option is also supported for the benefit of old applications.)
431        </entry><entry>0</entry></row>
432       <row><entry>
433         elementSetName</entry><entry>Element-Set name of records. 
434         Most targets should honor element set name <literal>B</literal>
435         and <literal>F</literal> for brief and full respectively.
436        </entry><entry>none</entry></row>
437       <row><entry>
438         preferredRecordSyntax</entry><entry>Preferred Syntax, such as
439         <literal>USMARC</literal>, <literal>SUTRS</literal>, etc.
440        </entry><entry>none</entry></row>
441       <row><entry>
442         schema</entry><entry>Schema for retrieval, such as
443         <literal>Gils-schema</literal>, <literal>Geo-schema</literal>, etc.
444        </entry><entry>none</entry></row>
445       <row><entry>
446         setname</entry><entry>Name of Result Set (Result Set ID).
447         If this option isn't set, the ZOOM module will automatically
448         allocate a result set name.
449        </entry><entry>default</entry></row>
450      </tbody>
451     </tgroup>
452    </table>
453    <para>
454     For servers that support Search Info report, the following
455     options may be read using <function>ZOOM_resultset_get</function>.
456     This detailed information is read after a successful search has
457     completed.
458    </para>
459    <para>
460     This information is a list of of items, where each item is
461     information about a term or subquery. All items in the list 
462     are prefixed by 
463     <literal>SearchResult.</literal><replaceable>no</replaceable>
464     where no presents the item number (0=first, 1=second). 
465     Read <literal>searchresult.size</literal> to determine the
466     number of items.
467    </para>
468    <table frame="top"><title>Search Info Report options</title>
469     <tgroup cols="2">
470      <colspec colwidth="4*" colname="name"></colspec>
471      <colspec colwidth="7*" colname="description"></colspec>
472      <thead>
473       <row>
474        <entry>Option</entry>
475        <entry>Description</entry>
476       </row>
477      </thead>
478      <tbody>
479       <row>
480        <entry>searchresult.size</entry>
481        <entry>
482         number of search result entries. This option is-nonexistant
483         if no entries are returned by the server.
484        </entry>
485       </row>
486       <row>
487        <entry>searchresult.<replaceable>no</replaceable>.id</entry>
488        <entry>sub query ID</entry>
489       </row>
490       <row>
491        <entry>searchresult.<replaceable>no</replaceable>.count</entry>
492        <entry>result count for item (number of hits)</entry>
493       </row>
494       <row>
495        <entry>searchresult.<replaceable>no</replaceable>.subquery.term</entry>
496        <entry>subquery term</entry>
497       </row>
498       <row>
499        <entry>
500         searchresult.<replaceable>no</replaceable>.interpretation.term
501        </entry>
502        <entry>interpretation term</entry>
503       </row>
504       <row>
505        <entry>
506         searchresult.<replaceable>no</replaceable>.recommendation.term
507        </entry>
508        <entry>recommendation term</entry>
509       </row>
510      </tbody>
511     </tgroup>
512    </table>
513    <sect2>
514     <title>Z39.50 Protocol behavior</title>
515     <para>
516      The creation of a result set involves at least a SearchRequest
517      - SearchResponse protocol handshake. Following that, if a sort
518      criteria was specified as part of the query, a SortRequest -
519      SortResponse handshake takes place. Note that it is necessary to
520      perform sorting before any retrieval takes place, so no records will
521      be returned from the target as part of the SearchResponse because these
522      would be unsorted. Hence, piggyback is disabled when sort criteria
523      are set. Following Search - and a possible sort - Retrieval takes
524      place - as one or more Present Requests/Response pairs being
525      transferred.
526      </para>
527     <para>
528      The API allows for two different modes for retrieval. A high level
529      mode which is somewhat more powerful and a low level one.
530      The low level is enabled when searching on a Connection object
531      for which the settings
532      <literal>smallSetUpperBound</literal>,
533      <literal>mediumSetPresentNumber</literal> and
534      <literal>largeSetLowerBound</literal> are set. The low level mode
535      thus allows you to precisely set how records are returned as part
536      of a search response as offered by the Z39.50 protocol.
537      Since the client may be retrieving records as part of the
538      search response, this mode doesn't work well if sorting is used.
539      </para>
540     <para>
541      The high-level mode allows you to fetch a range of records from
542      the result set with a given start offset. When you use this mode
543      the client will automatically use piggyback if that is possible
544      with the target and perform one or more present requests as needed.
545      Even if the target returns fewer records as part of a present response
546      because of a record size limit, etc. the client will repeat sending
547      present requests. As an example, if option <literal>start</literal>
548      is 0 (default) and <literal>count</literal> is 4, and
549      <literal>piggyback</literal> is 1 (default) and no sorting criteria
550      is specified, then the client will attempt to retrieve the 4
551      records as part the search response (using piggyback). On the other
552      hand, if either <literal>start</literal> is positive or if
553      a sorting criteria is set, or if <literal>piggyback</literal>
554      is 0, then the client will not perform piggyback but send Present
555      Requests instead.
556     </para>
557     <para>
558      If either of the options <literal>mediumSetElementSetName</literal> and
559      <literal>smallSetElementSetName</literal> are unset, the value
560      of option <literal>elementSetName</literal> is used for piggyback
561      searches. This means that for the high-level mode you only have
562      to specify one elementSetName option rather than three.
563      </para>
564    </sect2>
565    <sect2>
566     <title>SRW Protocol behavior</title>
567     <para>
568      Current version of &yaz; does not take advantage of a result set id
569      returned by the SRW server. Future versions might do, however.
570      Since, the ZOOM driver does not save result set IDs any
571      present (retrieval) is transformed to a SRW SearchRetrieveRequest
572      with same query but, possibly, different offsets.
573     </para>
574     <para>
575      Option <literal>schema</literal> specifies SRW schema
576      for retrieval. However, options <literal>elementSetName</literal> and
577      <literal>preferredRecordSyntax</literal> are ignored.
578     </para>
579     <para>
580      Options <literal>start</literal> and <literal>count</literal> 
581      are supported by SRW.
582      The remaining options
583      <literal>piggyback</literal>, 
584      <literal>smallSetUpperBound</literal>, 
585      <literal>largeSetLowerBound</literal>, 
586      <literal>mediumSetPresentNumber</literal>, 
587      <literal>mediumSetElementSetName</literal>,
588       <literal>smallSetElementSetName</literal> are
589      unsupported.
590     </para>
591     <para>
592      SRW supports CQL queries, <emphasis>not</emphasis> PQF.
593      If PQF is used, however, the PQF query is transferred anyway
594      using non-standard element <literal>pQuery</literal> in
595      SRW SearchRetrieveRequest.
596     </para>
597     <para>
598      Unfortunately, SRW does not define a database setting. Hence,
599      <literal>databaseName</literal> is unsupported and ignored.
600      However, the path part in host parameter for functions 
601      <function>ZOOM_connecton_new</function> and
602      <function>ZOOM_connection_connect</function> acts as a
603      database (at least for the &yaz; SRW server).
604     </para>
605    </sect2>
606   </sect1>
607   <sect1 id="zoom.records"><title>Records</title>
608    <para>
609     A record object is a retrieval record on the client side -
610     created from result sets.
611    </para>
612    <synopsis>
613      void ZOOM_resultset_records (ZOOM_resultset r,
614                                   ZOOM_record *recs,
615                                   size_t start, size_t count);
616      ZOOM_record ZOOM_resultset_record (ZOOM_resultset s, size_t pos);
617
618      const char *ZOOM_record_get (ZOOM_record rec, const char *type,
619                                   size_t *len);
620
621      ZOOM_record ZOOM_record_clone (ZOOM_record rec);
622
623      void ZOOM_record_destroy (ZOOM_record rec);
624    </synopsis>
625    <para>
626     References to temporary records are returned by functions 
627     <function>ZOOM_resultset_records</function> or
628     <function>ZOOM_resultset_record</function>.
629     </para>
630    <para>
631     If a persistent reference to a record is desired
632     <function>ZOOM_record_clone</function> should be used.
633     It returns a record reference that should be destroyed
634     by a call to <function>ZOOM_record_destroy</function>.
635    </para>
636    <para>
637     A single record is returned by function
638     <function>ZOOM_resultset_record</function> that takes a 
639     position as argument. First record has position zero.
640     If no record could be obtained <literal>NULL</literal> is returned.
641    </para>
642    <para>
643     Function <function>ZOOM_resultset_records</function> retrieves
644     a number of records from a result set. Parameter <literal>start</literal>
645     and <literal>count</literal> specifies the range of records to
646     be returned. Upon completion array
647     <literal>recs[0], ..recs[count-1]</literal>
648     holds record objects for the records. The array of records
649      <literal>recs</literal> should be allocated prior the call
650     <function>ZOOM_resultset_records</function>. Note that for those
651     records that couldn't be retrieved from the target
652     <literal>recs[ ..]</literal> is set to <literal>NULL</literal>.
653    </para>
654    <para id="zoom.record.get">
655     In order to extract information about a single record,
656     <function>ZOOM_record_get</function> is provided. The
657     function returns a pointer to certain record information. The
658     nature (type) of the pointer depends on the parameter,
659     <parameter>type</parameter>.
660    </para>
661    <para>
662     The <parameter>type</parameter> is a string of the format:
663    </para>
664    <para>
665     <replaceable>form</replaceable>[; charset=<replaceable>from</replaceable>[,<replaceable>to</replaceable>]]
666    </para>
667    <para>
668     where <replaceable>form</replaceable> specifies the format of the
669     returned record, <replaceable>from</replaceable>
670     specifies the character set of the record in its original form
671     (as returned by the server), <replaceable>to</replaceable> specifies
672     the output (returned)
673     character set encoding.
674     If charset is not given, then no character set conversion takes place.
675     If <replaceable>to</replaceable> is omitted UTF-8 is assumed.
676    </para>
677    <para>
678     In addition, for certain types, the length
679     <literal>len</literal> passed will be set to the size in bytes of
680     the returned information. 
681     </para>
682    <para>
683     The following are the supported values for <replaceable>form</replaceable>.
684     <variablelist>
685      <varlistentry><term><literal>database</literal></term>
686       <listitem><para>Database of record is returned
687         as a C null-terminated string. Return type
688         <literal>const char *</literal>. 
689        </para></listitem>
690      </varlistentry>
691      <varlistentry><term><literal>syntax</literal></term>
692       <listitem><para>The transfer syntax of the record is returned
693         as a C null-terminated string containing the symbolic name of
694         the record syntax, e.g. <literal>Usmarc</literal>. Return type
695         is
696         <literal>const char *</literal>. 
697        </para></listitem>
698      </varlistentry>
699      <varlistentry><term><literal>render</literal></term>
700       <listitem><para>The record is returned in a display friendly
701         format. Upon completion buffer is returned
702         (type <literal>const char *</literal>) and length is stored in
703         <literal>*len</literal>.
704        </para></listitem>
705      </varlistentry>
706      <varlistentry><term><literal>raw</literal></term>
707       <listitem><para>The record is returned in the internal
708         YAZ specific format. For GRS-1, Explain, and others, the
709         raw data is returned as type 
710         <literal>Z_External *</literal> which is just the type for
711         the member <literal>retrievalRecord</literal> in
712         type <literal>NamePlusRecord</literal>.
713         For SUTRS and octet aligned record (including all MARCs) the
714         octet buffer is returned and the length of the buffer.
715        </para></listitem>
716      </varlistentry>
717      <varlistentry><term><literal>xml</literal></term>
718       <listitem><para>The record is returned in XML if possible.
719         SRW/SRU and Z39.50 records with transfer syntax XML are
720         returned verbatim. MARC records are returned in
721         <ulink url="http://www.loc.gov/standards/marcxml/">
722          MARCXML
723          </ulink> 
724         (converted from ISO2709 to MARCXML by YAZ).
725         GRS-1 and OPAC records are not supported for this form.
726         Upon completion, the XML buffer is returned
727         (type <literal>const char *</literal>) and length is stored in
728         <literal>*len</literal>.
729        </para></listitem>
730      </varlistentry>
731      <varlistentry><term><literal>opac</literal></term>
732       <listitem><para>OPAC for record is returned in XML.
733        </para></listitem>
734      </varlistentry>
735     </variablelist>
736    </para>
737    <para>
738     Most
739     <ulink url="http://www.loc.gov/marc/">
740      MARC21
741     </ulink>
742     records uses the 
743     <ulink url="http://www.loc.gov/marc/specifications/speccharmarc8.html">
744      MARC-8
745     </ulink>
746     character set encoding.
747     An application that wishes to display in Latin-1 would use
748     <screen>
749      render; charset=marc8,iso-8859-1
750     </screen>
751    </para>
752    <sect2><title>Z39.50 Protocol behavior</title>
753     <para>
754      The functions <function>ZOOM_resultset_record</function> and
755      <function>ZOOM_resultset_records</function> inspects the client-side
756      record cache. Records not found in cache are fetched using
757      Present.
758      The functions may block (and perform network I/O)  - even though option
759      <literal>async</literal> is 1, because they return records objects.
760      (and there's no way to return records objects without retrieving them!).
761      </para>
762     <para>
763      There is a trick, however, in the usage of function
764      <function>ZOOM_resultset_records</function> that allows for
765      delayed retrieval (and makes it non-blocking). By using
766      a null pointer for <parameter>recs</parameter> you're indicating
767      you're not interested in getting records objects
768      <emphasis>now</emphasis>.
769     </para>
770    </sect2>
771    <sect2><title>SRW Protocol behavior</title>
772     <para>
773      The ZOOM driver for SRW treats records returned by a SRW server
774      as if they where Z39.50 records with transfer syntax XML and
775      no element set name or database name.
776     </para>
777    </sect2>
778   </sect1>
779   <sect1 id="zoom.scan"><title>Scan</title>
780    <para>
781     This section describes an interface for Scan. Scan is not an
782     official part of the ZOOM model yet. The result of a scan operation
783     is the <literal>ZOOM_scanset</literal> which is a set of terms
784     returned by a target.
785    </para>
786
787    <para>
788     The Scan interface is Z39.50 only. SRW version 1.0 does not
789     support this.
790    </para>
791
792    <synopsis>
793     ZOOM_scanset ZOOM_connection_scan(ZOOM_connection c,
794                                       const char *startpqf);
795
796     size_t ZOOM_scanset_size(ZOOM_scanset scan);
797
798     const char * ZOOM_scanset_term(ZOOM_scanset scan, size_t pos,
799                                    int *occ, size_t *len);
800
801     const char * ZOOM_scanset_display_term(ZOOM_scanset scan, size_t pos,
802                                            int *occ, size_t *len);
803
804     void ZOOM_scanset_destroy (ZOOM_scanset scan);
805
806     const char *ZOOM_scanset_option_get(ZOOM_scanset scan,
807                                          const char *key);
808
809     void ZOOM_scanset_option_set(ZOOM_scanset scan, const char *key,
810                                  const char *val);
811     </synopsis>
812    <para>
813     The scan set is created by function
814     <function>ZOOM_connection_scan</function> which performs a scan
815     operation on the connection using the specified
816     <parameter>startpqf</parameter>.
817     If the operation was successful, the size of the scan set can be
818     retrieved by a call to <function>ZOOM_scanset_size</function>.
819     Like result sets, the items are numbered 0,..size-1.
820     To obtain information about a particular scan term, call function
821     <function>ZOOM_scanset_term</function>. This function takes
822     a scan set offset <literal>pos</literal> and returns a pointer
823     to a <emphasis>raw term</emphasis> or <literal>NULL</literal> if
824     non-present.
825     If present, the <literal>occ</literal> and <literal>len</literal> 
826     are set to the number of occurrences and the length
827     of the actual term respectively.
828     <function>ZOOM_scanset_display_term</function> is similar to
829     <function>ZOOM_scanset_term</function> except that it returns
830     the <emphasis>display term</emphasis> rather than the raw term.
831     In a few cases, the term is different from display term. Always
832     use the display term for display and the raw term for subsequent
833     scan operations (to get more terms, next scan result, etc).
834    </para>
835    <para>
836     A scan set may be freed by a call to function
837     <function>ZOOM_scanset_destroy</function>.
838     Functions <function>ZOOM_scanset_option_get</function> and
839     <function>ZOOM_scanset_option_set</function> retrieves and sets
840     an option respectively.
841    </para>
842
843    <para>
844     The <parameter>startpqf</parameter> is a subset of PQF, namely
845     the Attributes+Term part. Multiple <literal>@attr</literal> can
846     be used. For example to scan in title (complete) phrases:
847     <literallayout>
848      @attr 1=4 @attr 6=2 "science o"
849     </literallayout>
850    </para>
851    
852    <table frame="top"><title>ZOOM Scan Set Options</title>
853     <tgroup cols="3">
854      <colspec colwidth="4*" colname="name"></colspec>
855      <colspec colwidth="7*" colname="description"></colspec>
856      <colspec colwidth="2*" colname="default"></colspec>
857      <thead>
858       <row>
859        <entry>Option</entry>
860        <entry>Description</entry>
861        <entry>Default</entry>
862       </row>
863      </thead>
864      <tbody>
865       <row><entry>
866         number</entry><entry>Number of Scan Terms requested in next scan.
867         After scan it holds the actual number of terms returned.
868        </entry><entry>10</entry></row>
869       <row><entry>
870         position</entry><entry>Preferred Position of term in response
871         in next scan; actual position after completion of scan.
872        </entry><entry>1</entry></row>
873       <row><entry>
874         stepSize</entry><entry>Step Size
875        </entry><entry>0</entry></row>
876       <row><entry>
877         scanStatus</entry><entry>An integer indicating the Scan Status
878         of last scan.
879        </entry><entry>0</entry></row>
880      </tbody>
881     </tgroup>
882    </table>
883   </sect1>
884
885   <sect1 id="zoom.ext"><title>Extended Services</title>
886    <para>
887     ZOOM offers an interface to a subset of the Z39.50 extended services
888     as well as a few privately defined ones:
889    </para>
890    <itemizedlist>
891     <listitem>
892      <para>
893       Z39.50 Item Order (ILL).
894       See <xref linkend="zoom.ext.itemorder"/>.
895      </para>
896     </listitem>
897     <listitem>
898      <para>
899       Record Update. This allows a client to insert, modify or delete
900       records.
901       See <xref linkend="zoom.ext.update"/>.
902      </para>
903     </listitem>
904     <listitem>
905      <para>
906       Database Create. This a non-standard feature. Allows a client
907       to create a database.
908       See <xref linkend="zoom.ext.dbcreate"/>.
909      </para>
910     </listitem>
911     <listitem>
912      <para>
913       Database Drop. This a non-standard feature. Allows a client
914       to delete/drop a database.
915       See <xref linkend="zoom.ext.dbdrop"/>.
916      </para>
917      </listitem>
918     <listitem>
919      <para>
920       Commit operation. This a non-standard feature. Allows a client
921       to commit operations.
922       See <xref linkend="zoom.ext.commit"/>.
923      </para>
924     </listitem>
925     <!-- all the ILL PDU options should go here too -->
926    </itemizedlist>
927    <para>
928     To create an extended service operation a <literal>ZOOM_package</literal>
929     must be created. The operation is a five step operation. The
930     package is created, package is configured by means of options,
931     the package is send, result is inspected (by means of options),
932     the package is destroyed.
933    </para>
934    <synopsis>
935     ZOOM_package ZOOM_connection_package(ZOOM_connection c,
936                                          ZOOM_options options);
937
938     const char *ZOOM_package_option_get(ZOOM_package p,
939                                         const char *key);
940     void ZOOM_package_option_set(ZOOM_package p, const char *key,
941                                  const char *val);
942     void ZOOM_package_send(ZOOM_package p, const char *type);
943
944     void ZOOM_package_destroy(ZOOM_package p);
945    </synopsis>
946    <para>
947     The <function>ZOOM_connection_package</function> creates a
948     package for the connection given using the options specified.
949    </para>
950    <para>
951     Functions <function>ZOOM_package_option_get</function> and
952     <function>ZOOM_package_option_set</function> gets and sets
953     options.
954    </para>
955    <para>
956     <function>ZOOM_package_send</function> sends
957     the package the via connection specified in 
958     <function>ZOOM_connection_package</function>.
959     The <parameter>type</parameter> specifies the actual extended service
960     package type to be sent.
961    </para>
962
963    <table frame="top"><title>Extended Service Common Options</title>
964     <tgroup cols="3">
965      <colspec colwidth="4*" colname="name"></colspec>
966      <colspec colwidth="7*" colname="description"></colspec>
967      <colspec colwidth="3*" colname="default"></colspec>
968      <thead>
969       <row>
970        <entry>Option</entry>
971        <entry>Description</entry>
972        <entry>Default</entry>
973       </row>
974      </thead>
975      <tbody>
976       <row>
977        <entry>package-name</entry>
978        <entry>Extended Service Request package name. Must be specified
979        as part of a request</entry>
980        <entry>none</entry>
981       </row>
982       <row>
983        <entry>user-id</entry>
984        <entry>User ID of Extended Service Package. Is a request option</entry>
985        <entry>none</entry>
986       </row>
987       <row>
988        <entry>function</entry>
989        <entry>
990         Function of package - one of <literal>create</literal>,
991         <literal>delete</literal>, <literal>modify</literal>. Is
992         a request option.
993        </entry>
994        <entry><literal>create</literal></entry>
995       </row>
996       <row>
997        <entry>targetReference</entry>
998        <entry>
999         Target Reference. This is part of the response as returned
1000         by the server. Read it after a succesful operation.
1001        </entry>
1002        <entry><literal>none</literal></entry>
1003       </row>
1004      </tbody>
1005     </tgroup>
1006    </table>
1007
1008    <sect2 id="zoom.ext.itemorder"><title>Item Order</title>
1009     <para>
1010      For Item Order, type must be set to <literal>itemorder</literal> in
1011      <function>ZOOM_package_send</function>.
1012     </para>
1013
1014     <table frame="top"><title>Item Order Options</title>
1015      <tgroup cols="3">
1016       <colspec colwidth="4*" colname="name"></colspec>
1017       <colspec colwidth="7*" colname="description"></colspec>
1018       <colspec colwidth="3*" colname="default"></colspec>
1019       <thead>
1020        <row>
1021         <entry>Option</entry>
1022         <entry>Description</entry>
1023         <entry>Default</entry>
1024        </row>
1025       </thead>
1026       <tbody>
1027        <row>
1028         <entry>contact-name</entry>
1029         <entry>ILL contact name</entry>
1030         <entry>none</entry>
1031        </row>
1032        <row>
1033         <entry>contact-phone</entry>
1034         <entry>ILL contact phone</entry>
1035         <entry>none</entry>
1036        </row>
1037        <row>
1038         <entry>contact-email</entry>
1039         <entry>ILL contact email</entry>
1040         <entry>none</entry>
1041        </row>
1042        <row>
1043         <entry>itemorder-item</entry>
1044         <entry>Position for item (record) requested. An integer</entry>
1045         <entry>1</entry>
1046        </row>
1047       </tbody>
1048      </tgroup>
1049     </table>
1050
1051    </sect2>
1052
1053    <sect2 id="zoom.ext.update"><title>Record Update</title>
1054     <para>
1055      For Record Update, type must be set to <literal>update</literal> in
1056      <function>ZOOM_package_send</function>.
1057     </para>
1058
1059     <table frame="top"><title>Record Update Options</title>
1060      <tgroup cols="3">
1061       <colspec colwidth="4*" colname="name"></colspec>
1062       <colspec colwidth="7*" colname="description"></colspec>
1063       <colspec colwidth="3*" colname="default"></colspec>
1064       <thead>
1065        <row>
1066         <entry>Option</entry>
1067         <entry>Description</entry>
1068         <entry>Default</entry>
1069        </row>
1070       </thead>
1071       <tbody>
1072        <row>
1073         <entry>action</entry>
1074         <entry>
1075          The update action. One of 
1076          <literal>specialUpdate</literal>,
1077          <literal>recordInsert</literal>,
1078          <literal>recordReplace</literal>,
1079          <literal>recordDelete</literal>,
1080          <literal>elementUpdate</literal>.
1081         </entry>
1082         <entry><literal>specialUpdate</literal></entry>
1083        </row>
1084        <row>
1085         <entry>recordIdOpaque</entry>
1086         <entry>Opaque Record ID</entry>
1087         <entry>none</entry>
1088        </row>
1089        <row>
1090         <entry>recordIdNumber</entry>
1091         <entry>Record ID number</entry>
1092         <entry>none</entry>
1093        </row>
1094        <row>
1095         <entry>record</entry>
1096         <entry>The record itself</entry>
1097         <entry>none</entry>
1098        </row>
1099        <row>
1100         <entry>syntax</entry>
1101         <entry>The record syntax (transfer syntax). Is a string that
1102          is a known record syntax.
1103         </entry>
1104         <entry>no syntax</entry>
1105        </row>
1106        <row>
1107         <entry>databaseName</entry>
1108         <entry>Database from connection object</entry>
1109         <entry>Default</entry>
1110        </row>
1111       </tbody>
1112      </tgroup>
1113     </table>
1114     
1115    </sect2>
1116
1117    <sect2 id="zoom.ext.dbcreate"><title>Database Create</title>
1118     <para>
1119      For Database Create, type must be set to <literal>create</literal> in
1120      <function>ZOOM_package_send</function>.
1121     </para>
1122     
1123     <table frame="top"><title>Database Create Options</title>
1124      <tgroup cols="3">
1125       <colspec colwidth="4*" colname="name"></colspec>
1126       <colspec colwidth="7*" colname="description"></colspec>
1127       <colspec colwidth="3*" colname="default"></colspec>
1128       <thead>
1129        <row>
1130         <entry>Option</entry>
1131         <entry>Description</entry>
1132         <entry>Default</entry>
1133        </row>
1134       </thead>
1135       <tbody>
1136        <row>
1137         <entry>databaseName</entry>
1138         <entry>Database from connection object</entry>
1139         <entry>Default</entry>
1140        </row>
1141       </tbody>
1142      </tgroup>
1143     </table>
1144    </sect2>
1145    
1146    <sect2 id="zoom.ext.dbdrop"><title>Database Drop</title>
1147     <para>
1148      For Database Drop, type must be set to <literal>drop</literal> in
1149      <function>ZOOM_package_send</function>.
1150     </para>
1151     
1152     <table frame="top"><title>Database Create Options</title>
1153      <tgroup cols="3">
1154       <colspec colwidth="4*" colname="name"></colspec>
1155       <colspec colwidth="7*" colname="description"></colspec>
1156       <colspec colwidth="3*" colname="default"></colspec>
1157       <thead>
1158        <row>
1159         <entry>Option</entry>
1160         <entry>Description</entry>
1161         <entry>Default</entry>
1162        </row>
1163       </thead>
1164       <tbody>
1165        <row>
1166         <entry>databaseName</entry>
1167         <entry>Database from connection object</entry>
1168         <entry>Default</entry>
1169        </row>
1170       </tbody>
1171      </tgroup>
1172     </table>
1173    </sect2>
1174    
1175    <sect2 id="zoom.ext.commit"><title>Commit Operation</title>
1176     <para>
1177      For Commit, type must be set to <literal>commit</literal> in
1178      <function>ZOOM_package_send</function>.
1179     </para>
1180    </sect2>
1181
1182    <sect2><title>Protocol behavior</title>
1183     <para>
1184      All the extended services are Z39.50-only.
1185     </para>
1186     <note>
1187      <para>
1188       The database create, drop and commit services are privately defined
1189       operations.
1190       Refer to <filename>esadmin.asn</filename> in YAZ for the ASN.1
1191       definitions.
1192      </para>
1193     </note>
1194    </sect2>
1195   </sect1>
1196
1197   <sect1 id="zoom.options"><title>Options</title>
1198    <para>
1199     Most &zoom; objects provide a way to specify options to change behavior.
1200     From an implementation point of view a set of options is just like
1201     an associative array / hash.
1202    </para>
1203    <synopsis>
1204      ZOOM_options ZOOM_options_create (void);
1205
1206      ZOOM_options ZOOM_options_create_with_parent (ZOOM_options parent);
1207
1208      void ZOOM_options_destroy (ZOOM_options opt);
1209    </synopsis>
1210    <synopsis>
1211      const char *ZOOM_options_get (ZOOM_options opt, const char *name);
1212
1213      void ZOOM_options_set (ZOOM_options opt, const char *name,
1214                             const char *v);
1215    </synopsis>
1216    <synopsis>
1217      typedef const char *(*ZOOM_options_callback)
1218                                      (void *handle, const char *name);
1219
1220      ZOOM_options_callback
1221              ZOOM_options_set_callback (ZOOM_options opt,
1222                                         ZOOM_options_callback c,
1223                                         void *handle);
1224    </synopsis>
1225   </sect1>
1226   <sect1 id="zoom.events"><title>Events</title>
1227    <para>
1228     If you're developing non-blocking applications, you have to deal 
1229     with events.
1230    </para>
1231    <synopsis>
1232     int ZOOM_event (int no, ZOOM_connection *cs);
1233    </synopsis>
1234    <para>
1235     The <function>ZOOM_event</function> executes pending events for
1236     a number of connections. Supply the number of connections in
1237     <literal>no</literal> and an array of connections in
1238     <literal>cs</literal> (<literal>cs[0] ... cs[no-1]</literal>).
1239     A pending event could be a sending a search, receiving a response,
1240     etc.
1241     When an event has occurred for one of the connections, this function
1242     returns a positive integer <literal>n</literal> denoting that an event
1243     occurred for connection <literal>cs[n-1]</literal>.
1244     When no events are pending for the connections, a value of zero is
1245     returned.
1246     To ensure that all outstanding requests are performed call this function
1247     repeatedly until zero is returned.
1248    </para>
1249    <para>
1250     If <function>ZOOM_event</function> returns and returns non-zero, the
1251     last event that occurred can be expected.
1252    </para>
1253    <synopsis>
1254     int ZOOM_connection_last_event(ZOOM_connection cs);
1255    </synopsis>
1256    <para>
1257     <function>ZOOM_connection_last_event</function> returns an event type
1258     (integer) for the last event.
1259    </para>
1260
1261    <table frame="top"><title>ZOOM Event IDs</title>
1262     <tgroup cols="2">
1263      <colspec colwidth="4*" colname="name"></colspec>
1264      <colspec colwidth="7*" colname="description"></colspec>
1265      <thead>
1266       <row>
1267        <entry>Event</entry>
1268        <entry>Description</entry>
1269       </row>
1270      </thead>
1271      <tbody>
1272       <row>
1273        <entry>ZOOM_EVENT_NONE</entry>
1274        <entry>No event has occurred</entry>
1275       </row>
1276       <row>
1277        <entry>ZOOM_EVENT_CONNECT</entry>
1278        <entry>TCP/IP connect has initiated</entry>
1279       </row>
1280       <row>
1281        <entry>ZOOM_EVENT_SEND_DATA</entry>
1282        <entry>Data has been transmitted (sending)</entry>
1283       </row>
1284       <row>
1285        <entry>ZOOM_EVENT_RECV_DATA</entry>
1286        <entry>Data has been received)</entry>
1287       </row>
1288       <row>
1289        <entry>ZOOM_EVENT_TIMEOUT</entry>
1290        <entry>Timeout</entry>
1291       </row>
1292       <row>
1293        <entry>ZOOM_EVENT_UNKNOWN</entry>
1294        <entry>Unknown event</entry>
1295       </row>
1296       <row>
1297        <entry>ZOOM_EVENT_SEND_APDU</entry>
1298        <entry>An APDU has been transmitted (sending)</entry>
1299       </row>
1300       <row>
1301        <entry>ZOOM_EVENT_RECV_APDU</entry>
1302        <entry>An APDU has been received</entry>
1303       </row>
1304       <row>
1305        <entry>ZOOM_EVENT_RECV_RECORD</entry>
1306        <entry>A result-set record has been received</entry>
1307       </row>
1308       <row>
1309        <entry>ZOOM_EVENT_RECV_SEARCH</entry>
1310        <entry>A search result been received</entry>
1311       </row>
1312      </tbody>
1313     </tgroup>
1314    </table>
1315   </sect1>
1316  </chapter>
1317  
1318  <!-- Keep this comment at the end of the file
1319  Local variables:
1320  mode: sgml
1321  sgml-omittag:t
1322  sgml-shorttag:t
1323  sgml-minimize-attributes:nil
1324  sgml-always-quote-attributes:t
1325  sgml-indent-step:1
1326  sgml-indent-data:t
1327  sgml-parent-document: "yaz.xml"
1328  sgml-local-catalogs: nil
1329  sgml-namecase-general:t
1330  End:
1331  -->
1332