1 <?xml version="1.0" standalone="no"?>
2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
3 "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"
5 <!ENTITY % local SYSTEM "local.ent">
7 <!ENTITY % entities SYSTEM "entities.ent">
9 <!ENTITY % idcommon SYSTEM "common/common.ent">
14 <title>YAZ++ User's Guide and Reference</title>
16 <author><firstname>Mike</firstname><surname>Taylor</surname></author>
17 <author><firstname>Adam</firstname><surname>Dickmeiss</surname></author>
20 <year>©right-year;</year>
21 <holder>Index Data Aps</holder>
25 <ulink url="&url.yazplusplus;">YAZ++</ulink>
26 is a set of libraries and header files that make it easier
27 to use the popular C-language
28 <ulink url="&url.yaz;">YAZ toolkit</ulink>
29 from C++, together with some utilities written using these
30 libraries. It includes an implementation of the C++ binding for
31 ZOOM (<link linkend="zoom">ZOOM-C++</link>).
34 This manual covers version &version;.
41 <imagedata fileref="common/id.png" format="PNG"/>
47 <chapter id="introduction">
48 <title>Introduction</title>
50 <ulink url="&url.yazplusplus;">YAZ++</ulink>
51 is a C++ layer for YAZ and implements the ANSI
52 <ulink url="&url.z39.50;">Z39.50</ulink> protocol for information
53 retrieval (client and server side).
56 The YAZ++ packages also features a ZOOM interface for C++ (
57 <ulink url="&url.zoom.bind.cplusplus;">ZOOM C++</ulink>).
60 Later versions (0.7+) of YAZ++ also supports SRU.
62 <section id="licensing">
63 <title>Licensing</title>
65 YAZ++ and ZOOM-C++ is is covered
66 by Revised <link linkend="license">BSD License</link>.
70 <chapter id="installation">
71 <title>Installation</title>
73 You need a C++ compiler to compile and use YAZ++.
74 The software was implemented using <ulink url="&url.gcc;">GCC</ulink>
75 so we know that works well with YAZ++. From time to time the
76 software is compiled on Windows using Visual C++.
77 Other compilers should work too. Let us know of portability
78 problems, etc. with your system.
81 YAZ++ is built on top of the
82 <ulink url="&url.yaz;">YAZ</ulink>
84 You need to install that first.
85 For some platforms there are binary packages for YAZ.
88 <title>Installation on Unix (from source)</title>
89 <para>On UNIX, the software is compiled as follows:
98 You can supply options for the <literal>configure</literal> script.
99 The most useful ones are:
102 <term><literal>--prefix </literal>directory</term>
104 Specifies installation prefix. By default
105 <filename>/usr/local</filename> is used.
109 <term><literal>--with-yaz </literal>directory</term>
111 Specifies the location of <filename>yaz-config</filename>.
112 The <filename>yaz-config</filename> program is generated in
113 the source directory of YAZ as well as the binaries
114 directory when YAZ is installed (via make install).
117 If you don't supply this option, <literal>configure</literal> will
118 look for <filename>yaz-config</filename> in directories of the
119 <envar>PATH</envar> environment - which is nearly always
124 For the whole list of <literal>configure</literal> options, refer
126 <literal>./configure --help</literal>.
129 Configure uses GNU's C/C++ compiler if available. To specify another
130 compiler, set <literal>CXX</literal>. To use other compiler flags,
131 specify <literal>CXXFLAGS</literal>. To use <literal>CC</literal>
132 with debugging you could use:
134 CXXFLAGS="-g" CXX=CC ./configure
138 This is what you have after successful compilation:
141 <term><filename>src/libyazpp.la</filename></term>
144 This library gets installed in your libraries directory
145 (<parameter>prefix</parameter><filename>/lib</filename>).
149 <term><filename>src/libzoompp.la</filename></term>
151 The <link linkend="zoom">ZOOM-C++</link> library.
152 This library gets installed in your libraries directory
153 (<parameter>prefix</parameter><filename>/lib</filename>).
157 <term><filename>include/yazpp/*.h</filename></term>
159 Various C++ header files, which you'll need for YAZ++
160 development. All these are installed in your header files area
161 (<parameter>prefix</parameter><filename>/include/yazpp</filename>).
165 <term><filename>yazpp-config</filename></term>
167 A Bourne shell-script utility that returns the values of the
168 <envar>CFLAGS</envar> and <envar>LIBS</envar>
169 environment variables
170 needed in order to compile your applications with the YAZ++
171 library. This script gets installed in your binaries directory
172 (<parameter>prefix</parameter><filename>/bin</filename>).
176 <term><filename>zoom/zclient</filename></term>
178 ZOOM C++ demonstration client that uses the ZOOM C++ classes.
179 This client does not get installed in the system directories.
183 <term><filename>src/yaz-my-client</filename></term>
185 YAZ C++ demonstration client. This client does not
186 get installed in the system directories.
190 <term><filename>src/yaz-my-server</filename></term>
192 YAZ C++ demonstration server. This server does not
193 get installed in the system directories.
199 <section id="windows">
200 <title>Installation on Windows</title>
202 YAZ++ is shipped with "makefiles" for the NMAKE tool that comes
203 with <ulink url="&url.vstudio;">Microsoft Visual Studio</ulink>.
204 Version 2003 (7) and 2005 (8) has been tested.
205 We expect that YAZ++ compiles with versions 5 and 6 as well.
208 Start a command prompt and switch the sub directory
209 <filename>WIN</filename> where the file <filename>makefile</filename>
210 is located. Customize the installation by editing the
211 <filename>makefile</filename> file (for example by using notepad).
214 The following summarizes the most important settings in that file:
216 <varlistentry><term><literal>DEBUG</literal></term>
218 If set to 1, the software is
219 compiled with debugging libraries (code generation is
220 multi-threaded debug DLL).
221 If set to 0, the software is compiled with release libraries
222 (code generation is multi-threaded DLL).
225 <varlistentry><term><filename>YAZ_DIR</filename></term>
227 Specifies the directory of the YAZ source.
233 When satisfied with the settings in the makefile, type
240 If the <filename>nmake</filename> command is not found on your system
241 you probably haven't defined the environment variables required to
242 use that tool. To fix that, find and run the batch file
243 <filename>vcvars32.bat</filename>. You need to run it from within
244 the command prompt or set the environment variables "globally";
245 otherwise it doesn't work.
249 If you wish to recompile YAZ++ - for example if you modify
250 settings in the <filename>makefile</filename> you can delete
251 object files, etc by running.
257 The following files are generated upon successful compilation:
260 <term><filename>bin/yazpp5.dll</filename></term>
262 YAZ++ DLL . Includes ZOOM C++ as well.
263 For the debug version <filename>lib/yazpp5d.dll</filename>
265 </para></listitem></varlistentry>
267 <term><filename>lib/yazpp5.lib</filename></term>
269 Import library for <filename>yazpp5.dll</filename>.
270 For the debug version <filename>lib/yazpp5d.lib</filename>
272 </para></listitem></varlistentry>
274 <term><filename>bin/yaz-my-client.exe</filename></term>
276 Z39.50 client demonstrating the YAZ++ API.
277 </para></listitem></varlistentry>
279 <term><filename>bin/yaz-my-server.exe</filename></term>
281 Z39.50 server demonstrating the YAZ++ API.
282 </para></listitem></varlistentry>
284 <term><filename>bin/zclient.exe</filename></term>
286 ZOOM C++ demo client. A simple WIN32 console application.
287 </para></listitem></varlistentry>
293 <title>ZOOM-C++</title>
294 <sect1 id="zoom-introduction">
295 <title>Introduction</title>
297 <ulink url="&url.zoom;">ZOOM</ulink>
298 is the emerging standard API for information retrieval programming
299 using the Z39.50 protocol. ZOOM's
300 <ulink url="&url.zoom.api;">Abstract API</ulink>
301 specifies semantics for classes representing key IR concepts such as
302 connections, queries, result sets and records; and there are various
303 <ulink url="&url.zoom.bind;">bindings</ulink>
304 specifying how those concepts should be represented in various
305 programming languages.
308 The YAZ++ library includes an implementation of the <ulink
309 url="&url.zoom.bind.cplusplus;">C++ binding</ulink>
310 for ZOOM, enabling quick, easy development of client applications.
313 For example, here is a tiny Z39.50 client that fetches and displays
314 the MARC record for Farlow & Brett Surman's
315 <citetitle>The Complete Dinosaur</citetitle>
316 from the Library of Congress's Z39.50 server:
319 #include <iostream>
320 #include <yazpp/zoom.h>
322 using namespace ZOOM;
324 int main(int argc, char **argv)
326 connection conn("z3950.loc.gov", 7090);
327 conn.option("databaseName", "Voyager");
328 conn.option("preferredRecordSyntax", "USMARC");
329 resultSet rs(conn, prefixQuery("@attr 1=7 0253333490"));
330 const record *rec = rs.getRecord(0);
331 cout << rec->render() << endl;
336 For the sake of simplicity, this program does not check
337 for errors: we show a more robust version of the same program
338 <link linkend="revised-sample">later</link>.)
342 YAZ++'s implementation of the C++ binding is a thin layer over YAZ's
343 implementation of the C binding. For information on the supported
344 options and other such details, see the ZOOM-C documentation, which
345 can be found on-line at
346 <ulink url="&url.yaz.zoom;"/>
349 All of the classes defined by ZOOM-C++ are in the
350 <literal>ZOOM</literal> namespace. We will now consider
351 the five main classes in turn:
355 <literal>connection</literal>
360 <literal>query</literal> and its subclasses
361 <literal>prefixQuery</literal> and
362 <literal>CCLQuery</literal>
367 <literal>resultSet</literal>
372 <literal>record</literal>
377 <literal>exception</literal> and its subclasses
378 <literal>systemException</literal>,
379 <literal>bib1Exception</literal> and
380 <literal>queryException</literal>
386 <sect1 id="zoom-connection">
387 <title><literal>ZOOM::connection</literal></title>
389 A <literal>ZOOM::connection</literal> object represents an open
390 connection to a Z39.50 server. Such a connection is forged by
391 constructing a <literal>connection</literal> object.
394 The class has this declaration:
399 connection (const char *hostname, int portnum);
401 const char *option (const char *key) const;
402 const char *option (const char *key, const char *val);
406 When a new <literal>connection</literal> is created, the hostname
407 and port number of a Z39.50 server must be supplied, and the
408 network connection is forged and wrapped in the new object. If the
409 connection can't be established - perhaps because the hostname
410 couldn't be resolved, or there is no server listening on the
411 specified port - then an
412 <link linkend="zoom-exception"><literal>exception</literal></link>
416 The only other methods on a <literal>connection</literal> object
417 are for getting and setting options. Any name-value pair of
418 strings may be set as options, and subsequently retrieved, but
419 certain options have special meanings which are understood by the
420 ZOOM code and affect the behaviour of the object that carries
421 them. For example, the value of the
422 <literal>databaseName</literal> option is used as the name of the
423 database to query when a search is executed against the
424 <literal>connection</literal>. For a full list of such special
425 options, see the ZOOM abstract API and the ZOOM-C documentation
428 <sect2 id="connection.references">
429 <title>References</title>
433 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.2">
434 Section 3.2 (Connection) of the ZOOM Abstract API</ulink>
439 <ulink url="&url.yaz.zoom.connections;">
440 The Connections section f the ZOOM-C documentation</ulink>
446 <sect1 id="zoom-query">
447 <title><literal>ZOOM::query</literal> and subclasses</title>
449 The <literal>ZOOM::query</literal> class is a virtual base class,
450 representing a query to be submitted to a server. This class has
451 no methods, but two (so far) concrete subclasses, each implementing
452 a specific query notation.
454 <sect2 id="zoom-prefixQuery">
455 <title><literal>ZOOM::prefixQuery</literal></title>
457 class prefixQuery : public query {
459 prefixQuery (const char *pqn);
464 This class enables a query to be created by compiling YAZ's
466 <ulink url="&url.yaz.pqf;">Prefix Query Notation (PQN)</ulink>.
469 <sect2 id="zoom-CCLQuery">
470 <title><literal>ZOOM::CCLQuery</literal></title>
472 class CCLQuery : public query {
474 CCLQuery (const char *ccl, void *qualset);
479 This class enables a query to be created using the simpler but
481 <ulink url="&url.yaz.ccl;">Common Command Language (CCL)</ulink>.
482 The qualifiers recognised by the CCL parser are specified in an
483 external configuration file in the format described by the YAZ
487 If query construction fails for either type of
488 <literal>query</literal> object - typically because the query
489 string itself is not valid PQN or CCL - then an
490 <link linkend="zoom-exception"><literal>exception</literal></link>
494 <sect2 id="queries.discussion">
495 <title>Discussion</title>
497 It will be readily recognised that these objects have no methods
498 other than their constructors: their only role in life is to be
499 used in searching, by being passed to the
500 <literal>resultSet</literal> class's constructor.
503 Given a suitable set of CCL qualifiers, the following pairs of
504 queries are equivalent:
507 prefixQuery("dinosaur");
508 CCLQuery("dinosaur");
510 prefixQuery("@and complete dinosaur");
511 CCLQuery("complete and dinosaur");
513 prefixQuery("@and complete @or dinosaur pterosaur");
514 CCLQuery("complete and (dinosaur or pterosaur)");
516 prefixQuery("@attr 1=7 0253333490");
517 CCLQuery("isbn=0253333490");
520 <sect2 id="query.references">
521 <title>References</title>
525 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.3">
526 Section 3.3 (Query) of the ZOOM Abstract API
532 <ulink url="&url.yaz.zoom.query;">
533 The Queries section of the ZOOM-C documentation
540 <sect1 id="zoom-resultset">
541 <title><literal>ZOOM::resultSet</literal></title>
543 A <literal>ZOOM::resultSet</literal> object represents a set of
544 records identified by a query that has been executed against a
545 particular connection. The sole purpose of both
546 <literal>connection</literal> and <literal>query</literal> objects
547 is that they can be used to create new
548 <literal>resultSet</literal>s - that is, to perform a search on the
549 server on the remote end of the connection.
552 The class has this declaration:
557 resultSet (connection &c, const query &q);
559 const char *option (const char *key) const;
560 const char *option (const char *key, const char *val);
561 size_t size () const;
562 const record *getRecord (size_t i) const;
566 New <literal>resultSet</literal>s are created by the constructor,
567 which is passed a <literal>connection</literal>, indicating the
568 server on which the search is to be performed, and a
569 <literal>query</literal>, indicating what search to perform. If
570 the search fails - for example, because the query uses attributes
571 that the server doesn't implement - then an
572 <link linkend="zoom-exception"><literal>exception</literal></link>
576 Like <literal>connection</literal>s, <literal>resultSet</literal>
577 objects can carry name-value options. The special options which
578 affect ZOOM-C++'s behaviour are the same as those for ZOOM-C and
579 are described in its documentation (link below). In particular,
580 the <literal>preferredRecordSyntax</literal> option may be set to
581 a string such as ``USMARC'', ``SUTRS'' etc. to indicate what the
582 format in which records should be retrieved; and the
583 <literal>elementSetName</literal> option indicates whether brief
584 records (``B''), full records (``F'') or some other composition
588 The <literal>size()</literal> method returns the number of records
589 in the result set. Zero is a legitimate value: a search that finds
590 no records is not the same as a search that fails.
593 Finally, the <literal>getRecord</literal> method returns the
594 <parameter>i</parameter>th record from the result set, where
595 <parameter>i</parameter> is zero-based: that is, legitmate values
596 range from zero up to one less than the result-set size. If the
597 method fails, for example because the requested record is out of
598 range, it <literal>throw</literal>s an
599 <link linkend="zoom-exception"><literal>exception</literal></link>.
601 <sect2 id="resultset.references">
602 <title>References</title>
606 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.4"
607 >Section 3.4 (Result Set) of the ZOOM Abstract API</ulink>
612 <ulink url="&url.yaz.zoom.resultsets;"
613 >The Result Sets section of the ZOOM-C documentation</ulink>
619 <sect1 id="zoom-record">
620 <title><literal>ZOOM::record</literal></title>
622 A <literal>ZOOM::record</literal> object represents a chunk of data
623 from a <literal>resultSet</literal> returned from a server.
626 The class has this declaration:
633 UNKNOWN, GRS1, SUTRS, USMARC, UKMARC, XML
635 record *clone () const;
636 syntax recsyn () const;
637 const char *render () const;
638 const char *rawdata () const;
642 Records returned from Z39.50 servers are encoded using a record
643 syntax: the various national MARC formats are commonly used for
644 bibliographic data, GRS-1 or XML for complex structured data, SUTRS
645 for simple human-readable text, etc. The
646 <literal>record::syntax</literal> enumeration specifies constants
647 representing common record syntaxes, and the
648 <literal>recsyn()</literal> method returns the value corresponding
649 to the record-syntax of the record on which it is invoked.
652 Because this interface uses an enumeration, it is difficult to
653 extend to other record syntaxes - for example, DANMARC, the MARC
654 variant widely used in Denmark. We might either grow the
655 enumeration substantially, or change the interface to return
656 either an integer or a string.
661 The simplest thing to do with a retrieved record is simply to
662 <literal>render()</literal> it. This returns a human-readable, but
663 not necessarily very pretty, representation of the contents of the
664 record. This is useful primarily for testing and debugging, since
665 the application has no control over how the record appears.
666 (The application must <emphasis>not</emphasis>
667 <literal>delete</literal> the returned string - it is ``owned'' by
671 More sophisticated applications will want to deal with the raw data
672 themselves: the <literal>rawdata()</literal> method returns it.
673 Its format will vary depending on the record syntax: SUTRS, MARC
674 and XML records are returned ``as is'', and GRS-1 records as a
675 pointer to their top-level node, which is a
676 <literal>Z_GenericRecord</literal> structure as defined in the
677 <literal><yaz/z-grs.h></literal> header file.
678 (The application must <emphasis>not</emphasis>
679 <literal>delete</literal> the returned data - it is ``owned'' by
683 Perceptive readers will notice that there are no methods for access
684 to individual fields within a record. That's because the different
685 record syntaxes are so different that there is no even a uniform
686 notion of what a field is across them all, let alone a sensible way
687 to implement such a function. Fetch the raw data instead, and pick
688 it apart ``by hand''.
690 <sect2 id="zoom.memory.management">
691 <title>Memory Management</title>
693 The <literal>record</literal> objects returned from
694 <literal>resultSet::getRecord()</literal> are ``owned'' by the
695 result set object: that means that the application is not
696 responsible for <literal>delete</literal>ing them - each
697 <literal>record</literal> is automatically deallocated when the
698 <literal>resultSet</literal> that owns it is
699 <literal>delete</literal>d.
702 Usually that's what you want: it means that you can easily fetch a
703 record, use it and forget all about it, like this:
706 resultSet rs(conn, query);
707 cout << rs.getRecord(0)->render();
710 But sometimes you want a <literal>record</literal> to live on past
711 the lifetime of the <literal>resultSet</literal> from which it was
712 fetched. In this case, the <literal>clone(f)</literal> method can
713 be used to make an autonomous copy. The application must
714 <literal>delete</literal> it when it doesn't need it any longer:
719 resultSet rs(conn, query);
720 rec = rs.getRecord(0)->clone();
721 // `rs' goes out of scope here, and is deleted
723 cout << rec->render();
727 <sect2 id="record.references">
728 <title>References</title>
732 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.5"
733 >Section 3.5 (Record) of the ZOOM Abstract API</ulink>
738 <ulink url="&url.yaz.zoom.records;"
739 >The Records section of the ZOOM-C documentation</ulink>
745 <sect1 id="zoom-exception">
746 <title><literal>ZOOM::exception</literal> and subclasses</title>
748 The <literal>ZOOM::exception</literal> class is a virtual base
749 class, representing a diagnostic generated by the ZOOM-C++ library
750 or returned from a server. Its subclasses represent particular
754 When any of the ZOOM methods fail, they respond by
755 <literal>throw</literal>ing an object of type
756 <literal>exception</literal> or one of its subclasses. This most
757 usually happens with the <literal>connection</literal> constructor,
758 the various query constructors, the <literal>resultSet</literal>
759 constructor (which is actually the searching method) and
760 <literal>resultSet::getRecord()</literal>.
763 The base class has this declaration:
768 exception (int code);
769 int errcode () const;
770 const char *errmsg () const;
774 It has three concrete subclasses:
776 <sect2 id="zoom-systemException">
777 <title><literal>ZOOM::systemException</literal></title>
779 class systemException: public exception {
782 int errcode () const;
783 const char *errmsg () const;
787 Represents a ``system error'', typically indicating that a system
788 call failed - often in the low-level networking code that
789 underlies Z39.50. <literal>errcode()</literal> returns the value
790 that the system variable <literal>errno</literal> had at the time
791 the exception was constructed; and <literal>errmsg()</literal>
792 returns a human-readable error-message corresponidng to that error
796 <sect2 id="zoom-bib1Exception">
797 <title><literal>ZOOM::bib1Exception</literal></title>
799 class bib1Exception: public exception {
801 bib1Exception (int errcode, const char *addinfo);
802 int errcode () const;
803 const char *errmsg () const;
804 const char *addinfo () const;
808 Represents an error condition communicated by a Z39.50 server.
809 <literal>errcode()</literal> returns the BIB-1 diagnostic code of
810 the error, and <literal>errmsg()</literal> a human-readable error
811 message corresponding to that code. <literal>addinfo()</literal>
812 returns any additional information associated with the error.
815 For example, if a ZOOM application tries to search in the
816 ``Voyager'' database of a server that does not have a database of
817 that name, a <literal>bib1Exception</literal> will be thrown in
818 which <literal>errcode()</literal> returns 109,
819 <literal>errmsg()</literal> returns the corresponding error
820 message ``Database unavailable'' and <literal>addinfo()</literal>
821 returns the name of the requested, but unavailable, database.
824 <sect2 id="zoom-queryException">
825 <title><literal>ZOOM::queryException</literal></title>
827 class queryException: public exception {
829 static const int PREFIX = 1;
830 static const int CCL = 2;
831 queryException (int qtype, const char *source);
832 int errcode () const;
833 const char *errmsg () const;
834 const char *addinfo () const;
838 This class represents an error in parsing a query into a form that
839 a Z39.50 can understand. It must be created with the
840 <literal>qtype</literal> parameter equal to one of the query-type
841 constants, which can be retrieved via the
842 <literal>errcode()</literal> method; <literal>errmsg()</literal>
843 returns an error-message specifying which kind of query was
844 malformed; and <literal>addinfo()</literal> returns a copy of the
845 query itself (that is, the value of <literal>source</literal> with
846 which the exception object was created.)
849 <sect2 id="revised-sample">
850 <title>Revised Sample Program</title>
852 Now we can revise the sample program from the
853 <link linkend="zoom-introduction">introduction</link>
854 to catch exceptions and report any errors:
857 /* g++ -o zoom-c++-hw zoom-c++-hw.cpp -lzoompp -lyaz */
859 #include <iostream>
860 #include <yazpp/zoom.h>
862 using namespace ZOOM;
864 int main(int argc, char **argv)
867 connection conn("z3950.loc.gov", 7090);
868 conn.option("databaseName", "Voyager");
869 conn.option("preferredRecordSyntax", "USMARC");
870 resultSet rs(conn, prefixQuery("@attr 1=7 0253333490"));
871 const record *rec = rs.getRecord(0);
872 cout << rec->render() << endl;
873 } catch (systemException &e) {
874 cerr << "System error " <<
875 e.errcode() << " (" << e.errmsg() << ")" << endl;
876 } catch (bib1Exception &e) {
877 cerr << "BIB-1 error " <<
878 e.errcode() << " (" << e.errmsg() << "): " << e.addinfo() << endl;
879 } catch (queryException &e) {
880 cerr << "Query error " <<
881 e.errcode() << " (" << e.errmsg() << "): " << e.addinfo() << endl;
882 } catch (exception &e) {
883 cerr << "Error " <<
884 e.errcode() << " (" << e.errmsg() << ")" << endl;
889 The heart of this program is the same as in the original version,
890 but it's now wrapped in a <literal>try</literal> block followed by
891 several <literal>catch</literal> blocks which try to give helpful
892 diagnostics if something goes wrong.
895 The first such block diagnoses system-level errors such as memory
896 exhaustion or a network connection being broken by a server's
897 untimely death; the second catches errors at the Z39.50 level,
898 such as a server's report that it can't provide records in USMARC
899 syntax; the third is there in case there's something wrong with
900 the syntax of the query (although in this case it's correct); and
901 finally, the last <literal>catch</literal> block is a
902 belt-and-braces measure to be sure that nothing escapes us.
905 <sect2 id="exception.references">
906 <title>References</title>
910 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.7"
911 >Section 3.7 (Exception) of the ZOOM Abstract API</ulink>
916 <ulink url="&url.z39.50.diagnostics;">Bib-1 Diagnostics</ulink> on the
917 <ulink url="&url.z39.50;">Z39.50 Maintenance Agency</ulink> site.
922 Because C does not support exceptions, ZOOM-C has no API element
923 that corresponds directly with ZOOM-C++'s
924 <literal>exception</literal> class and its subclasses. The
925 closest thing is the <literal>ZOOM_connection_error</literal>
926 function described in
927 <ulink url="&url.yaz.zoom.connections;"
928 >The Connections section</ulink> of the documentation.
934 <title>YAZ C++ API</title>
936 The YAZ C++ API is an client - and server API that exposes
937 all YAZ features. The API doesn't hide YAZ C data structures, but
938 provides a set of useful high-level objects for creating clients -
942 All definitions from YAZ++ are part of namespace
943 <literal>yazpp_1</literal>.
946 The following sections include a short description of the
947 interfaces and implementations (concrete classes).
950 In order to understand the structure, you should look at the
951 example client <filename>yaz-my-client.cpp</filename> and
952 the example server <filename>yaz-my-server.cpp</filename>.
953 If that is too easy, you can always turn to the implementation
954 of the proxy itself and send us a patch if you implement a new
959 The documentation here is very limited. We plan to enhance it -
960 provided there is interest for it.
963 <section id="interfaces"><title>Interfaces</title>
964 <section id="ISocketObservable"><title>ISocketObservable</title>
966 This interface is capable of observing sockets.
967 When a socket even occurs it invokes an object implementing the
968 <link linkend="ISocketObserver">ISocketObserver</link>
972 #include <yazpp/socket-observer.h>
974 class my_socketobservable : public ISocketObservable {
975 // Add an observer interested in socket fd
976 virtual void addObserver(int fd, ISocketObserver *observer) = 0;
977 // Delete an observer
978 virtual void deleteObserver(ISocketObserver *observer) = 0;
979 // Delete all observers
980 virtual void deleteObservers() = 0;
981 // Specify the events that the observer is interested in.
982 virtual void maskObserver(ISocketObserver *observer,
985 virtual void timeoutObserver(ISocketObserver *observer,
990 <section id="ISocketObserver">
991 <title>ISocketObserver</title>
993 This interface is interested in socket events supporting
994 the <link linkend="ISocketObservable">ISocketObservable</link>
998 #include <yazpp/socket-observer.h>
1000 class my_socketobserver : public ISocketObserver {
1002 // Notify the observer that something happened to socket
1003 virtual void socketNotify(int event) = 0;
1007 <section id="IPDU_Observable">
1008 <title>IPDU_Observable</title>
1010 This interface is is responsible for sending - and receiving PDUs over
1011 the network (YAZ COMSTACK). When events occur, an instance
1012 implementing <link linkend="IPDU_Observer">IPDU_Observer</link>
1016 #include <yazpp/pdu-observer.h>
1018 class my_pduobservable : public IPDU_Observable {
1020 // Send encoded PDU buffer of specified length
1021 virtual int send_PDU(const char *buf, int len) = 0;
1022 // Connect with server specified by addr.
1023 virtual void connect(IPDU_Observer *observer,
1024 const char *addr) = 0;
1025 // Listen on address addr.
1026 virtual void listen(IPDU_Observer *observer, const char *addr)=0;
1028 virtual void close() = 0;
1029 // Make clone of this object using this interface
1030 virtual IPDU_Observable *clone() = 0;
1031 // Destroy completely
1032 virtual void destroy() = 0;
1034 virtual void idleTime (int timeout) = 0;
1036 virtual const char *getpeername() = 0;
1038 virtual ~IPDU_Observable();
1042 <section id="IPDU_Observer">
1043 <title>IPDU_Observer</title>
1045 This interface is interested in PDUs and using an object implementing
1046 <link linkend="IPDU_Observable">IPDU_Observable</link>.
1049 #include <yazpp/pdu-observer.h>
1051 class my_pduobserver : public IPDU_Observer {
1053 // A PDU has been received
1054 virtual void recv_PDU(const char *buf, int len) = 0;
1055 // Called when Iyaz_PDU_Observable::connect was successful.
1056 virtual void connectNotify() = 0;
1057 // Called whenever the connection was closed
1058 virtual void failNotify() = 0;
1059 // Called whenever there is a timeout
1060 virtual void timeoutNotify() = 0;
1061 // Make clone of observer using IPDU_Observable interface
1062 virtual IPDU_Observer *sessionNotify(
1063 IPDU_Observable *the_PDU_Observable, int fd) = 0;
1067 <section id="query">
1068 <title>Yaz_Query</title>
1073 #include <yazpp/query.h>
1074 class my_query : public Yaz_Query {
1076 // Print query in buffer described by str and len
1077 virtual void print (char *str, int len) = 0;
1082 <section id="implementations">
1083 <title>Implementations</title>
1084 <section id="Yaz_SocketManager">
1085 <title>Yaz_SocketManager</title>
1087 This class implements the <link linkend="ISocketObservable">
1088 ISocketObservable</link> interface and is a portable
1089 socket wrapper around the select call.
1090 This implementation is useful for daemons,
1091 command line clients, etc.
1094 #include <yazpp/socket-manager.h>
1096 class SocketManager : public ISocketObservable {
1099 virtual void addObserver(int fd, ISocketObserver *observer);
1100 // Delete an observer
1101 virtual void deleteObserver(ISocketObserver *observer);
1102 // Delete all observers
1103 virtual void deleteObservers();
1104 // Set event mask for observer
1105 virtual void maskObserver(ISocketObserver *observer, int mask);
1107 virtual void timeoutObserver(ISocketObserver *observer,
1109 // Process one event. return > 0 if event could be processed;
1112 virtual ~SocketManager();
1116 <section id="PDU_Assoc">
1117 <title>PDU_Assoc</title>
1119 This class implements the interfaces
1120 <link linkend="IPDU_Observable">IPDU_Observable</link>
1122 <link linkend="ISocketObserver">ISocketObserver</link>.
1123 This object implements a non-blocking client/server channel
1124 that transmits BER encoded PDUs (or those offered by YAZ COMSTACK).
1127 #include <yazpp/pdu-assoc.h>
1129 class PDU_Assoc : public IPDU_Observable,
1132 COMSTACK comstack(const char *type_and_host, void **vp);
1133 // Create object using specified socketObservable
1134 PDU_Assoc(ISocketObservable *socketObservable);
1135 // Create Object using existing comstack
1136 PDU_Assoc(ISocketObservable *socketObservable,
1138 // Close socket and destroy object.
1139 virtual ~PDU_Assoc();
1141 IPDU_Observable *clone();
1143 int send_PDU(const char *buf, int len);
1144 // connect to server (client role)
1145 void connect(IPDU_Observer *observer, const char *addr);
1146 // listen for clients (server role)
1147 void listen(IPDU_Observer *observer, const char *addr);
1148 // Socket notification
1149 void socketNotify(int event);
1152 // Close and destroy
1155 void idleTime (int timeout);
1157 virtual void childNotify(COMSTACK cs);
1161 <section id="Z_Assoc">
1162 <title>Z_Assoc</title>
1164 This class implements the interface
1165 <link linkend="IPDU_Observer">IPDU_Obserer</link>.
1166 This object implements a Z39.50 client/server channel AKA
1170 #include <yazpp/z-assoc.h>
1172 class Z_Assoc : public IPDU_Observer {
1174 // Create object using the PDU Observer specified
1175 Z_Assoc(IPDU_Observable *the_PDU_Observable);
1176 // Destroy association and close PDU Observer
1179 void recv_PDU(const char *buf, int len);
1180 // Connect notification
1181 virtual void connectNotify() = 0;
1182 // Failure notification
1183 virtual void failNotify() = 0;
1184 // Timeout notification
1185 virtual void timeoutNotify() = 0;
1187 void timeout(int timeout);
1188 // Begin Z39.50 client role
1189 void client(const char *addr);
1190 // Begin Z39.50 server role
1191 void server(const char *addr);
1195 // Decode Z39.50 PDU.
1196 Z_APDU *decode_Z_PDU(const char *buf, int len);
1197 // Encode Z39.50 PDU.
1198 int encode_Z_PDU(Z_APDU *apdu, char **buf, int *len);
1200 int send_Z_PDU(Z_APDU *apdu);
1201 // Receive Z39.50 PDU
1202 virtual void recv_Z_PDU(Z_APDU *apdu) = 0;
1203 // Create Z39.50 PDU with reasonable defaults
1204 Z_APDU *create_Z_PDU(int type);
1209 void set_APDU_log(const char *fname);
1210 const char *get_APDU_log();
1213 void get_otherInfoAPDU(Z_APDU *apdu, Z_OtherInformation ***oip);
1214 Z_OtherInformationUnit *update_otherInformation (
1215 Z_OtherInformation **otherInformationP, int createFlag,
1216 int *oid, int categoryValue, int deleteFlag);
1217 void set_otherInformationString (
1218 Z_OtherInformation **otherInformationP,
1219 int *oid, int categoryValue,
1221 void set_otherInformationString (
1222 Z_OtherInformation **otherInformation,
1223 int oidval, int categoryValue,
1225 void set_otherInformationString (
1227 int oidval, int categoryValue,
1230 Z_ReferenceId *getRefID(char* str);
1231 Z_ReferenceId **get_referenceIdP(Z_APDU *apdu);
1232 void transfer_referenceId(Z_APDU *from, Z_APDU *to);
1234 const char *get_hostname();
1238 <section id="IR_Assoc">
1239 <title>IR_Assoc</title>
1241 This object is just a specialization of
1242 <link linkend="Z_Assoc">Z_Assoc</link> and provides
1243 more facilities for the Z39.50 client role.
1246 #include <yazpp/ir-assoc.h>
1248 class IR_Assoc : public Z_Assoc {
1253 The example client, <filename>yaz-my-client.cpp</filename>,
1257 <section id="Z_Server">
1258 <title>Z_Server</title>
1260 This object is just a specialization of
1261 <link linkend="Z_Assoc">Z_Assoc</link> and provides
1262 more facilities for the Z39.50 server role.
1265 #include <yazpp/z-server.h>
1267 class My_Server : public Z_Server {
1272 The example server, <filename>yaz-my-server.cpp</filename>,
1278 <appendix id="license">
1279 <title>License</title>
1281 Copyright © ©right-year; Index Data.
1284 All rights reserved.
1287 Redistribution and use in source and binary forms, with or without
1288 modification, are permitted provided that the following conditions are met:
1293 Redistributions of source code must retain the above copyright
1294 notice, this list of conditions and the following disclaimer.
1299 Redistributions in binary form must reproduce the above copyright
1300 notice, this list of conditions and the following disclaimer in the
1301 documentation and/or other materials provided with the distribution.
1306 Neither the name of Index Data nor the names of its contributors
1307 may be used to endorse or promote products derived from this
1308 software without specific prior written permission.
1313 THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
1314 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1315 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1316 DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR
1317 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1318 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1319 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1320 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1321 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1322 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1328 <!-- Keep this comment at the end of the file
1331 nxml-child-indent: 1