disable-zoom configure option
[yazpp-moved-to-github.git] / src / yaz-ir-assoc.cpp
1 /*
2  * Copyright (c) 1998-2000, Index Data.
3  * See the file LICENSE for details.
4  * 
5  * $Id: yaz-ir-assoc.cpp,v 1.18 2002-10-09 12:50:26 adam Exp $
6  */
7
8 #include <assert.h>
9
10 #include <yaz/log.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 = LOG_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 void Yaz_IR_Assoc::recv_Z_PDU(Z_APDU *apdu)
153 {
154     yaz_log (m_log, "recv_Z_PDU");
155     m_lastReceived = apdu->which;
156     switch (apdu->which)
157     {
158     case Z_APDU_initResponse:
159         yaz_log (m_log, "recv InitResponse");
160         recv_initResponse(apdu->u.initResponse);
161         break;
162     case Z_APDU_initRequest:
163         yaz_log (m_log, "recv InitRequest");
164         recv_initRequest(apdu->u.initRequest);
165         break;
166     case Z_APDU_searchRequest:
167         yaz_log (m_log, "recv searchRequest");
168         recv_searchRequest(apdu->u.searchRequest);
169         break;
170     case Z_APDU_searchResponse:
171         yaz_log (m_log, "recv searchResponse"); 
172         recv_searchResponse(apdu->u.searchResponse);
173         break;
174     case Z_APDU_presentRequest:
175         yaz_log (m_log, "recv presentRequest");
176         recv_presentRequest(apdu->u.presentRequest);
177         break;
178     case Z_APDU_presentResponse:
179         yaz_log (m_log, "recv presentResponse");
180         recv_presentResponse(apdu->u.presentResponse);
181         break;
182     case Z_APDU_extendedServicesResponse:
183         yaz_log (m_log, "recv extendedServiceResponse");
184         recv_extendedServicesResponse(apdu->u.extendedServicesResponse);
185         break;
186     }
187 }
188
189 int Yaz_IR_Assoc::send_searchRequest(Yaz_Z_Query *query,
190                                      char* pResultSetId,
191                                      char* pRefId)
192 {
193     Z_APDU *apdu = create_Z_PDU(Z_APDU_searchRequest);
194     Z_SearchRequest *req = apdu->u.searchRequest;
195     int recordSyntax;
196
197     req->query = query->get_Z_Query();
198     if (!req->query)
199         return -1;
200     get_databaseNames (&req->num_databaseNames, &req->databaseNames);
201     int oid_syntax[OID_SIZE];
202     oident prefsyn;
203     get_preferredRecordSyntax(&recordSyntax);
204     if (recordSyntax != VAL_NONE)
205     {
206         prefsyn.proto = PROTO_Z3950;
207         prefsyn.oclass = CLASS_RECSYN;
208         prefsyn.value = (enum oid_value) recordSyntax;
209         oid_ent_to_oid(&prefsyn, oid_syntax);
210         req->preferredRecordSyntax = oid_syntax;
211     }
212     yaz_log (m_log, "send_searchRequest");
213     assert (req->otherInfo == 0);
214     if (m_cookie)
215     {
216         set_otherInformationString(&req->otherInfo, VAL_COOKIE, 1, m_cookie);
217         assert (req->otherInfo);
218     }
219
220     if ( pRefId )
221     {
222         req->referenceId = getRefID(pRefId);
223     }
224
225     if ( pResultSetId )
226     {
227         req->resultSetName = pResultSetId;
228     }
229
230     return send_Z_PDU(apdu);
231 }
232
233 int Yaz_IR_Assoc::send_presentRequest(int start, 
234                                       int number, 
235                                       char* pResultSetId,
236                                       char* pRefId)
237 {
238     Z_APDU *apdu = create_Z_PDU(Z_APDU_presentRequest);
239     Z_PresentRequest *req = apdu->u.presentRequest;
240
241     req->resultSetStartPoint = &start;
242     req->numberOfRecordsRequested = &number;
243
244     int oid_syntax[OID_SIZE];
245     oident prefsyn;
246     int recordSyntax;
247     get_preferredRecordSyntax (&recordSyntax);
248     if (recordSyntax != VAL_NONE)
249     {
250         prefsyn.proto = PROTO_Z3950;
251         prefsyn.oclass = CLASS_RECSYN;
252         prefsyn.value = (enum oid_value) recordSyntax;
253         oid_ent_to_oid(&prefsyn, oid_syntax);
254         req->preferredRecordSyntax = oid_syntax;
255     }
256     Z_RecordComposition compo;
257     Z_ElementSetNames *elementSetNames;
258     get_elementSetName (&elementSetNames);
259     if (elementSetNames)
260     {
261         req->recordComposition = &compo;
262         compo.which = Z_RecordComp_simple;
263         compo.u.simple = elementSetNames;
264     }
265
266     if (m_cookie)
267         set_otherInformationString(&req->otherInfo, VAL_COOKIE, 1, m_cookie);
268
269     if ( pRefId )
270     {
271         req->referenceId = getRefID(pRefId);
272     }
273
274     if ( pResultSetId )
275     {
276         req->resultSetId = pResultSetId;
277     }
278
279     return send_Z_PDU(apdu);
280 }
281
282 void Yaz_IR_Assoc::set_proxy(const char *str)
283 {
284     delete [] m_proxy;
285     m_proxy = 0;
286     if (str)
287     {
288         m_proxy = new char[strlen(str)+1];
289         strcpy (m_proxy, str);
290     }
291 }
292
293 void Yaz_IR_Assoc::set_cookie(const char *str)
294 {
295     delete [] m_cookie;
296     m_cookie = 0;
297     if (str)
298     {
299         m_cookie = new char[strlen(str)+1];
300         strcpy(m_cookie, str);
301     }
302 }
303
304 const char *Yaz_IR_Assoc::get_cookie()
305 {
306     return m_cookie;
307 }
308
309 void Yaz_IR_Assoc::client(const char *addr)
310 {
311     delete [] m_host;
312     m_host = new char[strlen(addr)+1];
313     strcpy(m_host, addr);
314     const char *dbpart = strchr(m_host, '/');
315     if (dbpart)
316         set_databaseNames (dbpart+1, "+ ");
317     Yaz_Z_Assoc::client(m_proxy ? m_proxy : m_host);
318 }
319
320 const char *Yaz_IR_Assoc::get_proxy()
321 {
322     return m_proxy;
323 }
324
325 const char *Yaz_IR_Assoc::get_host()
326 {
327     return m_host;
328 }
329
330 void Yaz_IR_Assoc::recv_searchRequest(Z_SearchRequest *searchRequest)
331 {
332     Z_APDU *apdu = create_Z_PDU(Z_APDU_searchResponse);
333     send_Z_PDU(apdu);
334 }
335
336 void Yaz_IR_Assoc::recv_presentRequest(Z_PresentRequest *presentRequest)
337 {
338     Z_APDU *apdu = create_Z_PDU(Z_APDU_presentResponse);
339     send_Z_PDU(apdu);
340 }
341
342 void Yaz_IR_Assoc::recv_initRequest(Z_InitRequest *initRequest)
343 {
344     Z_APDU *apdu = create_Z_PDU(Z_APDU_initResponse);
345     send_Z_PDU(apdu);
346 }
347
348 void Yaz_IR_Assoc::recv_searchResponse (Z_SearchResponse *searchResponse)
349 {
350 }
351
352 void Yaz_IR_Assoc::recv_presentResponse (Z_PresentResponse *presentResponse)
353 {
354 }
355
356 void Yaz_IR_Assoc::recv_initResponse(Z_InitResponse *initResponse)
357 {
358 }
359
360 void Yaz_IR_Assoc::recv_extendedServicesResponse(Z_ExtendedServicesResponse *ExtendedServicesResponse)
361 {
362 }
363
364 int Yaz_IR_Assoc::get_lastReceived()
365 {
366     return m_lastReceived;
367 }
368
369 void Yaz_IR_Assoc::set_lastReceived(int lastReceived)
370 {
371     m_lastReceived = lastReceived;
372 }
373
374 int Yaz_IR_Assoc::send_initRequest(char* pRefId)
375 {
376     Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest);
377     Z_InitRequest *req = apdu->u.initRequest;
378     
379     ODR_MASK_SET(req->options, Z_Options_search);
380     ODR_MASK_SET(req->options, Z_Options_present);
381     ODR_MASK_SET(req->options, Z_Options_namedResultSets);
382     ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl);
383     ODR_MASK_SET(req->options, Z_Options_scan);
384     ODR_MASK_SET(req->options, Z_Options_sort);
385     ODR_MASK_SET(req->options, Z_Options_extendedServices);
386     ODR_MASK_SET(req->options, Z_Options_delSet);
387
388     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1);
389     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2);
390     ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3);
391
392     if ( pRefId )
393     {
394         req->referenceId = getRefID(pRefId);
395     }
396
397     if (m_proxy && m_host)
398         set_otherInformationString(&req->otherInfo, VAL_PROXY, 1, m_host);
399     if (m_cookie)
400         set_otherInformationString(&req->otherInfo, VAL_COOKIE, 1, m_cookie);
401     return send_Z_PDU(apdu);
402 }
403
404 int Yaz_IR_Assoc::send_deleteResultSetRequest(char* pResultSetId, char* pRefId)
405 {
406     char* ResultSetIds[1];
407
408     Z_APDU *apdu = create_Z_PDU(Z_APDU_deleteResultSetRequest);
409     Z_DeleteResultSetRequest *req = apdu->u.deleteResultSetRequest;
410
411     if ( pResultSetId )
412     {
413         *req->deleteFunction = Z_DeleteResultSetRequest_list;
414         req->num_resultSetList = 1;
415         ResultSetIds[0] = pResultSetId;
416         req->resultSetList = ResultSetIds;
417     }
418     else
419     {
420         *req->deleteFunction = Z_DeleteResultSetRequest_all;
421     }
422     
423     if ( pRefId )
424     {
425         req->referenceId = getRefID(pRefId);
426     }
427
428     if (m_proxy && m_host)
429         set_otherInformationString(&req->otherInfo, VAL_PROXY, 1, m_host);
430     if (m_cookie)
431         set_otherInformationString(&req->otherInfo, VAL_COOKIE, 1, m_cookie);
432
433
434     return send_Z_PDU(apdu);
435 }
436
437