From 88e190489a5c483e5b860048aeebde41bf262962 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Sat, 30 Nov 2002 22:33:21 +0000 Subject: [PATCH] Bash the implementation into the same shape as the interface, which I modified last week to bring it into alignment with the consensus I reached with Ashley. --- zoom/master-header | 22 +++++++++++----- zoom/zclient.cpp | 59 ++++++++++++++++++------------------------ zoom/zconn.cpp | 23 ++++++++++------- zoom/zexcept.cpp | 51 ++++++++++++++---------------------- zoom/zquery.cpp | 8 +++--- zoom/zrec.cpp | 73 +++++++++++++++++++++++++++++++++++----------------- zoom/zrs.cpp | 34 +++++------------------- 7 files changed, 131 insertions(+), 139 deletions(-) diff --git a/zoom/master-header b/zoom/master-header index e8ad2a8..b9049f8 100644 --- a/zoom/master-header +++ b/zoom/master-header @@ -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; }; } diff --git a/zoom/zclient.cpp b/zoom/zclient.cpp index 53e2f9d..f401ab8 100644 --- a/zoom/zclient.cpp +++ b/zoom/zclient.cpp @@ -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 @@ -10,48 +10,39 @@ int main(int argc, char **argv) { if (argc != 5) { - cerr << "Usage: " << argv[0] << - " <@prefix-search>\n"; + cerr << "Usage: " << + argv[0] << " <@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; } diff --git a/zoom/zconn.cpp b/zoom/zconn.cpp index 9b02a9b..d5d4c85 100644 --- a/zoom/zconn.cpp +++ b/zoom/zconn.cpp @@ -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() { diff --git a/zoom/zexcept.cpp b/zoom/zexcept.cpp index cef6297..04e6665 100644 --- a/zoom/zexcept.cpp +++ b/zoom/zexcept.cpp @@ -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 #include // for strerror(), strlen(), strcpy() #include // for sprintf() -#include #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; } } diff --git a/zoom/zquery.cpp b/zoom/zquery.cpp index 154e3ce..5b173c5 100644 --- a/zoom/zquery.cpp +++ b/zoom/zquery.cpp @@ -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."; } diff --git a/zoom/zrec.cpp b/zoom/zrec.cpp index 8537718..fc4bff6 100644 --- a/zoom/zrec.cpp +++ b/zoom/zrec.cpp @@ -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); } diff --git a/zoom/zrs.cpp b/zoom/zrs.cpp index 3ccce51..8ff9fe3 100644 --- a/zoom/zrs.cpp +++ b/zoom/zrs.cpp @@ -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); - } } -- 1.7.10.4