2 * Copyright (c) 1998-1999, Index Data.
3 * See the file LICENSE for details.
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Log: yaz-ir-assoc.cpp,v $
7 * Revision 1.5 1999-04-09 11:46:57 adam
8 * Added object Yaz_Z_Assoc. Much more functional client.
15 #include <yaz-ir-assoc.h>
17 Yaz_IR_Assoc::Yaz_IR_Assoc(IYaz_PDU_Observable *the_PDU_Observable)
18 : Yaz_Z_Assoc(the_PDU_Observable)
20 m_num_databaseNames = 0;
22 m_preferredRecordSyntax = VAL_NONE;
23 m_elementSetNames = 0;
28 const char *db = "Default";
29 set_databaseNames(1, &db);
32 Yaz_IR_Assoc::~Yaz_IR_Assoc()
34 if (m_elementSetNames)
35 delete [] m_elementSetNames->u.generic;
36 delete m_elementSetNames;
39 void Yaz_IR_Assoc::get_databaseNames (int *num, char ***list)
41 *num = m_num_databaseNames;
42 *list = m_databaseNames;
45 void Yaz_IR_Assoc::set_databaseNames (int num, const char **list)
48 logf (LOG_LOG, "Yaz_IR_Assoc::set_databaseNames num=%d", num);
49 for (i = 0; i<m_num_databaseNames; i++)
50 delete [] m_databaseNames[i];
51 delete [] m_databaseNames;
52 m_num_databaseNames = num;
53 m_databaseNames = new (char*) [num];
54 for (i = 0; i<m_num_databaseNames; i++)
56 m_databaseNames[i] = new char[strlen(list[i])+1];
57 strcpy(m_databaseNames[i], list[i]);
61 void Yaz_IR_Assoc::set_databaseNames(const char *dblist, const char *sep)
63 const char **list = new (const char*) [strlen(dblist)];
64 char *dbtmp = new char[strlen(dblist)+1];
65 strcpy(dbtmp, dblist);
68 for (char *cp = dbtmp; ; cp++)
69 if (*cp && !strchr(sep, *cp))
83 set_databaseNames (num, list);
88 void Yaz_IR_Assoc::set_preferredRecordSyntax (int value)
90 m_preferredRecordSyntax = value;
93 void Yaz_IR_Assoc::set_preferredRecordSyntax (const char *syntax)
95 m_preferredRecordSyntax = VAL_NONE;
96 if (syntax && *syntax)
97 m_preferredRecordSyntax = oid_getvalbyname (syntax);
100 void Yaz_IR_Assoc::get_preferredRecordSyntax (int *value)
102 *value = m_preferredRecordSyntax;
105 void Yaz_IR_Assoc::get_preferredRecordSyntax (const char **dst)
108 ent.proto = PROTO_Z3950;
109 ent.oclass = CLASS_RECSYN;
110 ent.value = (enum oid_value) m_preferredRecordSyntax;
113 oid_ent_to_oid (&ent, oid);
114 struct oident *entp = oid_getentbyoid (oid);
116 *dst = entp ? entp->desc : "";
119 void Yaz_IR_Assoc::set_elementSetName (const char *elementSetName)
121 if (m_elementSetNames)
122 delete [] m_elementSetNames->u.generic;
123 delete m_elementSetNames;
124 m_elementSetNames = 0;
125 if (elementSetName && *elementSetName)
127 m_elementSetNames = new Z_ElementSetNames;
128 m_elementSetNames->which = Z_ElementSetNames_generic;
129 m_elementSetNames->u.generic = new char[strlen(elementSetName)+1];
130 strcpy (m_elementSetNames->u.generic, elementSetName);
134 void Yaz_IR_Assoc::get_elementSetName (Z_ElementSetNames **elementSetNames)
136 *elementSetNames = m_elementSetNames;
139 void Yaz_IR_Assoc::get_elementSetName (const char **elementSetName)
141 if (!m_elementSetNames ||
142 m_elementSetNames->which != Z_ElementSetNames_generic)
147 *elementSetName = m_elementSetNames->u.generic;
150 void Yaz_IR_Assoc::set_otherInformationString (
151 Z_OtherInformation **otherInformation,
152 int *oid, int categoryValue,
155 Z_OtherInformationUnit *oi =
156 set_otherInformation(otherInformation, oid, categoryValue);
159 oi->information.characterInfo = odr_strdup (odr_encode(), str);
162 Z_OtherInformationUnit *Yaz_IR_Assoc::set_otherInformation (
163 Z_OtherInformation **otherInformationP,
164 int *oid, int categoryValue)
167 Z_OtherInformation *otherInformation = *otherInformationP;
168 if (!otherInformation)
170 otherInformation = *otherInformationP = (Z_OtherInformation *)
171 odr_malloc (odr_encode(), sizeof(*otherInformation));
172 otherInformation->num_elements = 0;
173 otherInformation->list = (Z_OtherInformationUnit **)
174 odr_malloc (odr_encode(), 8*sizeof(*otherInformation));
175 for (i = 0; i<8; i++)
176 otherInformation->list[i] = 0;
178 for (i = 0; i<otherInformation->num_elements; i++)
180 assert (otherInformation->list[i]);
183 if (!otherInformation->list[i]->category)
184 return otherInformation->list[i];
188 if (otherInformation->list[i]->category &&
190 *otherInformation->list[i]->category->categoryValue &&
191 !oid_oidcmp (oid, otherInformation->list[i]->category->
193 return otherInformation->list[i];
196 otherInformation->list[i] = (Z_OtherInformationUnit*)
197 odr_malloc (odr_encode(), sizeof(Z_OtherInformationUnit));
200 otherInformation->list[i]->category = (Z_InfoCategory*)
201 odr_malloc (odr_encode(), sizeof(Z_InfoCategory));
202 otherInformation->list[i]->category->categoryTypeId = (int*)
203 odr_oiddup (odr_encode(), oid);
204 otherInformation->list[i]->category->categoryValue = (int*)
205 odr_malloc (odr_encode(), sizeof(int));
206 *otherInformation->list[i]->category->categoryValue =
210 otherInformation->list[i]->category = 0;
211 otherInformation->list[i]->which = Z_OtherInfo_characterInfo;
212 otherInformation->list[i]->information.characterInfo = 0;
214 otherInformation->num_elements = i+1;
215 return otherInformation->list[i];
218 void Yaz_IR_Assoc::recv_Z_PDU(Z_APDU *apdu)
220 logf (LOG_LOG, "recv_Z_PDU");
221 m_lastReceived = apdu->which;
224 case Z_APDU_initResponse:
225 logf (LOG_LOG, "recv InitResponse");
226 recv_initResponse(apdu->u.initResponse);
228 case Z_APDU_initRequest:
229 logf (LOG_LOG, "recv InitRequest");
230 recv_initRequest(apdu->u.initRequest);
232 case Z_APDU_searchRequest:
233 logf (LOG_LOG, "recv searchRequest");
234 recv_searchRequest(apdu->u.searchRequest);
236 case Z_APDU_searchResponse:
237 logf (LOG_LOG, "recv searchResponse");
238 recv_searchResponse(apdu->u.searchResponse);
240 case Z_APDU_presentRequest:
241 logf (LOG_LOG, "recv presentRequest");
242 recv_presentRequest(apdu->u.presentRequest);
244 case Z_APDU_presentResponse:
245 logf (LOG_LOG, "recv presentResponse");
246 recv_presentResponse(apdu->u.presentResponse);
251 int Yaz_IR_Assoc::send_searchRequest(Yaz_Z_Query *query)
253 Z_APDU *apdu = create_Z_PDU(Z_APDU_searchRequest);
254 Z_SearchRequest *req = apdu->u.searchRequest;
257 req->query = query->get_Z_Query();
260 get_databaseNames (&req->num_databaseNames, &req->databaseNames);
261 for (int i = 0; i<req->num_databaseNames; i++)
262 logf (LOG_LOG, "Database %s", req->databaseNames[i]);
263 int oid_syntax[OID_SIZE];
265 get_preferredRecordSyntax(&recordSyntax);
266 if (recordSyntax != VAL_NONE)
268 prefsyn.proto = PROTO_Z3950;
269 prefsyn.oclass = CLASS_RECSYN;
270 prefsyn.value = (enum oid_value) recordSyntax;
271 oid_ent_to_oid(&prefsyn, oid_syntax);
272 req->preferredRecordSyntax = oid_syntax;
274 logf (LOG_LOG, "send_searchRequest");
275 return send_Z_PDU(apdu);
278 int Yaz_IR_Assoc::send_presentRequest(int start, int number)
280 Z_APDU *apdu = create_Z_PDU(Z_APDU_presentRequest);
281 Z_PresentRequest *req = apdu->u.presentRequest;
283 req->resultSetStartPoint = &start;
284 req->numberOfRecordsRequested = &number;
286 int oid_syntax[OID_SIZE];
289 get_preferredRecordSyntax (&recordSyntax);
290 if (recordSyntax != VAL_NONE)
292 prefsyn.proto = PROTO_Z3950;
293 prefsyn.oclass = CLASS_RECSYN;
294 prefsyn.value = (enum oid_value) recordSyntax;
295 oid_ent_to_oid(&prefsyn, oid_syntax);
296 req->preferredRecordSyntax = oid_syntax;
298 Z_RecordComposition compo;
299 Z_ElementSetNames *elementSetNames;
300 get_elementSetName (&elementSetNames);
303 req->recordComposition = &compo;
304 compo.which = Z_RecordComp_simple;
305 compo.u.simple = elementSetNames;
307 return send_Z_PDU(apdu);
310 void Yaz_IR_Assoc::set_proxy(const char *str)
313 m_proxy = new char[strlen(str)+1];
314 strcpy (m_proxy, str);
317 void Yaz_IR_Assoc::client(const char *addr)
320 m_host = new char[strlen(addr)+1];
321 strcpy(m_host, addr);
322 const char *zurl_p = (m_proxy ? m_proxy : m_host);
323 char *zurl = new char[strlen(zurl_p)+1];
324 strcpy(zurl, zurl_p);
325 char *dbpart = strchr(zurl, '/');
328 set_databaseNames (dbpart+1, "+ ");
331 Yaz_Z_Assoc::client(zurl);
335 const char *Yaz_IR_Assoc::get_proxy()
340 const char *Yaz_IR_Assoc::get_host()
345 void Yaz_IR_Assoc::recv_searchRequest(Z_SearchRequest *searchRequest)
347 Z_APDU *apdu = create_Z_PDU(Z_APDU_searchResponse);
351 void Yaz_IR_Assoc::recv_presentRequest(Z_PresentRequest *presentRequest)
353 Z_APDU *apdu = create_Z_PDU(Z_APDU_presentResponse);
357 void Yaz_IR_Assoc::recv_initRequest(Z_InitRequest *initRequest)
359 Z_APDU *apdu = create_Z_PDU(Z_APDU_initResponse);
363 void Yaz_IR_Assoc::recv_searchResponse (Z_SearchResponse *searchResponse)
367 void Yaz_IR_Assoc::recv_presentResponse (Z_PresentResponse *presentResponse)
371 void Yaz_IR_Assoc::recv_initResponse(Z_InitResponse *initResponse)
375 int Yaz_IR_Assoc::get_lastReceived()
377 return m_lastReceived;
380 void Yaz_IR_Assoc::set_lastReceived(int lastReceived)
382 m_lastReceived = lastReceived;
385 int Yaz_IR_Assoc::send_initRequest()
388 Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest);
389 Z_InitRequest *req = apdu->u.initRequest;
391 ODR_MASK_SET(req->options, Z_Options_search);
392 ODR_MASK_SET(req->options, Z_Options_present);
393 ODR_MASK_SET(req->options, Z_Options_namedResultSets);
394 ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl);
395 ODR_MASK_SET(req->options, Z_Options_scan);
396 ODR_MASK_SET(req->options, Z_Options_sort);
397 ODR_MASK_SET(req->options, Z_Options_extendedServices);
398 ODR_MASK_SET(req->options, Z_Options_delSet);
400 ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1);
401 ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2);
402 ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3);
404 if (m_proxy && m_host)
408 ent.proto = PROTO_Z3950;
409 ent.oclass = CLASS_USERINFO;
410 ent.value = VAL_PROXY;
411 oid_ent_to_oid (&ent, oid);
412 logf (LOG_LOG, "proxy host %s", m_host);
413 set_otherInformationString(&req->otherInfo, oid, 1, m_host);
415 return send_Z_PDU(apdu);