- return 0;
-}
-
-ZOOM_API(const char *)
- ZOOM_record_get(ZOOM_record rec, const char *type_spec, int *len)
-{
- char type[40];
- char charset[40];
- char xpath[512];
- const char *cp;
- int i;
- Z_NamePlusRecord *npr;
-
- if (len)
- *len = 0; /* default return */
-
- if (!rec)
- return 0;
- npr = rec->npr;
- if (!npr)
- return 0;
-
- cp = type_spec;
- for (i = 0; cp[i] && i < sizeof(type)-1; i++)
- {
- if (cp[i] == ';' || cp[i] == ' ')
- break;
- type[i] = cp[i];
- }
- type[i] = '\0';
- charset[0] = '\0';
- while (type_spec[i] == ';')
- {
- i++;
- while (type_spec[i] == ' ')
- i++;
- if (!strncmp(type_spec+i, "charset=", 8))
- {
- int j = 0;
- i = i + 8; /* skip charset= */
- for (j = 0; type_spec[i] && j < sizeof(charset)-1; i++, j++)
- {
- if (type_spec[i] == ';' || type_spec[i] == ' ')
- break;
- charset[j] = cp[i];
- }
- charset[j] = '\0';
- }
- else if (!strncmp(type_spec+i, "xpath=", 6))
- {
- int j = 0;
- i = i + 6;
- for (j = 0; type_spec[i] && j < sizeof(xpath)-1; i++, j++)
- xpath[j] = cp[i];
- xpath[j] = '\0';
- }
- while (type_spec[i] == ' ')
- i++;
- }
- if (!strcmp(type, "database"))
- {
- if (len)
- *len = (npr->databaseName ? strlen(npr->databaseName) : 0);
- return npr->databaseName;
- }
- else if (!strcmp(type, "syntax"))
- {
- const char *desc = 0;
- if (npr->which == Z_NamePlusRecord_databaseRecord)
- {
- Z_External *r = (Z_External *) npr->u.databaseRecord;
- desc = yaz_oid_to_string(yaz_oid_std(), r->direct_reference, 0);
- }
- if (!desc)
- desc = "none";
- if (len)
- *len = strlen(desc);
- return desc;
- }
- if (npr->which != Z_NamePlusRecord_databaseRecord)
- return 0;
-
- /* from now on - we have a database record .. */
- if (!strcmp(type, "render"))
- {
- Z_External *r = (Z_External *) npr->u.databaseRecord;
- const Odr_oid *oid = r->direct_reference;
-
- /* render bibliographic record .. */
- if (r->which == Z_External_OPAC)
- {
- r = r->u.opac->bibliographicRecord;
- if (!r)
- return 0;
- oid = r->direct_reference;
- }
- if (r->which == Z_External_sutrs)
- return record_iconv_return(rec, len,
- (char*) r->u.sutrs->buf,
- r->u.sutrs->len,
- charset);
- else if (r->which == Z_External_octet)
- {
- if (yaz_oid_is_iso2709(oid))
- {
- const char *ret_buf = marc_iconv_return(
- rec, YAZ_MARC_LINE, len,
- (const char *) r->u.octet_aligned->buf,
- r->u.octet_aligned->len,
- charset);
- if (ret_buf)
- return ret_buf;
- }
- return record_iconv_return(rec, len,
- (const char *) r->u.octet_aligned->buf,
- r->u.octet_aligned->len,
- charset);
- }
- else if (r->which == Z_External_grs1)
- {
- if (!rec->wrbuf_marc)
- rec->wrbuf_marc = wrbuf_alloc();
- wrbuf_rewind(rec->wrbuf_marc);
- yaz_display_grs1(rec->wrbuf_marc, r->u.grs1, 0);
- return record_iconv_return(rec, len,
- wrbuf_buf(rec->wrbuf_marc),
- wrbuf_len(rec->wrbuf_marc),
- charset);
- }
- return 0;
- }
- else if (!strcmp(type, "xml"))
- {
- Z_External *r = (Z_External *) npr->u.databaseRecord;
- const Odr_oid *oid = r->direct_reference;
-
- /* render bibliographic record .. */
- if (r->which == Z_External_OPAC)
- {
- r = r->u.opac->bibliographicRecord;
- if (!r)
- return 0;
- oid = r->direct_reference;
- }
-
- if (r->which == Z_External_sutrs)
- return record_iconv_return(rec, len,
- (const char *) r->u.sutrs->buf,
- r->u.sutrs->len,
- charset);
- else if (r->which == Z_External_octet)
- {
- int marc_decode_type = YAZ_MARC_MARCXML;
- if (yaz_oid_is_iso2709(oid))
- {
- const char *ret_buf = marc_iconv_return(
- rec, marc_decode_type, len,
- (const char *) r->u.octet_aligned->buf,
- r->u.octet_aligned->len,
- charset);
- if (ret_buf)
- return ret_buf;
- }
- return record_iconv_return(rec, len,
- (const char *) r->u.octet_aligned->buf,
- r->u.octet_aligned->len,
- charset);
- }
- else if (r->which == Z_External_grs1)
- {
- if (len) *len = 5;
- return "GRS-1";
- }
- return 0;
- }
- else if (!strcmp(type, "raw"))
- {
- Z_External *r = (Z_External *) npr->u.databaseRecord;
-
- if (r->which == Z_External_sutrs)
- {
- if (len) *len = r->u.sutrs->len;
- return (const char *) r->u.sutrs->buf;
- }
- else if (r->which == Z_External_octet)
- {
- if (len) *len = r->u.octet_aligned->len;
- return (const char *) r->u.octet_aligned->buf;
- }
- else /* grs-1, explain, OPAC, ... */
- {
- if (len) *len = -1;
- return (const char *) npr->u.databaseRecord;
- }
- return 0;
- }
- else if (!strcmp (type, "ext"))
- {
- if (len) *len = -1;
- return (const char *) npr->u.databaseRecord;
- }
- else if (!strcmp (type, "opac"))
-
- {
- Z_External *r = (Z_External *) npr->u.databaseRecord;
- if (r->which == Z_External_OPAC)
- {
- if (!rec->wrbuf_opac)
- rec->wrbuf_opac = wrbuf_alloc();
- wrbuf_rewind(rec->wrbuf_opac);
- yaz_display_OPAC(rec->wrbuf_opac, r->u.opac, 0);
- return record_iconv_return(rec, len,
- wrbuf_buf(rec->wrbuf_opac),
- wrbuf_len(rec->wrbuf_opac),
- charset);
- }
- }
- return 0;
-}
-
-static int strcmp_null(const char *v1, const char *v2)
-{
- if (!v1 && !v2)
- return 0;
- if (!v1 || !v2)
- return -1;
- return strcmp(v1, v2);
-}
-
-static size_t record_hash(int pos)
-{
- if (pos < 0)
- pos = 0;
- return pos % RECORD_HASH_SIZE;
-}
-
-static void record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr,
- int pos,
- const char *syntax, const char *elementSetName)
-{
- ZOOM_record_cache rc;
-
- ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_RECV_RECORD);
- ZOOM_connection_put_event(r->connection, event);
-
- for (rc = r->record_hash[record_hash(pos)]; rc; rc = rc->next)
- {
- if (pos == rc->pos)
- {
- if (strcmp_null(r->schema, rc->schema))
- continue;
- if (strcmp_null(elementSetName,rc->elementSetName))
- continue;
- if (strcmp_null(syntax, rc->syntax))
- continue;
- /* not destroying rc->npr (it's handled by nmem )*/
- rc->rec.npr = npr;
- /* keeping wrbuf_marc too */
- return;
- }
- }
- rc = (ZOOM_record_cache) odr_malloc(r->odr, sizeof(*rc));
- rc->rec.npr = npr;
- rc->rec.odr = 0;
- rc->rec.wrbuf_marc = 0;
- rc->rec.wrbuf_iconv = 0;
- rc->rec.wrbuf_opac = 0;
- if (elementSetName)
- rc->elementSetName = odr_strdup(r->odr, elementSetName);
- else
- rc->elementSetName = 0;
-
- if (syntax)
- rc->syntax = odr_strdup(r->odr, syntax);
- else
- rc->syntax = 0;
-
- if (r->schema)
- rc->schema = odr_strdup(r->odr, r->schema);
- else
- rc->schema = 0;
-
- rc->pos = pos;
- rc->next = r->record_hash[record_hash(pos)];
- r->record_hash[record_hash(pos)] = rc;
-}
-
-static ZOOM_record record_cache_lookup(ZOOM_resultset r, int pos,
- const char *syntax,
- const char *elementSetName)
-{
- ZOOM_record_cache rc;
-
- for (rc = r->record_hash[record_hash(pos)]; rc; rc = rc->next)
- {
- if (pos == rc->pos)
- {
- if (strcmp_null(r->schema, rc->schema))
- continue;
- if (strcmp_null(elementSetName,rc->elementSetName))
- continue;
- if (strcmp_null(syntax, rc->syntax))
- continue;
- return &rc->rec;
- }
- }
- return 0;
-}
-
-static void handle_records(ZOOM_connection c, Z_Records *sr,
- int present_phase)
-{
- ZOOM_resultset resultset;
- int *start, *count;
- const char *syntax = 0, *elementSetName = 0;
-
- if (!c->tasks)
- return ;
- switch (c->tasks->which)
- {
- case ZOOM_TASK_SEARCH:
- resultset = c->tasks->u.search.resultset;
- start = &c->tasks->u.search.start;
- count = &c->tasks->u.search.count;
- syntax = c->tasks->u.search.syntax;
- elementSetName = c->tasks->u.search.elementSetName;
- break;
- case ZOOM_TASK_RETRIEVE:
- resultset = c->tasks->u.retrieve.resultset;
- start = &c->tasks->u.retrieve.start;
- count = &c->tasks->u.retrieve.count;
- syntax = c->tasks->u.retrieve.syntax;
- elementSetName = c->tasks->u.retrieve.elementSetName;
- break;
- default:
- return;
- }
- if (sr && sr->which == Z_Records_NSD)
- response_default_diag(c, sr->u.nonSurrogateDiagnostic);
- else if (sr && sr->which == Z_Records_multipleNSD)
- {
- if (sr->u.multipleNonSurDiagnostics->num_diagRecs >= 1)
- response_diag(c, sr->u.multipleNonSurDiagnostics->diagRecs[0]);
- else
- set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0);
- }
- else
- {
- if (*count + *start > resultset->size)
- *count = resultset->size - *start;
- if (*count < 0)
- *count = 0;
- if (sr && sr->which == Z_Records_DBOSD)
- {
- int i;
- NMEM nmem = odr_extract_mem(c->odr_in);
- Z_NamePlusRecordList *p =
- sr->u.databaseOrSurDiagnostics;
- for (i = 0; i<p->num_records; i++)
- {
- record_cache_add(resultset, p->records[i], i + *start,
- syntax, elementSetName);
- }
- *count -= i;
- if (*count < 0)
- *count = 0;
- *start += i;
- yaz_log(log_details,
- "handle_records resultset=%p start=%d count=%d",
- resultset, *start, *count);
-
- /* transfer our response to search_nmem .. we need it later */
- nmem_transfer(odr_getmem(resultset->odr), nmem);
- nmem_destroy(nmem);
- if (present_phase && p->num_records == 0)
- {
- /* present response and we didn't get any records! */
- Z_NamePlusRecord *myrec =
- zget_surrogateDiagRec(resultset->odr, 0, 14, 0);
- record_cache_add(resultset, myrec, *start,
- syntax, elementSetName);
- }
- }
- else if (present_phase)
- {
- /* present response and we didn't get any records! */
- Z_NamePlusRecord *myrec =
- zget_surrogateDiagRec(resultset->odr, 0, 14, 0);
- record_cache_add(resultset, myrec, *start, syntax, elementSetName);
- }
- }
-}
-
-static void handle_present_response(ZOOM_connection c, Z_PresentResponse *pr)
-{
- handle_records(c, pr->records, 1);
-}
-
-static void handle_queryExpressionTerm(ZOOM_options opt, const char *name,
- Z_Term *term)
-{
- switch (term->which)
- {
- case Z_Term_general:
- ZOOM_options_setl(opt, name,
- (const char *)(term->u.general->buf),
- term->u.general->len);
- break;
- case Z_Term_characterString:
- ZOOM_options_set(opt, name, term->u.characterString);
- break;
- case Z_Term_numeric:
- ZOOM_options_set_int(opt, name, *term->u.numeric);
- break;
- }
-}
-
-static void handle_queryExpression(ZOOM_options opt, const char *name,
- Z_QueryExpression *exp)
-{
- char opt_name[80];
-
- switch (exp->which)
- {
- case Z_QueryExpression_term:
- if (exp->u.term && exp->u.term->queryTerm)
- {
- sprintf(opt_name, "%s.term", name);
- handle_queryExpressionTerm(opt, opt_name, exp->u.term->queryTerm);
- }
- break;
- case Z_QueryExpression_query:
- break;
- }
-}
-
-static void handle_searchResult(ZOOM_connection c, ZOOM_resultset resultset,
- Z_OtherInformation *o)
-{
- int i;
- for (i = 0; o && i < o->num_elements; i++)
- {
- if (o->list[i]->which == Z_OtherInfo_externallyDefinedInfo)
- {
- Z_External *ext = o->list[i]->information.externallyDefinedInfo;
-
- if (ext->which == Z_External_searchResult1)
- {
- int j;
- Z_SearchInfoReport *sr = ext->u.searchResult1;
-
- if (sr->num)
- ZOOM_options_set_int(
- resultset->options, "searchresult.size", sr->num);
-
- for (j = 0; j < sr->num; j++)
- {
- Z_SearchInfoReport_s *ent =
- ext->u.searchResult1->elements[j];
- char pref[80];
-
- sprintf(pref, "searchresult.%d", j);
-
- if (ent->subqueryId)
- {
- char opt_name[80];
- sprintf(opt_name, "%s.id", pref);
- ZOOM_options_set(resultset->options, opt_name,
- ent->subqueryId);
- }
- if (ent->subqueryExpression)
- {
- char opt_name[80];
- sprintf(opt_name, "%s.subquery", pref);
- handle_queryExpression(resultset->options, opt_name,
- ent->subqueryExpression);
- }
- if (ent->subqueryInterpretation)
- {
- char opt_name[80];
- sprintf(opt_name, "%s.interpretation", pref);
- handle_queryExpression(resultset->options, opt_name,
- ent->subqueryInterpretation);
- }
- if (ent->subqueryRecommendation)
- {
- char opt_name[80];
- sprintf(opt_name, "%s.recommendation", pref);
- handle_queryExpression(resultset->options, opt_name,
- ent->subqueryRecommendation);
- }
- if (ent->subqueryCount)
- {
- char opt_name[80];
- sprintf(opt_name, "%s.count", pref);
- ZOOM_options_set_int(resultset->options, opt_name,
- *ent->subqueryCount);
- }
- }
- }
- }
- }
-}
-
-static void handle_search_response(ZOOM_connection c, Z_SearchResponse *sr)
-{
- ZOOM_resultset resultset;
- ZOOM_Event event;
-
- if (!c->tasks || c->tasks->which != ZOOM_TASK_SEARCH)
- return ;
-
- event = ZOOM_Event_create(ZOOM_EVENT_RECV_SEARCH);
- ZOOM_connection_put_event(c, event);
-
- resultset = c->tasks->u.search.resultset;
-
- if (sr->resultSetStatus)
- {
- ZOOM_options_set_int(resultset->options, "resultSetStatus",
- *sr->resultSetStatus);
- }
- if (sr->presentStatus)
- {
- ZOOM_options_set_int(resultset->options, "presentStatus",
- *sr->presentStatus);
- }
- handle_searchResult(c, resultset, sr->additionalSearchInfo);
-
- resultset->size = *sr->resultCount;
- handle_records(c, sr->records, 0);
-}
-
-static void sort_response(ZOOM_connection c, Z_SortResponse *res)
-{
- if (res->diagnostics && res->num_diagnostics > 0)
- response_diag(c, res->diagnostics[0]);
-}
-
-static int scan_response(ZOOM_connection c, Z_ScanResponse *res)
-{
- NMEM nmem = odr_extract_mem(c->odr_in);
- ZOOM_scanset scan;
-
- if (!c->tasks || c->tasks->which != ZOOM_TASK_SCAN)
- return 0;
- scan = c->tasks->u.scan.scan;
-
- if (res->entries && res->entries->nonsurrogateDiagnostics)
- response_diag(c, res->entries->nonsurrogateDiagnostics[0]);
- scan->scan_response = res;
- nmem_transfer(odr_getmem(scan->odr), nmem);
- if (res->stepSize)
- ZOOM_options_set_int(scan->options, "stepSize", *res->stepSize);
- if (res->positionOfTerm)
- ZOOM_options_set_int(scan->options, "position", *res->positionOfTerm);
- if (res->scanStatus)
- ZOOM_options_set_int(scan->options, "scanStatus", *res->scanStatus);
- if (res->numberOfEntriesReturned)
- ZOOM_options_set_int(scan->options, "number",
- *res->numberOfEntriesReturned);
- nmem_destroy(nmem);
- return 1;
-}
-
-static zoom_ret send_sort(ZOOM_connection c,
- ZOOM_resultset resultset)
-{
- if (c->error)
- resultset->r_sort_spec = 0;
- if (resultset->r_sort_spec)
- {
- Z_APDU *apdu = zget_APDU(c->odr_out, Z_APDU_sortRequest);
- Z_SortRequest *req = apdu->u.sortRequest;
-
- req->num_inputResultSetNames = 1;
- req->inputResultSetNames = (Z_InternationalString **)
- odr_malloc(c->odr_out, sizeof(*req->inputResultSetNames));
- req->inputResultSetNames[0] =
- odr_strdup(c->odr_out, resultset->setname);
- req->sortedResultSetName = odr_strdup(c->odr_out, resultset->setname);
- req->sortSequence = resultset->r_sort_spec;
- resultset->r_sort_spec = 0;
- return send_APDU(c, apdu);
- }
- return zoom_complete;
-}
-
-static zoom_ret send_present(ZOOM_connection c)
-{
- Z_APDU *apdu = 0;
- Z_PresentRequest *req = 0;
- int i = 0;
- const char *syntax = 0;
- const char *elementSetName = 0;
- ZOOM_resultset resultset;
- int *start, *count;
-
- if (!c->tasks)
- {
- yaz_log(log_details, "%p send_present no tasks", c);
- return zoom_complete;
- }
-
- switch (c->tasks->which)
- {
- case ZOOM_TASK_SEARCH:
- resultset = c->tasks->u.search.resultset;
- start = &c->tasks->u.search.start;
- count = &c->tasks->u.search.count;
- syntax = c->tasks->u.search.syntax;
- elementSetName = c->tasks->u.search.elementSetName;
- break;
- case ZOOM_TASK_RETRIEVE:
- resultset = c->tasks->u.retrieve.resultset;
- start = &c->tasks->u.retrieve.start;
- count = &c->tasks->u.retrieve.count;
- syntax = c->tasks->u.retrieve.syntax;
- elementSetName = c->tasks->u.retrieve.elementSetName;
- break;
- default:
- return zoom_complete;
- }
- yaz_log(log_details, "%p send_present start=%d count=%d",
- c, *start, *count);
-
- if (*start < 0 || *count < 0 || *start + *count > resultset->size)
- {
- set_dset_error(c, YAZ_BIB1_PRESENT_REQUEST_OUT_OF_RANGE, "Bib-1",
- "", 0);
- }
- if (c->error) /* don't continue on error */
- return zoom_complete;
- yaz_log(log_details, "send_present resultset=%p start=%d count=%d",
- resultset, *start, *count);
-
- for (i = 0; i < *count; i++)
- {
- ZOOM_record rec =
- record_cache_lookup(resultset, i + *start, syntax, elementSetName);
- if (!rec)
- break;
- else
- {
- ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_RECV_RECORD);
- ZOOM_connection_put_event(c, event);
- }
- }
- *start += i;
- *count -= i;
-
- if (*count == 0)
- {
- yaz_log(log_details, "%p send_present skip=%d no more to fetch", c, i);
- return zoom_complete;
- }
-
- apdu = zget_APDU(c->odr_out, Z_APDU_presentRequest);
- req = apdu->u.presentRequest;
-
- if (i)
- yaz_log(log_details, "%p send_present skip=%d", c, i);
-
- *req->resultSetStartPoint = *start + 1;
- *req->numberOfRecordsRequested = resultset->step>0 ?
- resultset->step : *count;
- if (*req->numberOfRecordsRequested + *start > resultset->size)
- *req->numberOfRecordsRequested = resultset->size - *start;
- assert(*req->numberOfRecordsRequested > 0);
-
- if (syntax && *syntax)
- req->preferredRecordSyntax =
- zoom_yaz_str_to_z3950oid(c, CLASS_RECSYN, syntax);
-
- if (resultset->schema && *resultset->schema)
- {
- Z_RecordComposition *compo = (Z_RecordComposition *)
- odr_malloc(c->odr_out, sizeof(*compo));
-
- req->recordComposition = compo;
- compo->which = Z_RecordComp_complex;
- compo->u.complex = (Z_CompSpec *)
- odr_malloc(c->odr_out, sizeof(*compo->u.complex));
- compo->u.complex->selectAlternativeSyntax = (bool_t *)
- odr_malloc(c->odr_out, sizeof(bool_t));
- *compo->u.complex->selectAlternativeSyntax = 0;
-
- compo->u.complex->generic = (Z_Specification *)
- odr_malloc(c->odr_out, sizeof(*compo->u.complex->generic));
-
- compo->u.complex->generic->which = Z_Schema_oid;
- compo->u.complex->generic->schema.oid = (Odr_oid *)
- zoom_yaz_str_to_z3950oid (c, CLASS_SCHEMA, resultset->schema);
-
- if (!compo->u.complex->generic->schema.oid)
- {
- /* OID wasn't a schema! Try record syntax instead. */
-
- compo->u.complex->generic->schema.oid = (Odr_oid *)
- zoom_yaz_str_to_z3950oid (c, CLASS_RECSYN, resultset->schema);
- }
- if (elementSetName && *elementSetName)
- {
- compo->u.complex->generic->elementSpec = (Z_ElementSpec *)
- odr_malloc(c->odr_out, sizeof(Z_ElementSpec));
- compo->u.complex->generic->elementSpec->which =
- Z_ElementSpec_elementSetName;
- compo->u.complex->generic->elementSpec->u.elementSetName =
- odr_strdup(c->odr_out, elementSetName);
- }
- else
- compo->u.complex->generic->elementSpec = 0;
- compo->u.complex->num_dbSpecific = 0;
- compo->u.complex->dbSpecific = 0;
- compo->u.complex->num_recordSyntax = 0;
- compo->u.complex->recordSyntax = 0;
- }
- else if (elementSetName && *elementSetName)
- {
- Z_ElementSetNames *esn = (Z_ElementSetNames *)
- odr_malloc(c->odr_out, sizeof(*esn));
- Z_RecordComposition *compo = (Z_RecordComposition *)
- odr_malloc(c->odr_out, sizeof(*compo));
-
- esn->which = Z_ElementSetNames_generic;
- esn->u.generic = odr_strdup(c->odr_out, elementSetName);
- compo->which = Z_RecordComp_simple;
- compo->u.simple = esn;
- req->recordComposition = compo;
- }
- req->resultSetId = odr_strdup(c->odr_out, resultset->setname);
- return send_APDU(c, apdu);
-}
-
-ZOOM_API(ZOOM_scanset)
- ZOOM_connection_scan(ZOOM_connection c, const char *start)
-{
- ZOOM_scanset s;
- ZOOM_query q = ZOOM_query_create();
-
- ZOOM_query_prefix(q, start);
-
- s = ZOOM_connection_scan1(c, q);
- ZOOM_query_destroy(q);
- return s;
-
-}
-
-ZOOM_API(ZOOM_scanset)
- ZOOM_connection_scan1(ZOOM_connection c, ZOOM_query q)
-{
- char *start;
- char *freeme = 0;
- ZOOM_scanset scan = 0;
-
- /*
- * We need to check the query-type, so we can recognise CQL and
- * CCL and compile them into a form that we can use here. The
- * ZOOM_query structure has no explicit `type' member, but
- * inspection of the ZOOM_query_prefix() and ZOOM_query_cql()
- * functions shows how the structure is set up in each case.
- */
- if (!q->z_query)
- return 0;
- else if (q->z_query->which == Z_Query_type_1)
- {
- yaz_log(log_api, "%p ZOOM_connection_scan1 q=%p PQF '%s'",
- c, q, q->query_string);
- start = q->query_string;
- }
- else if (q->z_query->which == Z_Query_type_104)
- {
- yaz_log(log_api, "%p ZOOM_connection_scan1 q=%p CQL '%s'",
- c, q, q->query_string);
- start = freeme = cql2pqf(c, q->query_string);
- if (start == 0)
- return 0;
- }
- else
- {
- yaz_log(YLOG_FATAL, "%p ZOOM_connection_scan1 q=%p unknown type '%s'",
- c, q, q->query_string);
- abort();
- }
-
- scan = (ZOOM_scanset) xmalloc(sizeof(*scan));
- scan->connection = c;
- scan->odr = odr_createmem(ODR_DECODE);
- scan->options = ZOOM_options_create_with_parent(c->options);
- scan->refcount = 1;
- scan->scan_response = 0;
- scan->termListAndStartPoint =
- p_query_scan(scan->odr, PROTO_Z3950, &scan->attributeSet, start);
- xfree(freeme);
-
- {
- const char *cp = ZOOM_options_get(scan->options, "rpnCharset");
- if (cp)
- {
- yaz_iconv_t cd = yaz_iconv_open(cp, "UTF-8");
- if (cd)
- {
- yaz_query_charset_convert_apt(scan->termListAndStartPoint,
- scan->odr, cd);
- }
- }
- }
-
-
- scan->databaseNames = set_DatabaseNames(c, c->options,
- &scan->num_databaseNames,
- scan->odr);
- if (scan->termListAndStartPoint != 0)
- {
- ZOOM_task task = ZOOM_connection_add_task(c, ZOOM_TASK_SCAN);
- task->u.scan.scan = scan;
-
- (scan->refcount)++;
- if (!c->async)
- {
- while (ZOOM_event(1, &c))
- ;
- }
- }
- return scan;
-}
-
-ZOOM_API(void)
- ZOOM_scanset_destroy(ZOOM_scanset scan)
-{
- if (!scan)
- return;
- (scan->refcount)--;
- if (scan->refcount == 0)
- {
- odr_destroy(scan->odr);
-
- ZOOM_options_destroy(scan->options);
- xfree(scan);
- }
-}
-
-static zoom_ret send_package(ZOOM_connection c)
-{
- ZOOM_Event event;
-
- yaz_log(log_details, "%p send_package", c);
- if (!c->tasks)
- return zoom_complete;
- assert (c->tasks->which == ZOOM_TASK_PACKAGE);
-
- event = ZOOM_Event_create(ZOOM_EVENT_SEND_APDU);
- ZOOM_connection_put_event(c, event);
-
- c->buf_out = c->tasks->u.package->buf_out;
- c->len_out = c->tasks->u.package->len_out;
-
- return do_write(c);
-}
-
-static zoom_ret send_scan(ZOOM_connection c)
-{
- ZOOM_scanset scan;
- Z_APDU *apdu = zget_APDU(c->odr_out, Z_APDU_scanRequest);
- Z_ScanRequest *req = apdu->u.scanRequest;
-
- yaz_log(log_details, "%p send_scan", c);
- if (!c->tasks)
- return zoom_complete;
- assert (c->tasks->which == ZOOM_TASK_SCAN);
- scan = c->tasks->u.scan.scan;
-
- req->termListAndStartPoint = scan->termListAndStartPoint;
- req->attributeSet = scan->attributeSet;
-
- *req->numberOfTermsRequested =
- ZOOM_options_get_int(scan->options, "number", 10);
-
- req->preferredPositionInResponse =
- odr_intdup(c->odr_out,
- ZOOM_options_get_int(scan->options, "position", 1));
-
- req->stepSize =
- odr_intdup(c->odr_out,
- ZOOM_options_get_int(scan->options, "stepSize", 0));
-
- req->databaseNames = scan->databaseNames;
- req->num_databaseNames = scan->num_databaseNames;
-
- return send_APDU(c, apdu);
-}
-
-ZOOM_API(size_t)
- ZOOM_scanset_size(ZOOM_scanset scan)
-{
- if (!scan || !scan->scan_response || !scan->scan_response->entries)
- return 0;
- return scan->scan_response->entries->num_entries;
-}
-
-ZOOM_API(const char *)
- ZOOM_scanset_term(ZOOM_scanset scan, size_t pos,
- int *occ, int *len)
-{
- const char *term = 0;
- size_t noent = ZOOM_scanset_size(scan);
- Z_ScanResponse *res = scan->scan_response;
-
- *len = 0;
- *occ = 0;
- if (pos >= noent)
- return 0;
- if (res->entries->entries[pos]->which == Z_Entry_termInfo)