X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Ffilter_backend_test.cpp;h=da2f4f5397ba27c82a371f669b04c66c33ba0767;hb=b70b9ec78f0ab1c3ed3b432de986159129a0e4ed;hp=d8e9cdbea0f2f83af6007bd254f5c1b8af916b69;hpb=b3a5a3535ff97f71581c9b496f95e0820120f743;p=metaproxy-moved-to-github.git diff --git a/src/filter_backend_test.cpp b/src/filter_backend_test.cpp index d8e9cdb..da2f4f5 100644 --- a/src/filter_backend_test.cpp +++ b/src/filter_backend_test.cpp @@ -1,39 +1,46 @@ -/* $Id: filter_backend_test.cpp,v 1.4 2005-10-25 21:32:01 adam Exp $ - Copyright (c) 2005, Index Data. +/* $Id: filter_backend_test.cpp,v 1.22 2007-01-25 14:05:54 adam Exp $ + Copyright (c) 2005-2007, Index Data. -%LICENSE% + See the LICENSE file for details */ #include "config.hpp" #include "filter.hpp" -#include "router.hpp" #include "package.hpp" +#include "util.hpp" +#include "filter_backend_test.hpp" -#include +#include +#include +#include +#include -#include "filter_backend_test.hpp" +#include #include #include #include #include -#include -#include -#include - -namespace yf = yp2::filter; +namespace mp = metaproxy_1; +namespace yf = mp::filter; +using namespace mp; -namespace yp2 { +namespace metaproxy_1 { namespace filter { class Session_info { int dummy; }; - class Backend_test::Rep { - friend class Backend_test; - - private: + class BackendTest::Rep { + friend class BackendTest; + + Z_Records *fetch( + ODR odr, Odr_oid *preferredRecordSyntax, + Z_ElementSetNames *esn, + int start, int number, int &error_code, std::string &addinfo, + int *number_returned, int *next_position); + bool m_support_named_result_sets; session_map m_sessions; @@ -41,16 +48,123 @@ namespace yp2 { } } -yf::Backend_test::Backend_test() { - m_p = new Backend_test::Rep; + +static const int result_set_size = 42; + +// an ISO2709 USMARC/MARC21 record that we return.. +static const char *marc_record = + "\x30\x30\x33\x36\x36\x6E\x61\x6D\x20\x20\x32\x32\x30\x30\x31\x36" + "\x39\x38\x61\x20\x34\x35\x30\x30\x30\x30\x31\x30\x30\x31\x33\x30" + "\x30\x30\x30\x30\x30\x30\x33\x30\x30\x30\x34\x30\x30\x30\x31\x33" + "\x30\x30\x35\x30\x30\x31\x37\x30\x30\x30\x31\x37\x30\x30\x38\x30" + "\x30\x34\x31\x30\x30\x30\x33\x34\x30\x31\x30\x30\x30\x31\x37\x30" + "\x30\x31\x37\x39\x30\x34\x30\x30\x30\x31\x33\x30\x30\x30\x37\x35" + "\x30\x35\x30\x30\x30\x31\x32\x30\x30\x30\x38\x38\x31\x30\x30\x30" + "\x30\x31\x37\x30\x30\x31\x30\x30\x32\x34\x35\x30\x30\x33\x30\x30" + "\x30\x31\x31\x37\x32\x36\x30\x30\x30\x31\x32\x30\x30\x31\x34\x37" + "\x32\x36\x33\x30\x30\x30\x39\x30\x30\x31\x35\x39\x33\x30\x30\x30" + "\x30\x31\x31\x30\x30\x31\x36\x38\x1E\x20\x20\x20\x31\x31\x32\x32" + "\x34\x34\x36\x36\x20\x1E\x44\x4C\x43\x1E\x30\x30\x30\x30\x30\x30" + "\x30\x30\x30\x30\x30\x30\x30\x30\x2E\x30\x1E\x39\x31\x30\x37\x31" + "\x30\x63\x31\x39\x39\x31\x30\x37\x30\x31\x6E\x6A\x75\x20\x20\x20" + "\x20\x20\x20\x20\x20\x20\x20\x20\x30\x30\x30\x31\x30\x20\x65\x6E" + "\x67\x20\x20\x1E\x20\x20\x1F\x61\x44\x4C\x43\x1F\x63\x44\x4C\x43" + "\x1E\x30\x30\x1F\x61\x31\x32\x33\x2D\x78\x79\x7A\x1E\x31\x30\x1F" + "\x61\x4A\x61\x63\x6B\x20\x43\x6F\x6C\x6C\x69\x6E\x73\x1E\x31\x30" + "\x1F\x61\x48\x6F\x77\x20\x74\x6F\x20\x70\x72\x6F\x67\x72\x61\x6D" + "\x20\x61\x20\x63\x6F\x6D\x70\x75\x74\x65\x72\x1E\x31\x20\x1F\x61" + "\x50\x65\x6E\x67\x75\x69\x6E\x1E\x20\x20\x1F\x61\x38\x37\x31\x30" + "\x1E\x20\x20\x1F\x61\x70\x2E\x20\x63\x6D\x2E\x1E\x20\x20\x1F\x61" + "\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20\x1E\x1D"; + + +yf::BackendTest::BackendTest() : m_p(new BackendTest::Rep) { m_p->m_support_named_result_sets = false; } -yf::Backend_test::~Backend_test() { - delete m_p; +yf::BackendTest::~BackendTest() { } -void yf::Backend_test::process(Package &package) const +Z_Records *yf::BackendTest::Rep::fetch( + ODR odr, Odr_oid *preferredRecordSyntax, + Z_ElementSetNames *esn, + int start, int number, int &error_code, std::string &addinfo, + int *number_returned, int *next_position) +{ + oident *prefformat; + oid_value form; + + if (number + start - 1 > result_set_size || start < 1) + { + error_code = YAZ_BIB1_PRESENT_REQUEST_OUT_OF_RANGE; + return 0; + } + + if (!(prefformat = oid_getentbyoid(preferredRecordSyntax))) + form = VAL_NONE; + else + form = prefformat->value; + switch(form) + { + case VAL_NONE: + case VAL_USMARC: + break; + default: + error_code = YAZ_BIB1_RECORD_SYNTAX_UNSUPP; + return 0; + } + + // no element set, "B" and "F" are supported + if (esn) + { + if (esn->which != Z_ElementSetNames_generic) + { + error_code + = YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_; + return 0; + } + const char *name = esn->u.generic; + if (strcmp(name, "B") && strcmp(name, "F")) + { + error_code + = YAZ_BIB1_SPECIFIED_ELEMENT_SET_NAME_NOT_VALID_FOR_SPECIFIED_; + addinfo = std::string(name); + return 0; + } + } + Z_Records *rec = (Z_Records *) odr_malloc(odr, sizeof(Z_Records)); + rec->which = Z_Records_DBOSD; + rec->u.databaseOrSurDiagnostics = (Z_NamePlusRecordList *) + odr_malloc(odr, sizeof(Z_NamePlusRecordList)); + rec->u.databaseOrSurDiagnostics->num_records = number; + rec->u.databaseOrSurDiagnostics->records = (Z_NamePlusRecord **) + odr_malloc(odr, sizeof(Z_NamePlusRecord *) * number); + int i; + for (i = 0; iu.databaseOrSurDiagnostics->records[i] = (Z_NamePlusRecord *) + odr_malloc(odr, sizeof(Z_NamePlusRecord)); + Z_NamePlusRecord *npr = rec->u.databaseOrSurDiagnostics->records[i]; + npr->databaseName = 0; + npr->which = Z_NamePlusRecord_databaseRecord; + + char *tmp_rec = odr_strdup(odr, marc_record); + char offset_str[30]; + sprintf(offset_str, "test__%09d_", i+start); + memcpy(tmp_rec+186, offset_str, strlen(offset_str)); + npr->u.databaseRecord = z_ext_record(odr, VAL_USMARC, + tmp_rec, strlen(tmp_rec)); + + } + *number_returned = number; + if (start + number > result_set_size) + *next_position = 0; + else + *next_position = start + number; + return rec; +} + +void yf::BackendTest::process(Package &package) const { Z_GDU *gdu = package.request().get(); @@ -60,38 +174,34 @@ void yf::Backend_test::process(Package &package) const { Z_APDU *apdu_req = gdu->u.z3950; Z_APDU *apdu_res = 0; - ODR odr = odr_createmem(ODR_ENCODE); + mp::odr odr; if (apdu_req->which != Z_APDU_initRequest && - !m_p->m_sessions.active(package.session())) + !m_p->m_sessions.exist(package.session())) { - apdu_res = zget_APDU(odr, Z_APDU_close); - *apdu_res->u.close->closeReason = Z_Close_protocolError; - apdu_res->u.close->diagnosticInformation = - odr_strdup(odr, "no init for filter_backend_test"); - + apdu_res = odr.create_close(apdu_req, + Z_Close_protocolError, + "no init for filter_backend_test"); package.session().close(); } else if (apdu_req->which == Z_APDU_initRequest) { - apdu_res = zget_APDU(odr, Z_APDU_initResponse); + apdu_res = odr.create_initResponse(apdu_req, 0, 0); Z_InitRequest *req = apdu_req->u.initRequest; Z_InitResponse *resp = apdu_res->u.initResponse; + + resp->implementationName = "backend_test"; + if (ODR_MASK_GET(req->options, Z_Options_namedResultSets)) + m_p->m_support_named_result_sets = true; int i; static const int masks[] = { - Z_Options_search, Z_Options_present, -1 + Z_Options_search, Z_Options_present, + Z_Options_namedResultSets, -1 }; for (i = 0; masks[i] != -1; i++) if (ODR_MASK_GET(req->options, masks[i])) ODR_MASK_SET(resp->options, masks[i]); - if (m_p->m_support_named_result_sets) - { - if (ODR_MASK_GET(req->options, Z_Options_namedResultSets)) - ODR_MASK_SET(resp->options, Z_Options_namedResultSets); - else - m_p->m_support_named_result_sets = false; - } static const int versions[] = { Z_ProtocolVersion_1, Z_ProtocolVersion_2, @@ -109,45 +219,138 @@ void yf::Backend_test::process(Package &package) const } else if (apdu_req->which == Z_APDU_searchRequest) { - apdu_res = zget_APDU(odr, Z_APDU_searchResponse); Z_SearchRequest *req = apdu_req->u.searchRequest; - Z_SearchResponse *resp = apdu_res->u.searchResponse; if (!m_p->m_support_named_result_sets && strcmp(req->resultSetName, "default")) { - Z_Records *rec = (Z_Records *) - odr_malloc(odr, sizeof(Z_Records)); - resp->records = rec; - rec->which = Z_Records_NSD; - rec->u.nonSurrogateDiagnostic = - zget_DefaultDiagFormat( - odr, YAZ_BIB1_RESULT_SET_NAMING_UNSUPP, 0); + apdu_res = + odr.create_searchResponse( + apdu_req, YAZ_BIB1_RESULT_SET_NAMING_UNSUPP, 0); } else - *resp->resultCount = 42; + { + Z_Records *records = 0; + int number_returned = 0; + int next_position = 0; + int error_code = 0; + std::string addinfo; + + int number = 0; + mp::util::piggyback(*req->smallSetUpperBound, + *req->largeSetLowerBound, + *req->mediumSetPresentNumber, + result_set_size, + number); + + if (number) + { // not a large set for sure + Z_ElementSetNames *esn; + if (number > *req->smallSetUpperBound) + esn = req->mediumSetElementSetNames; + else + esn = req->smallSetElementSetNames; + records = m_p->fetch( + odr, req->preferredRecordSyntax, esn, + 1, number, + error_code, addinfo, + &number_returned, + &next_position); + } + if (error_code) + { + apdu_res = + odr.create_searchResponse( + apdu_req, error_code, addinfo.c_str()); + Z_SearchResponse *resp = apdu_res->u.searchResponse; + *resp->resultCount = result_set_size; + } + else + { + apdu_res = + odr.create_searchResponse(apdu_req, 0, 0); + Z_SearchResponse *resp = apdu_res->u.searchResponse; + *resp->resultCount = result_set_size; + *resp->numberOfRecordsReturned = number_returned; + *resp->nextResultSetPosition = next_position; + resp->records = records; + } + } } else if (apdu_req->which == Z_APDU_presentRequest) { - apdu_res = zget_APDU(odr, Z_APDU_presentResponse); + Z_PresentRequest *req = apdu_req->u.presentRequest; + int number_returned = 0; + int next_position = 0; + int error_code = 0; + std::string addinfo; + Z_ElementSetNames *esn = 0; + + if (req->recordComposition) + { + if (req->recordComposition->which == Z_RecordComp_simple) + esn = req->recordComposition->u.simple; + else + { + apdu_res = + odr.create_presentResponse( + apdu_req, + YAZ_BIB1_ONLY_A_SINGLE_ELEMENT_SET_NAME_SUPPORTED, + 0); + package.response() = apdu_res; + return; + } + } + Z_Records *records = m_p->fetch( + odr, req->preferredRecordSyntax, esn, + *req->resultSetStartPoint, *req->numberOfRecordsRequested, + error_code, addinfo, + &number_returned, + &next_position); + + if (error_code) + { + apdu_res = + odr.create_presentResponse(apdu_req, error_code, + addinfo.c_str()); + } + else + { + apdu_res = + odr.create_presentResponse(apdu_req, 0, 0); + Z_PresentResponse *resp = apdu_res->u.presentResponse; + resp->records = records; + *resp->numberOfRecordsReturned = number_returned; + *resp->nextResultSetPosition = next_position; + } } else { - apdu_res = zget_APDU(odr, Z_APDU_close); - *apdu_res->u.close->closeReason = Z_Close_protocolError; - apdu_res->u.close->diagnosticInformation = - odr_strdup(odr, "bad APDU in filter_backend_test"); - + apdu_res = odr.create_close(apdu_req, + Z_Close_protocolError, + "backend_test: unhandled APDU"); package.session().close(); } if (apdu_res) package.response() = apdu_res; - odr_destroy(odr); } if (package.session().is_closed()) m_p->m_sessions.release(package.session()); } +static mp::filter::Base* filter_creator() +{ + return new mp::filter::BackendTest; +} + +extern "C" { + struct metaproxy_1_filter_struct metaproxy_1_filter_backend_test = { + 0, + "backend_test", + filter_creator + }; +} + /* * Local variables: