metaproxy 1.22.1
util.cpp
Go to the documentation of this file.
1/* This file is part of Metaproxy.
2 Copyright (C) Index Data
3
4Metaproxy is free software; you can redistribute it and/or modify it under
5the terms of the GNU General Public License as published by the Free
6Software Foundation; either version 2, or (at your option) any later
7version.
8
9Metaproxy is distributed in the hope that it will be useful, but WITHOUT ANY
10WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18
19#include "config.hpp"
20#include <metaproxy/util.hpp>
21
22#include <yaz/odr.h>
23#include <yaz/comstack.h>
24#include <yaz/pquery.h>
25#include <yaz/otherinfo.h>
26#include <yaz/querytowrbuf.h>
27#include <yaz/oid_db.h>
28#include <yaz/srw.h>
29#include <yaz/match_glob.h>
30
31#include <boost/algorithm/string.hpp>
32
33#include <iostream>
34
35namespace mp = metaproxy_1;
36
37// Doxygen doesn't like mp::util, so we use this instead
38namespace mp_util = metaproxy_1::util;
39
40const char *
41mp_util::record_composition_to_esn(Z_RecordComposition *comp)
42{
43 if (comp && comp->which == Z_RecordComp_complex)
44 {
45 if (comp->u.complex->generic
46 && comp->u.complex->generic->elementSpec
47 && (comp->u.complex->generic->elementSpec->which ==
48 Z_ElementSpec_elementSetName))
49 return comp->u.complex->generic->elementSpec->u.elementSetName;
50 }
51 else if (comp && comp->which == Z_RecordComp_simple &&
52 comp->u.simple->which == Z_ElementSetNames_generic)
53 return comp->u.simple->u.generic;
54 return 0;
55}
56
57
58
59std::string mp_util::http_header_value(const Z_HTTP_Header* header,
60 const std::string name)
61{
62 while (header && header->name
63 && std::string(header->name) != name)
64 header = header->next;
65
66 if (header && header->name && std::string(header->name) == name
67 && header->value)
68 return std::string(header->value);
69
70 return std::string();
71}
72
73std::string mp_util::http_headers_debug(const Z_HTTP_Request &http_req)
74{
75 std::string message("<html>\n<body>\n<h1>"
76 "Metaproxy SRUtoZ3950 filter"
77 "</h1>\n");
78
79 message += "<h3>HTTP Info</h3><br/>\n";
80 message += "<p>\n";
81 message += "<b>Method: </b> " + std::string(http_req.method) + "<br/>\n";
82 message += "<b>Version:</b> " + std::string(http_req.version) + "<br/>\n";
83 message += "<b>Path: </b> " + std::string(http_req.path) + "<br/>\n";
84
85 message += "<b>Content-Type:</b>"
86 + mp_util::http_header_value(http_req.headers, "Content-Type")
87 + "<br/>\n";
88 message += "<b>Content-Length:</b>"
89 + mp_util::http_header_value(http_req.headers, "Content-Length")
90 + "<br/>\n";
91 message += "</p>\n";
92
93 message += "<h3>Headers</h3><br/>\n";
94 message += "<p>\n";
95 Z_HTTP_Header* header = http_req.headers;
96 while (header){
97 message += "<b>Header: </b> <i>"
98 + std::string(header->name) + ":</i> "
99 + std::string(header->value) + "<br/>\n";
100 header = header->next;
101 }
102 message += "</p>\n";
103 message += "</body>\n</html>\n";
104 return message;
105}
106
107
108void mp_util::http_response(metaproxy_1::Package &package,
109 const std::string &content,
110 int http_code)
111{
112
113 Z_GDU *zgdu_req = package.request().get();
114 Z_GDU *zgdu_res = 0;
115 mp::odr odr;
116 zgdu_res
117 = odr.create_HTTP_Response(package.session(),
118 zgdu_req->u.HTTP_Request,
119 http_code);
120
121 zgdu_res->u.HTTP_Response->content_len = content.size();
122 zgdu_res->u.HTTP_Response->content_buf
123 = (char*) odr_malloc(odr, zgdu_res->u.HTTP_Response->content_len);
124
125 strncpy(zgdu_res->u.HTTP_Response->content_buf,
126 content.c_str(), zgdu_res->u.HTTP_Response->content_len);
127
128 //z_HTTP_header_add(odr, &hres->headers,
129 // "Content-Type", content_type.c_str());
130 package.response() = zgdu_res;
131}
132
133
134int mp_util::memcmp2(const void *buf1, int len1,
135 const void *buf2, int len2)
136{
137 int d = len1 - len2;
138
139 // compare buffer (common length)
140 int c = memcmp(buf1, buf2, d > 0 ? len2 : len1);
141 if (c > 0)
142 return 1;
143 else if (c < 0)
144 return -1;
145
146 // compare (remaining bytes)
147 if (d > 0)
148 return 1;
149 else if (d < 0)
150 return -1;
151 return 0;
152}
153
154bool mp_util::match(const std::list<std::string> &db1,
155 const std::list<std::string> &db2)
156{
157 std::list<std::string>::const_iterator it1 = db1.begin();
158 std::list<std::string>::const_iterator it2 = db2.begin();
159 while (it1 != db1.end() && it2 != db2.end())
160 {
161 std::string s1 = database_name_normalize(*it1);
162 std::string s2 = database_name_normalize(*it2);
163 if (s1.compare(s2) != 0)
164 return false;
165 it1++;
166 it2++;
167 }
168 return it1 == db1.end() && it2 == db2.end();
169}
170
171std::string mp_util::database_name_normalize(const std::string &s)
172{
173 std::string r = s;
174 size_t i;
175 for (i = 0; i < r.length(); i++)
176 {
177 int ch = r[i];
178 if (ch >= 'A' && ch <= 'Z')
179 r[i] = ch + 'a' - 'A';
180 }
181 return r;
182
183}
184
185Z_RecordComposition *mp_util::piggyback_to_RecordComposition(
186 ODR odr, Odr_int result_set_size, Z_SearchRequest *sreq)
187{
188 Z_RecordComposition *comp = 0;
189 Odr_int present_dummy;
190 const char *element_set_name = 0;
191 mp::util::piggyback_sr(sreq, result_set_size,
192 present_dummy, &element_set_name);
193 if (element_set_name)
194 {
195 comp = (Z_RecordComposition *) odr_malloc(odr, sizeof(*comp));
196 comp->which = Z_RecordComp_simple;
197 comp->u.simple = (Z_ElementSetNames *)
198 odr_malloc(odr, sizeof(Z_ElementSetNames));
199 comp->u.simple->which = Z_ElementSetNames_generic;
200 comp->u.simple->u.generic = odr_strdup(odr, element_set_name);
201 }
202 return comp;
203}
204
205void mp_util::piggyback_sr(Z_SearchRequest *sreq,
206 Odr_int result_set_size,
207 Odr_int &number_to_present,
208 const char **element_set_name)
209{
210 Z_ElementSetNames *esn;
211 const char *smallSetElementSetNames = 0;
212 const char *mediumSetElementSetNames = 0;
213
214 esn = sreq->smallSetElementSetNames;
215 if (esn && esn->which == Z_ElementSetNames_generic)
216 smallSetElementSetNames = esn->u.generic;
217
218 esn = sreq->mediumSetElementSetNames;
219 if (esn && esn->which == Z_ElementSetNames_generic)
220 mediumSetElementSetNames = esn->u.generic;
221
222 piggyback(*sreq->smallSetUpperBound,
223 *sreq->largeSetLowerBound,
224 *sreq->mediumSetPresentNumber,
225 smallSetElementSetNames,
226 mediumSetElementSetNames,
228 number_to_present,
229 element_set_name);
230}
231
232void mp_util::piggyback(int smallSetUpperBound,
233 int largeSetLowerBound,
234 int mediumSetPresentNumber,
235 int result_set_size,
236 int &number_to_present)
237{
238 Odr_int tmp = number_to_present;
239 piggyback(smallSetUpperBound, largeSetLowerBound, mediumSetPresentNumber,
240 0, 0, result_set_size, tmp, 0);
241 number_to_present = tmp;
242}
243
244void mp_util::piggyback(Odr_int smallSetUpperBound,
245 Odr_int largeSetLowerBound,
246 Odr_int mediumSetPresentNumber,
247 const char *smallSetElementSetNames,
248 const char *mediumSetElementSetNames,
249 Odr_int result_set_size,
250 Odr_int &number_to_present,
251 const char **element_set_name)
252{
253 // deal with piggyback
254
255 if (result_set_size < smallSetUpperBound)
256 {
257 // small set . Return all records in set
258 number_to_present = result_set_size;
259 if (element_set_name && smallSetElementSetNames)
260 *element_set_name = smallSetElementSetNames;
261
262 }
263 else if (result_set_size > largeSetLowerBound)
264 {
265 // large set . Return no records
266 number_to_present = 0;
267 if (element_set_name)
268 *element_set_name = 0;
269 }
270 else
271 {
272 // medium set . Return mediumSetPresentNumber records
273 number_to_present = mediumSetPresentNumber;
274 if (number_to_present > result_set_size)
275 number_to_present = result_set_size;
276 if (element_set_name && mediumSetElementSetNames)
277 *element_set_name = mediumSetElementSetNames;
278 }
279}
280
281bool mp_util::pqf(ODR odr, Z_APDU *apdu, const std::string &q)
282{
283 YAZ_PQF_Parser pqf_parser = yaz_pqf_create();
284
285 Z_RPNQuery *rpn = yaz_pqf_parse(pqf_parser, odr, q.c_str());
286 if (!rpn)
287 {
288 yaz_pqf_destroy(pqf_parser);
289 return false;
290 }
291 yaz_pqf_destroy(pqf_parser);
292 Z_Query *query = (Z_Query *) odr_malloc(odr, sizeof(Z_Query));
293 query->which = Z_Query_type_1;
294 query->u.type_1 = rpn;
295
296 apdu->u.searchRequest->query = query;
297 return true;
298}
299
300
301std::string mp_util::zQueryToString(Z_Query *query)
302{
303 std::string query_str = "";
304
305 if (query && query->which == Z_Query_type_1)
306 {
307 Z_RPNQuery *rpn = query->u.type_1;
308
309 if (rpn)
310 {
311 mp::wrbuf w;
312
313 // put query in w
314 yaz_rpnquery_to_wrbuf(w, rpn);
315
316 // from w to std::string
317 query_str = std::string(w.buf(), w.len());
318 }
319 }
320
321#if 0
322 if (query && query->which == Z_Query_type_1){
323
324 // allocate wrbuf (strings in YAZ!)
325 WRBUF w = wrbuf_alloc();
326
327 // put query in w
328 yaz_query_to_wrbuf(w, query);
329
330 // from w to std::string
331 query_str = std::string(wrbuf_buf(w), wrbuf_len(w));
332
333 // destroy wrbuf
334 wrbuf_free(w, 1);
335 }
336#endif
337 return query_str;
338}
339
340void mp_util::get_default_diag(Z_DefaultDiagFormat *r,
341 int &error_code, std::string &addinfo)
342{
343 error_code = *r->condition;
344 switch (r->which)
345 {
346 case Z_DefaultDiagFormat_v2Addinfo:
347 addinfo = std::string(r->u.v2Addinfo);
348 break;
349 case Z_DefaultDiagFormat_v3Addinfo:
350 addinfo = r->u.v3Addinfo;
351 break;
352 }
353}
354
355void mp_util::get_init_diagnostics(
356 Z_InitResponse *initrs, int &error_code, std::string &addinfo)
357{
358
359 Z_DefaultDiagFormat *df = yaz_decode_init_diag(0, initrs);
360
361 if (df)
362 get_default_diag(df, error_code, addinfo);
363}
364
365int mp_util::get_or_remove_vhost_otherinfo(
366 Z_OtherInformation **otherInformation,
367 bool remove_flag,
368 std::list<std::string> &vhosts)
369{
370 int cat;
371 for (cat = 1; ; cat++)
372 {
373 // check virtual host
374 const char *vhost =
375 yaz_oi_get_string_oid(otherInformation,
376 yaz_oid_userinfo_proxy,
377 cat /* categoryValue */,
378 remove_flag /* delete flag */);
379 if (!vhost)
380 break;
381 vhosts.push_back(std::string(vhost));
382 }
383 --cat;
384 return cat;
385}
386
387void mp_util::get_vhost_otherinfo(
388 Z_OtherInformation *otherInformation,
389 std::list<std::string> &vhosts)
390{
391 get_or_remove_vhost_otherinfo(&otherInformation, false, vhosts);
392}
393
394int mp_util::remove_vhost_otherinfo(
395 Z_OtherInformation **otherInformation,
396 std::list<std::string> &vhosts)
397{
398 return get_or_remove_vhost_otherinfo(otherInformation, true, vhosts);
399}
400
401void mp_util::set_vhost_otherinfo(
402 Z_OtherInformation **otherInformation, ODR odr,
403 const std::list<std::string> &vhosts)
404{
405 int cat;
406 std::list<std::string>::const_iterator it = vhosts.begin();
407
408 for (cat = 1; it != vhosts.end() ; cat++, it++)
409 {
410 yaz_oi_set_string_oid(otherInformation, odr,
411 yaz_oid_userinfo_proxy, cat, it->c_str());
412 }
413}
414
415void mp_util::set_vhost_otherinfo(
416 Z_OtherInformation **otherInformation, ODR odr,
417 const std::string vhost, const int cat)
418{
419 yaz_oi_set_string_oid(otherInformation, odr,
420 yaz_oid_userinfo_proxy, cat, vhost.c_str());
421}
422
423void mp_util::split_zurl(std::string zurl, std::string &host,
424 std::list<std::string> &db)
425{
426 const char *zurl_cstr = zurl.c_str();
427 const char *args = 0;
428 cs_get_host_args(zurl_cstr, &args);
429
430 if (args && *args)
431 {
432 host = std::string(zurl_cstr, args - zurl_cstr - 1);
433
434 const char *cp1 = args;
435 while (1)
436 {
437 const char *cp2 = strchr(cp1, '+');
438 if (cp2)
439 db.push_back(std::string(cp1, cp2 - cp1));
440 else
441 {
442 db.push_back(std::string(cp1));
443 break;
444 }
445 cp1 = cp2+1;
446 }
447 }
448 else
449 host = zurl;
450}
451
452bool mp_util::set_databases_from_zurl(
453 ODR odr, std::string zurl,
454 int *db_num, char ***db_strings)
455{
456 std::string host;
457 std::list<std::string> dblist;
458
459 split_zurl(zurl, host, dblist);
460
461 if (dblist.size() == 0)
462 return false;
463 *db_num = dblist.size();
464 *db_strings = (char **) odr_malloc(odr, sizeof(char*) * (*db_num));
465
466 std::list<std::string>::const_iterator it = dblist.begin();
467 for (int i = 0; it != dblist.end(); it++, i++)
468 (*db_strings)[i] = odr_strdup(odr, it->c_str());
469 return true;
470}
471
472mp::odr::odr(int type)
473{
474 m_odr = odr_createmem(type);
475}
476
477mp::odr::odr()
478{
479 m_odr = odr_createmem(ODR_ENCODE);
480}
481
482mp::odr::~odr()
483{
484 odr_destroy(m_odr);
485}
486
487mp::odr::operator ODR() const
488{
489 return m_odr;
490}
491
492Z_APDU *mp::odr::create_close(const Z_APDU *in_apdu,
493 int reason, const char *addinfo)
494{
495 Z_APDU *apdu = create_APDU(Z_APDU_close, in_apdu);
496
497 *apdu->u.close->closeReason = reason;
498 if (addinfo)
499 apdu->u.close->diagnosticInformation = odr_strdup(m_odr, addinfo);
500 return apdu;
501}
502
503Z_APDU *mp::odr::create_APDU(int type, const Z_APDU *in_apdu)
504{
505 return mp::util::create_APDU(m_odr, type, in_apdu);
506}
507
508Z_APDU *mp_util::create_APDU(ODR odr, int type, const Z_APDU *in_apdu)
509{
510 Z_APDU *out_apdu = zget_APDU(odr, type);
511 transfer_referenceId(odr, in_apdu, out_apdu);
512 return out_apdu;
513}
514
515void mp_util::transfer_referenceId(ODR odr, const Z_APDU *src, Z_APDU *dst)
516{
517 Z_ReferenceId **id_to = mp::util::get_referenceId(dst);
518 *id_to = 0;
519 if (src)
520 {
521 Z_ReferenceId **id_from = mp::util::get_referenceId(src);
522 if (id_from && *id_from)
523 *id_to = odr_create_Odr_oct(odr, (*id_from)->buf,
524 (*id_from)->len);
525 }
526}
527
528Z_APDU *mp::odr::create_initResponse(const Z_APDU *in_apdu,
529 int error, const char *addinfo)
530{
531 Z_APDU *apdu = create_APDU(Z_APDU_initResponse, in_apdu);
532 if (error)
533 {
534 apdu->u.initResponse->userInformationField =
535 zget_init_diagnostics(m_odr, error, addinfo);
536 *apdu->u.initResponse->result = 0;
537 }
538 apdu->u.initResponse->implementationName =
539 odr_prepend(m_odr, "Metaproxy",
540 apdu->u.initResponse->implementationName);
541 apdu->u.initResponse->implementationVersion =
542 odr_prepend(m_odr,
543 VERSION, apdu->u.initResponse->implementationVersion);
544
545 return apdu;
546}
547
548Z_APDU *mp::odr::create_searchResponse(const Z_APDU *in_apdu,
549 int error, const char *addinfo)
550{
551 Z_APDU *apdu = create_APDU(Z_APDU_searchResponse, in_apdu);
552 if (error)
553 {
554 Z_Records *rec = (Z_Records *) odr_malloc(m_odr, sizeof(Z_Records));
555 *apdu->u.searchResponse->searchStatus = 0;
556 apdu->u.searchResponse->records = rec;
557 rec->which = Z_Records_NSD;
558 rec->u.nonSurrogateDiagnostic =
559 zget_DefaultDiagFormat(m_odr, error, addinfo);
560
561 }
562 return apdu;
563}
564
565Z_APDU *mp::odr::create_presentResponse(const Z_APDU *in_apdu,
566 int error, const char *addinfo)
567{
568 Z_APDU *apdu = create_APDU(Z_APDU_presentResponse, in_apdu);
569 if (error)
570 {
571 Z_Records *rec = (Z_Records *) odr_malloc(m_odr, sizeof(Z_Records));
572 apdu->u.presentResponse->records = rec;
573
574 rec->which = Z_Records_NSD;
575 rec->u.nonSurrogateDiagnostic =
576 zget_DefaultDiagFormat(m_odr, error, addinfo);
577 *apdu->u.presentResponse->presentStatus = Z_PresentStatus_failure;
578 }
579 return apdu;
580}
581
582Z_APDU *mp::odr::create_scanResponse(const Z_APDU *in_apdu,
583 int error, const char *addinfo)
584{
585 Z_APDU *apdu = create_APDU(Z_APDU_scanResponse, in_apdu);
586 Z_ScanResponse *res = apdu->u.scanResponse;
587 res->entries = (Z_ListEntries *) odr_malloc(m_odr, sizeof(*res->entries));
588 res->entries->num_entries = 0;
589 res->entries->entries = 0;
590
591 if (error)
592 {
593 *res->scanStatus = Z_Scan_failure;
594
595 res->entries->num_nonsurrogateDiagnostics = 1;
596 res->entries->nonsurrogateDiagnostics = (Z_DiagRec **)
597 odr_malloc(m_odr, sizeof(Z_DiagRec *));
598 res->entries->nonsurrogateDiagnostics[0] =
599 zget_DiagRec(m_odr, error, addinfo);
600 }
601 else
602 {
603 res->entries->num_nonsurrogateDiagnostics = 0;
604 res->entries->nonsurrogateDiagnostics = 0;
605 }
606 return apdu;
607}
608
609Z_GDU *mp::odr::create_HTTP_Response_details(mp::Session &session,
610 Z_HTTP_Request *hreq, int code,
611 const char *details)
612{
613 const char *response_version = "1.0";
614 bool keepalive = false;
615 if (!strcmp(hreq->version, "1.0"))
616 {
617 const char *v = z_HTTP_header_lookup(hreq->headers, "Connection");
618 if (v && !strcmp(v, "Keep-Alive"))
619 keepalive = true;
620 else
621 session.close();
622 response_version = "1.0";
623 }
624 else
625 {
626 const char *v = z_HTTP_header_lookup(hreq->headers, "Connection");
627 if (v && !strcmp(v, "close"))
628 session.close();
629 else
630 keepalive = true;
631 response_version = "1.1";
632 }
633
634 Z_GDU *gdu = z_get_HTTP_Response_server(
635 m_odr, code, details, "Metaproxy/" VERSION,
636 "http://www.indexdata.com/metaproxy");
637 Z_HTTP_Response *hres = gdu->u.HTTP_Response;
638 hres->version = odr_strdup(m_odr, response_version);
639 if (keepalive)
640 z_HTTP_header_add(m_odr, &hres->headers, "Connection", "Keep-Alive");
641 return gdu;
642}
643
644Z_GDU *mp::odr::create_HTTP_Response(mp::Session &session,
645 Z_HTTP_Request *hreq, int code)
646{
647 return create_HTTP_Response_details(session, hreq, code, 0);
648
649}
650
651Z_ReferenceId **mp_util::get_referenceId(const Z_APDU *apdu)
652{
653 switch (apdu->which)
654 {
655 case Z_APDU_initRequest:
656 return &apdu->u.initRequest->referenceId;
657 case Z_APDU_initResponse:
658 return &apdu->u.initResponse->referenceId;
659 case Z_APDU_searchRequest:
660 return &apdu->u.searchRequest->referenceId;
661 case Z_APDU_searchResponse:
662 return &apdu->u.searchResponse->referenceId;
663 case Z_APDU_presentRequest:
664 return &apdu->u.presentRequest->referenceId;
665 case Z_APDU_presentResponse:
666 return &apdu->u.presentResponse->referenceId;
667 case Z_APDU_deleteResultSetRequest:
668 return &apdu->u.deleteResultSetRequest->referenceId;
669 case Z_APDU_deleteResultSetResponse:
670 return &apdu->u.deleteResultSetResponse->referenceId;
671 case Z_APDU_accessControlRequest:
672 return &apdu->u.accessControlRequest->referenceId;
673 case Z_APDU_accessControlResponse:
674 return &apdu->u.accessControlResponse->referenceId;
675 case Z_APDU_resourceControlRequest:
676 return &apdu->u.resourceControlRequest->referenceId;
677 case Z_APDU_resourceControlResponse:
678 return &apdu->u.resourceControlResponse->referenceId;
679 case Z_APDU_triggerResourceControlRequest:
680 return &apdu->u.triggerResourceControlRequest->referenceId;
681 case Z_APDU_resourceReportRequest:
682 return &apdu->u.resourceReportRequest->referenceId;
683 case Z_APDU_resourceReportResponse:
684 return &apdu->u.resourceReportResponse->referenceId;
685 case Z_APDU_scanRequest:
686 return &apdu->u.scanRequest->referenceId;
687 case Z_APDU_scanResponse:
688 return &apdu->u.scanResponse->referenceId;
689 case Z_APDU_sortRequest:
690 return &apdu->u.sortRequest->referenceId;
691 case Z_APDU_sortResponse:
692 return &apdu->u.sortResponse->referenceId;
693 case Z_APDU_segmentRequest:
694 return &apdu->u.segmentRequest->referenceId;
695 case Z_APDU_extendedServicesRequest:
696 return &apdu->u.extendedServicesRequest->referenceId;
697 case Z_APDU_extendedServicesResponse:
698 return &apdu->u.extendedServicesResponse->referenceId;
699 case Z_APDU_close:
700 return &apdu->u.close->referenceId;
701 }
702 return 0;
703}
704
705std::string mp_util::uri_encode(std::string s)
706{
707 char *x = (char *) xmalloc(1 + s.length() * 3);
708 yaz_encode_uri_component(x, s.c_str());
709 std::string result(x);
710 xfree(x);
711 return result;
712}
713
714
715std::string mp_util::uri_decode(std::string s)
716{
717 char *x = (char *) xmalloc(1 + s.length());
718 yaz_decode_uri_component(x, s.c_str(), s.length());
719 std::string result(x);
720 xfree(x);
721 return result;
722}
723
724mp::wrbuf::wrbuf()
725{
726 m_wrbuf = wrbuf_alloc();
727}
728
729mp::wrbuf::~wrbuf()
730{
731 wrbuf_destroy(m_wrbuf);
732}
733
734mp::wrbuf::operator WRBUF() const
735{
736 return m_wrbuf;
737}
738
739size_t mp::wrbuf::len()
740{
741 return wrbuf_len(m_wrbuf);
742}
743
744const char *mp::wrbuf::buf()
745{
746 return wrbuf_buf(m_wrbuf);
747}
748
749const char *mp::wrbuf::c_str()
750{
751 return wrbuf_cstr(m_wrbuf);
752}
753
754const char *mp::wrbuf::c_str_null()
755{
756 return wrbuf_cstr_null(m_wrbuf);
757}
758
759bool mp::util::match_ip(const std::string &pattern, const std::string &value)
760{
761 std::vector<std::string> globitems;
762 // split may produce empty strings as results - in particular
763 // the empty pattern produces one empty string (vector size 1)
764 boost::split(globitems, pattern, boost::is_any_of(" "));
765 bool ret_value = true; // for now (if only empty values)
766 const char *value_c = value.c_str();
767 int ipv4_mapped = strlen(value_c) > 7 && memcmp(value_c, "::ffff:", 7) == 0;
768 std::vector<std::string>::const_iterator it = globitems.begin();
769 for (; it != globitems.end(); it++)
770 {
771 const char *c_str = (*it).c_str();
772 if (*c_str)
773 {
774 ret_value = false; // at least one non-empty value
775 if (yaz_match_glob(c_str, value_c))
776 return true;
777 if (!strchr(c_str, ':') && ipv4_mapped &&
778 yaz_match_glob(c_str, value_c + 7))
779 return true;
780 }
781 }
782 return ret_value;
783}
784
785/*
786 * Local variables:
787 * c-basic-offset: 4
788 * c-file-style: "Stroustrup"
789 * indent-tabs-mode: nil
790 * End:
791 * vim: shiftwidth=4 tabstop=8 expandtab
792 */
793
#define VERSION
Definition config.hpp:88
static const int result_set_size