Update for YAZ 3s new OID system
[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.28 2007-04-12 15:00:33 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, OID_STR_COOKIE, 1, m_cookie);
209         assert (req->otherInfo);
210     }
211
212     if ( pRefId )
213     {
214         req->referenceId = getRefID(pRefId);
215     }
216
217     if ( pResultSetId )
218     {
219         req->resultSetName = pResultSetId;
220     }
221
222     return send_Z_PDU(apdu, 0);
223 }
224
225 int IR_Assoc::send_presentRequest(int start, 
226                                       int number, 
227                                       char* pResultSetId,
228                                       char* pRefId)
229 {
230     Z_APDU *apdu = create_Z_PDU(Z_APDU_presentRequest);
231     Z_PresentRequest *req = apdu->u.presentRequest;
232
233     req->resultSetStartPoint = &start;
234     req->numberOfRecordsRequested = &number;
235
236     const char *recordSyntax;
237     get_preferredRecordSyntax (&recordSyntax);
238     if (recordSyntax && *recordSyntax)
239     {
240         req->preferredRecordSyntax =
241             yaz_string_to_oid_odr(yaz_oid_std(), CLASS_RECSYN, recordSyntax,
242                                   odr_encode());
243     }
244     Z_RecordComposition compo;
245     Z_ElementSetNames *elementSetNames;
246     get_elementSetName (&elementSetNames);
247     if (elementSetNames)
248     {
249         req->recordComposition = &compo;
250         compo.which = Z_RecordComp_simple;
251         compo.u.simple = elementSetNames;
252     }
253
254     if (m_cookie)
255         set_otherInformationString(&req->otherInfo, OID_STR_COOKIE, 
256                                    1, m_cookie);
257
258     if ( pRefId )
259     {
260         req->referenceId = getRefID(pRefId);
261     }
262
263     if ( pResultSetId )
264     {
265         req->resultSetId = pResultSetId;
266     }
267
268     return send_Z_PDU(apdu, 0);
269 }
270
271 void IR_Assoc::set_proxy(const char *str)
272 {
273     delete [] m_proxy;
274     m_proxy = 0;
275     if (str)
276     {
277         m_proxy = new char[strlen(str)+1];
278         strcpy (m_proxy, str);
279     }
280 }
281
282 void IR_Assoc::set_cookie(const char *str)
283 {
284     delete [] m_cookie;
285     m_cookie = 0;
286     if (str)
287     {
288         m_cookie = new char[strlen(str)+1];
289         strcpy(m_cookie, str);
290     }
291 }
292
293 const char *IR_Assoc::get_cookie()
294 {
295     return m_cookie;
296 }
297
298 void IR_Assoc::client(const char *addr)
299 {
300     delete [] m_host;
301     m_host = new char[strlen(addr)+1];
302     strcpy(m_host, addr);
303     const char *dbpart = strchr(m_host, '/');
304     if (dbpart)
305         set_databaseNames (dbpart+1, "+ ");
306     Z_Assoc::client(m_proxy ? m_proxy : m_host);
307 }
308
309 const char *IR_Assoc::get_proxy()
310 {
311     return m_proxy;
312 }
313
314 const char *IR_Assoc::get_host()
315 {
316     return m_host;
317 }
318
319 void IR_Assoc::recv_searchRequest(Z_SearchRequest *searchRequest)
320 {
321     Z_APDU *apdu = create_Z_PDU(Z_APDU_searchResponse);
322     send_Z_PDU(apdu, 0);
323 }
324
325 void IR_Assoc::recv_presentRequest(Z_PresentRequest *presentRequest)
326 {
327     Z_APDU *apdu = create_Z_PDU(Z_APDU_presentResponse);
328     send_Z_PDU(apdu, 0);
329 }
330
331 void IR_Assoc::recv_initRequest(Z_InitRequest *initRequest)
332 {
333     Z_APDU *apdu = create_Z_PDU(Z_APDU_initResponse);
334     send_Z_PDU(apdu, 0);
335 }
336
337 void IR_Assoc::recv_searchResponse (Z_SearchResponse *searchResponse)
338 {
339 }
340
341 void IR_Assoc::recv_presentResponse (Z_PresentResponse *presentResponse)
342 {
343 }
344
345 void IR_Assoc::recv_initResponse(Z_InitResponse *initResponse)
346 {
347 }
348
349 void IR_Assoc::recv_extendedServicesResponse(Z_ExtendedServicesResponse *ExtendedServicesResponse)
350 {
351 }
352
353 int IR_Assoc::get_lastReceived()
354 {
355     return m_lastReceived;
356 }
357
358 void IR_Assoc::set_lastReceived(int lastReceived)
359 {
360     m_lastReceived = lastReceived;
361 }
362
363 int IR_Assoc::send_initRequest(char* pRefId)
364 {
365     Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest);
366     Z_InitRequest *req = apdu->u.initRequest;
367     
368     ODR_MASK_SET(req->options, Z_Options_search);
369     ODR_MASK_SET(req->options, Z_Options_present);
370     ODR_MASK_SET(req->options, Z_Options_namedResultSets);
371     ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl);
372     ODR_MASK_SET(req->options, Z_Options_scan);
373     ODR_MASK_SET(req->options, Z_Options_sort);
374     ODR_MASK_SET(req->options, Z_Options_extendedServices);
375     ODR_MASK_SET(req->options, Z_Options_delSet);
376
377     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1);
378     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2);
379     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3);
380
381     if ( pRefId )
382     {
383         req->referenceId = getRefID(pRefId);
384     }
385
386     if (m_proxy && m_host)
387         set_otherInformationString(&req->otherInfo, OID_STR_PROXY, 1, m_host);
388     if (m_cookie)
389         set_otherInformationString(&req->otherInfo, OID_STR_COOKIE, 1, m_cookie);
390     return send_Z_PDU(apdu, 0);
391 }
392
393 int IR_Assoc::send_deleteResultSetRequest(char* pResultSetId, char* pRefId)
394 {
395     char* ResultSetIds[1];
396
397     Z_APDU *apdu = create_Z_PDU(Z_APDU_deleteResultSetRequest);
398     Z_DeleteResultSetRequest *req = apdu->u.deleteResultSetRequest;
399
400     if ( pResultSetId )
401     {
402         *req->deleteFunction = Z_DeleteResultSetRequest_list;
403         req->num_resultSetList = 1;
404         ResultSetIds[0] = pResultSetId;
405         req->resultSetList = ResultSetIds;
406     }
407     else
408     {
409         *req->deleteFunction = Z_DeleteResultSetRequest_all;
410     }
411     
412     if ( pRefId )
413     {
414         req->referenceId = getRefID(pRefId);
415     }
416
417     if (m_proxy && m_host)
418         set_otherInformationString(&req->otherInfo, OID_STR_PROXY, 1, m_host);
419     if (m_cookie)
420         set_otherInformationString(&req->otherInfo, OID_STR_COOKIE, 1, m_cookie);
421
422     return send_Z_PDU(apdu, 0);
423 }
424
425
426 /*
427  * Local variables:
428  * c-basic-offset: 4
429  * indent-tabs-mode: nil
430  * End:
431  * vim: shiftwidth=4 tabstop=8 expandtab
432  */
433