Bash the implementation into the same shape as the interface,
authorMike Taylor <mike@indexdata.com>
Sat, 30 Nov 2002 22:33:21 +0000 (22:33 +0000)
committerMike Taylor <mike@indexdata.com>
Sat, 30 Nov 2002 22:33:21 +0000 (22:33 +0000)
which I modified last week to bring it into alignment with the
consensus I reached with Ashley.

zoom/master-header
zoom/zclient.cpp
zoom/zconn.cpp
zoom/zexcept.cpp
zoom/zquery.cpp
zoom/zrec.cpp
zoom/zrs.cpp

index e8ad2a8..b9049f8 100644 (file)
@@ -1,4 +1,4 @@
-// $Id: master-header,v 1.11 2002-11-25 13:33:22 mike Exp $
+// $Id: master-header,v 1.12 2002-11-30 22:33:21 mike Exp $
 //
 // ZOOM C++ Binding.
 // The ZOOM homepage is at http://zoom.z3950.org/
@@ -67,6 +67,10 @@ namespace ZOOM {
   class YAZ_EXPORT resultSet {
 *   connection &owner;
 *   ZOOM_resultset rs;
+*   friend class record; // for _getYazResultSet() & _getYazConnection()
+*   ZOOM_resultset _getYazResultSet () const { return rs; }
+*   ZOOM_connection _getYazConnection () const {
+*      return owner._getYazConnection(); }
     // resultSets are non-copyable.
     resultSet (const resultSet &);
     resultSet &operator= (const resultSet &);
@@ -79,18 +83,19 @@ namespace ZOOM {
   };
 
   class YAZ_EXPORT record {
-*   const resultSet *owner;
+*   const resultSet &owner;
 *   ZOOM_record r;
 *   friend class resultSet; // so it can use this constructor
-*   record::record (const resultSet *rs, ZOOM_record rec):
-*      owner (rs), r (rec) {}
   public:
     class syntax {
     public:
       enum value {
        UNKNOWN, GRS1, SUTRS, USMARC, UKMARC, XML
       };
-      syntax (value rs) : i(rs) {};
+*   private:
+*     enum value val;
+*   public:
+      syntax (value rs);
       operator std::string () const;
       bool operator== (const syntax &s) const;
       bool operator== (value rs) const;
@@ -124,24 +129,27 @@ namespace ZOOM {
   public:
     systemException ();                // Uses value of system `errno'
     systemException (int code);
+*   virtual std::string errmsg () const; // Why do I have to repeat this?
   };
 
   // bib1Exception::errcode() returns a code from the
   // Bib-1 Diagnostic Set.
   class YAZ_EXPORT bib1Exception: public exception {
-*   const char *info;
+*   const string &info;
   public:
 *   ~bib1Exception ();
     bib1Exception (int code, const std::string &addinfo);
+*   virtual std::string errmsg () const; // Why do I have to repeat this?
     std::string addinfo () const;
   };
 
   class YAZ_EXPORT queryException : public exception {
-*   const char *q;
+*   const string &q;
   public:
 *   ~queryException ();
     enum { PREFIX, CCL };
     queryException (int qtype, const std::string &source);
+*   virtual std::string errmsg () const; // Why do I have to repeat this?
     std::string addinfo () const;
   };
 }
index 53e2f9d..f401ab8 100644 (file)
@@ -1,4 +1,4 @@
-// $Header: /home/cvsroot/yaz++/zoom/zclient.cpp,v 1.4 2002-10-09 09:07:10 mike Exp $
+// $Id: zclient.cpp,v 1.5 2002-11-30 22:33:21 mike Exp $
 
 // Simple sample client
 
 int main(int argc, char **argv)
 {
     if (argc != 5) {
-       cerr << "Usage: " << argv[0] <<
-           " <host> <port> <db> <@prefix-search>\n";
+       cerr << "Usage: " <<
+           argv[0] << " <host> <port> <dbname> <@prefix-search>\n";
        return 1;
     }
 
-    const char *hostname = argv[1];
-    const int port = atoi(argv[2]);
-    const char *dbname = argv[3];
-    const char *searchSpec = argv[4];
-
-    ZOOM::connection *conn;
+    using namespace ZOOM;
     try {
-       conn = new ZOOM::connection(hostname, port);
-    } catch(ZOOM::bib1Exception& err) {
-       cerr << argv[0] << ": connect: bib1Exception " <<
+       connection conn(argv[1], atoi(argv[2]));
+       conn.option("databaseName", argv[3]);
+       conn.option("preferredRecordSyntax",
+                   record::syntax(record::syntax::XML));
+       prefixQuery pq(argv[4]);
+       resultSet rs(conn, pq);
+
+       size_t n = rs.size();
+       cout << "found " << n << " records:\n";
+       for (size_t i = 0; i < n; i++) {
+           const record rec(rs, i);
+           cout << "=== record " << i+1 <<
+               " (record-syntax " << (string) rec.recsyn() << ")" <<
+               " ===\n" << rec.render();
+       }
+
+    } catch(bib1Exception& err) {
+       cerr << argv[0] << ": bib1Exception " <<
            err.errmsg() << " (" << err.addinfo() << ")\n";
        return 2;
-    } catch(ZOOM::exception& err) {
-       cerr << argv[0] << ": connect: exception " <<
-           err.errmsg() << "\n";
-       return 2;
-    }
 
-    conn->option("databaseName", dbname);
-    ZOOM::prefixQuery pq(searchSpec);
-    ZOOM::resultSet *rs;
-    try {
-       rs = new ZOOM::resultSet(*conn, pq);
-    } catch(ZOOM::bib1Exception err) {
-       //fprintf(stderr, "caught exception 0x%lx\n", (long) &err);
-       cerr << argv[0] << ": search: " <<
-           err.errmsg() << " (" << err.addinfo() << ")\n";
+    } catch(exception& err) {
+       cerr << argv[0] << ": exception " <<
+           err.errmsg() << "\n";
        return 3;
     }
 
-    size_t n = rs->size();
-    cout << "found " << n << " records:\n";
-    for (size_t i = 0; i < n; i++) {
-       const ZOOM::record *rec = rs->getRecord(i);
-       cout << "=== record " << i+1 << " (recsyn " << rec->recsyn()
-            << ") ===\n" << rec->render();
-    }
-
     return 0;
 }
index 9b02a9b..d5d4c85 100644 (file)
@@ -1,4 +1,4 @@
-// $Header: /home/cvsroot/yaz++/zoom/zconn.cpp,v 1.3 2002-10-09 09:07:10 mike Exp $
+// $Header: /home/cvsroot/yaz++/zoom/zconn.cpp,v 1.4 2002-11-30 22:33:21 mike Exp $
 
 // Z39.50 Connection class
 
@@ -6,26 +6,29 @@
 
 
 namespace ZOOM {
-    connection::connection(const char *hostname, int portnum) {
-       c = ZOOM_connection_new(hostname, portnum);
+    connection::connection(const string &hostname, int portnum) {
+       const char *line_printer_size_hostname = hostname.c_str();
+       //###cerr << "opening " << hostname << ":" << portnum << "\n";
+       c = ZOOM_connection_new(line_printer_size_hostname, portnum);
+       //###cerr << "opened, got " << c << "\n";
 
        int errcode;
        const char *errmsg;     // unused: carries same info as `errcode'
        const char *addinfo;
        if ((errcode = ZOOM_connection_error(c, &errmsg, &addinfo)) != 0) {
+           //###cerr << "oops: no connect, errcode=" << errcode << "\n";
            throw bib1Exception(errcode, addinfo);
        }
     }
 
-    const char *connection::option(const char *key) const {
-       return ZOOM_connection_option_get(c, key);
+    string connection::option(const string &key) const {
+       return ZOOM_connection_option_get(c, key.c_str());
     }
 
-    const char *connection::option(const char *key, const char *val) {
-       // ### There may be memory-management issues here.
-       const char *old = ZOOM_connection_option_get(c, key);
-       ZOOM_connection_option_set(c, key, val);
-       return old;
+    bool connection::option(const string &key, const string &val) {
+       // No way to tell whether ZOOM_connection_option_set() accepts key
+       ZOOM_connection_option_set(c, key.c_str(), val.c_str());
+       return true;
     }
 
     connection::~connection() {
index cef6297..04e6665 100644 (file)
@@ -1,11 +1,10 @@
-// $Header: /home/cvsroot/yaz++/zoom/zexcept.cpp,v 1.6 2002-11-12 22:43:56 mike Exp $
+// $Header: /home/cvsroot/yaz++/zoom/zexcept.cpp,v 1.7 2002-11-30 22:33:21 mike Exp $
 
 // Z39.50 Exception classes
 
 #include <errno.h>
 #include <string.h>            // for strerror(), strlen(), strcpy()
 #include <stdio.h>             // for sprintf()
-#include <yaz/diagbib1.h>
 #include "zoom.h"
 
 
@@ -14,11 +13,15 @@ namespace ZOOM {
        code = errcode;
     }
 
+    exception::~exception() {
+       // Nothing to do, but G++ requires this to be explicit anyway
+    }
+
     int exception::errcode() const {
        return code;
     }
 
-    const char *exception::errmsg() const {
+    string exception::errmsg() const {
        static char buf[40];
        sprintf(buf, "error #%d", code);
        return buf;
@@ -30,31 +33,18 @@ namespace ZOOM {
        code = errno;
     }
 
-    const char *systemException::errmsg() const {
+    string systemException::errmsg() const {
        return strerror(code);
     }
 
 
     
-    bib1Exception::bib1Exception(int errcode, const char *addinfo) :
-       exception(errcode) {
-       info = new char[strlen(addinfo)+1];
-       strcpy((char*) info, addinfo);
-       //fprintf(stderr, "made new bib1Exception 0x%lx (%d, 0x%lx=%s)\n",
-               //(long) this, code, (long) info, info);
+    bib1Exception::bib1Exception(int errcode, const string &addinfo) :
+       exception(errcode), info(addinfo) {
+       cerr << "WARNING: made bib1Exception(" << errcode << "=" <<
+           ZOOM_diag_str(errcode) << ", '" << addinfo << "')\n";
     }
 
-#if 0
-    bib1Exception::bib1Exception(bib1Exception& src) :
-       exception(src) {
-        code = src.code;
-       info = new char[strlen(src.info)+1];
-       strcpy((char*) info, src.info);
-       //fprintf(stderr, "copied bib1Exception 0x%lx to 0x%lx (%d, 0x%lx=%s)\n",
-               //(long) &src, (long) this, code, (long) info, info);
-    }
-#endif
-
     bib1Exception::~bib1Exception() {
        //fprintf(stderr, "deleting bib1Exception 0x%lx (%d, 0x%lx=%s)\n",
                //(long) this, code, (long) info, info);
@@ -62,30 +52,27 @@ namespace ZOOM {
        //  ### Don't actually do the deletion for now.  Exception
        //  reference semantics are too weird for me to grok so I'm
        //  doing The Wrong Thing in the knowledge that it will more
-       //  or less work -- it just leaks memory.
+       //  or less work -- it just leaks memory.  (Or does it?)
     }
 
-    const char *bib1Exception::errmsg() const {
-       return diagbib1_str(code);
+    string bib1Exception::errmsg() const {
+       return ZOOM_diag_str(code);
     }
 
-    const char *bib1Exception::addinfo() const {
+    string bib1Exception::addinfo() const {
        return info;
     }
 
 
 
-    queryException::queryException(int qtype, const char *source) :
-       exception(qtype) {
-       q = new char[strlen(source)+1];
-       strcpy((char*) q, source);
-    }
+    queryException::queryException(int qtype, const string &source) :
+       exception(qtype), q(source) {}
 
     queryException::~queryException() {
        //delete q; // ### see comment on bib1Exception destructor
     }
 
-    const char *queryException::errmsg() const {
+    string queryException::errmsg() const {
        switch (code) {
        case PREFIX: return "bad prefix search";
        case CCL: return "bad CCL search";
@@ -94,7 +81,7 @@ namespace ZOOM {
        return "bad search (unknown type)";
     }
 
-    const char *queryException::addinfo() const {
+    string queryException::addinfo() const {
        return q;
     }
 }
index 154e3ce..5b173c5 100644 (file)
@@ -1,4 +1,4 @@
-// $Header: /home/cvsroot/yaz++/zoom/zquery.cpp,v 1.3 2002-10-09 09:07:10 mike Exp $
+// $Header: /home/cvsroot/yaz++/zoom/zquery.cpp,v 1.4 2002-11-30 22:33:21 mike Exp $
 
 // Z39.50 Query classes
 
@@ -13,9 +13,9 @@ namespace ZOOM {
 
 
 
-    prefixQuery::prefixQuery(const char *pqn) {
+    prefixQuery::prefixQuery(const string &pqn) {
        q = ZOOM_query_create();
-       if (ZOOM_query_prefix(q, pqn) == -1) {
+       if (ZOOM_query_prefix(q, pqn.c_str()) == -1) {
            ZOOM_query_destroy(q);
            throw queryException(queryException::PREFIX, pqn);
        }
@@ -43,7 +43,7 @@ namespace ZOOM {
 
 
 
-    CCLQuery::CCLQuery(const char *ccl, void *qualset) {
+    CCLQuery::CCLQuery(const string &ccl, void *qualset) {
        throw "Oops.  No CCL support in ZOOM-C yet.  Sorry.";
     }
 
index 8537718..fc4bff6 100644 (file)
@@ -1,4 +1,4 @@
-// $Header: /home/cvsroot/yaz++/zoom/zrec.cpp,v 1.4 2002-10-09 09:07:10 mike Exp $
+// $Header: /home/cvsroot/yaz++/zoom/zrec.cpp,v 1.5 2002-11-30 22:33:21 mike Exp $
 
 // Z39.50 Record class
 
@@ -7,26 +7,51 @@
 
 
 namespace ZOOM {
-    record::~record() {
-       if (owner == 0) {
-           // Must have been clone()d
-           ZOOM_record_destroy(r);
+    record::syntax::syntax (value rs): val(rs) {}
+
+    record::syntax::operator string() const {
+       switch (val) {
+       case GRS1:   return "grs1";
+       case SUTRS:  return "sutrs";
+       case USMARC: return "usmarc";
+       case UKMARC: return "ukmarc";
+       case XML:    return "xml";
+       default: break;
        }
+       return "unknown";
+    }
+
+    bool record::syntax::operator==(const record::syntax &s) const {
+       return s.val == val;
     }
 
-    // ### Would this operation be better expressed as a copy constructor?
-    record *record::clone() const {
-       // It's tempting just to replace `r' with a clone, and return
-       // `this', but probably more honest to allocate a new C++
-       // record object.
+    bool record::syntax::operator==(record::syntax::value rs) const {
+       return rs == val;
+    }
 
-       record *rec = new record(0, 0);
-       if ((rec->r = ZOOM_record_clone(r)) == 0) {
-           // Presumably an out-of-memory error
-           throw systemException();
+    record::syntax::operator record::syntax::value() const {
+       return val;
+    }
+
+
+    record::record(resultSet &rs, size_t i): owner(rs) {
+       if ((r = ZOOM_resultset_record(rs._getYazResultSet(), i)) == 0) {
+           const char *errmsg; // unused: carries same info as `errcode'
+           const char *addinfo;
+           int errcode = ZOOM_connection_error(rs._getYazConnection(),
+                                               &errmsg, &addinfo);
+           throw bib1Exception(errcode, addinfo);
        }
 
-       return rec;
+       // Memory management is odd here.  The ZOOM-C record we've
+       // just fetched (`r') is owned by the ZOOM-C result-set we
+       // fetched it from (`rs.rs'), so the underlying (ZOOM-C)
+       // record is _not_ destroyed when this object is destroyed:
+       // it's done when the underlying result-set is deleted.
+    }
+
+    record::~record() {
+       // Nothing to do -- see comment in constructor
     }
 
     // It's tempting to modify this method just to return either the
@@ -40,29 +65,29 @@ namespace ZOOM {
 
        // These string constants are from yaz/util/oid.c
        if (!yaz_matchstr(syn, "xml"))
-           return XML;
+           return syntax::XML;
        else if (!yaz_matchstr(syn, "GRS-1"))
-           return GRS1;
+           return syntax::GRS1;
        else if (!yaz_matchstr(syn, "SUTRS"))
-           return SUTRS;
+           return syntax::SUTRS;
        else if (!yaz_matchstr(syn, "USmarc"))
-           return USMARC;
+           return syntax::USMARC;
        else if (!yaz_matchstr(syn, "UKmarc"))
-           return UKMARC;
+           return syntax::UKMARC;
        else if (!yaz_matchstr(syn, "XML") ||
                 !yaz_matchstr(syn, "text-XML") ||
                 !yaz_matchstr(syn, "application-XML"))
-           return XML;
+           return syntax::XML;
 
-       return UNKNOWN;
+       return syntax::UNKNOWN;
     }
 
-    const char *record::render() const {
+    string record::render() const {
        int len;
        return ZOOM_record_get(r, "render", &len);
     }
 
-    const char *record::rawdata() const {
+    string record::rawdata() const {
        int len;
        return ZOOM_record_get(r, "raw", &len);
     }
index 3ccce51..8ff9fe3 100644 (file)
@@ -1,4 +1,4 @@
-// $Header: /home/cvsroot/yaz++/zoom/zrs.cpp,v 1.3 2002-10-09 09:07:10 mike Exp $
+// $Header: /home/cvsroot/yaz++/zoom/zrs.cpp,v 1.4 2002-11-30 22:33:21 mike Exp $
 
 // Z39.50 Result Set class
 
@@ -22,38 +22,16 @@ namespace ZOOM {
        ZOOM_resultset_destroy(rs);
     }
 
-    const char *resultSet::option(const char *key) const {
-       return ZOOM_resultset_option_get(rs, key);
+    string resultSet::option(const string &key) const {
+       return ZOOM_resultset_option_get(rs, key.c_str());
     }
 
-    const char *resultSet::option(const char *key, const char *val) {
-       // ### There may be memory-management issues here.
-       const char *old = ZOOM_resultset_option_get(rs, key);
-       ZOOM_resultset_option_set(rs, key, val);
-       return old;
+    bool resultSet::option(const string &key, const string &val) {
+      ZOOM_resultset_option_set(rs, key.c_str(), val.c_str());
+       return true;
     }
 
     size_t resultSet::size() const {
        return ZOOM_resultset_size(rs);
     }
-
-    const record *resultSet::getRecord(size_t i) const {
-       ZOOM_record rec;
-       if ((rec = ZOOM_resultset_record(rs, i)) == 0) {
-           const char *errmsg; // unused: carries same info as `errcode'
-           const char *addinfo;
-           int errcode = ZOOM_connection_error(owner._getYazConnection(),
-                                               &errmsg, &addinfo);
-           throw bib1Exception(errcode, addinfo);
-       }
-
-       // Memory management is odd here.  The ZOOM-C record we've
-       // just fetched (`rec') is owned by the ZOOM-C result-set we
-       // fetched it from (`rs'), so all we need to allocate is a
-       // ZOOM-C++ wrapper for it, which is destroyed at the
-       // appropriate time -- but the underlying (ZOOM-C) record is
-       // _not_ destroyed at that time, because it's done when the
-       // underlying result-set is deleted.
-       return new record(this, rec);
-    }
 }