+ *f_resp->resultCount = result_set_size;
+ if (z_records_diag)
+ {
+ // search error
+ f_resp->records = z_records_diag;
+ package.response() = f_apdu;
+ return;
+ }
+ // assume OK
+ m_sets[resultSet.m_setname] = resultSet;
+
+ int number;
+ yp2::util::piggyback(smallSetUpperBound,
+ largeSetLowerBound,
+ mediumSetPresentNumber,
+ result_set_size,
+ number);
+ Package pp(package.session(), package.origin());
+ if (number > 0)
+ {
+ pp.copy_filter(package);
+ Z_APDU *p_apdu = zget_APDU(odr, Z_APDU_presentRequest);
+ Z_PresentRequest *p_req = p_apdu->u.presentRequest;
+ p_req->preferredRecordSyntax = req->preferredRecordSyntax;
+ p_req->resultSetId = req->resultSetName;
+ *p_req->resultSetStartPoint = 1;
+ *p_req->numberOfRecordsRequested = number;
+ pp.request() = p_apdu;
+ present(pp, p_apdu);
+
+ if (pp.session().is_closed())
+ package.session().close();
+
+ Z_GDU *gdu = pp.response().get();
+ if (gdu && gdu->which == Z_GDU_Z3950 && gdu->u.z3950->which ==
+ Z_APDU_presentResponse)
+ {
+ Z_PresentResponse *p_res = gdu->u.z3950->u.presentResponse;
+ f_resp->records = p_res->records;
+ *f_resp->numberOfRecordsReturned =
+ *p_res->numberOfRecordsReturned;
+ *f_resp->nextResultSetPosition =
+ *p_res->nextResultSetPosition;
+ }
+ else
+ {
+ package.response() = pp.response();
+ return;
+ }
+ }
+ package.response() = f_apdu; // in this scope because of p
+}
+
+void yf::Multi::Frontend::present(Package &package, Z_APDU *apdu_req)
+{
+ // create present request
+ Z_PresentRequest *req = apdu_req->u.presentRequest;
+
+ Sets_it it;
+ it = m_sets.find(std::string(req->resultSetId));
+ if (it == m_sets.end())
+ {
+ yp2::odr odr;
+ Z_APDU *apdu =
+ odr.create_presentResponse(
+ apdu_req,
+ YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
+ req->resultSetId);
+ package.response() = apdu;
+ return;
+ }
+ std::list<Multi::FrontendSet::PresentJob> jobs;
+ int start = *req->resultSetStartPoint;
+ int number = *req->numberOfRecordsRequested;
+ it->second.round_robin(start, number, jobs);
+
+ std::list<BackendPtr> present_backend_list;
+
+ std::list<BackendSet>::const_iterator bsit;
+ bsit = it->second.m_backend_sets.begin();
+ for (; bsit != it->second.m_backend_sets.end(); bsit++)
+ {
+ std::list<Multi::FrontendSet::PresentJob>::const_iterator jit;
+ int start = -1;
+ int end = -1;
+
+ for (jit = jobs.begin(); jit != jobs.end(); jit++)
+ {
+ if (jit->m_backend == bsit->m_backend)
+ {
+ if (start == -1 || jit->m_pos < start)
+ start = jit->m_pos;
+ if (end == -1 || jit->m_pos > end)
+ end = jit->m_pos;
+ }
+ }
+ if (start != -1)
+ {
+ PackagePtr p = bsit->m_backend->m_package;
+
+ *req->resultSetStartPoint = start;
+ *req->numberOfRecordsRequested = end - start + 1;
+
+ p->request() = apdu_req;
+ p->copy_filter(package);
+
+ present_backend_list.push_back(bsit->m_backend);
+ }
+ }
+ multi_move(present_backend_list);
+
+ // look at each response
+ Z_Records *z_records_diag = 0;
+
+ std::list<BackendPtr>::const_iterator pbit = present_backend_list.begin();
+ for (; pbit != present_backend_list.end(); pbit++)
+ {
+ PackagePtr p = (*pbit)->m_package;
+
+ if (p->session().is_closed()) // if any backend closes, close frontend
+ package.session().close();
+
+ Z_GDU *gdu = p->response().get();
+ if (gdu && gdu->which == Z_GDU_Z3950 && gdu->u.z3950->which ==
+ Z_APDU_presentResponse)
+ {
+ Z_APDU *b_apdu = gdu->u.z3950;
+ Z_PresentResponse *b_resp = b_apdu->u.presentResponse;
+
+ // see we get any errors (AKA diagnstics)
+ if (b_resp->records)
+ {
+ if (b_resp->records->which != Z_Records_DBOSD)
+ z_records_diag = b_resp->records;
+ // we may set this multiple times (TOO BAD!)
+ }
+ }
+ else
+ {
+ // if any target does not return present response - return that
+ package.response() = p->response();
+ return;
+ }
+ }