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