More work on timeout handling. Work on yaz-client.
[yazpp-moved-to-github.git] / src / yaz-client.cpp
1 /*
2  * Copyright (c) 1998-1999, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  * 
6  * $Log: yaz-client.cpp,v $
7  * Revision 1.4  1999-03-23 14:17:57  adam
8  * More work on timeout handling. Work on yaz-client.
9  *
10  * Revision 1.3  1999/02/02 14:01:18  adam
11  * First WIN32 port of YAZ++.
12  *
13  * Revision 1.2  1999/01/28 13:08:42  adam
14  * Yaz_PDU_Assoc better encapsulated. Memory leak fix in
15  * yaz-socket-manager.cc.
16  *
17  * Revision 1.1.1.1  1999/01/28 09:41:07  adam
18  * First implementation of YAZ++.
19  *
20  */
21
22 #include <log.h>
23 #include <yaz-ir-assoc.h>
24 #include <yaz-pdu-assoc.h>
25 #include <yaz-socket-manager.h>
26 #include <yaz-z-query.h>
27
28 class YAZ_EXPORT MyClient : public Yaz_IR_Assoc {
29 public:
30     MyClient(IYaz_PDU_Observable *the_PDU_Observable);
31     void recv_Z_PDU(Z_APDU *apdu);
32     IYaz_PDU_Observer *clone(IYaz_PDU_Observable *the_PDU_Observable);
33     void init();
34     void search(Yaz_Z_Query *query);
35     void present(int start, int number);
36     void set_databaseNames (int num, char **list);
37     void set_syntax (const char *syntax);
38     void set_elementSetName (const char *elementSetName);
39 private:
40     int m_num_databaseNames;
41     char **m_databaseNames;
42     int m_recordSyntax;
43     Z_ElementSetNames *m_elementSetNames;
44 };
45
46 void MyClient::recv_Z_PDU(Z_APDU *apdu)
47 {
48     logf (LOG_LOG, "recv_APDU");
49     switch (apdu->which)
50     {
51     case Z_APDU_initResponse:
52         logf (LOG_LOG, "got InitResponse");
53         break;
54     case Z_APDU_searchResponse:
55         logf (LOG_LOG, "got searchResponse");
56         break;
57     case Z_APDU_presentResponse:
58         logf (LOG_LOG, "got presentResponse");
59         break;
60     }
61 }
62
63 IYaz_PDU_Observer *MyClient::clone(IYaz_PDU_Observable *the_PDU_Observable)
64 {
65     return new MyClient(the_PDU_Observable);
66 }
67
68 MyClient::MyClient(IYaz_PDU_Observable *the_PDU_Observable) :
69     Yaz_IR_Assoc (the_PDU_Observable)
70 {
71     m_num_databaseNames = 0;
72     m_databaseNames = 0;
73     m_recordSyntax = VAL_NONE;
74 }
75
76 void MyClient::set_databaseNames (int num, char **list)
77 {
78     int i;
79     for (i = 0; i<m_num_databaseNames; i++)
80         delete m_databaseNames[i];
81     delete m_databaseNames;
82     m_databaseNames = 0;
83     m_num_databaseNames = num;
84     m_databaseNames = new (char*) [num];
85     for (i = 0; i<m_num_databaseNames; i++)
86     {
87         m_databaseNames[i] = new char[strlen(list[i])+1];
88         strcpy (m_databaseNames[i], list[i]);
89     }
90 }
91
92 void MyClient::set_syntax (const char *syntax)
93 {
94     m_recordSyntax = VAL_NONE;
95     if (syntax && *syntax)
96         m_recordSyntax = oid_getvalbyname (syntax);
97 }
98
99 void MyClient::set_elementSetName (const char *elementSetName)
100 {
101     if (m_elementSetNames)
102         delete [] m_elementSetNames->u.generic;
103     delete m_elementSetNames;
104     m_elementSetNames = 0;
105     if (elementSetName && *elementSetName)
106     {
107         m_elementSetNames = new Z_ElementSetNames;
108         m_elementSetNames->which = Z_ElementSetNames_generic;
109         m_elementSetNames->u.generic = new char[strlen(elementSetName)+1];
110         strcpy (m_elementSetNames->u.generic, elementSetName);
111     }
112 }
113
114 void MyClient::search(Yaz_Z_Query *query)
115 {
116     Z_APDU *apdu = create_Z_PDU(Z_APDU_searchRequest);
117     Z_SearchRequest *req = apdu->u.searchRequest;
118
119     req->num_databaseNames = m_num_databaseNames;
120     req->databaseNames = m_databaseNames;
121     req->query = query->get_Z_Query();
122
123     int oid_syntax[OID_SIZE];
124     oident prefsyn;
125     if (m_recordSyntax != VAL_NONE)
126     {
127         prefsyn.proto = PROTO_Z3950;
128         prefsyn.oclass = CLASS_RECSYN;
129         prefsyn.value = (enum oid_value) m_recordSyntax;
130         oid_ent_to_oid(&prefsyn, oid_syntax);
131         req->preferredRecordSyntax = oid_syntax;
132     }
133     send_Z_PDU(apdu);
134 }
135
136 void MyClient::present(int start, int number)
137 {
138     Z_APDU *apdu = create_Z_PDU(Z_APDU_presentRequest);
139     Z_PresentRequest *req = apdu->u.presentRequest;
140
141     req->resultSetStartPoint = &start;
142     req->numberOfRecordsRequested = &number;
143
144     int oid_syntax[OID_SIZE];
145     oident prefsyn;
146     if (m_recordSyntax != VAL_NONE)
147     {
148         prefsyn.proto = PROTO_Z3950;
149         prefsyn.oclass = CLASS_RECSYN;
150         prefsyn.value = (enum oid_value) m_recordSyntax;
151         oid_ent_to_oid(&prefsyn, oid_syntax);
152         req->preferredRecordSyntax = oid_syntax;
153     }
154     Z_RecordComposition compo;
155     if (m_elementSetNames)
156     {
157         req->recordComposition = &compo;
158         compo.which = Z_RecordComp_simple;
159         compo.u.simple = m_elementSetNames;
160     }
161     send_Z_PDU(apdu);
162 }
163
164 void MyClient::init()
165 {
166     Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest);
167     Z_InitRequest *req = apdu->u.initRequest;
168     
169     ODR_MASK_SET(req->options, Z_Options_search);
170     ODR_MASK_SET(req->options, Z_Options_present);
171     ODR_MASK_SET(req->options, Z_Options_namedResultSets);
172     ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl);
173     ODR_MASK_SET(req->options, Z_Options_scan);
174     ODR_MASK_SET(req->options, Z_Options_sort);
175     ODR_MASK_SET(req->options, Z_Options_extendedServices);
176     ODR_MASK_SET(req->options, Z_Options_delSet);
177
178     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1);
179     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2);
180     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3);
181
182     send_Z_PDU(apdu);
183 }
184
185 int main(int argc, char **argv)
186 {
187     Yaz_SocketManager mySocketManager;
188     Yaz_PDU_Assoc *some = new Yaz_PDU_Assoc(&mySocketManager, 0);
189
190     MyClient z(some);
191
192     z.client(argc < 2 ? "localhost:9999" : argv[1]);
193     z.init();
194     while (mySocketManager.processEvent() > 0)
195         ;
196     return 0;
197 }