Happy new year
[yazpp-moved-to-github.git] / src / yaz-ir-assoc.cpp
1 /* This file is part of the yazpp toolkit.
2  * Copyright (C) 1998-2011 Index Data and Mike Taylor
3  * See the file LICENSE for details.
4  */
5
6 #include <assert.h>
7
8 #include <yaz/log.h>
9 #include <yazpp/ir-assoc.h>
10 #include <yaz/oid_db.h>
11
12 using namespace yazpp_1;
13
14 IR_Assoc::IR_Assoc(IPDU_Observable *the_PDU_Observable)
15     : Z_Assoc(the_PDU_Observable)
16 {
17     m_num_databaseNames = 0;
18     m_databaseNames = 0;
19     m_preferredRecordSyntax = 0;
20     m_elementSetNames = 0;
21     m_lastReceived = 0;
22     m_host = 0;
23     m_proxy = 0;
24     m_cookie = 0;
25     m_log = YLOG_DEBUG;
26     const char *db = "Default";
27     set_databaseNames(1, &db);
28 }
29
30 IR_Assoc::~IR_Assoc()
31 {
32     xfree(m_preferredRecordSyntax);
33     if (m_elementSetNames)
34         delete [] m_elementSetNames->u.generic;
35     delete [] m_elementSetNames;
36     delete [] m_host;
37     delete [] m_proxy;
38     delete [] m_cookie;
39 }
40
41 void IR_Assoc::get_databaseNames (int *num, char ***list)
42 {
43     *num = m_num_databaseNames;
44     *list = m_databaseNames;
45 }
46
47 typedef char *charp;
48 void IR_Assoc::set_databaseNames (int num, const char **list)
49 {
50     int i;
51     yaz_log (m_log, "IR_Assoc::set_databaseNames num=%d", num);
52     for (i = 0; i<m_num_databaseNames; i++)
53         delete [] m_databaseNames[i];
54     delete [] m_databaseNames;
55     m_num_databaseNames = num;
56
57     m_databaseNames = new char *[num];
58     for (i = 0; i<m_num_databaseNames; i++)
59     {
60         m_databaseNames[i] = new char[strlen(list[i])+1];
61         strcpy(m_databaseNames[i], list[i]);
62     }
63 }
64
65 void IR_Assoc::set_databaseNames(const char *dblist, const char *sep)
66 {
67     const char **list = new const char* [strlen(dblist)];
68     char *dbtmp = new char[strlen(dblist)+1];
69     strcpy(dbtmp, dblist);
70     int num = 0;
71     int len = 0;
72     for (char *cp = dbtmp; ; cp++)
73         if (*cp && !strchr(sep, *cp))
74             len++;
75         else
76         {
77             if (len)
78             {
79                 list[num] = cp - len;
80                 num++;
81             }
82             if (!*cp)
83                 break;
84             *cp = '\0';
85             len = 0;
86         }
87     set_databaseNames (num, list);
88     delete [] dbtmp;
89     delete [] list;
90 }
91
92 void IR_Assoc::set_preferredRecordSyntax (const char *syntax)
93 {
94     xfree(m_preferredRecordSyntax);
95     m_preferredRecordSyntax = 0;    
96     if (syntax && *syntax)
97         m_preferredRecordSyntax = xstrdup(syntax);
98 }
99
100 void IR_Assoc::get_preferredRecordSyntax (const char **dst)
101 {
102     if (m_preferredRecordSyntax)
103         *dst = m_preferredRecordSyntax;
104     else
105         *dst = "";
106 }
107
108 void IR_Assoc::set_elementSetName (const char *elementSetName)
109 {
110     if (m_elementSetNames)
111         delete [] m_elementSetNames->u.generic;
112     delete m_elementSetNames;
113     m_elementSetNames = 0;
114     if (elementSetName && *elementSetName)
115     {
116         m_elementSetNames = new Z_ElementSetNames;
117         m_elementSetNames->which = Z_ElementSetNames_generic;
118         m_elementSetNames->u.generic = new char[strlen(elementSetName)+1];
119         strcpy (m_elementSetNames->u.generic, elementSetName);
120     }
121 }
122
123 void IR_Assoc::get_elementSetName (Z_ElementSetNames **elementSetNames)
124 {
125     *elementSetNames = m_elementSetNames;
126 }
127
128 void IR_Assoc::get_elementSetName (const char **elementSetName)
129 {
130     if (!m_elementSetNames ||
131         m_elementSetNames->which != Z_ElementSetNames_generic)
132     {
133         *elementSetName = 0;
134         return;
135     }
136     *elementSetName = m_elementSetNames->u.generic;
137 }
138
139
140 void IR_Assoc::recv_GDU(Z_GDU *apdu, int len)
141 {
142     if (apdu->which == Z_GDU_Z3950)
143             recv_Z_PDU(apdu->u.z3950, len);
144 }
145
146 void IR_Assoc::recv_Z_PDU(Z_APDU *apdu, int len)
147 {
148     yaz_log (m_log, "recv_Z_PDU %d bytes", len);
149     m_lastReceived = apdu->which;
150     switch (apdu->which)
151     {
152     case Z_APDU_initResponse:
153         yaz_log (m_log, "recv InitResponse");
154         recv_initResponse(apdu->u.initResponse);
155         break;
156     case Z_APDU_initRequest:
157         yaz_log (m_log, "recv InitRequest");
158         recv_initRequest(apdu->u.initRequest);
159         break;
160     case Z_APDU_searchRequest:
161         yaz_log (m_log, "recv searchRequest");
162         recv_searchRequest(apdu->u.searchRequest);
163         break;
164     case Z_APDU_searchResponse:
165         yaz_log (m_log, "recv searchResponse"); 
166         recv_searchResponse(apdu->u.searchResponse);
167         break;
168     case Z_APDU_presentRequest:
169         yaz_log (m_log, "recv presentRequest");
170         recv_presentRequest(apdu->u.presentRequest);
171         break;
172     case Z_APDU_presentResponse:
173         yaz_log (m_log, "recv presentResponse");
174         recv_presentResponse(apdu->u.presentResponse);
175         break;
176     case Z_APDU_extendedServicesResponse:
177         yaz_log (m_log, "recv extendedServiceResponse");
178         recv_extendedServicesResponse(apdu->u.extendedServicesResponse);
179         break;
180     }
181 }
182
183 int IR_Assoc::send_searchRequest(Yaz_Z_Query *query,
184                                      char* pResultSetId,
185                                      char* pRefId)
186 {
187     Z_APDU *apdu = create_Z_PDU(Z_APDU_searchRequest);
188     Z_SearchRequest *req = apdu->u.searchRequest;
189
190     req->query = query->get_Z_Query();
191     if (!req->query)
192         return -1;
193     get_databaseNames (&req->num_databaseNames, &req->databaseNames);
194     const char *recordSyntax;
195     get_preferredRecordSyntax(&recordSyntax);
196     if (recordSyntax && *recordSyntax)
197     {
198         req->preferredRecordSyntax
199             = yaz_string_to_oid_odr(yaz_oid_std(), CLASS_RECSYN, recordSyntax,
200                                     odr_encode());
201     }
202     yaz_log (m_log, "send_searchRequest");
203     assert (req->otherInfo == 0);
204     if (m_cookie)
205     {
206         set_otherInformationString(&req->otherInfo, yaz_oid_userinfo_cookie, 
207                                    1, m_cookie);
208         assert (req->otherInfo);
209     }
210
211     if ( pRefId )
212     {
213         req->referenceId = getRefID(pRefId);
214     }
215
216     if ( pResultSetId )
217     {
218         req->resultSetName = pResultSetId;
219     }
220
221     return send_Z_PDU(apdu, 0);
222 }
223
224 int IR_Assoc::send_presentRequest(Odr_int start, 
225                                   Odr_int number, 
226                                   char* pResultSetId,
227                                   char* pRefId)
228 {
229     Z_APDU *apdu = create_Z_PDU(Z_APDU_presentRequest);
230     Z_PresentRequest *req = apdu->u.presentRequest;
231
232     req->resultSetStartPoint = &start;
233     req->numberOfRecordsRequested = &number;
234
235     const char *recordSyntax;
236     get_preferredRecordSyntax (&recordSyntax);
237     if (recordSyntax && *recordSyntax)
238     {
239         req->preferredRecordSyntax =
240             yaz_string_to_oid_odr(yaz_oid_std(), CLASS_RECSYN, recordSyntax,
241                                   odr_encode());
242     }
243     Z_RecordComposition compo;
244     Z_ElementSetNames *elementSetNames;
245     get_elementSetName (&elementSetNames);
246     if (elementSetNames)
247     {
248         req->recordComposition = &compo;
249         compo.which = Z_RecordComp_simple;
250         compo.u.simple = elementSetNames;
251     }
252
253     if (m_cookie)
254         set_otherInformationString(&req->otherInfo, yaz_oid_userinfo_cookie, 
255                                    1, m_cookie);
256
257     if ( pRefId )
258     {
259         req->referenceId = getRefID(pRefId);
260     }
261
262     if ( pResultSetId )
263     {
264         req->resultSetId = pResultSetId;
265     }
266
267     return send_Z_PDU(apdu, 0);
268 }
269
270 void IR_Assoc::set_proxy(const char *str)
271 {
272     delete [] m_proxy;
273     m_proxy = 0;
274     if (str)
275     {
276         m_proxy = new char[strlen(str)+1];
277         strcpy (m_proxy, str);
278     }
279 }
280
281 void IR_Assoc::set_cookie(const char *str)
282 {
283     delete [] m_cookie;
284     m_cookie = 0;
285     if (str)
286     {
287         m_cookie = new char[strlen(str)+1];
288         strcpy(m_cookie, str);
289     }
290 }
291
292 const char *IR_Assoc::get_cookie()
293 {
294     return m_cookie;
295 }
296
297 void IR_Assoc::client(const char *addr)
298 {
299     delete [] m_host;
300     m_host = new char[strlen(addr)+1];
301     strcpy(m_host, addr);
302     const char *dbpart = strchr(m_host, '/');
303     if (dbpart)
304         set_databaseNames (dbpart+1, "+ ");
305     Z_Assoc::client(m_proxy ? m_proxy : m_host);
306 }
307
308 const char *IR_Assoc::get_proxy()
309 {
310     return m_proxy;
311 }
312
313 const char *IR_Assoc::get_host()
314 {
315     return m_host;
316 }
317
318 void IR_Assoc::recv_searchRequest(Z_SearchRequest *searchRequest)
319 {
320     Z_APDU *apdu = create_Z_PDU(Z_APDU_searchResponse);
321     send_Z_PDU(apdu, 0);
322 }
323
324 void IR_Assoc::recv_presentRequest(Z_PresentRequest *presentRequest)
325 {
326     Z_APDU *apdu = create_Z_PDU(Z_APDU_presentResponse);
327     send_Z_PDU(apdu, 0);
328 }
329
330 void IR_Assoc::recv_initRequest(Z_InitRequest *initRequest)
331 {
332     Z_APDU *apdu = create_Z_PDU(Z_APDU_initResponse);
333     send_Z_PDU(apdu, 0);
334 }
335
336 void IR_Assoc::recv_searchResponse (Z_SearchResponse *searchResponse)
337 {
338 }
339
340 void IR_Assoc::recv_presentResponse (Z_PresentResponse *presentResponse)
341 {
342 }
343
344 void IR_Assoc::recv_initResponse(Z_InitResponse *initResponse)
345 {
346 }
347
348 void IR_Assoc::recv_extendedServicesResponse(Z_ExtendedServicesResponse *ExtendedServicesResponse)
349 {
350 }
351
352 int IR_Assoc::get_lastReceived()
353 {
354     return m_lastReceived;
355 }
356
357 void IR_Assoc::set_lastReceived(int lastReceived)
358 {
359     m_lastReceived = lastReceived;
360 }
361
362 int IR_Assoc::send_initRequest(char* pRefId)
363 {
364     Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest);
365     Z_InitRequest *req = apdu->u.initRequest;
366     
367     ODR_MASK_SET(req->options, Z_Options_search);
368     ODR_MASK_SET(req->options, Z_Options_present);
369     ODR_MASK_SET(req->options, Z_Options_namedResultSets);
370     ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl);
371     ODR_MASK_SET(req->options, Z_Options_scan);
372     ODR_MASK_SET(req->options, Z_Options_sort);
373     ODR_MASK_SET(req->options, Z_Options_extendedServices);
374     ODR_MASK_SET(req->options, Z_Options_delSet);
375
376     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1);
377     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2);
378     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3);
379
380     if ( pRefId )
381     {
382         req->referenceId = getRefID(pRefId);
383     }
384
385     if (m_proxy && m_host)
386         set_otherInformationString(&req->otherInfo, yaz_oid_userinfo_proxy, 
387                                    1, m_host);
388     if (m_cookie)
389         set_otherInformationString(&req->otherInfo, yaz_oid_userinfo_cookie, 
390                                    1, m_cookie);
391     return send_Z_PDU(apdu, 0);
392 }
393
394 int IR_Assoc::send_deleteResultSetRequest(char* pResultSetId, char* pRefId)
395 {
396     char* ResultSetIds[1];
397
398     Z_APDU *apdu = create_Z_PDU(Z_APDU_deleteResultSetRequest);
399     Z_DeleteResultSetRequest *req = apdu->u.deleteResultSetRequest;
400
401     if ( pResultSetId )
402     {
403         *req->deleteFunction = Z_DeleteResultSetRequest_list;
404         req->num_resultSetList = 1;
405         ResultSetIds[0] = pResultSetId;
406         req->resultSetList = ResultSetIds;
407     }
408     else
409     {
410         *req->deleteFunction = Z_DeleteResultSetRequest_all;
411     }
412     
413     if ( pRefId )
414     {
415         req->referenceId = getRefID(pRefId);
416     }
417
418     if (m_proxy && m_host)
419         set_otherInformationString(&req->otherInfo, yaz_oid_userinfo_proxy, 
420                                    1, m_host);
421     if (m_cookie)
422         set_otherInformationString(&req->otherInfo, yaz_oid_userinfo_cookie, 
423                                    1, m_cookie);
424
425     return send_Z_PDU(apdu, 0);
426 }
427
428
429 /*
430  * Local variables:
431  * c-basic-offset: 4
432  * c-file-style: "Stroustrup"
433  * indent-tabs-mode: nil
434  * End:
435  * vim: shiftwidth=4 tabstop=8 expandtab
436  */
437