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