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