+ if (records && records->which == Z_Records_DBOSD && start_pos == 1)
+ {
+ std::list<RecordListPtr>::const_iterator it = s->record_lists.begin();
+
+ for (; it != s->record_lists.end(); it++)
+ if ((*it)->cmp(syntax))
+ return;
+
+ Z_NamePlusRecordList *nprl = records->u.databaseOrSurDiagnostics;
+ int i; // i is number of records fetched in last response
+
+ int pos = 1;
+ RecordListPtr rlp(new RecordList(syntax,
+ m_p->m_namespaces.c_str(),
+ m_p->m_xpath_expr.c_str(),
+ m_p->m_debug));
+ for (i = 0; i < nprl->num_records; i++, pos++)
+ rlp->add(nprl->records[i]);
+
+ int end_pos = m_p->m_prefetch;
+ if (end_pos > s->hit_count)
+ end_pos = s->hit_count;
+ while (i && pos <= end_pos)
+ {
+ mp::odr odr;
+ i = 0;
+
+ Package present_package(package.session(), package.origin());
+ present_package.copy_filter(package);
+
+ Z_APDU *p_apdu = zget_APDU(odr, Z_APDU_presentRequest);
+ Z_PresentRequest *p_req = p_apdu->u.presentRequest;
+
+ *p_req->resultSetStartPoint = pos;
+ *p_req->numberOfRecordsRequested = end_pos - pos + 1;
+ p_req->preferredRecordSyntax = syntax;
+ p_req->resultSetId = odr_strdup(odr, resultSetId);
+
+ present_package.request() = p_apdu;
+ present_package.move();
+
+ Z_GDU *gdu_res = present_package.response().get();
+ if (gdu_res && gdu_res->which == Z_GDU_Z3950 &&
+ gdu_res->u.z3950->which == Z_APDU_presentResponse)
+ {
+ Z_PresentResponse *res = gdu_res->u.z3950->u.presentResponse;
+ Z_Records *records = res->records;
+ if (records && records->which == Z_Records_DBOSD)
+ {
+ Z_NamePlusRecordList *nprl =
+ records->u.databaseOrSurDiagnostics;
+ for (i = 0; i < nprl->num_records; i++, pos++)
+ rlp->add(nprl->records[i]);
+ }
+ }
+ }
+ s->record_lists.push_back(rlp);
+ rlp->sort();
+
+ for (i = 0; i < nprl->num_records; i++)
+ nprl->records[i] = rlp->get(i, m_p->m_ascending);
+ }
+}
+
+void yf::Sort::Frontend::handle_search(mp::Package &package, Z_APDU *apdu_req)
+{
+ Z_SearchRequest *req = apdu_req->u.searchRequest;
+ std::string resultSetId = req->resultSetName;
+ Package b_package(package.session(), package.origin());
+ mp::odr odr;
+ Odr_oid *syntax = 0;
+
+ if (req->preferredRecordSyntax)
+ syntax = odr_oiddup(odr, req->preferredRecordSyntax);
+
+ b_package.copy_filter(package);
+ Sets_it sets_it = m_sets.find(req->resultSetName);
+ if (sets_it != m_sets.end())
+ {
+ // result set already exist
+ // if replace indicator is off: we return diagnostic if
+ // result set already exist.
+ if (*req->replaceIndicator == 0)
+ {
+ Z_APDU *apdu =
+ odr.create_searchResponse(
+ apdu_req,
+ YAZ_BIB1_RESULT_SET_EXISTS_AND_REPLACE_INDICATOR_OFF,
+ 0);
+ package.response() = apdu;
+ return;
+ }
+ m_sets.erase(resultSetId);
+ }
+ ResultSetPtr s(new ResultSet);
+ m_sets[resultSetId] = s;
+ package.move();
+ Z_GDU *gdu_res = package.response().get();
+ if (gdu_res && gdu_res->which == Z_GDU_Z3950 && gdu_res->u.z3950->which ==
+ Z_APDU_searchResponse)
+ {
+ Z_SearchResponse *res = gdu_res->u.z3950->u.searchResponse;
+ s->hit_count = *res->resultCount;
+ handle_records(b_package, apdu_req, res->records, 1, s,
+ syntax, resultSetId.c_str());
+ package.response() = gdu_res;
+ }
+}
+
+void yf::Sort::Frontend::handle_present(mp::Package &package, Z_APDU *apdu_req)
+{
+ Z_PresentRequest *req = apdu_req->u.presentRequest;
+ std::string resultSetId = req->resultSetId;
+ Package b_package(package.session(), package.origin());
+ mp::odr odr;
+ Odr_oid *syntax = 0;
+ Odr_int start = *req->resultSetStartPoint;
+
+ if (req->preferredRecordSyntax)
+ syntax = odr_oiddup(odr, req->preferredRecordSyntax);
+
+ b_package.copy_filter(package);
+ Sets_it sets_it = m_sets.find(resultSetId);
+ if (sets_it == m_sets.end())
+ {
+ Z_APDU *apdu =
+ odr.create_presentResponse(
+ apdu_req,
+ YAZ_BIB1_SPECIFIED_RESULT_SET_DOES_NOT_EXIST,
+ resultSetId.c_str());
+ package.response() = apdu;
+ return;
+ }
+ ResultSetPtr rset = sets_it->second;
+ std::list<RecordListPtr>::const_iterator it = rset->record_lists.begin();
+ for (; it != rset->record_lists.end(); it++)
+ if ((*it)->cmp(req->preferredRecordSyntax))
+ {
+ if (*req->resultSetStartPoint - 1 + *req->numberOfRecordsRequested
+ <= (*it)->size())
+ {
+ int i;
+ Z_APDU *p_apdu = zget_APDU(odr, Z_APDU_presentResponse);
+ Z_PresentResponse *p_res = p_apdu->u.presentResponse;
+
+ *p_res->nextResultSetPosition = *req->resultSetStartPoint +
+ *req->numberOfRecordsRequested;
+ *p_res->numberOfRecordsReturned =
+ *req->numberOfRecordsRequested;
+ p_res->records = (Z_Records *)
+ odr_malloc(odr, sizeof(*p_res->records));
+ p_res->records->which = Z_Records_DBOSD;
+ Z_NamePlusRecordList *nprl = (Z_NamePlusRecordList *)
+ odr_malloc(odr, sizeof(*nprl));
+ p_res->records->u.databaseOrSurDiagnostics = nprl;
+ nprl->num_records = *req->numberOfRecordsRequested;
+ nprl->records = (Z_NamePlusRecord **)
+ odr_malloc(odr, nprl->num_records * sizeof(*nprl->records));
+ for (i = 0; i < nprl->num_records; i++)
+ {
+ int pos = i + *req->resultSetStartPoint - 1;
+ nprl->records[i] = (*it)->get(pos, m_p->m_ascending);
+ }
+ package.response() = p_apdu;
+ return;
+ }
+ break;
+ }
+ package.move();
+ Z_GDU *gdu_res = package.response().get();
+ if (gdu_res && gdu_res->which == Z_GDU_Z3950 && gdu_res->u.z3950->which ==
+ Z_APDU_presentResponse)
+ {
+ Z_PresentResponse *res = gdu_res->u.z3950->u.presentResponse;
+ handle_records(b_package, apdu_req, res->records,
+ start, rset, syntax, resultSetId.c_str());
+ package.response() = gdu_res;
+ }
+}
+
+void yf::Sort::Frontend::handle_package(mp::Package &package)
+{
+ Z_GDU *gdu = package.request().get();
+ if (gdu && gdu->which == Z_GDU_Z3950)
+ {
+ Z_APDU *apdu_req = gdu->u.z3950;
+ switch (apdu_req->which)
+ {
+ case Z_APDU_searchRequest:
+ handle_search(package, apdu_req);
+ return;
+ case Z_APDU_presentRequest:
+ handle_present(package, apdu_req);
+ return;
+ }
+ }