X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=ir-tcl.c;h=abe271c47f2ed75de9a129dafda8c9292e47f573;hb=4ccc8ab7a1f708af5fd89c71771040eaf6e6da4a;hp=c6e789b67ca0a037bcff01e1508623b9d0c58475;hpb=0b673e359cca2fdb88719de3d20d5488ead9fefb;p=ir-tcl-moved-to-github.git diff --git a/ir-tcl.c b/ir-tcl.c index c6e789b..abe271c 100644 --- a/ir-tcl.c +++ b/ir-tcl.c @@ -1,10 +1,23 @@ /* * IR toolkit for tcl/tk - * (c) Index Data 1995-2001 + * (c) Index Data 1995-2003 * See the file LICENSE for details. * * $Log: ir-tcl.c,v $ - * Revision 1.117 2001-03-26 11:39:34 adam + * Revision 1.121 2003-01-30 13:27:07 adam + * Changed version to 1.4.1. Added WIN32 version resource. + * IrTcl ignores unexpected PDU's, rather than die. + * + * Revision 1.120 2002/03/20 14:48:54 adam + * implemented USR.1 SearchResult-1 + * + * Revision 1.119 2001/12/03 00:31:06 adam + * Towards 1.4. Configure updates. + * + * Revision 1.118 2001/03/27 16:27:21 adam + * Fixed bug in do_responseStatus. + * + * Revision 1.117 2001/03/26 11:39:34 adam * Fixed bug in ir_deleteDiags - crash when receiving multiple diags. * * Revision 1.116 2001/02/09 11:58:04 adam @@ -1035,7 +1048,7 @@ static int do_implementationName (void *obj, Tcl_Interp *interp, if (argc == 0) return ir_tcl_strdup (interp, &p->implementationName, - "Index Data/IrTcl on YAZ"); + "IrTcl/YAZ"); else if (argc == -1) return ir_tcl_strdel (interp, &p->implementationName); if (argc == 3) @@ -1058,7 +1071,7 @@ static int do_implementationId (void *obj, Tcl_Interp *interp, IrTcl_Obj *p = obj; if (argc == 0) - return ir_tcl_strdup (interp, &p->implementationId, "YAZ (id=81)"); + return ir_tcl_strdup (interp, &p->implementationId, "81"); else if (argc == -1) return ir_tcl_strdel (interp, &p->implementationId); Tcl_AppendResult (interp, p->implementationId, (char*) NULL); @@ -1075,10 +1088,10 @@ static int do_implementationVersion (void *obj, Tcl_Interp *interp, if (argc == 0) return ir_tcl_strdup (interp, &p->implementationVersion, - "YAZ: " YAZ_VERSION #ifdef IR_TCL_VERSION - " / Irtcl: " IR_TCL_VERSION + IR_TCL_VERSION "/" #endif + YAZ_VERSION ); else if (argc == -1) return ir_tcl_strdel (interp, &p->implementationVersion); @@ -2263,7 +2276,7 @@ static int do_presentResponse (void *o, Tcl_Interp *interp, * do_sortResponse: add sort response handler */ static int do_sortResponse (void *o, Tcl_Interp *interp, - int argc, char **argv) + int argc, char **argv) { IrTcl_SetObj *obj = o; @@ -2318,6 +2331,54 @@ static int do_searchStatus (void *o, Tcl_Interp *interp, return ir_tcl_get_set_int (&obj->searchStatus, interp, argc, argv); } +static void reset_searchResult (IrTcl_SetObj *setobj) +{ + int i; + for (i = 0; isearchResult_num; i++) + xfree (setobj->searchResult_terms[i]); + xfree (setobj->searchResult_terms); + xfree (setobj->searchResult_count); + setobj->searchResult_terms = 0; + setobj->searchResult_num = 0; +} + + +/* + * do_searchResult Get USR:Search-Result1 (after search response) + */ +static int do_searchResult (void *o, Tcl_Interp *interp, + int argc, char **argv) +{ + IrTcl_SetObj *obj = o; + int i; + + if (argc == 0) + { + obj->searchResult_num = 0; + obj->searchResult_terms = 0; + obj->searchResult_count = 0; + return TCL_OK; + } + else if (argc == -1) + { + reset_searchResult (obj); + return TCL_OK; + } + for (i = 0; isearchResult_num; i++) + { + char str[40]; + sprintf (str, "%d", obj->searchResult_count[i]); + Tcl_AppendResult (interp, "{", NULL); + if (obj->searchResult_terms[i]) + Tcl_AppendElement (interp, obj->searchResult_terms[i]); + else + Tcl_AppendElement (interp, ""); + Tcl_AppendElement (interp, str); + Tcl_AppendResult (interp, "} ", NULL); + } + return TCL_OK; +} + /* * do_presentStatus: Get search status (after search/present response) */ @@ -2786,6 +2847,10 @@ static int do_responseStatus (void *o, Tcl_Interp *interp, Tcl_AppendElement (interp, "NSD"); return ir_diagResult (interp, obj->nonSurrogateDiagnosticList, obj->nonSurrogateDiagnosticNum); + case Z_Records_multipleNSD: + Tcl_AppendElement (interp, "NSD"); + return ir_diagResult (interp, obj->nonSurrogateDiagnosticList, + obj->nonSurrogateDiagnosticNum); } return TCL_OK; } @@ -3219,6 +3284,7 @@ static IrTcl_Method ir_set_method_tab[] = { { "sort", do_sort, NULL }, { "sortResponse", do_sortResponse, NULL}, { "sortStatus", do_sortStatus, NULL}, + { "searchResult", do_searchResult, NULL}, { NULL, NULL} }; @@ -3450,7 +3516,8 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv) req->num_databaseNames = p->set_inher.num_databaseNames; req->databaseNames = p->set_inher.databaseNames; -#if !CCL2RPN +#if 1 +/* !CCL2RPN */ if (!(req->termListAndStartPoint = p_query_scan (p->odr_out, p->protocol_type, &req->attributeSet, start_term))) @@ -4066,6 +4133,77 @@ static void ir_handleZRecords (void *o, Z_Records *zrs, IrTcl_SetObj *setobj, } } +static char *set_queryExpression (Z_QueryExpression *qe) +{ + char *termz = 0; + if (!qe) + return 0; + if (qe->which == Z_QueryExpression_term) + { + if (qe->u.term->queryTerm) + { + Z_Term *term = qe->u.term->queryTerm; + if (term->which == Z_Term_general) + { + termz = xmalloc (term->u.general->len+1); + memcpy (termz, term->u.general->buf, term->u.general->len); + termz[term->u.general->len] = 0; + } + } + } + return termz; +} + +static void set_searchResult (Z_OtherInformation *o, + IrTcl_SetObj *setobj) +{ + int i; + if (!o) + return ; + for (i = 0; i < o->num_elements; i++) + { + if (o->list[i]->which == Z_OtherInfo_externallyDefinedInfo) + { + ODR odr = odr_createmem (ODR_DECODE); + Z_External *ext = o->list[i]->information.externallyDefinedInfo; + Z_SearchInfoReport *sr = 0; + + if (ext->which == Z_External_single) + { + odr_setbuf (odr, ext->u.single_ASN1_type->buf, + ext->u.single_ASN1_type->len, 0); + z_SearchInfoReport (odr, &sr, 0, "searchInfo"); + } + if (ext->which == Z_External_searchResult1) + sr = ext->u.searchResult1; + if (sr) + { + int j; + reset_searchResult (setobj); + + setobj->searchResult_num = sr->num; + setobj->searchResult_terms = + xmalloc (sr->num * sizeof(*setobj->searchResult_terms)); + setobj->searchResult_count = + xmalloc (sr->num * sizeof(*setobj->searchResult_count)); + + for (j = 0; j < sr->num; j++) + { + setobj->searchResult_terms[j] = + set_queryExpression ( + sr->elements[j]->subqueryExpression); + if (sr->elements[j]->subqueryCount) + setobj->searchResult_count[j] = + *sr->elements[j]->subqueryCount; + else + setobj->searchResult_count[j] = 0; + } + } + odr_destroy (odr); + } + } +} + static void ir_searchResponse (void *o, Z_SearchResponse *searchrs, IrTcl_SetObj *setobj) { @@ -4089,6 +4227,7 @@ static void ir_searchResponse (void *o, Z_SearchResponse *searchrs, logf (LOG_DEBUG, "status %d hits %d", setobj->searchStatus, setobj->resultCount); + set_searchResult (searchrs->additionalSearchInfo, setobj); if (zrs) { const char *es; @@ -4264,6 +4403,7 @@ static void ir_select_read (ClientData clientData) char *object_name; Tcl_CmdInfo cmd_info; const char *apdu_call; + int round = 0; logf(LOG_DEBUG, "Read handler fd=%d", cs_fileno(p->cs_link)); if (p->state == IR_TCL_R_Connecting) @@ -4302,6 +4442,8 @@ static void ir_select_read (ClientData clientData) { p->state = IR_TCL_R_Reading; + round++; + yaz_log(LOG_DEBUG, "round %d", round); /* read incoming APDU */ if ((r=cs_get (p->cs_link, &p->buf_in, &p->len_in)) == 1) { @@ -4346,10 +4488,12 @@ static void ir_select_read (ClientData clientData) } /* handle APDU and invoke callback */ rq = p->request_queue; - if (!rq) - { - logf (LOG_FATAL, "Internal error. No queue entry"); - exit (1); + if (!rq) + { + /* no corresponding request. Skip it. */ + logf(LOG_DEBUG, "no corresponding request. Skipping it"); + p->state = IR_TCL_R_Idle; + return; } object_name = rq->object_name; logf (LOG_DEBUG, "Object %s", object_name);