From c6e5ad789740135af3558298f6e2014ae99ee7dd Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 9 Apr 1999 11:46:57 +0000 Subject: [PATCH] Added object Yaz_Z_Assoc. Much more functional client. --- include/yaz-ir-assoc.h | 107 ++++++----- include/yaz-pdu-observer.h | 7 +- include/yaz-proxy.h | 11 +- include/yaz-z-assoc.h | 59 ++++++ include/yaz-z-query.h | 7 +- src/Makefile.in | 9 +- src/yaz-client.cpp | 346 ++++++++++++++++++++++------------- src/yaz-ir-assoc.cpp | 429 ++++++++++++++++++++++++++++++++++++-------- src/yaz-pdu-assoc.cpp | 29 +-- src/yaz-proxy-main.cpp | 9 +- src/yaz-proxy.cpp | 9 +- src/yaz-server.cpp | 11 +- src/yaz-socket-manager.cpp | 11 +- src/yaz-z-assoc.cpp | 133 ++++++++++++++ src/yaz-z-query.cpp | 12 +- 15 files changed, 909 insertions(+), 280 deletions(-) create mode 100644 include/yaz-z-assoc.h create mode 100644 src/yaz-z-assoc.cpp diff --git a/include/yaz-ir-assoc.h b/include/yaz-ir-assoc.h index a5f998d..ad7efbb 100644 --- a/include/yaz-ir-assoc.h +++ b/include/yaz-ir-assoc.h @@ -4,65 +4,80 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-ir-assoc.h,v $ - * Revision 1.4 1999-03-23 14:17:57 adam - * More work on timeout handling. Work on yaz-client. - * - * Revision 1.3 1999/02/02 14:01:12 adam - * First WIN32 port of YAZ++. - * - * Revision 1.2 1999/01/28 13:08:39 adam - * Yaz_PDU_Assoc better encapsulated. Memory leak fix in - * yaz-socket-manager.cc. - * - * Revision 1.1.1.1 1999/01/28 09:41:07 adam - * First implementation of YAZ++. + * Revision 1.5 1999-04-09 11:47:23 adam + * Added object Yaz_Z_Assoc. Much more functional client. * */ - -#include -#include -#include +#include +#include /** Information Retrieval Assocation. This object implements the client - and server role of a generic Z39.50 Association. */ -class YAZ_EXPORT Yaz_IR_Assoc : public IYaz_PDU_Observer { +class YAZ_EXPORT Yaz_IR_Assoc: public Yaz_Z_Assoc { public: /// Create object using the PDU Observer specified Yaz_IR_Assoc(IYaz_PDU_Observable *the_PDU_Observable); /// Destroy assocation and close PDU Observer virtual ~Yaz_IR_Assoc(); - /// Receive PDU - void recv_PDU(const char *buf, int len); - /// Connect notification - void connectNotify(); - /// Failure notification - void failNotify(); - /// Timeout notification - void timeoutNotify(); - /// Begin Z39.50 client role - void client(const char *addr); - /// Begin Z39.50 server role - void server(const char *addr); - /// Decode Z39.50 PDU. - Z_APDU *decode_Z_PDU(const char *buf, int len); - /// Encode Z39.50 PDU. - int encode_Z_PDU(Z_APDU *apdu, char **buf, int *len); - /// Send Z39.50 PDU - int send_Z_PDU(Z_APDU *apdu); /// Receive Z39.50 PDU - virtual void recv_Z_PDU(Z_APDU *apdu) = 0; - /// Create Z39.50 PDU with reasonable defaults - Z_APDU *create_Z_PDU(int type); - /// Request Alloc - ODR odr_encode (); + void recv_Z_PDU(Z_APDU *apdu); + /// Set Database Names + void set_databaseNames (int num, const char **list); + void set_databaseNames(const char *dblist, const char *sep); + /// Get Database Names + void get_databaseNames (int *num, char ***list); + + void client(const char *addr); + + /// Set Preferred Record Syntax + void set_preferredRecordSyntax (int value); + void set_preferredRecordSyntax (const char *syntax); + /// Get Preferred Record Syntax + void get_preferredRecordSyntax (int *val); + void get_preferredRecordSyntax (const char **syntax); + + /// Set ElementSetName + void set_elementSetName (const char *elementSetName); + /// Get ElementSetName + void get_elementSetName (const char **elementSetName); + void get_elementSetName (Z_ElementSetNames **elementSetNames); + + int get_lastReceived(); + void set_lastReceived(int lastReceived); + + /// OtherInformation + Z_OtherInformationUnit *set_otherInformation( + Z_OtherInformation **otherInformationP, int *oid, + int categoryValue); + void set_otherInformationString (Z_OtherInformation **otherInformationP, + int *oid, int categoryValue, + const char *str); + + /// Settings + void set_proxy(const char *str); + const char *get_proxy(); + const char *get_host(); + + /// Send Services + int send_initRequest(); + int send_searchRequest(Yaz_Z_Query *query); + int send_presentRequest(int start, int number); + /// Recv Services + virtual void recv_initRequest(Z_InitRequest *initRequest); + virtual void recv_initResponse(Z_InitResponse *initResponse); + virtual void recv_searchRequest(Z_SearchRequest *searchRequest); + virtual void recv_presentRequest(Z_PresentRequest *presentRequest); + virtual void recv_searchResponse(Z_SearchResponse *searchResponse); + virtual void recv_presentResponse(Z_PresentResponse *presentResponse); private: - static int yaz_init_flag; - static int yaz_init_func(); - IYaz_PDU_Observable *m_PDU_Observable; - ODR m_odr_in; - ODR m_odr_out; - ODR m_odr_print; + char *m_proxy; + char *m_host; + int m_num_databaseNames; + char **m_databaseNames; + int m_preferredRecordSyntax; + Z_ElementSetNames *m_elementSetNames; + int m_lastReceived; }; diff --git a/include/yaz-pdu-observer.h b/include/yaz-pdu-observer.h index 78618bf..f89436f 100644 --- a/include/yaz-pdu-observer.h +++ b/include/yaz-pdu-observer.h @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-pdu-observer.h,v $ - * Revision 1.4 1999-03-23 14:17:57 adam + * Revision 1.5 1999-04-09 11:47:23 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + * Revision 1.4 1999/03/23 14:17:57 adam * More work on timeout handling. Work on yaz-client. * * Revision 1.3 1999/02/02 14:01:14 adam @@ -60,7 +63,7 @@ class YAZ_EXPORT IYaz_PDU_Observer { virtual void connectNotify() = 0; /// Called whenever the connection was closed virtual void failNotify() = 0; - /// Called whenever the connection was closed + /// Called whenever there is a timeout virtual void timeoutNotify() = 0; /// Make clone of observer using IYaz_PDU_Observable interface virtual IYaz_PDU_Observer *clone(IYaz_PDU_Observable *the_PDU_Observable) = 0; diff --git a/include/yaz-proxy.h b/include/yaz-proxy.h index 8b09c91..9d8e213 100644 --- a/include/yaz-proxy.h +++ b/include/yaz-proxy.h @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-proxy.h,v $ - * Revision 1.2 1999-02-02 14:01:15 adam + * Revision 1.3 1999-04-09 11:47:23 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + * Revision 1.2 1999/02/02 14:01:15 adam * First WIN32 port of YAZ++. * * Revision 1.1.1.1 1999/01/28 09:41:07 adam @@ -13,12 +16,12 @@ * */ -#include +#include class Yaz_Proxy; /// Private class -class YAZ_EXPORT Yaz_ProxyClient : public Yaz_IR_Assoc { +class YAZ_EXPORT Yaz_ProxyClient : public Yaz_Z_Assoc { friend Yaz_Proxy; Yaz_ProxyClient(IYaz_PDU_Observable *the_PDU_Observable); void recv_Z_PDU(Z_APDU *apdu); @@ -36,7 +39,7 @@ class YAZ_EXPORT Yaz_ProxyMap { }; /// Information Retrieval Proxy Server. -class YAZ_EXPORT Yaz_Proxy : public Yaz_IR_Assoc { +class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc { public: Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable); ~Yaz_Proxy(); diff --git a/include/yaz-z-assoc.h b/include/yaz-z-assoc.h new file mode 100644 index 0000000..caec440 --- /dev/null +++ b/include/yaz-z-assoc.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1998-1999, Index Data. + * See the file LICENSE for details. + * Sebastian Hammer, Adam Dickmeiss + * + * $Log: yaz-z-assoc.h,v $ + * Revision 1.1 1999-04-09 11:47:23 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + */ + +#include +#include +#include + +/** Z39.50 Assocation. + This object implements the client - and server role of a generic + Z39.50 Association. +*/ +class YAZ_EXPORT Yaz_Z_Assoc : public IYaz_PDU_Observer { + public: + /// Create object using the PDU Observer specified + Yaz_Z_Assoc(IYaz_PDU_Observable *the_PDU_Observable); + /// Destroy assocation and close PDU Observer + virtual ~Yaz_Z_Assoc(); + /// Receive PDU + void recv_PDU(const char *buf, int len); + /// Connect notification + void connectNotify(); + /// Failure notification + void failNotify(); + /// Timeout notification + void timeoutNotify(); + /// Begin Z39.50 client role + void client(const char *addr); + /// Begin Z39.50 server role + void server(const char *addr); + /// Close connection + void close(); + /// Decode Z39.50 PDU. + Z_APDU *decode_Z_PDU(const char *buf, int len); + /// Encode Z39.50 PDU. + int encode_Z_PDU(Z_APDU *apdu, char **buf, int *len); + /// Send Z39.50 PDU + int send_Z_PDU(Z_APDU *apdu); + /// Receive Z39.50 PDU + virtual void recv_Z_PDU(Z_APDU *apdu) = 0; + /// Create Z39.50 PDU with reasonable defaults + Z_APDU *create_Z_PDU(int type); + /// Request Alloc + ODR odr_encode (); + private: + static int yaz_init_flag; + static int yaz_init_func(); + IYaz_PDU_Observable *m_PDU_Observable; + ODR m_odr_in; + ODR m_odr_out; + ODR m_odr_print; +}; diff --git a/include/yaz-z-query.h b/include/yaz-z-query.h index b35bb8b..8febc1e 100644 --- a/include/yaz-z-query.h +++ b/include/yaz-z-query.h @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-z-query.h,v $ - * Revision 1.1 1999-03-23 14:17:57 adam + * Revision 1.2 1999-04-09 11:47:23 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + * Revision 1.1 1999/03/23 14:17:57 adam * More work on timeout handling. Work on yaz-client. * */ @@ -22,7 +25,7 @@ class YAZ_EXPORT Yaz_Z_Query : public Yaz_Query { /// Delete Query virtual ~Yaz_Z_Query(); /// Set RPN - void set_rpn (const char *rpn); + int set_rpn (const char *rpn); /// Set Z Query void set_Z_Query (Z_Query *z_query); /// Get Z Query diff --git a/src/Makefile.in b/src/Makefile.in index b14caa9..bef737b 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ # Copyright (C) 1999, Index Data ApS # All rights reserved. # Sebastian Hammer, Adam Dickmeiss -# $Id: Makefile.in,v 1.3 1999-03-23 14:17:57 adam Exp $ +# $Id: Makefile.in,v 1.4 1999-04-09 11:46:57 adam Exp $ SHELL=/bin/sh @@ -18,8 +18,7 @@ LIBDIR=../../yaz/lib INCLUDE=-I../../yaz/z39.50 -I../../yaz/include -I../include DEFS=$(INCLUDE) $(CDEFS) YAZLIBS=$(LIBDIR)/libasn.a \ - $(LIBDIR)/libcomstack.a $(LIBDIR)/ccl.a \ - $(LIBDIR)/libodr.a $(LIBDIR)/libutil.a + $(LIBDIR)/libcomstack.a $(LIBDIR)/libodr.a $(LIBDIR)/libutil.a PROG1=yaz-client PROGO1=yaz-client.o PROG2=yaz-server @@ -27,8 +26,8 @@ PROGO2=yaz-server.o PROG3=yaz-proxy PROGO3=yaz-proxy-main.o LIB=libyaz++.lib -PO=yaz-socket-manager.o yaz-pdu-assoc.o yaz-ir-assoc.o yaz-proxy.o \ - yaz-z-query.o +PO=yaz-socket-manager.o yaz-pdu-assoc.o yaz-z-assoc.o yaz-proxy.o \ + yaz-z-query.o yaz-ir-assoc.o .SUFFIXES: .cpp diff --git a/src/yaz-client.cpp b/src/yaz-client.cpp index 7f67f35..8a88bc3 100644 --- a/src/yaz-client.cpp +++ b/src/yaz-client.cpp @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-client.cpp,v $ - * Revision 1.4 1999-03-23 14:17:57 adam + * Revision 1.5 1999-04-09 11:46:57 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + * Revision 1.4 1999/03/23 14:17:57 adam * More work on timeout handling. Work on yaz-client. * * Revision 1.3 1999/02/02 14:01:18 adam @@ -20,166 +23,266 @@ */ #include +#include #include #include #include -#include + +extern "C" { +#if HAVE_READLINE_READLINE_H +#include +#endif +#if HAVE_READLINE_HISTORY_H +#include +#endif +} class YAZ_EXPORT MyClient : public Yaz_IR_Assoc { +private: + int m_interactive_flag; + char m_thisCommand[1024]; + char m_lastCommand[1024]; + Yaz_SocketManager *m_socketManager; public: - MyClient(IYaz_PDU_Observable *the_PDU_Observable); - void recv_Z_PDU(Z_APDU *apdu); + MyClient(IYaz_PDU_Observable *the_PDU_Observable, + Yaz_SocketManager *the_SocketManager); IYaz_PDU_Observer *clone(IYaz_PDU_Observable *the_PDU_Observable); - void init(); - void search(Yaz_Z_Query *query); - void present(int start, int number); - void set_databaseNames (int num, char **list); - void set_syntax (const char *syntax); - void set_elementSetName (const char *elementSetName); -private: - int m_num_databaseNames; - char **m_databaseNames; - int m_recordSyntax; - Z_ElementSetNames *m_elementSetNames; + int args(Yaz_SocketManager *socketManager, int argc, char **argv); + int interactive(Yaz_SocketManager *socketManager); + int wait(); + void recv_initResponse(Z_InitResponse *initResponse); + void recv_searchResponse(Z_SearchResponse *searchResponse); + int processCommand(const char *cmd); + const char *MyClient::getCommand(); + int cmd_open(char *host); + int cmd_quit(char *args); + int cmd_close(char *args); + int cmd_find(char *args); }; -void MyClient::recv_Z_PDU(Z_APDU *apdu) -{ - logf (LOG_LOG, "recv_APDU"); - switch (apdu->which) - { - case Z_APDU_initResponse: - logf (LOG_LOG, "got InitResponse"); - break; - case Z_APDU_searchResponse: - logf (LOG_LOG, "got searchResponse"); - break; - case Z_APDU_presentResponse: - logf (LOG_LOG, "got presentResponse"); - break; - } -} - IYaz_PDU_Observer *MyClient::clone(IYaz_PDU_Observable *the_PDU_Observable) { - return new MyClient(the_PDU_Observable); + return new MyClient(the_PDU_Observable, m_socketManager); } -MyClient::MyClient(IYaz_PDU_Observable *the_PDU_Observable) : +MyClient::MyClient(IYaz_PDU_Observable *the_PDU_Observable, + Yaz_SocketManager *the_socketManager) : Yaz_IR_Assoc (the_PDU_Observable) { - m_num_databaseNames = 0; - m_databaseNames = 0; - m_recordSyntax = VAL_NONE; + m_interactive_flag = 1; + m_thisCommand[0] = '\0'; + m_lastCommand[0] = '\0'; + m_socketManager = the_socketManager; } -void MyClient::set_databaseNames (int num, char **list) +void usage(char *prog) { - int i; - for (i = 0; iresult) + printf ("Ok\n"); + else + printf ("Fail\n"); } -void MyClient::set_elementSetName (const char *elementSetName) +void MyClient::recv_searchResponse(Z_SearchResponse *searchResponse) { - if (m_elementSetNames) - delete [] m_elementSetNames->u.generic; - delete m_elementSetNames; - m_elementSetNames = 0; - if (elementSetName && *elementSetName) + printf ("Got SearchResponse. Status "); + if (!*searchResponse->searchStatus) { - m_elementSetNames = new Z_ElementSetNames; - m_elementSetNames->which = Z_ElementSetNames_generic; - m_elementSetNames->u.generic = new char[strlen(elementSetName)+1]; - strcpy (m_elementSetNames->u.generic, elementSetName); + printf ("Fail\n"); + return; } + printf ("Ok\n"); + printf ("Hits: %d\n", *searchResponse->resultCount); } -void MyClient::search(Yaz_Z_Query *query) +int MyClient::wait() { - Z_APDU *apdu = create_Z_PDU(Z_APDU_searchRequest); - Z_SearchRequest *req = apdu->u.searchRequest; - - req->num_databaseNames = m_num_databaseNames; - req->databaseNames = m_databaseNames; - req->query = query->get_Z_Query(); - - int oid_syntax[OID_SIZE]; - oident prefsyn; - if (m_recordSyntax != VAL_NONE) + set_lastReceived(0); + while (m_socketManager->processEvent() > 0) { - prefsyn.proto = PROTO_Z3950; - prefsyn.oclass = CLASS_RECSYN; - prefsyn.value = (enum oid_value) m_recordSyntax; - oid_ent_to_oid(&prefsyn, oid_syntax); - req->preferredRecordSyntax = oid_syntax; + if (get_lastReceived()) + return 1; } - send_Z_PDU(apdu); + return 0; +} + +#define C_PROMPT "Z>" + +int MyClient::cmd_open(char *host) +{ + client (host); + if (send_initRequest() >= 0) + wait(); + else + close(); + return 1; } -void MyClient::present(int start, int number) +int MyClient::cmd_quit(char *args) { - Z_APDU *apdu = create_Z_PDU(Z_APDU_presentRequest); - Z_PresentRequest *req = apdu->u.presentRequest; + return 0; +} - req->resultSetStartPoint = &start; - req->numberOfRecordsRequested = &number; +int MyClient::cmd_close(char *args) +{ + close(); + return 1; +} - int oid_syntax[OID_SIZE]; - oident prefsyn; - if (m_recordSyntax != VAL_NONE) +int MyClient::cmd_find(char *args) +{ + Yaz_Z_Query query; + + if (query.set_rpn(args) <= 0) { - prefsyn.proto = PROTO_Z3950; - prefsyn.oclass = CLASS_RECSYN; - prefsyn.value = (enum oid_value) m_recordSyntax; - oid_ent_to_oid(&prefsyn, oid_syntax); - req->preferredRecordSyntax = oid_syntax; + printf ("Bad RPN query\n"); + return 1; } - Z_RecordComposition compo; - if (m_elementSetNames) + if (send_searchRequest(&query) >= 0) + wait(); + return 1; +} + +int MyClient::processCommand(const char *commandLine) +{ + char cmdStr[1024], cmdArgs[1024]; + cmdArgs[0] = '\0'; + cmdStr[0] = '\0'; + static struct { + char *cmd; + int (MyClient::*fun)(char *arg); + char *ad; + } cmd[] = { + {"open", &cmd_open, "('tcp'|'osi')':'['/'][':']"}, + {"quit", &cmd_quit, ""}, + {"close", &cmd_close, ""}, + {"find", &cmd_find, ""}, + {0,0,0} + }; + + if (sscanf(commandLine, "%s %[^;]", cmdStr, cmdArgs) < 1) + return 1; + int i; + for (i = 0; cmd[i].cmd; i++) + if (!strncmp(cmd[i].cmd, cmdStr, strlen(cmdStr))) + break; + + int res = 1; + if (cmd[i].cmd) // Invoke command handler + res = (this->*cmd[i].fun)(cmdArgs); + else // Dump help screen { - req->recordComposition = &compo; - compo.which = Z_RecordComp_simple; - compo.u.simple = m_elementSetNames; + printf("Unknown command: %s.\n", cmdStr); + printf("Currently recognized commands:\n"); + for (i = 0; cmd[i].cmd; i++) + printf(" %s %s\n", cmd[i].cmd, cmd[i].ad); } - send_Z_PDU(apdu); + return res; } -void MyClient::init() +const char *MyClient::getCommand() { - Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest); - Z_InitRequest *req = apdu->u.initRequest; - - ODR_MASK_SET(req->options, Z_Options_search); - ODR_MASK_SET(req->options, Z_Options_present); - ODR_MASK_SET(req->options, Z_Options_namedResultSets); - ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl); - ODR_MASK_SET(req->options, Z_Options_scan); - ODR_MASK_SET(req->options, Z_Options_sort); - ODR_MASK_SET(req->options, Z_Options_extendedServices); - ODR_MASK_SET(req->options, Z_Options_delSet); +#if HAVE_READLINE_READLINE_H + // Read using GNU readline + char *line_in; + line_in=readline(C_PROMPT); + if (!line_in) + return 0; +#if HAVE_READLINE_HISTORY_H + if (*line_in) + add_history(line_in); +#endif + strncpy(m_thisCommand,line_in, 1023); + m_thisCommand[1023] = '\0'; + free (line_in); +#else + // Read using fgets(3) + printf (C_PROMPT); + fflush(stdout); + if (!fgets(m_thisCommand, 1023, stdin)) + return 0; +#endif + // Remove trailing whitespace + char *cp = m_thisCommand + strlen(m_thisCommand); + while (cp != m_thisCommand && strchr("\t \n", cp[-1])) + cp--; + *cp = '\0'; + cp = m_thisCommand; + // Remove leading spaces... + while (strchr ("\t \n", *cp)) + cp++; + // Save command if non-empty + if (*cp != '\0') + strcpy (m_lastCommand, cp); + return m_lastCommand; +} - ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1); - ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2); - ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3); +int MyClient::interactive(Yaz_SocketManager *socketManager) +{ + const char *cmd; + if (!m_interactive_flag) + return 0; + while ((cmd = getCommand())) + { + if (!processCommand(cmd)) + break; + } + return 0; +} - send_Z_PDU(apdu); +int MyClient::args(Yaz_SocketManager *socketManager, int argc, char **argv) +{ + char *host = 0; + char *proxy = 0; + char *arg; + char *prog = argv[0]; + int ret; + + while ((ret = options("p:v:q", argv, argc, &arg)) != -2) + { + switch (ret) + { + case 0: + if (host) + { + usage(prog); + return 1; + } + host = arg; + break; + case 'p': + if (proxy) + { + usage(prog); + return 1; + } + set_proxy(arg); + break; + case 'v': + log_init_level (log_mask_str(arg)); + break; + case 'q': + m_interactive_flag = 0; + break; + default: + usage(prog); + return 1; + } + } + if (host) + { + client (host); + send_initRequest(); + wait (); + } + return 0; } int main(int argc, char **argv) @@ -187,11 +290,10 @@ int main(int argc, char **argv) Yaz_SocketManager mySocketManager; Yaz_PDU_Assoc *some = new Yaz_PDU_Assoc(&mySocketManager, 0); - MyClient z(some); + MyClient z(some, &mySocketManager); - z.client(argc < 2 ? "localhost:9999" : argv[1]); - z.init(); - while (mySocketManager.processEvent() > 0) - ; - return 0; + if (z.args(&mySocketManager, argc, argv)) + exit (1); + if (z.interactive(&mySocketManager)) + exit (1); } diff --git a/src/yaz-ir-assoc.cpp b/src/yaz-ir-assoc.cpp index f941e6c..4217bcd 100644 --- a/src/yaz-ir-assoc.cpp +++ b/src/yaz-ir-assoc.cpp @@ -4,131 +4,414 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-ir-assoc.cpp,v $ - * Revision 1.4 1999-03-23 14:17:57 adam - * More work on timeout handling. Work on yaz-client. - * - * Revision 1.3 1999/02/02 14:01:19 adam - * First WIN32 port of YAZ++. - * - * Revision 1.2 1999/01/28 13:08:43 adam - * Yaz_PDU_Assoc better encapsulated. Memory leak fix in - * yaz-socket-manager.cc. - * - * Revision 1.1.1.1 1999/01/28 09:41:07 adam - * First implementation of YAZ++. + * Revision 1.5 1999-04-09 11:46:57 adam + * Added object Yaz_Z_Assoc. Much more functional client. * */ +#include + #include #include -int Yaz_IR_Assoc::yaz_init_func() +Yaz_IR_Assoc::Yaz_IR_Assoc(IYaz_PDU_Observable *the_PDU_Observable) + : Yaz_Z_Assoc(the_PDU_Observable) { - logf (LOG_LOG, "nmem_init"); - nmem_init(); - logf (LOG_LOG, "done"); - return 1; + m_num_databaseNames = 0; + m_databaseNames = 0; + m_preferredRecordSyntax = VAL_NONE; + m_elementSetNames = 0; + m_lastReceived = 0; + m_host = 0; + m_proxy = 0; + + const char *db = "Default"; + set_databaseNames(1, &db); } -int Yaz_IR_Assoc::yaz_init_flag = Yaz_IR_Assoc::yaz_init_func(); +Yaz_IR_Assoc::~Yaz_IR_Assoc() +{ + if (m_elementSetNames) + delete [] m_elementSetNames->u.generic; + delete m_elementSetNames; +} -Yaz_IR_Assoc::Yaz_IR_Assoc(IYaz_PDU_Observable *the_PDU_Observable) +void Yaz_IR_Assoc::get_databaseNames (int *num, char ***list) { - m_PDU_Observable = the_PDU_Observable; - m_odr_in = odr_createmem (ODR_DECODE); - m_odr_out = odr_createmem (ODR_ENCODE); - m_odr_print = odr_createmem (ODR_PRINT); + *num = m_num_databaseNames; + *list = m_databaseNames; } -Yaz_IR_Assoc::~Yaz_IR_Assoc() +void Yaz_IR_Assoc::set_databaseNames (int num, const char **list) { - m_PDU_Observable->destroy(); - delete m_PDU_Observable; - odr_destroy (m_odr_print); - odr_destroy (m_odr_out); - odr_destroy (m_odr_in); + int i; + logf (LOG_LOG, "Yaz_IR_Assoc::set_databaseNames num=%d", num); + for (i = 0; i 0) - return m_PDU_Observable->send_PDU(buf, len); - return -1; + *value = m_preferredRecordSyntax; } -Z_APDU *Yaz_IR_Assoc::decode_Z_PDU(const char *buf, int len) +void Yaz_IR_Assoc::get_preferredRecordSyntax (const char **dst) { - Z_APDU *apdu; + struct oident ent; + ent.proto = PROTO_Z3950; + ent.oclass = CLASS_RECSYN; + ent.value = (enum oid_value) m_preferredRecordSyntax; - odr_reset (m_odr_in); - odr_setbuf (m_odr_in, (char*) buf, len, 0); + int oid[OID_SIZE]; + oid_ent_to_oid (&ent, oid); + struct oident *entp = oid_getentbyoid (oid); + + *dst = entp ? entp->desc : ""; +} - if (!z_APDU(m_odr_in, &apdu, 0)) +void Yaz_IR_Assoc::set_elementSetName (const char *elementSetName) +{ + if (m_elementSetNames) + delete [] m_elementSetNames->u.generic; + delete m_elementSetNames; + m_elementSetNames = 0; + if (elementSetName && *elementSetName) { - logf(LOG_LOG, "ODR error on incoming PDU: %s [near byte %d] ", - odr_errmsg(odr_geterror(m_odr_in)), - odr_offset(m_odr_in)); - logf(LOG_LOG, "PDU dump:"); - odr_dumpBER(log_file(), buf, len); - return 0; + m_elementSetNames = new Z_ElementSetNames; + m_elementSetNames->which = Z_ElementSetNames_generic; + m_elementSetNames->u.generic = new char[strlen(elementSetName)+1]; + strcpy (m_elementSetNames->u.generic, elementSetName); } - else +} + +void Yaz_IR_Assoc::get_elementSetName (Z_ElementSetNames **elementSetNames) +{ + *elementSetNames = m_elementSetNames; +} + +void Yaz_IR_Assoc::get_elementSetName (const char **elementSetName) +{ + if (!m_elementSetNames || + m_elementSetNames->which != Z_ElementSetNames_generic) { - logf (LOG_LOG, "decoded ok"); - return apdu; + *elementSetName = 0; + return; } + *elementSetName = m_elementSetNames->u.generic; } -int Yaz_IR_Assoc::encode_Z_PDU(Z_APDU *apdu, char **buf, int *len) +void Yaz_IR_Assoc::set_otherInformationString ( + Z_OtherInformation **otherInformation, + int *oid, int categoryValue, + const char *str) { - if (!z_APDU(m_odr_out, &apdu, 0)) - return -1; - *buf = odr_getbuf (m_odr_out, len, 0); - odr_reset (m_odr_out); - return *len; + Z_OtherInformationUnit *oi = + set_otherInformation(otherInformation, oid, categoryValue); + if (!oi) + return; + oi->information.characterInfo = odr_strdup (odr_encode(), str); } -void Yaz_IR_Assoc::connectNotify() +Z_OtherInformationUnit *Yaz_IR_Assoc::set_otherInformation ( + Z_OtherInformation **otherInformationP, + int *oid, int categoryValue) { - logf (LOG_LOG, "connectNotify"); + int i; + Z_OtherInformation *otherInformation = *otherInformationP; + if (!otherInformation) + { + otherInformation = *otherInformationP = (Z_OtherInformation *) + odr_malloc (odr_encode(), sizeof(*otherInformation)); + otherInformation->num_elements = 0; + otherInformation->list = (Z_OtherInformationUnit **) + odr_malloc (odr_encode(), 8*sizeof(*otherInformation)); + for (i = 0; i<8; i++) + otherInformation->list[i] = 0; + } + for (i = 0; inum_elements; i++) + { + assert (otherInformation->list[i]); + if (!oid) + { + if (!otherInformation->list[i]->category) + return otherInformation->list[i]; + } + else + { + if (otherInformation->list[i]->category && + categoryValue == + *otherInformation->list[i]->category->categoryValue && + !oid_oidcmp (oid, otherInformation->list[i]->category-> + categoryTypeId)) + return otherInformation->list[i]; + } + } + otherInformation->list[i] = (Z_OtherInformationUnit*) + odr_malloc (odr_encode(), sizeof(Z_OtherInformationUnit)); + if (oid) + { + otherInformation->list[i]->category = (Z_InfoCategory*) + odr_malloc (odr_encode(), sizeof(Z_InfoCategory)); + otherInformation->list[i]->category->categoryTypeId = (int*) + odr_oiddup (odr_encode(), oid); + otherInformation->list[i]->category->categoryValue = (int*) + odr_malloc (odr_encode(), sizeof(int)); + *otherInformation->list[i]->category->categoryValue = + categoryValue; + } + else + otherInformation->list[i]->category = 0; + otherInformation->list[i]->which = Z_OtherInfo_characterInfo; + otherInformation->list[i]->information.characterInfo = 0; + + otherInformation->num_elements = i+1; + return otherInformation->list[i]; +} + +void Yaz_IR_Assoc::recv_Z_PDU(Z_APDU *apdu) +{ + logf (LOG_LOG, "recv_Z_PDU"); + m_lastReceived = apdu->which; + switch (apdu->which) + { + case Z_APDU_initResponse: + logf (LOG_LOG, "recv InitResponse"); + recv_initResponse(apdu->u.initResponse); + break; + case Z_APDU_initRequest: + logf (LOG_LOG, "recv InitRequest"); + recv_initRequest(apdu->u.initRequest); + break; + case Z_APDU_searchRequest: + logf (LOG_LOG, "recv searchRequest"); + recv_searchRequest(apdu->u.searchRequest); + break; + case Z_APDU_searchResponse: + logf (LOG_LOG, "recv searchResponse"); + recv_searchResponse(apdu->u.searchResponse); + break; + case Z_APDU_presentRequest: + logf (LOG_LOG, "recv presentRequest"); + recv_presentRequest(apdu->u.presentRequest); + break; + case Z_APDU_presentResponse: + logf (LOG_LOG, "recv presentResponse"); + recv_presentResponse(apdu->u.presentResponse); + break; + } +} + +int Yaz_IR_Assoc::send_searchRequest(Yaz_Z_Query *query) +{ + Z_APDU *apdu = create_Z_PDU(Z_APDU_searchRequest); + Z_SearchRequest *req = apdu->u.searchRequest; + int recordSyntax; + + req->query = query->get_Z_Query(); + if (!req->query) + return -1; + get_databaseNames (&req->num_databaseNames, &req->databaseNames); + for (int i = 0; inum_databaseNames; i++) + logf (LOG_LOG, "Database %s", req->databaseNames[i]); + int oid_syntax[OID_SIZE]; + oident prefsyn; + get_preferredRecordSyntax(&recordSyntax); + if (recordSyntax != VAL_NONE) + { + prefsyn.proto = PROTO_Z3950; + prefsyn.oclass = CLASS_RECSYN; + prefsyn.value = (enum oid_value) recordSyntax; + oid_ent_to_oid(&prefsyn, oid_syntax); + req->preferredRecordSyntax = oid_syntax; + } + logf (LOG_LOG, "send_searchRequest"); + return send_Z_PDU(apdu); } -void Yaz_IR_Assoc::failNotify() +int Yaz_IR_Assoc::send_presentRequest(int start, int number) { - logf (LOG_LOG, "failNotify"); + Z_APDU *apdu = create_Z_PDU(Z_APDU_presentRequest); + Z_PresentRequest *req = apdu->u.presentRequest; + + req->resultSetStartPoint = &start; + req->numberOfRecordsRequested = &number; + + int oid_syntax[OID_SIZE]; + oident prefsyn; + int recordSyntax; + get_preferredRecordSyntax (&recordSyntax); + if (recordSyntax != VAL_NONE) + { + prefsyn.proto = PROTO_Z3950; + prefsyn.oclass = CLASS_RECSYN; + prefsyn.value = (enum oid_value) recordSyntax; + oid_ent_to_oid(&prefsyn, oid_syntax); + req->preferredRecordSyntax = oid_syntax; + } + Z_RecordComposition compo; + Z_ElementSetNames *elementSetNames; + get_elementSetName (&elementSetNames); + if (elementSetNames) + { + req->recordComposition = &compo; + compo.which = Z_RecordComp_simple; + compo.u.simple = elementSetNames; + } + return send_Z_PDU(apdu); } -void Yaz_IR_Assoc::timeoutNotify() +void Yaz_IR_Assoc::set_proxy(const char *str) { - logf (LOG_LOG, "timeoutNotify"); + delete m_proxy; + m_proxy = new char[strlen(str)+1]; + strcpy (m_proxy, str); } void Yaz_IR_Assoc::client(const char *addr) { - m_PDU_Observable->connect (this, addr); + delete [] m_host; + m_host = new char[strlen(addr)+1]; + strcpy(m_host, addr); + const char *zurl_p = (m_proxy ? m_proxy : m_host); + char *zurl = new char[strlen(zurl_p)+1]; + strcpy(zurl, zurl_p); + char *dbpart = strchr(zurl, '/'); + if (dbpart) + { + set_databaseNames (dbpart+1, "+ "); + *dbpart = '\0'; + } + Yaz_Z_Assoc::client(zurl); + delete [] zurl; +} + +const char *Yaz_IR_Assoc::get_proxy() +{ + return m_proxy; +} + +const char *Yaz_IR_Assoc::get_host() +{ + return m_host; +} + +void Yaz_IR_Assoc::recv_searchRequest(Z_SearchRequest *searchRequest) +{ + Z_APDU *apdu = create_Z_PDU(Z_APDU_searchResponse); + send_Z_PDU(apdu); +} + +void Yaz_IR_Assoc::recv_presentRequest(Z_PresentRequest *presentRequest) +{ + Z_APDU *apdu = create_Z_PDU(Z_APDU_presentResponse); + send_Z_PDU(apdu); } -void Yaz_IR_Assoc::server(const char *addr) +void Yaz_IR_Assoc::recv_initRequest(Z_InitRequest *initRequest) { - m_PDU_Observable->listen (this, addr); + Z_APDU *apdu = create_Z_PDU(Z_APDU_initResponse); + send_Z_PDU(apdu); } -ODR Yaz_IR_Assoc::odr_encode() +void Yaz_IR_Assoc::recv_searchResponse (Z_SearchResponse *searchResponse) { - return m_odr_out; } + +void Yaz_IR_Assoc::recv_presentResponse (Z_PresentResponse *presentResponse) +{ +} + +void Yaz_IR_Assoc::recv_initResponse(Z_InitResponse *initResponse) +{ +} + +int Yaz_IR_Assoc::get_lastReceived() +{ + return m_lastReceived; +} + +void Yaz_IR_Assoc::set_lastReceived(int lastReceived) +{ + m_lastReceived = lastReceived; +} + +int Yaz_IR_Assoc::send_initRequest() +{ + + Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest); + Z_InitRequest *req = apdu->u.initRequest; + + ODR_MASK_SET(req->options, Z_Options_search); + ODR_MASK_SET(req->options, Z_Options_present); + ODR_MASK_SET(req->options, Z_Options_namedResultSets); + ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl); + ODR_MASK_SET(req->options, Z_Options_scan); + ODR_MASK_SET(req->options, Z_Options_sort); + ODR_MASK_SET(req->options, Z_Options_extendedServices); + ODR_MASK_SET(req->options, Z_Options_delSet); + + ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1); + ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2); + ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3); + + if (m_proxy && m_host) + { + int oid[OID_SIZE]; + struct oident ent; + ent.proto = PROTO_Z3950; + ent.oclass = CLASS_USERINFO; + ent.value = VAL_PROXY; + oid_ent_to_oid (&ent, oid); + logf (LOG_LOG, "proxy host %s", m_host); + set_otherInformationString(&req->otherInfo, oid, 1, m_host); + } + return send_Z_PDU(apdu); +} + diff --git a/src/yaz-pdu-assoc.cpp b/src/yaz-pdu-assoc.cpp index e0c0c9d..e20837b 100644 --- a/src/yaz-pdu-assoc.cpp +++ b/src/yaz-pdu-assoc.cpp @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-pdu-assoc.cpp,v $ - * Revision 1.4 1999-03-23 14:17:57 adam + * Revision 1.5 1999-04-09 11:46:57 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + * Revision 1.4 1999/03/23 14:17:57 adam * More work on timeout handling. Work on yaz-client. * * Revision 1.3 1999/02/02 14:01:20 adam @@ -55,7 +58,7 @@ Yaz_PDU_Assoc::~Yaz_PDU_Assoc() void Yaz_PDU_Assoc::socketNotify(int event) { - logf (LOG_LOG, "socketNotify p=%p event = %d", this, event); + logf (LOG_LOG, "Yaz_PDU_Assoc::socketNotify p=%p event = %d", this, event); if (m_state == Connected) { m_state = Ready; @@ -215,9 +218,12 @@ Yaz_PDU_Assoc::PDU_Queue::~PDU_Queue() int Yaz_PDU_Assoc::flush_PDU() { int r; - + + logf (LOG_LOG, "Yaz_PDU_Assoc::flush_PDU"); if (m_state != Ready) + { return 1; + } PDU_Queue *q = m_queue_out; if (!q) { @@ -237,13 +243,12 @@ int Yaz_PDU_Assoc::flush_PDU() m_socketObservable->maskObserver(this, YAZ_SOCKET_OBSERVE_READ| YAZ_SOCKET_OBSERVE_EXCEPT| YAZ_SOCKET_OBSERVE_WRITE); - logf (LOG_LOG, "put %d bytes (incomplete write)", q->m_len); + logf (LOG_LOG, "flush_PDU put %d bytes (incomplete write)", q->m_len); return r; } - logf (LOG_LOG, "put %d bytes fd=%d", q->m_len, cs_fileno(m_cs)); + logf (LOG_LOG, "flush_PDU put %d bytes fd=%d", q->m_len, cs_fileno(m_cs)); // whole packet sent... delete this and proceed to next ... m_queue_out = q->m_next; - logf (LOG_LOG, "m_queue_out = %p", m_queue_out); delete q; // don't select on write if queue is empty ... if (!m_queue_out) @@ -254,7 +259,7 @@ int Yaz_PDU_Assoc::flush_PDU() int Yaz_PDU_Assoc::send_PDU(const char *buf, int len) { - logf (LOG_LOG, "send_PDU"); + logf (LOG_LOG, "Yaz_PDU_Assoc::send_PDU"); PDU_Queue **pq = &m_queue_out; int is_idle = (*pq ? 0 : 1); @@ -267,13 +272,9 @@ int Yaz_PDU_Assoc::send_PDU(const char *buf, int len) pq = &(*pq)->m_next; *pq = new PDU_Queue(buf, len); if (is_idle) - { return flush_PDU (); - } else - { logf (LOG_LOG, "cannot send_PDU fd=%d", cs_fileno(m_cs)); - } return 0; } @@ -342,8 +343,14 @@ void Yaz_PDU_Assoc::connect(IYaz_PDU_Observer *observer, YAZ_SOCKET_OBSERVE_EXCEPT| YAZ_SOCKET_OBSERVE_WRITE); if (res == 1) + { + logf (LOG_LOG, "Connect pending"); m_state = Connecting; + } else + { + logf (LOG_LOG, "Connect complete"); m_state = Connected; + } } } diff --git a/src/yaz-proxy-main.cpp b/src/yaz-proxy-main.cpp index 320a92a..b7292fd 100644 --- a/src/yaz-proxy-main.cpp +++ b/src/yaz-proxy-main.cpp @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-proxy-main.cpp,v $ - * Revision 1.3 1999-02-02 14:01:21 adam + * Revision 1.4 1999-04-09 11:46:57 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + * Revision 1.3 1999/02/02 14:01:21 adam * First WIN32 port of YAZ++. * * Revision 1.2 1999/01/28 13:08:45 adam @@ -26,8 +29,8 @@ int main(int argc, char **argv) { Yaz_SocketManager mySocketManager; Yaz_Proxy proxy(new Yaz_PDU_Assoc(&mySocketManager, 0)); - - proxy.server("@:9999"); + + proxy.server(argc < 2 ? "@:9999" : argv[1]); while (mySocketManager.processEvent() > 0) ; return 0; diff --git a/src/yaz-proxy.cpp b/src/yaz-proxy.cpp index a37500a..59ccc36 100644 --- a/src/yaz-proxy.cpp +++ b/src/yaz-proxy.cpp @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-proxy.cpp,v $ - * Revision 1.2 1999-01-28 13:08:46 adam + * Revision 1.3 1999-04-09 11:46:57 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + * Revision 1.2 1999/01/28 13:08:46 adam * Yaz_PDU_Assoc better encapsulated. Memory leak fix in * yaz-socket-manager.cc. * @@ -20,7 +23,7 @@ #include Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable) : - Yaz_IR_Assoc(the_PDU_Observable) + Yaz_Z_Assoc(the_PDU_Observable) { m_PDU_Observable = the_PDU_Observable; m_maps = 0; @@ -73,7 +76,7 @@ IYaz_PDU_Observer *Yaz_ProxyClient::clone(IYaz_PDU_Observable } Yaz_ProxyClient::Yaz_ProxyClient(IYaz_PDU_Observable *the_PDU_Observable) : - Yaz_IR_Assoc (the_PDU_Observable) + Yaz_Z_Assoc (the_PDU_Observable) { } diff --git a/src/yaz-server.cpp b/src/yaz-server.cpp index 932910c..2d2c244 100644 --- a/src/yaz-server.cpp +++ b/src/yaz-server.cpp @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-server.cpp,v $ - * Revision 1.4 1999-03-23 14:17:57 adam + * Revision 1.5 1999-04-09 11:46:57 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + * Revision 1.4 1999/03/23 14:17:57 adam * More work on timeout handling. Work on yaz-client. * * Revision 1.3 1999/02/02 14:01:22 adam @@ -20,11 +23,11 @@ */ #include -#include +#include #include #include -class MyServer : public Yaz_IR_Assoc { +class MyServer : public Yaz_Z_Assoc { public: MyServer(IYaz_PDU_Observable *the_PDU_Observable); void recv_Z_PDU(Z_APDU *apdu); @@ -69,7 +72,7 @@ IYaz_PDU_Observer *MyServer::clone(IYaz_PDU_Observable *the_PDU_Observable) } MyServer::MyServer(IYaz_PDU_Observable *the_PDU_Observable) : - Yaz_IR_Assoc (the_PDU_Observable) + Yaz_Z_Assoc (the_PDU_Observable) { m_no = 0; } diff --git a/src/yaz-socket-manager.cpp b/src/yaz-socket-manager.cpp index eeb06e2..43d90ca 100644 --- a/src/yaz-socket-manager.cpp +++ b/src/yaz-socket-manager.cpp @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-socket-manager.cpp,v $ - * Revision 1.4 1999-03-23 14:17:57 adam + * Revision 1.5 1999-04-09 11:46:57 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + * Revision 1.4 1999/03/23 14:17:57 adam * More work on timeout handling. Work on yaz-client. * * Revision 1.3 1999/02/02 14:01:23 adam @@ -110,6 +113,7 @@ int Yaz_SocketManager::processEvent() YazSocketEntry *p; YazSocketEvent *event = getEvent(); unsigned timeout = 0; + logf (LOG_LOG, "processEvent"); if (event) { event->observer->socketNotify(event->event); @@ -153,7 +157,12 @@ int Yaz_SocketManager::processEvent() } } if (!no) + { + logf (LOG_LOG, "no pending events return 0"); + if (!m_observers) + logf (LOG_LOG, "no observers"); return 0; + } struct timeval to; to.tv_sec = timeout; diff --git a/src/yaz-z-assoc.cpp b/src/yaz-z-assoc.cpp new file mode 100644 index 0000000..360bcf6 --- /dev/null +++ b/src/yaz-z-assoc.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 1998-1999, Index Data. + * See the file LICENSE for details. + * Sebastian Hammer, Adam Dickmeiss + * + * $Log: yaz-z-assoc.cpp,v $ + * Revision 1.1 1999-04-09 11:46:57 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + */ + +#include +#include + +int Yaz_Z_Assoc::yaz_init_func() +{ + logf (LOG_LOG, "nmem_init"); + nmem_init(); + logf (LOG_LOG, "done"); + return 1; +} + +int Yaz_Z_Assoc::yaz_init_flag = Yaz_Z_Assoc::yaz_init_func(); + +Yaz_Z_Assoc::Yaz_Z_Assoc(IYaz_PDU_Observable *the_PDU_Observable) +{ + m_PDU_Observable = the_PDU_Observable; + m_odr_in = odr_createmem (ODR_DECODE); + m_odr_out = odr_createmem (ODR_ENCODE); + m_odr_print = odr_createmem (ODR_PRINT); +} + +Yaz_Z_Assoc::~Yaz_Z_Assoc() +{ + m_PDU_Observable->destroy(); + delete m_PDU_Observable; + odr_destroy (m_odr_print); + odr_destroy (m_odr_out); + odr_destroy (m_odr_in); +} + +void Yaz_Z_Assoc::recv_PDU(const char *buf, int len) +{ + logf (LOG_LOG, "recv_PDU len=%d", len); + Z_APDU *apdu = decode_Z_PDU (buf, len); + if (apdu) + recv_Z_PDU (apdu); +} + +Z_APDU *Yaz_Z_Assoc::create_Z_PDU(int type) +{ + return zget_APDU(m_odr_out, type); +} + +int Yaz_Z_Assoc::send_Z_PDU(Z_APDU *apdu) +{ + char *buf; + int len; + logf (LOG_LOG, "Yaz_Z_Assoc:send_Z_PDU"); + if (encode_Z_PDU(apdu, &buf, &len) > 0) + return m_PDU_Observable->send_PDU(buf, len); + return -1; +} + +Z_APDU *Yaz_Z_Assoc::decode_Z_PDU(const char *buf, int len) +{ + Z_APDU *apdu; + + odr_reset (m_odr_in); + odr_setbuf (m_odr_in, (char*) buf, len, 0); + + if (!z_APDU(m_odr_in, &apdu, 0)) + { + logf(LOG_LOG, "ODR error on incoming PDU: %s [near byte %d] ", + odr_errmsg(odr_geterror(m_odr_in)), + odr_offset(m_odr_in)); + logf(LOG_LOG, "PDU dump:"); + odr_dumpBER(log_file(), buf, len); + return 0; + } + else + { + logf (LOG_LOG, "decoded ok"); + return apdu; + } +} + +int Yaz_Z_Assoc::encode_Z_PDU(Z_APDU *apdu, char **buf, int *len) +{ + if (!z_APDU(m_odr_out, &apdu, 0)) + { + logf (LOG_LOG, "yaz_Z_Assoc::encode_Z_PDU failed"); + return -1; + } + *buf = odr_getbuf (m_odr_out, len, 0); + odr_reset (m_odr_out); + return *len; +} + +void Yaz_Z_Assoc::connectNotify() +{ + logf (LOG_LOG, "connectNotify"); +} + +void Yaz_Z_Assoc::failNotify() +{ + logf (LOG_LOG, "failNotify"); +} + +void Yaz_Z_Assoc::timeoutNotify() +{ + logf (LOG_LOG, "timeoutNotify"); +} + +void Yaz_Z_Assoc::client(const char *addr) +{ + m_PDU_Observable->connect (this, addr); +} + +void Yaz_Z_Assoc::close() +{ + m_PDU_Observable->close (); +} + +void Yaz_Z_Assoc::server(const char *addr) +{ + m_PDU_Observable->listen (this, addr); +} + +ODR Yaz_Z_Assoc::odr_encode() +{ + return m_odr_out; +} diff --git a/src/yaz-z-query.cpp b/src/yaz-z-query.cpp index e7d9b48..3fbd3e6 100644 --- a/src/yaz-z-query.cpp +++ b/src/yaz-z-query.cpp @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-z-query.cpp,v $ - * Revision 1.1 1999-03-23 14:17:57 adam + * Revision 1.2 1999-04-09 11:46:57 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + * Revision 1.1 1999/03/23 14:17:57 adam * More work on timeout handling. Work on yaz-client. * */ @@ -18,7 +21,7 @@ Yaz_Z_Query::Yaz_Z_Query() odr_decode = odr_createmem (ODR_DECODE); } -void Yaz_Z_Query::set_rpn (const char *rpn) +int Yaz_Z_Query::set_rpn (const char *rpn) { buf = 0; odr_reset (odr_encode); @@ -26,10 +29,11 @@ void Yaz_Z_Query::set_rpn (const char *rpn) query->which = Z_Query_type_1; query->u.type_1 = p_query_rpn (odr_encode, PROTO_Z3950, rpn); if (!query->u.type_1) - return; + return -1; if (!z_Query (odr_encode, &query, 0)) - return; + return -1; buf = odr_getbuf (odr_encode, &len, 0); + return len; } void Yaz_Z_Query::set_Z_Query(Z_Query *z_query) -- 1.7.10.4