1 /* $Id: filter_sru_to_z3950.cpp,v 1.36 2008-01-29 16:51:12 adam Exp $
2 Copyright (c) 2005-2007, Index Data.
4 This file is part of Metaproxy.
6 Metaproxy is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
11 Metaproxy is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with Metaproxy; see the file LICENSE. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 #include "package.hpp"
26 #include "gduutil.hpp"
27 #include "sru_util.hpp"
28 #include "filter_sru_to_z3950.hpp"
31 #include <yaz/z-core.h>
33 #include <yaz/pquery.h>
34 #include <yaz/oid_db.h>
36 #include <boost/thread/mutex.hpp>
44 namespace mp = metaproxy_1;
45 namespace mp_util = metaproxy_1::util;
46 namespace yf = mp::filter;
49 namespace metaproxy_1 {
51 class SRUtoZ3950::Impl {
53 void configure(const xmlNode *xmlnode);
54 void process(metaproxy_1::Package &package);
56 union SRW_query {char * cql; char * xcql; char * pqf;};
57 typedef const int& SRW_query_type;
58 std::map<std::string, const xmlNode *> m_database_explain;
61 bool z3950_build_query(mp::odr &odr_en, Z_Query *z_query,
62 const SRW_query &query,
63 SRW_query_type query_type) const;
65 bool z3950_init_request(mp::Package &package,
67 Z_SRW_PDU *sru_pdu_req,
68 Z_SRW_PDU *sru_pdu_res) const;
70 bool z3950_close_request(mp::Package &package) const;
72 bool z3950_search_request(
75 Z_SRW_PDU *sru_pdu_res,
76 Z_SRW_searchRetrieveRequest const *sr_req) const;
78 bool z3950_present_request(
81 Z_SRW_PDU *sru_pdu_res,
82 Z_SRW_searchRetrieveRequest const *sr_req) const;
84 bool z3950_scan_request(mp::Package &package,
86 Z_SRW_PDU *sru_pdu_res,
90 bool z3950_to_srw_diagnostics_ok(mp::odr &odr_en,
91 Z_SRW_searchRetrieveResponse *srw_res,
92 Z_Records *records) const;
94 int z3950_to_srw_diag(mp::odr &odr_en,
95 Z_SRW_searchRetrieveResponse *srw_res,
96 Z_DefaultDiagFormat *ddf) const;
101 yf::SRUtoZ3950::SRUtoZ3950() : m_p(new Impl)
105 yf::SRUtoZ3950::~SRUtoZ3950()
106 { // must have a destructor because of boost::scoped_ptr
109 void yf::SRUtoZ3950::configure(const xmlNode *xmlnode)
111 m_p->configure(xmlnode);
114 void yf::SRUtoZ3950::process(mp::Package &package) const
116 m_p->process(package);
119 void yf::SRUtoZ3950::Impl::configure(const xmlNode *confignode)
121 const xmlNode * dbnode;
123 for (dbnode = confignode->children; dbnode; dbnode = dbnode->next){
124 if (dbnode->type != XML_ELEMENT_NODE)
127 std::string database;
128 mp::xml::check_element_mp(dbnode, "database");
130 for (struct _xmlAttr *attr = dbnode->properties;
131 attr; attr = attr->next){
133 mp::xml::check_attribute(attr, "", "name");
134 database = mp::xml::get_text(attr);
136 const xmlNode *explainnode;
137 for (explainnode = dbnode->children;
138 explainnode; explainnode = explainnode->next){
139 if (explainnode->type != XML_ELEMENT_NODE)
144 // assigning explain node to database name - no check yet
145 m_database_explain.insert(std::make_pair(database, explainnode));
150 void yf::SRUtoZ3950::Impl::process(mp::Package &package)
152 Z_GDU *zgdu_req = package.request().get();
154 // ignoring all non HTTP_Request packages
155 if (!zgdu_req || !(zgdu_req->which == Z_GDU_HTTP_Request)){
160 // only working on HTTP_Request packages now
164 mp::odr odr_de(ODR_DECODE);
165 Z_SRW_PDU *sru_pdu_req = 0;
167 mp::odr odr_en(ODR_ENCODE);
168 Z_SRW_PDU *sru_pdu_res = yaz_srw_get(odr_en, Z_SRW_explain_response);
170 // determine database with the HTTP header information only
171 mp_util::SRUServerInfo sruinfo = mp_util::get_sru_server_info(package);
172 std::map<std::string, const xmlNode *>::iterator idbexp;
173 idbexp = m_database_explain.find(sruinfo.database);
175 // assign explain config XML DOM node if database is known
176 const xmlNode *explainnode = 0;
177 if (idbexp != m_database_explain.end()){
178 explainnode = idbexp->second;
180 // just moving package if database is not known
187 // decode SRU request
190 char *stylesheet = 0;
192 // filter acts as sink for non-valid SRU requests
193 if (! (sru_pdu_req = mp_util::decode_sru_request(package, odr_de, odr_en,
195 charset, stylesheet)))
199 mp_util::build_sru_explain(package, odr_en, sru_pdu_res,
200 sruinfo, explainnode);
201 mp_util::build_sru_response(package, odr_en, soap,
202 sru_pdu_res, charset, stylesheet);
206 metaproxy_1::odr odr;
208 odr.create_HTTP_Response(package.session(),
209 zgdu_req->u.HTTP_Request, 400);
210 package.response() = zgdu_res;
215 // filter acts as sink for SRU explain requests
216 if (sru_pdu_req && sru_pdu_req->which == Z_SRW_explain_request)
218 Z_SRW_explainRequest *er_req = sru_pdu_req->u.explain_request;
219 //mp_util::build_simple_explain(package, odr_en, sru_pdu_res,
221 mp_util::build_sru_explain(package, odr_en, sru_pdu_res,
222 sruinfo, explainnode, er_req);
225 && sru_pdu_req->which == Z_SRW_searchRetrieve_request
226 && sru_pdu_req->u.request)
228 Z_SRW_searchRetrieveRequest *sr_req = sru_pdu_req->u.request;
230 sru_pdu_res = yaz_srw_get(odr_en, Z_SRW_searchRetrieve_response);
232 // checking that we have a query
233 ok = mp_util::check_sru_query_exists(package, odr_en,
234 sru_pdu_res, sr_req);
236 if (ok && z3950_init_request(package, odr_en, sru_pdu_req, sru_pdu_res))
239 ok = z3950_search_request(package, odr_en,
240 sru_pdu_res, sr_req);
243 && sru_pdu_res->u.response->numberOfRecords
244 && *(sru_pdu_res->u.response->numberOfRecords)
245 && sr_req->maximumRecords
246 && *(sr_req->maximumRecords))
248 ok = z3950_present_request(package, odr_en,
251 z3950_close_request(package);
258 && sru_pdu_req->which == Z_SRW_scan_request
259 && sru_pdu_req->u.scan_request)
261 Z_SRW_scanRequest *sr_req = sru_pdu_req->u.scan_request;
263 sru_pdu_res = yaz_srw_get(odr_en, Z_SRW_scan_response);
265 // we do not do scan at the moment, therefore issuing a diagnostic
266 yaz_add_srw_diagnostic(odr_en,
267 &(sru_pdu_res->u.scan_response->diagnostics),
268 &(sru_pdu_res->u.scan_response->num_diagnostics),
271 // to be used when we do scan
272 if (false && z3950_init_request(package, odr_en, sru_pdu_req,
275 z3950_scan_request(package, odr_en, sru_pdu_res, sr_req);
276 z3950_close_request(package);
281 //std::cout << "SRU OPERATION NOT SUPPORTED \n";
282 sru_pdu_res = yaz_srw_get(odr_en, Z_SRW_explain_response);
284 // TODO: make nice diagnostic return package
288 // build and send SRU response
289 mp_util::build_sru_response(package, odr_en, soap,
290 sru_pdu_res, charset, stylesheet);
296 yf::SRUtoZ3950::Impl::z3950_init_request(mp::Package &package,
298 Z_SRW_PDU *sru_pdu_req,
299 Z_SRW_PDU *sru_pdu_res) const
301 // prepare Z3950 package
302 Package z3950_package(package.session(), package.origin());
303 z3950_package.copy_filter(package);
305 // set initRequest APDU
306 Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_initRequest);
307 Z_InitRequest *init_req = apdu->u.initRequest;
308 //TODO: add user name in apdu
309 //TODO: add user passwd in apdu
310 //init_req->idAuthentication = org_init->idAuthentication;
311 //init_req->implementationId = "IDxyz";
312 //init_req->implementationName = "NAMExyz";
313 //init_req->implementationVersion = "VERSIONxyz";
315 ODR_MASK_SET(init_req->options, Z_Options_search);
316 ODR_MASK_SET(init_req->options, Z_Options_present);
317 ODR_MASK_SET(init_req->options, Z_Options_namedResultSets);
318 ODR_MASK_SET(init_req->options, Z_Options_scan);
320 ODR_MASK_SET(init_req->protocolVersion, Z_ProtocolVersion_1);
321 ODR_MASK_SET(init_req->protocolVersion, Z_ProtocolVersion_2);
322 ODR_MASK_SET(init_req->protocolVersion, Z_ProtocolVersion_3);
324 Z_SRW_extra_arg *arg;
325 for ( arg = sru_pdu_req->extra_args; arg; arg = arg->next)
326 if (!strcmp(arg->name, "x-target"))
328 std::string target(arg->value);
329 mp_util::set_vhost_otherinfo(&init_req->otherInfo,
334 z3950_package.request() = apdu;
336 // send Z3950 package
337 z3950_package.move();
339 // dead Z3950 backend detection
340 if (z3950_package.session().is_closed()){
341 yaz_add_srw_diagnostic(odr_en,
342 &(sru_pdu_res->u.response->diagnostics),
343 &(sru_pdu_res->u.response->num_diagnostics),
348 // check successful initResponse
349 Z_GDU *z3950_gdu = z3950_package.response().get();
351 if (z3950_gdu && z3950_gdu->which == Z_GDU_Z3950
352 && z3950_gdu->u.z3950->which == Z_APDU_initResponse
353 && *z3950_gdu->u.z3950->u.initResponse->result)
356 yaz_add_srw_diagnostic(odr_en,
357 &(sru_pdu_res->u.response->diagnostics),
358 &(sru_pdu_res->u.response->num_diagnostics),
364 yf::SRUtoZ3950::Impl::z3950_close_request(mp::Package &package) const
366 // prepare and close Z3950 package
367 Package z3950_package(package.session(), package.origin());
368 z3950_package.copy_filter(package);
369 z3950_package.session().close();
372 //mp::odr odr_en(ODR_ENCODE);
373 //Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_close);
374 //z3950_package.request() = apdu;
376 z3950_package.move();
378 // check successful close response
379 //Z_GDU *z3950_gdu = z3950_package.response().get();
380 //if (z3950_gdu && z3950_gdu->which == Z_GDU_Z3950
381 // && z3950_gdu->u.z3950->which == Z_APDU_close)
384 if (z3950_package.session().is_closed()){
390 bool yf::SRUtoZ3950::Impl::z3950_search_request(mp::Package &package,
392 Z_SRW_PDU *sru_pdu_res,
393 Z_SRW_searchRetrieveRequest
397 assert(sru_pdu_res->u.response);
399 Package z3950_package(package.session(), package.origin());
400 z3950_package.copy_filter(package);
402 //add stuff in z3950 apdu
403 Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_searchRequest);
404 Z_SearchRequest *z_searchRequest = apdu->u.searchRequest;
407 z_searchRequest->num_databaseNames = 1;
408 z_searchRequest->databaseNames = (char**)
409 odr_malloc(odr_en, sizeof(char *));
411 if (sr_req->database)
412 z_searchRequest->databaseNames[0]
413 = odr_strdup(odr_en, const_cast<char *>(sr_req->database));
415 z_searchRequest->databaseNames[0]
416 = odr_strdup(odr_en, "Default");
420 Z_Query *z_query = (Z_Query *) odr_malloc(odr_en, sizeof(Z_Query));
421 z_searchRequest->query = z_query;
423 if (!z3950_build_query(odr_en, z_query,
424 (const SRW_query&)sr_req->query,
427 yaz_add_srw_diagnostic(odr_en,
428 &(sru_pdu_res->u.response->diagnostics),
429 &(sru_pdu_res->u.response->num_diagnostics),
434 z3950_package.request() = apdu;
436 // send Z39.50 package off to backend
437 z3950_package.move();
440 Z_GDU *z3950_gdu = z3950_package.response().get();
442 //TODO: check success condition
443 //int yaz_diag_bib1_to_srw (int bib1_code);
444 //int yaz_diag_srw_to_bib1(int srw_code);
445 //Se kode i src/seshigh.c (srw_bend_search, srw_bend_init).
447 if (!z3950_gdu || z3950_gdu->which != Z_GDU_Z3950
448 || z3950_gdu->u.z3950->which != Z_APDU_searchResponse
449 || !z3950_gdu->u.z3950->u.searchResponse
450 || !z3950_gdu->u.z3950->u.searchResponse->searchStatus)
452 yaz_add_srw_diagnostic(odr_en,
453 &(sru_pdu_res->u.response->diagnostics),
454 &(sru_pdu_res->u.response->num_diagnostics),
459 // everything fine, continuing
460 Z_SearchResponse *sr = z3950_gdu->u.z3950->u.searchResponse;
462 // checking non surrogate diagnostics in Z3950 search response package
463 if (!z3950_to_srw_diagnostics_ok(odr_en, sru_pdu_res->u.response,
469 // Finally, roll on and srw'fy number of records
470 sru_pdu_res->u.response->numberOfRecords
471 = (int *) odr_malloc(odr_en, sizeof(int *));
472 *(sru_pdu_res->u.response->numberOfRecords) = *(sr->resultCount);
474 // srw'fy nextRecordPosition
475 //sru_pdu_res->u.response->nextRecordPosition
476 // = (int *) odr_malloc(odr_en, sizeof(int *));
477 //*(sru_pdu_res->u.response->nextRecordPosition) = 1;
483 yf::SRUtoZ3950::Impl::z3950_present_request(mp::Package &package,
485 Z_SRW_PDU *sru_pdu_res,
486 Z_SRW_searchRetrieveRequest
490 assert(sru_pdu_res->u.response);
496 // no need to work if nobody wants record ..
497 if (!(sr_req->maximumRecords) || 0 == *(sr_req->maximumRecords))
500 bool send_z3950_present = true;
502 // recordXPath unsupported.
503 if (sr_req->recordXPath)
505 send_z3950_present = false;
506 yaz_add_srw_diagnostic(odr_en,
507 &(sru_pdu_res->u.response->diagnostics),
508 &(sru_pdu_res->u.response->num_diagnostics),
512 // resultSetTTL unsupported.
513 // resultSetIdleTime in response
514 if (sr_req->resultSetTTL)
516 send_z3950_present = false;
517 yaz_add_srw_diagnostic(odr_en,
518 &(sru_pdu_res->u.response->diagnostics),
519 &(sru_pdu_res->u.response->num_diagnostics),
524 if (sr_req->sort_type != Z_SRW_sort_type_none)
526 send_z3950_present = false;
527 yaz_add_srw_diagnostic(odr_en,
528 &(sru_pdu_res->u.response->diagnostics),
529 &(sru_pdu_res->u.response->num_diagnostics),
533 // start record requested negative, or larger than number of records
534 if (sr_req->startRecord
536 ((*(sr_req->startRecord) < 0) // negative
538 (sru_pdu_res->u.response->numberOfRecords //out of range
539 && *(sr_req->startRecord)
540 > *(sru_pdu_res->u.response->numberOfRecords))
543 send_z3950_present = false;
544 yaz_add_srw_diagnostic(odr_en,
545 &(sru_pdu_res->u.response->diagnostics),
546 &(sru_pdu_res->u.response->num_diagnostics),
550 // maximumRecords requested negative
551 if (sr_req->maximumRecords
552 && *(sr_req->maximumRecords) < 0)
555 send_z3950_present = false;
556 yaz_add_srw_diagnostic(odr_en,
557 &(sru_pdu_res->u.response->diagnostics),
558 &(sru_pdu_res->u.response->num_diagnostics),
559 6, "maximumRecords");
562 // exit on all these above diagnostics
563 if (!send_z3950_present)
566 // now packaging the z3950 present request
567 Package z3950_package(package.session(), package.origin());
568 z3950_package.copy_filter(package);
569 Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_presentRequest);
571 assert(apdu->u.presentRequest);
573 // z3950'fy start record position
574 if (sr_req->startRecord)
575 *(apdu->u.presentRequest->resultSetStartPoint)
576 = *(sr_req->startRecord);
578 *(apdu->u.presentRequest->resultSetStartPoint) = 1;
580 // z3950'fy number of records requested
581 // protect against requesting records out of range
582 if (sr_req->maximumRecords)
583 *(apdu->u.presentRequest->numberOfRecordsRequested)
584 = std::min(*(sr_req->maximumRecords),
585 *(sru_pdu_res->u.response->numberOfRecords)
586 - *(apdu->u.presentRequest->resultSetStartPoint)
589 // z3950'fy recordPacking
590 int record_packing = Z_SRW_recordPacking_XML;
591 if (sr_req->recordPacking && 's' == *(sr_req->recordPacking))
592 record_packing = Z_SRW_recordPacking_string;
594 // RecordSyntax will always be XML
595 apdu->u.presentRequest->preferredRecordSyntax
596 = odr_oiddup(odr_en, yaz_oid_recsyn_xml);
598 // z3950'fy record schema
599 if (sr_req->recordSchema)
601 apdu->u.presentRequest->recordComposition
602 = (Z_RecordComposition *)
603 odr_malloc(odr_en, sizeof(Z_RecordComposition));
604 apdu->u.presentRequest->recordComposition->which
605 = Z_RecordComp_simple;
606 apdu->u.presentRequest->recordComposition->u.simple
607 = mp_util::build_esn_from_schema(odr_en,
608 (const char *) sr_req->recordSchema);
611 // z3950'fy time to live - flagged as diagnostics above
612 //if (sr_req->resultSetTTL)
614 // attaching Z3950 package to filter chain
615 z3950_package.request() = apdu;
617 // sending Z30.50 present request
618 z3950_package.move();
620 //check successful Z3950 present response
621 Z_GDU *z3950_gdu = z3950_package.response().get();
622 if (!z3950_gdu || z3950_gdu->which != Z_GDU_Z3950
623 || z3950_gdu->u.z3950->which != Z_APDU_presentResponse
624 || !z3950_gdu->u.z3950->u.presentResponse)
627 yaz_add_srw_diagnostic(odr_en,
628 &(sru_pdu_res->u.response->diagnostics),
629 &(sru_pdu_res->u.response->num_diagnostics),
635 // everything fine, continuing
637 Z_PresentResponse *pr = z3950_gdu->u.z3950->u.presentResponse;
638 Z_SRW_searchRetrieveResponse *sru_res = sru_pdu_res->u.response;
641 // checking non surrogate diagnostics in Z3950 present response package
642 if (!z3950_to_srw_diagnostics_ok(odr_en, sru_pdu_res->u.response,
648 // copy all records if existing
649 if (pr->records && pr->records->which == Z_Records_DBOSD)
651 // srw'fy number of returned records
653 = pr->records->u.databaseOrSurDiagnostics->num_records;
656 = (Z_SRW_record *) odr_malloc(odr_en,
658 * sizeof(Z_SRW_record));
661 // srw'fy nextRecordPosition
662 // next position never zero or behind the last z3950 record
663 if (pr->nextResultSetPosition
664 && *(pr->nextResultSetPosition) > 0
665 && *(pr->nextResultSetPosition)
666 <= *(sru_pdu_res->u.response->numberOfRecords))
667 sru_res->nextRecordPosition
668 = odr_intdup(odr_en, *(pr->nextResultSetPosition));
670 // inserting all records
671 for (int i = 0; i < sru_res->num_records; i++)
673 Z_NamePlusRecord *npr
674 = pr->records->u.databaseOrSurDiagnostics->records[i];
676 sru_res->records[i].recordPosition
678 i + *(apdu->u.presentRequest->resultSetStartPoint));
680 sru_res->records[i].recordPacking = record_packing;
682 if (npr->which != Z_NamePlusRecord_databaseRecord)
684 sru_res->records[i].recordSchema = "diagnostic";
685 sru_res->records[i].recordData_buf = "67";
686 sru_res->records[i].recordData_len = 2;
690 Z_External *r = npr->u.databaseRecord;
691 if (r->direct_reference
692 && !oid_oidcmp(r->direct_reference, yaz_oid_recsyn_xml))
694 sru_res->records[i].recordSchema = "dc";
695 sru_res->records[i].recordData_buf
696 = odr_strdupn(odr_en,
697 (const char *)r->u.octet_aligned->buf,
698 r->u.octet_aligned->len);
699 sru_res->records[i].recordData_len
700 = r->u.octet_aligned->len;
704 sru_res->records[i].recordSchema = "diagnostic";
705 sru_res->records[i].recordData_buf = "67";
706 sru_res->records[i].recordData_len = 2;
716 yf::SRUtoZ3950::Impl::z3950_scan_request(mp::Package &package,
718 Z_SRW_PDU *sru_pdu_res,
719 Z_SRW_scanRequest const *sr_req) const
721 assert(sru_pdu_res->u.scan_response);
723 Package z3950_package(package.session(), package.origin());
724 z3950_package.copy_filter(package);
725 //mp::odr odr_en(ODR_ENCODE);
726 Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_scanRequest);
728 //TODO: add stuff in apdu
729 Z_ScanRequest *z_scanRequest = apdu->u.scanRequest;
731 // database repackaging
732 z_scanRequest->num_databaseNames = 1;
733 z_scanRequest->databaseNames = (char**)
734 odr_malloc(odr_en, sizeof(char *));
735 if (sr_req->database)
736 z_scanRequest->databaseNames[0]
737 = odr_strdup(odr_en, const_cast<char *>(sr_req->database));
739 z_scanRequest->databaseNames[0]
740 = odr_strdup(odr_en, "Default");
744 // CQL or XCQL scan is not possible in Z3950, flagging a diagnostic
745 if (sr_req->query_type != Z_SRW_query_type_pqf)
747 //send_to_srw_client_error(7, "query");
751 // PQF query repackaging
752 // need to use Z_AttributesPlusTerm structure, not Z_Query
753 // this can be digget out of a
754 // Z_query->type1(Z_RPNQuery)->RPNStructure(Z_RPNStructure)
755 // ->u.simple(Z_Operand)->u.attributesPlusTerm(Z_AttributesPlusTerm )
757 //Z_Query *z_query = (Z_Query *) odr_malloc(odr_en, sizeof(Z_Query));
758 //z_searchRequest->query = z_query;
760 //if (!z3950_build_query(odr_en, z_query,
761 // (const SRW_query&)sr_req->query,
762 // sr_req->query_type))
764 //send_to_srw_client_error(7, "query");
770 z3950_package.request() = apdu;
771 std::cout << "z3950_scan_request " << *apdu << "\n";
773 z3950_package.move();
774 //TODO: check success condition
779 bool yf::SRUtoZ3950::Impl::z3950_build_query(mp::odr &odr_en, Z_Query *z_query,
780 const SRW_query &query,
781 SRW_query_type query_type) const
783 if (query_type == Z_SRW_query_type_cql)
785 Z_External *ext = (Z_External *)
786 odr_malloc(odr_en, sizeof(*ext));
787 ext->direct_reference =
788 odr_getoidbystr(odr_en, "1.2.840.10003.16.2");
789 ext->indirect_reference = 0;
791 ext->which = Z_External_CQL;
792 ext->u.cql = const_cast<char *>(query.cql);
794 z_query->which = Z_Query_type_104;
795 z_query->u.type_104 = ext;
799 if (query_type == Z_SRW_query_type_pqf)
801 Z_RPNQuery *RPNquery;
802 YAZ_PQF_Parser pqf_parser;
804 pqf_parser = yaz_pqf_create ();
806 RPNquery = yaz_pqf_parse (pqf_parser, odr_en, query.pqf);
809 std::cout << "TODO: Handeling of bad PQF\n";
810 std::cout << "TODO: Diagnostic to be send\n";
812 z_query->which = Z_Query_type_1;
813 z_query->u.type_1 = RPNquery;
815 yaz_pqf_destroy(pqf_parser);
823 yf::SRUtoZ3950::Impl::z3950_to_srw_diagnostics_ok(mp::odr &odr_en,
824 Z_SRW_searchRetrieveResponse
826 Z_Records *records) const
828 // checking non surrogate diagnostics in Z3950 present response package
830 && records->which == Z_Records_NSD
831 && records->u.nonSurrogateDiagnostic)
833 z3950_to_srw_diag(odr_en, sru_res,
834 records->u.nonSurrogateDiagnostic);
842 yf::SRUtoZ3950::Impl::z3950_to_srw_diag(mp::odr &odr_en,
843 Z_SRW_searchRetrieveResponse *sru_res,
844 Z_DefaultDiagFormat *ddf) const
846 int bib1_code = *ddf->condition;
847 sru_res->num_diagnostics = 1;
848 sru_res->diagnostics = (Z_SRW_diagnostic *)
849 odr_malloc(odr_en, sizeof(*sru_res->diagnostics));
850 yaz_mk_std_diagnostic(odr_en, sru_res->diagnostics,
851 yaz_diag_bib1_to_srw(bib1_code),
858 static mp::filter::Base* filter_creator()
860 return new mp::filter::SRUtoZ3950;
864 struct metaproxy_1_filter_struct metaproxy_1_filter_sru_to_z3950 = {
875 * indent-tabs-mode: nil
876 * c-file-style: "stroustrup"
878 * vim: shiftwidth=4 tabstop=8 expandtab