1 /* $Id: util.cpp,v 1.18 2006-06-19 23:54:02 adam Exp $
2 Copyright (c) 2005-2006, Index Data.
4 See the LICENSE file for details
10 #include <yaz/pquery.h>
11 #include <yaz/otherinfo.h>
12 #include <yaz/querytowrbuf.h> // for yaz_query_to_wrbuf()
17 namespace mp = metaproxy_1;
19 // Doxygen doesn't like mp::util, so we use this instead
20 namespace mp_util = metaproxy_1::util;
22 int mp_util::memcmp2(const void *buf1, int len1,
23 const void *buf2, int len2)
27 // compare buffer (common length)
28 int c = memcmp(buf1, buf2, d > 0 ? len2 : len1);
34 // compare (remaining bytes)
43 std::string mp_util::database_name_normalize(const std::string &s)
47 for (i = 0; i < r.length(); i++)
50 if (ch >= 'A' && ch <= 'Z')
51 r[i] = ch + 'a' - 'A';
57 void mp_util::piggyback(int smallSetUpperBound,
58 int largeSetLowerBound,
59 int mediumSetPresentNumber,
61 int &number_to_present)
63 // deal with piggyback
65 if (result_set_size < smallSetUpperBound)
67 // small set . Return all records in set
68 number_to_present = result_set_size;
70 else if (result_set_size > largeSetLowerBound)
72 // large set . Return no records
73 number_to_present = 0;
77 // medium set . Return mediumSetPresentNumber records
78 number_to_present = mediumSetPresentNumber;
79 if (number_to_present > result_set_size)
80 number_to_present = result_set_size;
85 bool mp_util::pqf(ODR odr, Z_APDU *apdu, const std::string &q)
87 YAZ_PQF_Parser pqf_parser = yaz_pqf_create();
89 Z_RPNQuery *rpn = yaz_pqf_parse(pqf_parser, odr, q.c_str());
92 yaz_pqf_destroy(pqf_parser);
95 yaz_pqf_destroy(pqf_parser);
96 Z_Query *query = (Z_Query *) odr_malloc(odr, sizeof(Z_Query));
97 query->which = Z_Query_type_1;
98 query->u.type_1 = rpn;
100 apdu->u.searchRequest->query = query;
105 std::string mp_util::zQueryToString(Z_Query *query)
107 std::string query_str = "";
109 if (query && query->which == Z_Query_type_1){
110 Z_RPNQuery *rpn = query->u.type_1;
114 // allocate wrbuf (strings in YAZ!)
115 WRBUF w = wrbuf_alloc();
118 yaz_rpnquery_to_wrbuf(w, rpn);
120 // from w to std::string
121 query_str = std::string(wrbuf_buf(w), wrbuf_len(w));
129 if (query && query->which == Z_Query_type_1){
131 // allocate wrbuf (strings in YAZ!)
132 WRBUF w = wrbuf_alloc();
135 yaz_query_to_wrbuf(w, query);
137 // from w to std::string
138 query_str = std::string(wrbuf_buf(w), wrbuf_len(w));
147 void mp_util::get_default_diag(Z_DefaultDiagFormat *r,
148 int &error_code, std::string &addinfo)
150 error_code = *r->condition;
153 case Z_DefaultDiagFormat_v2Addinfo:
154 addinfo = std::string(r->u.v2Addinfo);
156 case Z_DefaultDiagFormat_v3Addinfo:
157 addinfo = r->u.v3Addinfo;
162 void mp_util::get_init_diagnostics(
163 Z_InitResponse *initrs, int &error_code, std::string &addinfo)
165 Z_External *uif = initrs->userInformationField;
167 if (uif && uif->which == Z_External_userInfo1)
169 Z_OtherInformation *ui = uif->u.userInfo1;
171 for (i = 0; i < ui->num_elements; i++)
173 Z_OtherInformationUnit *unit = ui->list[i];
174 if (unit->which == Z_OtherInfo_externallyDefinedInfo &&
175 unit->information.externallyDefinedInfo &&
176 unit->information.externallyDefinedInfo->which ==
179 Z_DiagnosticFormat *diag =
180 unit->information.externallyDefinedInfo->u.diag1;
184 Z_DiagnosticFormat_s *ds = diag->elements[0];
185 if (ds->which == Z_DiagnosticFormat_s_defaultDiagRec)
186 mp::util::get_default_diag(ds->u.defaultDiagRec,
187 error_code, addinfo);
194 int mp_util::get_vhost_otherinfo(
195 Z_OtherInformation **otherInformation,
197 std::list<std::string> &vhosts)
200 for (cat = 1; ; cat++)
202 // check virtual host
204 yaz_oi_get_string_oidval(otherInformation,
206 cat /* categoryValue */,
207 remove_flag /* delete flag */);
210 vhosts.push_back(std::string(vhost));
216 void mp_util::set_vhost_otherinfo(
217 Z_OtherInformation **otherInformation, ODR odr,
218 const std::list<std::string> &vhosts)
221 std::list<std::string>::const_iterator it = vhosts.begin();
222 for (cat = 1; it != vhosts.end() ; cat++, it++)
224 yaz_oi_set_string_oidval(otherInformation, odr,
225 VAL_PROXY, cat, it->c_str());
229 void mp_util::split_zurl(std::string zurl, std::string &host,
230 std::list<std::string> &db)
232 const char *zurl_cstr = zurl.c_str();
233 const char *sep = strchr(zurl_cstr, '/');
237 host = std::string(zurl_cstr, sep - zurl_cstr);
239 const char *cp1 = sep+1;
242 const char *cp2 = strchr(cp1, '+');
244 db.push_back(std::string(cp1, cp2 - cp1));
247 db.push_back(std::string(cp1));
259 bool mp_util::set_databases_from_zurl(
260 ODR odr, std::string zurl,
261 int *db_num, char ***db_strings)
264 std::list<std::string> dblist;
266 split_zurl(zurl, host, dblist);
268 if (dblist.size() == 0)
270 *db_num = dblist.size();
271 *db_strings = (char **) odr_malloc(odr, sizeof(char*) * (*db_num));
273 std::list<std::string>::const_iterator it = dblist.begin();
274 for (int i = 0; it != dblist.end(); it++, i++)
275 (*db_strings)[i] = odr_strdup(odr, it->c_str());
279 mp::odr::odr(int type)
281 m_odr = odr_createmem(type);
286 m_odr = odr_createmem(ODR_ENCODE);
294 mp::odr::operator ODR() const
299 Z_APDU *mp::odr::create_close(const Z_APDU *in_apdu,
300 int reason, const char *addinfo)
302 Z_APDU *apdu = create_APDU(Z_APDU_close, in_apdu);
304 *apdu->u.close->closeReason = reason;
306 apdu->u.close->diagnosticInformation = odr_strdup(m_odr, addinfo);
310 Z_APDU *mp::odr::create_APDU(int type, const Z_APDU *in_apdu)
312 return mp::util::create_APDU(m_odr, type, in_apdu);
315 Z_APDU *mp_util::create_APDU(ODR odr, int type, const Z_APDU *in_apdu)
317 Z_APDU *out_apdu = zget_APDU(odr, type);
318 transfer_referenceId(odr, in_apdu, out_apdu);
322 void mp_util::transfer_referenceId(ODR odr, const Z_APDU *src, Z_APDU *dst)
324 Z_ReferenceId **id_to = mp::util::get_referenceId(dst);
328 Z_ReferenceId **id_from = mp::util::get_referenceId(src);
329 if (id_from && *id_from && id_to)
331 *id_to = (Z_ReferenceId*) odr_malloc (odr, sizeof(**id_to));
332 (*id_to)->size = (*id_to)->len = (*id_from)->len;
333 (*id_to)->buf = (unsigned char*) odr_malloc(odr, (*id_to)->len);
334 memcpy((*id_to)->buf, (*id_from)->buf, (*id_to)->len);
341 Z_APDU *mp::odr::create_initResponse(const Z_APDU *in_apdu,
342 int error, const char *addinfo)
344 Z_APDU *apdu = create_APDU(Z_APDU_initResponse, in_apdu);
347 apdu->u.initResponse->userInformationField =
348 zget_init_diagnostics(m_odr, error, addinfo);
349 *apdu->u.initResponse->result = 0;
354 Z_APDU *mp::odr::create_searchResponse(const Z_APDU *in_apdu,
355 int error, const char *addinfo)
357 Z_APDU *apdu = create_APDU(Z_APDU_searchResponse, in_apdu);
360 Z_Records *rec = (Z_Records *) odr_malloc(m_odr, sizeof(Z_Records));
361 *apdu->u.searchResponse->searchStatus = 0;
362 apdu->u.searchResponse->records = rec;
363 rec->which = Z_Records_NSD;
364 rec->u.nonSurrogateDiagnostic =
365 zget_DefaultDiagFormat(m_odr, error, addinfo);
371 Z_APDU *mp::odr::create_presentResponse(const Z_APDU *in_apdu,
372 int error, const char *addinfo)
374 Z_APDU *apdu = create_APDU(Z_APDU_presentResponse, in_apdu);
377 Z_Records *rec = (Z_Records *) odr_malloc(m_odr, sizeof(Z_Records));
378 apdu->u.presentResponse->records = rec;
380 rec->which = Z_Records_NSD;
381 rec->u.nonSurrogateDiagnostic =
382 zget_DefaultDiagFormat(m_odr, error, addinfo);
383 *apdu->u.presentResponse->presentStatus = Z_PresentStatus_failure;
388 Z_APDU *mp::odr::create_scanResponse(const Z_APDU *in_apdu,
389 int error, const char *addinfo)
391 Z_APDU *apdu = create_APDU(Z_APDU_scanResponse, in_apdu);
392 Z_ScanResponse *res = apdu->u.scanResponse;
393 res->entries = (Z_ListEntries *) odr_malloc(m_odr, sizeof(*res->entries));
394 res->entries->num_entries = 0;
395 res->entries->entries = 0;
399 *res->scanStatus = Z_Scan_failure;
401 res->entries->num_nonsurrogateDiagnostics = 1;
402 res->entries->nonsurrogateDiagnostics = (Z_DiagRec **)
403 odr_malloc(m_odr, sizeof(Z_DiagRec *));
404 res->entries->nonsurrogateDiagnostics[0] =
405 zget_DiagRec(m_odr, error, addinfo);
409 res->entries->num_nonsurrogateDiagnostics = 0;
410 res->entries->nonsurrogateDiagnostics = 0;
415 Z_GDU *mp::odr::create_HTTP_Response(mp::Session &session,
416 Z_HTTP_Request *hreq, int code)
418 const char *response_version = "1.0";
419 bool keepalive = false;
420 if (!strcmp(hreq->version, "1.0"))
422 const char *v = z_HTTP_header_lookup(hreq->headers, "Connection");
423 if (v && !strcmp(v, "Keep-Alive"))
427 response_version = "1.0";
431 const char *v = z_HTTP_header_lookup(hreq->headers, "Connection");
432 if (v && !strcmp(v, "close"))
436 response_version = "1.1";
439 Z_GDU *gdu = z_get_HTTP_Response(m_odr, code);
440 Z_HTTP_Response *hres = gdu->u.HTTP_Response;
441 hres->version = odr_strdup(m_odr, response_version);
443 z_HTTP_header_add(m_odr, &hres->headers, "Connection", "Keep-Alive");
448 Z_ReferenceId **mp_util::get_referenceId(const Z_APDU *apdu)
452 case Z_APDU_initRequest:
453 return &apdu->u.initRequest->referenceId;
454 case Z_APDU_initResponse:
455 return &apdu->u.initResponse->referenceId;
456 case Z_APDU_searchRequest:
457 return &apdu->u.searchRequest->referenceId;
458 case Z_APDU_searchResponse:
459 return &apdu->u.searchResponse->referenceId;
460 case Z_APDU_presentRequest:
461 return &apdu->u.presentRequest->referenceId;
462 case Z_APDU_presentResponse:
463 return &apdu->u.presentResponse->referenceId;
464 case Z_APDU_deleteResultSetRequest:
465 return &apdu->u.deleteResultSetRequest->referenceId;
466 case Z_APDU_deleteResultSetResponse:
467 return &apdu->u.deleteResultSetResponse->referenceId;
468 case Z_APDU_accessControlRequest:
469 return &apdu->u.accessControlRequest->referenceId;
470 case Z_APDU_accessControlResponse:
471 return &apdu->u.accessControlResponse->referenceId;
472 case Z_APDU_resourceControlRequest:
473 return &apdu->u.resourceControlRequest->referenceId;
474 case Z_APDU_resourceControlResponse:
475 return &apdu->u.resourceControlResponse->referenceId;
476 case Z_APDU_triggerResourceControlRequest:
477 return &apdu->u.triggerResourceControlRequest->referenceId;
478 case Z_APDU_resourceReportRequest:
479 return &apdu->u.resourceReportRequest->referenceId;
480 case Z_APDU_resourceReportResponse:
481 return &apdu->u.resourceReportResponse->referenceId;
482 case Z_APDU_scanRequest:
483 return &apdu->u.scanRequest->referenceId;
484 case Z_APDU_scanResponse:
485 return &apdu->u.scanResponse->referenceId;
486 case Z_APDU_sortRequest:
487 return &apdu->u.sortRequest->referenceId;
488 case Z_APDU_sortResponse:
489 return &apdu->u.sortResponse->referenceId;
490 case Z_APDU_segmentRequest:
491 return &apdu->u.segmentRequest->referenceId;
492 case Z_APDU_extendedServicesRequest:
493 return &apdu->u.extendedServicesRequest->referenceId;
494 case Z_APDU_extendedServicesResponse:
495 return &apdu->u.extendedServicesResponse->referenceId;
497 return &apdu->u.close->referenceId;
506 * indent-tabs-mode: nil
507 * c-file-style: "stroustrup"
509 * vim: shiftwidth=4 tabstop=8 expandtab