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 Visual Studio 2013 (12.0) has been tested.
207 Start a command prompt and switch the sub directory
208 <filename>WIN</filename> where the file <filename>makefile</filename>
209 is located. Customize the installation by editing the
210 <filename>makefile</filename> file (for example by using notepad).
213 The following summarizes the most important settings in that file:
215 <varlistentry><term><literal>DEBUG</literal></term>
217 If set to 1, the software is
218 compiled with debugging libraries (code generation is
219 multi-threaded debug DLL).
220 If set to 0, the software is compiled with release libraries
221 (code generation is multi-threaded DLL).
224 <varlistentry><term><filename>YAZ_DIR</filename></term>
226 Specifies the directory of the YAZ source.
232 When satisfied with the settings in the makefile, type
239 If the <filename>nmake</filename> command is not found on your system
240 you probably haven't defined the environment variables required to
241 use that tool. To fix that, find and run the batch file
242 <filename>vcvars32.bat</filename>. You need to run it from within
243 the command prompt or set the environment variables "globally";
244 otherwise it doesn't work.
248 If you wish to recompile YAZ++ - for example if you modify
249 settings in the <filename>makefile</filename> you can delete
250 object files, etc by running.
256 The following files are generated upon successful compilation:
259 <term><filename>bin/yazpp5.dll</filename></term>
261 YAZ++ DLL . Includes ZOOM C++ as well.
262 For the debug version <filename>lib/yazpp5d.dll</filename>
264 </para></listitem></varlistentry>
266 <term><filename>lib/yazpp5.lib</filename></term>
268 Import library for <filename>yazpp5.dll</filename>.
269 For the debug version <filename>lib/yazpp5d.lib</filename>
271 </para></listitem></varlistentry>
273 <term><filename>bin/yaz-my-client.exe</filename></term>
275 Z39.50 client demonstrating the YAZ++ API.
276 </para></listitem></varlistentry>
278 <term><filename>bin/yaz-my-server.exe</filename></term>
280 Z39.50 server demonstrating the YAZ++ API.
281 </para></listitem></varlistentry>
283 <term><filename>bin/zclient.exe</filename></term>
285 ZOOM C++ demo client. A simple Windows console application.
286 </para></listitem></varlistentry>
292 <title>ZOOM-C++</title>
293 <sect1 id="zoom-introduction">
294 <title>Introduction</title>
296 <ulink url="&url.zoom;">ZOOM</ulink>
297 is the emerging standard API for information retrieval programming
298 using the Z39.50 protocol. ZOOM's
299 <ulink url="&url.zoom.api;">Abstract API</ulink>
300 specifies semantics for classes representing key IR concepts such as
301 connections, queries, result sets and records; and there are various
302 <ulink url="&url.zoom.bind;">bindings</ulink>
303 specifying how those concepts should be represented in various
304 programming languages.
307 The YAZ++ library includes an implementation of the <ulink
308 url="&url.zoom.bind.cplusplus;">C++ binding</ulink>
309 for ZOOM, enabling quick, easy development of client applications.
312 For example, here is a tiny Z39.50 client that fetches and displays
313 the MARC record for Farlow & Brett Surman's
314 <citetitle>The Complete Dinosaur</citetitle>
315 from the Library of Congress's Z39.50 server:
318 #include <iostream>
319 #include <yazpp/zoom.h>
321 using namespace ZOOM;
323 int main(int argc, char **argv)
325 connection conn("z3950.loc.gov", 7090);
326 conn.option("databaseName", "Voyager");
327 conn.option("preferredRecordSyntax", "USMARC");
328 resultSet rs(conn, prefixQuery("@attr 1=7 0253333490"));
329 const record *rec = rs.getRecord(0);
330 cout << rec->render() << endl;
335 For the sake of simplicity, this program does not check
336 for errors: we show a more robust version of the same program
337 <link linkend="revised-sample">later</link>.)
341 YAZ++'s implementation of the C++ binding is a thin layer over YAZ's
342 implementation of the C binding. For information on the supported
343 options and other such details, see the ZOOM-C documentation, which
344 can be found on-line at
345 <ulink url="&url.yaz.zoom;"/>
348 All of the classes defined by ZOOM-C++ are in the
349 <literal>ZOOM</literal> namespace. We will now consider
350 the five main classes in turn:
354 <literal>connection</literal>
359 <literal>query</literal> and its subclasses
360 <literal>prefixQuery</literal> and
361 <literal>CCLQuery</literal>
366 <literal>resultSet</literal>
371 <literal>record</literal>
376 <literal>exception</literal> and its subclasses
377 <literal>systemException</literal>,
378 <literal>bib1Exception</literal> and
379 <literal>queryException</literal>
385 <sect1 id="zoom-connection">
386 <title><literal>ZOOM::connection</literal></title>
388 A <literal>ZOOM::connection</literal> object represents an open
389 connection to a Z39.50 server. Such a connection is forged by
390 constructing a <literal>connection</literal> object.
393 The class has this declaration:
398 connection (const char *hostname, int portnum);
400 const char *option (const char *key) const;
401 const char *option (const char *key, const char *val);
405 When a new <literal>connection</literal> is created, the hostname
406 and port number of a Z39.50 server must be supplied, and the
407 network connection is forged and wrapped in the new object. If the
408 connection can't be established - perhaps because the hostname
409 couldn't be resolved, or there is no server listening on the
410 specified port - then an
411 <link linkend="zoom-exception"><literal>exception</literal></link>
415 The only other methods on a <literal>connection</literal> object
416 are for getting and setting options. Any name-value pair of
417 strings may be set as options, and subsequently retrieved, but
418 certain options have special meanings which are understood by the
419 ZOOM code and affect the behaviour of the object that carries
420 them. For example, the value of the
421 <literal>databaseName</literal> option is used as the name of the
422 database to query when a search is executed against the
423 <literal>connection</literal>. For a full list of such special
424 options, see the ZOOM abstract API and the ZOOM-C documentation
427 <sect2 id="connection.references">
428 <title>References</title>
432 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.2">
433 Section 3.2 (Connection) of the ZOOM Abstract API</ulink>
438 <ulink url="&url.yaz.zoom.connections;">
439 The Connections section f the ZOOM-C documentation</ulink>
445 <sect1 id="zoom-query">
446 <title><literal>ZOOM::query</literal> and subclasses</title>
448 The <literal>ZOOM::query</literal> class is a virtual base class,
449 representing a query to be submitted to a server. This class has
450 no methods, but two (so far) concrete subclasses, each implementing
451 a specific query notation.
453 <sect2 id="zoom-prefixQuery">
454 <title><literal>ZOOM::prefixQuery</literal></title>
456 class prefixQuery : public query {
458 prefixQuery (const char *pqn);
463 This class enables a query to be created by compiling YAZ's
465 <ulink url="&url.yaz.pqf;">Prefix Query Notation (PQN)</ulink>.
468 <sect2 id="zoom-CCLQuery">
469 <title><literal>ZOOM::CCLQuery</literal></title>
471 class CCLQuery : public query {
473 CCLQuery (const char *ccl, void *qualset);
478 This class enables a query to be created using the simpler but
480 <ulink url="&url.yaz.ccl;">Common Command Language (CCL)</ulink>.
481 The qualifiers recognised by the CCL parser are specified in an
482 external configuration file in the format described by the YAZ
486 If query construction fails for either type of
487 <literal>query</literal> object - typically because the query
488 string itself is not valid PQN or CCL - then an
489 <link linkend="zoom-exception"><literal>exception</literal></link>
493 <sect2 id="queries.discussion">
494 <title>Discussion</title>
496 It will be readily recognised that these objects have no methods
497 other than their constructors: their only role in life is to be
498 used in searching, by being passed to the
499 <literal>resultSet</literal> class's constructor.
502 Given a suitable set of CCL qualifiers, the following pairs of
503 queries are equivalent:
506 prefixQuery("dinosaur");
507 CCLQuery("dinosaur");
509 prefixQuery("@and complete dinosaur");
510 CCLQuery("complete and dinosaur");
512 prefixQuery("@and complete @or dinosaur pterosaur");
513 CCLQuery("complete and (dinosaur or pterosaur)");
515 prefixQuery("@attr 1=7 0253333490");
516 CCLQuery("isbn=0253333490");
519 <sect2 id="query.references">
520 <title>References</title>
524 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.3">
525 Section 3.3 (Query) of the ZOOM Abstract API
531 <ulink url="&url.yaz.zoom.query;">
532 The Queries section of the ZOOM-C documentation
539 <sect1 id="zoom-resultset">
540 <title><literal>ZOOM::resultSet</literal></title>
542 A <literal>ZOOM::resultSet</literal> object represents a set of
543 records identified by a query that has been executed against a
544 particular connection. The sole purpose of both
545 <literal>connection</literal> and <literal>query</literal> objects
546 is that they can be used to create new
547 <literal>resultSet</literal>s - that is, to perform a search on the
548 server on the remote end of the connection.
551 The class has this declaration:
556 resultSet (connection &c, const query &q);
558 const char *option (const char *key) const;
559 const char *option (const char *key, const char *val);
560 size_t size () const;
561 const record *getRecord (size_t i) const;
565 New <literal>resultSet</literal>s are created by the constructor,
566 which is passed a <literal>connection</literal>, indicating the
567 server on which the search is to be performed, and a
568 <literal>query</literal>, indicating what search to perform. If
569 the search fails - for example, because the query uses attributes
570 that the server doesn't implement - then an
571 <link linkend="zoom-exception"><literal>exception</literal></link>
575 Like <literal>connection</literal>s, <literal>resultSet</literal>
576 objects can carry name-value options. The special options which
577 affect ZOOM-C++'s behaviour are the same as those for ZOOM-C and
578 are described in its documentation (link below). In particular,
579 the <literal>preferredRecordSyntax</literal> option may be set to
580 a string such as ``USMARC'', ``SUTRS'' etc. to indicate what the
581 format in which records should be retrieved; and the
582 <literal>elementSetName</literal> option indicates whether brief
583 records (``B''), full records (``F'') or some other composition
587 The <literal>size()</literal> method returns the number of records
588 in the result set. Zero is a legitimate value: a search that finds
589 no records is not the same as a search that fails.
592 Finally, the <literal>getRecord</literal> method returns the
593 <parameter>i</parameter>th record from the result set, where
594 <parameter>i</parameter> is zero-based: that is, legitmate values
595 range from zero up to one less than the result-set size. If the
596 method fails, for example because the requested record is out of
597 range, it <literal>throw</literal>s an
598 <link linkend="zoom-exception"><literal>exception</literal></link>.
600 <sect2 id="resultset.references">
601 <title>References</title>
605 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.4"
606 >Section 3.4 (Result Set) of the ZOOM Abstract API</ulink>
611 <ulink url="&url.yaz.zoom.resultsets;"
612 >The Result Sets section of the ZOOM-C documentation</ulink>
618 <sect1 id="zoom-record">
619 <title><literal>ZOOM::record</literal></title>
621 A <literal>ZOOM::record</literal> object represents a chunk of data
622 from a <literal>resultSet</literal> returned from a server.
625 The class has this declaration:
632 UNKNOWN, GRS1, SUTRS, USMARC, UKMARC, XML
634 record *clone () const;
635 syntax recsyn () const;
636 const char *render () const;
637 const char *rawdata () const;
641 Records returned from Z39.50 servers are encoded using a record
642 syntax: the various national MARC formats are commonly used for
643 bibliographic data, GRS-1 or XML for complex structured data, SUTRS
644 for simple human-readable text, etc. The
645 <literal>record::syntax</literal> enumeration specifies constants
646 representing common record syntaxes, and the
647 <literal>recsyn()</literal> method returns the value corresponding
648 to the record-syntax of the record on which it is invoked.
651 Because this interface uses an enumeration, it is difficult to
652 extend to other record syntaxes - for example, DANMARC, the MARC
653 variant widely used in Denmark. We might either grow the
654 enumeration substantially, or change the interface to return
655 either an integer or a string.
660 The simplest thing to do with a retrieved record is simply to
661 <literal>render()</literal> it. This returns a human-readable, but
662 not necessarily very pretty, representation of the contents of the
663 record. This is useful primarily for testing and debugging, since
664 the application has no control over how the record appears.
665 (The application must <emphasis>not</emphasis>
666 <literal>delete</literal> the returned string - it is ``owned'' by
670 More sophisticated applications will want to deal with the raw data
671 themselves: the <literal>rawdata()</literal> method returns it.
672 Its format will vary depending on the record syntax: SUTRS, MARC
673 and XML records are returned ``as is'', and GRS-1 records as a
674 pointer to their top-level node, which is a
675 <literal>Z_GenericRecord</literal> structure as defined in the
676 <literal><yaz/z-grs.h></literal> header file.
677 (The application must <emphasis>not</emphasis>
678 <literal>delete</literal> the returned data - it is ``owned'' by
682 Perceptive readers will notice that there are no methods for access
683 to individual fields within a record. That's because the different
684 record syntaxes are so different that there is no even a uniform
685 notion of what a field is across them all, let alone a sensible way
686 to implement such a function. Fetch the raw data instead, and pick
687 it apart ``by hand''.
689 <sect2 id="zoom.memory.management">
690 <title>Memory Management</title>
692 The <literal>record</literal> objects returned from
693 <literal>resultSet::getRecord()</literal> are ``owned'' by the
694 result set object: that means that the application is not
695 responsible for <literal>delete</literal>ing them - each
696 <literal>record</literal> is automatically deallocated when the
697 <literal>resultSet</literal> that owns it is
698 <literal>delete</literal>d.
701 Usually that's what you want: it means that you can easily fetch a
702 record, use it and forget all about it, like this:
705 resultSet rs(conn, query);
706 cout << rs.getRecord(0)->render();
709 But sometimes you want a <literal>record</literal> to live on past
710 the lifetime of the <literal>resultSet</literal> from which it was
711 fetched. In this case, the <literal>clone(f)</literal> method can
712 be used to make an autonomous copy. The application must
713 <literal>delete</literal> it when it doesn't need it any longer:
718 resultSet rs(conn, query);
719 rec = rs.getRecord(0)->clone();
720 // `rs' goes out of scope here, and is deleted
722 cout << rec->render();
726 <sect2 id="record.references">
727 <title>References</title>
731 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.5"
732 >Section 3.5 (Record) of the ZOOM Abstract API</ulink>
737 <ulink url="&url.yaz.zoom.records;"
738 >The Records section of the ZOOM-C documentation</ulink>
744 <sect1 id="zoom-exception">
745 <title><literal>ZOOM::exception</literal> and subclasses</title>
747 The <literal>ZOOM::exception</literal> class is a virtual base
748 class, representing a diagnostic generated by the ZOOM-C++ library
749 or returned from a server. Its subclasses represent particular
753 When any of the ZOOM methods fail, they respond by
754 <literal>throw</literal>ing an object of type
755 <literal>exception</literal> or one of its subclasses. This most
756 usually happens with the <literal>connection</literal> constructor,
757 the various query constructors, the <literal>resultSet</literal>
758 constructor (which is actually the searching method) and
759 <literal>resultSet::getRecord()</literal>.
762 The base class has this declaration:
767 exception (int code);
768 int errcode () const;
769 const char *errmsg () const;
773 It has three concrete subclasses:
775 <sect2 id="zoom-systemException">
776 <title><literal>ZOOM::systemException</literal></title>
778 class systemException: public exception {
781 int errcode () const;
782 const char *errmsg () const;
786 Represents a ``system error'', typically indicating that a system
787 call failed - often in the low-level networking code that
788 underlies Z39.50. <literal>errcode()</literal> returns the value
789 that the system variable <literal>errno</literal> had at the time
790 the exception was constructed; and <literal>errmsg()</literal>
791 returns a human-readable error-message corresponidng to that error
795 <sect2 id="zoom-bib1Exception">
796 <title><literal>ZOOM::bib1Exception</literal></title>
798 class bib1Exception: public exception {
800 bib1Exception (int errcode, const char *addinfo);
801 int errcode () const;
802 const char *errmsg () const;
803 const char *addinfo () const;
807 Represents an error condition communicated by a Z39.50 server.
808 <literal>errcode()</literal> returns the BIB-1 diagnostic code of
809 the error, and <literal>errmsg()</literal> a human-readable error
810 message corresponding to that code. <literal>addinfo()</literal>
811 returns any additional information associated with the error.
814 For example, if a ZOOM application tries to search in the
815 ``Voyager'' database of a server that does not have a database of
816 that name, a <literal>bib1Exception</literal> will be thrown in
817 which <literal>errcode()</literal> returns 109,
818 <literal>errmsg()</literal> returns the corresponding error
819 message ``Database unavailable'' and <literal>addinfo()</literal>
820 returns the name of the requested, but unavailable, database.
823 <sect2 id="zoom-queryException">
824 <title><literal>ZOOM::queryException</literal></title>
826 class queryException: public exception {
828 static const int PREFIX = 1;
829 static const int CCL = 2;
830 queryException (int qtype, const char *source);
831 int errcode () const;
832 const char *errmsg () const;
833 const char *addinfo () const;
837 This class represents an error in parsing a query into a form that
838 a Z39.50 can understand. It must be created with the
839 <literal>qtype</literal> parameter equal to one of the query-type
840 constants, which can be retrieved via the
841 <literal>errcode()</literal> method; <literal>errmsg()</literal>
842 returns an error-message specifying which kind of query was
843 malformed; and <literal>addinfo()</literal> returns a copy of the
844 query itself (that is, the value of <literal>source</literal> with
845 which the exception object was created.)
848 <sect2 id="revised-sample">
849 <title>Revised Sample Program</title>
851 Now we can revise the sample program from the
852 <link linkend="zoom-introduction">introduction</link>
853 to catch exceptions and report any errors:
856 /* g++ -o zoom-c++-hw zoom-c++-hw.cpp -lzoompp -lyaz */
858 #include <iostream>
859 #include <yazpp/zoom.h>
861 using namespace ZOOM;
863 int main(int argc, char **argv)
866 connection conn("z3950.loc.gov", 7090);
867 conn.option("databaseName", "Voyager");
868 conn.option("preferredRecordSyntax", "USMARC");
869 resultSet rs(conn, prefixQuery("@attr 1=7 0253333490"));
870 const record *rec = rs.getRecord(0);
871 cout << rec->render() << endl;
872 } catch (systemException &e) {
873 cerr << "System error " <<
874 e.errcode() << " (" << e.errmsg() << ")" << endl;
875 } catch (bib1Exception &e) {
876 cerr << "BIB-1 error " <<
877 e.errcode() << " (" << e.errmsg() << "): " << e.addinfo() << endl;
878 } catch (queryException &e) {
879 cerr << "Query error " <<
880 e.errcode() << " (" << e.errmsg() << "): " << e.addinfo() << endl;
881 } catch (exception &e) {
882 cerr << "Error " <<
883 e.errcode() << " (" << e.errmsg() << ")" << endl;
888 The heart of this program is the same as in the original version,
889 but it's now wrapped in a <literal>try</literal> block followed by
890 several <literal>catch</literal> blocks which try to give helpful
891 diagnostics if something goes wrong.
894 The first such block diagnoses system-level errors such as memory
895 exhaustion or a network connection being broken by a server's
896 untimely death; the second catches errors at the Z39.50 level,
897 such as a server's report that it can't provide records in USMARC
898 syntax; the third is there in case there's something wrong with
899 the syntax of the query (although in this case it's correct); and
900 finally, the last <literal>catch</literal> block is a
901 belt-and-braces measure to be sure that nothing escapes us.
904 <sect2 id="exception.references">
905 <title>References</title>
909 <ulink url="http://zoom.z3950.org/api/zoom-1.3.html#3.7"
910 >Section 3.7 (Exception) of the ZOOM Abstract API</ulink>
915 <ulink url="&url.z39.50.diagnostics;">Bib-1 Diagnostics</ulink> on the
916 <ulink url="&url.z39.50;">Z39.50 Maintenance Agency</ulink> site.
921 Because C does not support exceptions, ZOOM-C has no API element
922 that corresponds directly with ZOOM-C++'s
923 <literal>exception</literal> class and its subclasses. The
924 closest thing is the <literal>ZOOM_connection_error</literal>
925 function described in
926 <ulink url="&url.yaz.zoom.connections;"
927 >The Connections section</ulink> of the documentation.
933 <title>YAZ C++ API</title>
935 The YAZ C++ API is an client - and server API that exposes
936 all YAZ features. The API doesn't hide YAZ C data structures, but
937 provides a set of useful high-level objects for creating clients -
941 All definitions from YAZ++ are part of namespace
942 <literal>yazpp_1</literal>.
945 The following sections include a short description of the
946 interfaces and implementations (concrete classes).
949 In order to understand the structure, you should look at the
950 example client <filename>yaz-my-client.cpp</filename> and
951 the example server <filename>yaz-my-server.cpp</filename>.
952 If that is too easy, you can always turn to the implementation
953 of the proxy itself and send us a patch if you implement a new
958 The documentation here is very limited. We plan to enhance it -
959 provided there is interest for it.
962 <section id="interfaces"><title>Interfaces</title>
963 <section id="ISocketObservable"><title>ISocketObservable</title>
965 This interface is capable of observing sockets.
966 When a socket even occurs it invokes an object implementing the
967 <link linkend="ISocketObserver">ISocketObserver</link>
971 #include <yazpp/socket-observer.h>
973 class my_socketobservable : public ISocketObservable {
974 // Add an observer interested in socket fd
975 virtual void addObserver(int fd, ISocketObserver *observer) = 0;
976 // Delete an observer
977 virtual void deleteObserver(ISocketObserver *observer) = 0;
978 // Delete all observers
979 virtual void deleteObservers() = 0;
980 // Specify the events that the observer is interested in.
981 virtual void maskObserver(ISocketObserver *observer,
984 virtual void timeoutObserver(ISocketObserver *observer,
989 <section id="ISocketObserver">
990 <title>ISocketObserver</title>
992 This interface is interested in socket events supporting
993 the <link linkend="ISocketObservable">ISocketObservable</link>
997 #include <yazpp/socket-observer.h>
999 class my_socketobserver : public ISocketObserver {
1001 // Notify the observer that something happened to socket
1002 virtual void socketNotify(int event) = 0;
1006 <section id="IPDU_Observable">
1007 <title>IPDU_Observable</title>
1009 This interface is is responsible for sending - and receiving PDUs over
1010 the network (YAZ COMSTACK). When events occur, an instance
1011 implementing <link linkend="IPDU_Observer">IPDU_Observer</link>
1015 #include <yazpp/pdu-observer.h>
1017 class my_pduobservable : public IPDU_Observable {
1019 // Send encoded PDU buffer of specified length
1020 virtual int send_PDU(const char *buf, int len) = 0;
1021 // Connect with server specified by addr.
1022 virtual void connect(IPDU_Observer *observer,
1023 const char *addr) = 0;
1024 // Listen on address addr.
1025 virtual void listen(IPDU_Observer *observer, const char *addr)=0;
1027 virtual void close() = 0;
1028 // Make clone of this object using this interface
1029 virtual IPDU_Observable *clone() = 0;
1030 // Destroy completely
1031 virtual void destroy() = 0;
1033 virtual void idleTime (int timeout) = 0;
1035 virtual const char *getpeername() = 0;
1037 virtual ~IPDU_Observable();
1041 <section id="IPDU_Observer">
1042 <title>IPDU_Observer</title>
1044 This interface is interested in PDUs and using an object implementing
1045 <link linkend="IPDU_Observable">IPDU_Observable</link>.
1048 #include <yazpp/pdu-observer.h>
1050 class my_pduobserver : public IPDU_Observer {
1052 // A PDU has been received
1053 virtual void recv_PDU(const char *buf, int len) = 0;
1054 // Called when Iyaz_PDU_Observable::connect was successful.
1055 virtual void connectNotify() = 0;
1056 // Called whenever the connection was closed
1057 virtual void failNotify() = 0;
1058 // Called whenever there is a timeout
1059 virtual void timeoutNotify() = 0;
1060 // Make clone of observer using IPDU_Observable interface
1061 virtual IPDU_Observer *sessionNotify(
1062 IPDU_Observable *the_PDU_Observable, int fd) = 0;
1066 <section id="query">
1067 <title>Yaz_Query</title>
1072 #include <yazpp/query.h>
1073 class my_query : public Yaz_Query {
1075 // Print query in buffer described by str and len
1076 virtual void print (char *str, int len) = 0;
1081 <section id="implementations">
1082 <title>Implementations</title>
1083 <section id="Yaz_SocketManager">
1084 <title>Yaz_SocketManager</title>
1086 This class implements the <link linkend="ISocketObservable">
1087 ISocketObservable</link> interface and is a portable
1088 socket wrapper around the select call.
1089 This implementation is useful for daemons,
1090 command line clients, etc.
1093 #include <yazpp/socket-manager.h>
1095 class SocketManager : public ISocketObservable {
1098 virtual void addObserver(int fd, ISocketObserver *observer);
1099 // Delete an observer
1100 virtual void deleteObserver(ISocketObserver *observer);
1101 // Delete all observers
1102 virtual void deleteObservers();
1103 // Set event mask for observer
1104 virtual void maskObserver(ISocketObserver *observer, int mask);
1106 virtual void timeoutObserver(ISocketObserver *observer,
1108 // Process one event. return > 0 if event could be processed;
1111 virtual ~SocketManager();
1115 <section id="PDU_Assoc">
1116 <title>PDU_Assoc</title>
1118 This class implements the interfaces
1119 <link linkend="IPDU_Observable">IPDU_Observable</link>
1121 <link linkend="ISocketObserver">ISocketObserver</link>.
1122 This object implements a non-blocking client/server channel
1123 that transmits BER encoded PDUs (or those offered by YAZ COMSTACK).
1126 #include <yazpp/pdu-assoc.h>
1128 class PDU_Assoc : public IPDU_Observable,
1131 COMSTACK comstack(const char *type_and_host, void **vp);
1132 // Create object using specified socketObservable
1133 PDU_Assoc(ISocketObservable *socketObservable);
1134 // Create Object using existing comstack
1135 PDU_Assoc(ISocketObservable *socketObservable,
1137 // Close socket and destroy object.
1138 virtual ~PDU_Assoc();
1140 IPDU_Observable *clone();
1142 int send_PDU(const char *buf, int len);
1143 // connect to server (client role)
1144 void connect(IPDU_Observer *observer, const char *addr);
1145 // listen for clients (server role)
1146 void listen(IPDU_Observer *observer, const char *addr);
1147 // Socket notification
1148 void socketNotify(int event);
1151 // Close and destroy
1154 void idleTime (int timeout);
1156 virtual void childNotify(COMSTACK cs);
1160 <section id="Z_Assoc">
1161 <title>Z_Assoc</title>
1163 This class implements the interface
1164 <link linkend="IPDU_Observer">IPDU_Obserer</link>.
1165 This object implements a Z39.50 client/server channel AKA
1169 #include <yazpp/z-assoc.h>
1171 class Z_Assoc : public IPDU_Observer {
1173 // Create object using the PDU Observer specified
1174 Z_Assoc(IPDU_Observable *the_PDU_Observable);
1175 // Destroy association and close PDU Observer
1178 void recv_PDU(const char *buf, int len);
1179 // Connect notification
1180 virtual void connectNotify() = 0;
1181 // Failure notification
1182 virtual void failNotify() = 0;
1183 // Timeout notification
1184 virtual void timeoutNotify() = 0;
1186 void timeout(int timeout);
1187 // Begin Z39.50 client role
1188 void client(const char *addr);
1189 // Begin Z39.50 server role
1190 void server(const char *addr);
1194 // Decode Z39.50 PDU.
1195 Z_APDU *decode_Z_PDU(const char *buf, int len);
1196 // Encode Z39.50 PDU.
1197 int encode_Z_PDU(Z_APDU *apdu, char **buf, int *len);
1199 int send_Z_PDU(Z_APDU *apdu);
1200 // Receive Z39.50 PDU
1201 virtual void recv_Z_PDU(Z_APDU *apdu) = 0;
1202 // Create Z39.50 PDU with reasonable defaults
1203 Z_APDU *create_Z_PDU(int type);
1208 void set_APDU_log(const char *fname);
1209 const char *get_APDU_log();
1212 void get_otherInfoAPDU(Z_APDU *apdu, Z_OtherInformation ***oip);
1213 Z_OtherInformationUnit *update_otherInformation (
1214 Z_OtherInformation **otherInformationP, int createFlag,
1215 int *oid, int categoryValue, int deleteFlag);
1216 void set_otherInformationString (
1217 Z_OtherInformation **otherInformationP,
1218 int *oid, int categoryValue,
1220 void set_otherInformationString (
1221 Z_OtherInformation **otherInformation,
1222 int oidval, int categoryValue,
1224 void set_otherInformationString (
1226 int oidval, int categoryValue,
1229 Z_ReferenceId *getRefID(char* str);
1230 Z_ReferenceId **get_referenceIdP(Z_APDU *apdu);
1231 void transfer_referenceId(Z_APDU *from, Z_APDU *to);
1233 const char *get_hostname();
1237 <section id="IR_Assoc">
1238 <title>IR_Assoc</title>
1240 This object is just a specialization of
1241 <link linkend="Z_Assoc">Z_Assoc</link> and provides
1242 more facilities for the Z39.50 client role.
1245 #include <yazpp/ir-assoc.h>
1247 class IR_Assoc : public Z_Assoc {
1252 The example client, <filename>yaz-my-client.cpp</filename>,
1256 <section id="Z_Server">
1257 <title>Z_Server</title>
1259 This object is just a specialization of
1260 <link linkend="Z_Assoc">Z_Assoc</link> and provides
1261 more facilities for the Z39.50 server role.
1264 #include <yazpp/z-server.h>
1266 class My_Server : public Z_Server {
1271 The example server, <filename>yaz-my-server.cpp</filename>,
1277 <appendix id="license">
1278 <title>License</title>
1280 Copyright © ©right-year; Index Data.
1283 All rights reserved.
1286 Redistribution and use in source and binary forms, with or without
1287 modification, are permitted provided that the following conditions are met:
1292 Redistributions of source code must retain the above copyright
1293 notice, this list of conditions and the following disclaimer.
1298 Redistributions in binary form must reproduce the above copyright
1299 notice, this list of conditions and the following disclaimer in the
1300 documentation and/or other materials provided with the distribution.
1305 Neither the name of Index Data nor the names of its contributors
1306 may be used to endorse or promote products derived from this
1307 software without specific prior written permission.
1312 THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
1313 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1314 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1315 DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR
1316 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1317 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1318 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1319 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1320 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1321 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1327 <!-- Keep this comment at the end of the file
1330 nxml-child-indent: 1