X-Git-Url: http://lists.indexdata.com/cgi-bin?a=blobdiff_plain;f=ir-tcl.c;h=78aaccac3a25cbf88980c5378dc6c5f13e21f938;hb=13d9f750171f21457dd31c119737ef4a8080b04d;hp=a9742c167f388782ef122f32489de454c64b25a2;hpb=0b17556c40fba07f064ed5e48015604568c9f583;p=ir-tcl-moved-to-github.git diff --git a/ir-tcl.c b/ir-tcl.c index a9742c1..78aacca 100644 --- a/ir-tcl.c +++ b/ir-tcl.c @@ -1,11 +1,22 @@ /* * IR toolkit for tcl/tk - * (c) Index Data 1995 + * (c) Index Data 1995-1996 * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * * $Log: ir-tcl.c,v $ - * Revision 1.91 1996-07-03 13:31:11 adam + * Revision 1.94 1996-08-21 13:32:53 adam + * Implemented saveFile method and extended loadFile method to work with it. + * + * Revision 1.93 1996/08/16 15:07:45 adam + * First work on Explain. + * + * Revision 1.92 1996/08/09 15:33:07 adam + * Modified the code to use tk4.1/tcl7.5 patch level 1. The time-driven + * polling is no longer activated on Windows since asynchrounous I/O works + * better. + * + * Revision 1.91 1996/07/03 13:31:11 adam * The xmalloc/xfree functions from YAZ are used to manage memory. * * Revision 1.90 1996/06/27 14:21:00 adam @@ -327,7 +338,11 @@ #include #include +#ifdef WINDOWS + +#else #include +#endif #include #include @@ -373,6 +388,7 @@ static void delete_IR_record (IrTcl_RecordList *rl) break; } xfree (rl->u.dbrec.buf); + rl->u.dbrec.buf = NULL; break; case Z_NamePlusRecord_surrogateDiagnostic: ir_deleteDiags (&rl->u.surrogateDiagnostics.list, @@ -925,7 +941,11 @@ static int do_implementationVersion (void *obj, Tcl_Interp *interp, if (argc == 0) return ir_tcl_strdup (interp, &p->implementationVersion, - "YAZ: " YAZ_VERSION " / IrTcl: " IR_TCL_VERSION); + "YAZ: " YAZ_VERSION +#ifdef IR_TCL_VERSION + " / Irtcl: " IR_TCL_VERSION +#endif + ); else if (argc == -1) return ir_tcl_strdel (interp, &p->implementationVersion); Tcl_AppendResult (interp, p->implementationVersion, (char*) NULL); @@ -2414,7 +2434,7 @@ static int do_getSutrs (void *o, Tcl_Interp *interp, int argc, char **argv) /* - * do_getGrs: Get a GRS1 Record + * do_getGrs: Get a GRS-1 Record */ static int do_getGrs (void *o, Tcl_Interp *interp, int argc, char **argv) { @@ -2449,6 +2469,54 @@ static int do_getGrs (void *o, Tcl_Interp *interp, int argc, char **argv) /* + * do_getExplain: Get an Explain Record + */ +static int do_getExplain (void *o, Tcl_Interp *interp, int argc, char **argv) +{ + IrTcl_SetObj *obj = o; + IrTcl_Obj *p = obj->parent; + void *rr; + Z_ext_typeent *etype; + int offset; + IrTcl_RecordList *rl; + + if (argc <= 0) + return TCL_OK; + if (argc < 3) + { + sprintf (interp->result, "wrong # args"); + return TCL_ERROR; + } + if (Tcl_GetInt (interp, argv[2], &offset)==TCL_ERROR) + return TCL_ERROR; + rl = find_IR_record (obj, offset); + if (!rl) + { + Tcl_AppendResult (interp, "No record at #", argv[2], NULL); + return TCL_ERROR; + } + if (rl->which != Z_NamePlusRecord_databaseRecord) + { + Tcl_AppendResult (interp, "No DB record at #", argv[2], NULL); + return TCL_ERROR; + } + if (rl->u.dbrec.type != VAL_EXPLAIN) + return TCL_OK; + + if (!(etype = z_ext_getentbyref (VAL_EXPLAIN))) + return TCL_OK; + + odr_setbuf (p->odr_in, rl->u.dbrec.buf, rl->u.dbrec.size, 0); + if (!(*etype->fun)(p->odr_in, &rr, 0)) + return TCL_OK; + + if (etype->what != Z_External_explainRecord) + return TCL_OK; + + return ir_tcl_get_explain (interp, rr, argc, argv); +} + +/* * do_responseStatus: Return response status (present or search) */ static int do_responseStatus (void *o, Tcl_Interp *interp, @@ -2568,47 +2636,165 @@ static int do_present (void *o, Tcl_Interp *interp, int argc, char **argv) return ir_tcl_send_APDU (interp, p, apdu, "present", *argv); } +#define IR_TCL_RECORD_ENCODING_ISO2709 1 +#define IR_TCL_RECORD_ENCODING_RAW 2 + +typedef struct { + int encoding; + int syntax; + int size; +} IrTcl_FileRecordHead; + /* * do_loadFile: Load result set from file */ - static int do_loadFile (void *o, Tcl_Interp *interp, int argc, char **argv) { IrTcl_SetObj *setobj = o; FILE *inf; size_t size; - int no = 1; + int offset; + int start = 1; + int number = 30000; char *buf; - + if (argc <= 0) return TCL_OK; - if (argc != 3) + if (argc < 3) { interp->result = "wrong # args"; return TCL_ERROR; } + if (argc > 3) + start = atoi (argv[3]); + if (argc > 4) + number = atoi (argv[4]); + offset = start; + inf = fopen (argv[2], "r"); if (!inf) { Tcl_AppendResult (interp, "Cannot open ", argv[2], NULL); return TCL_ERROR; } - while ((buf = ir_tcl_fread_marc (inf, &size))) + while (offset < (start+number)) { + IrTcl_FileRecordHead head; IrTcl_RecordList *rl; - rl = new_IR_record (setobj, no, Z_NamePlusRecord_databaseRecord, "F"); - rl->u.dbrec.type = VAL_USMARC; - rl->u.dbrec.buf = buf; - rl->u.dbrec.size = size; - no++; + if (fread (&head, sizeof(head), 1, inf) < 1) + break; + rl = new_IR_record (setobj, offset, + Z_NamePlusRecord_databaseRecord, + (argc > 5) ? argv[5] : NULL); + rl->u.dbrec.type = head.syntax; + if (head.encoding == IR_TCL_RECORD_ENCODING_ISO2709) + { + if (!(buf = ir_tcl_fread_marc (inf, &size))) + break; + rl->u.dbrec.buf = buf; + rl->u.dbrec.size = size; + if (size != head.size) + { + Tcl_AppendResult (interp, "Bad ISO2709 encoding in file", + argv[2], NULL); + fclose (inf); + return TCL_ERROR; + } + } + else if (head.encoding == IR_TCL_RECORD_ENCODING_RAW) + { + rl->u.dbrec.size = head.size; + rl->u.dbrec.buf = ir_tcl_malloc (head.size + 1); + if (fread (rl->u.dbrec.buf, rl->u.dbrec.size, 1, inf) < 1) + { + Tcl_AppendResult (interp, "Bad RAW encoding in file", + argv[2], NULL); + fclose (inf); + return TCL_ERROR; + } + rl->u.dbrec.buf[rl->u.dbrec.size] = '\0'; + } + else + { + rl->u.dbrec.buf = NULL; + rl->u.dbrec.size = 0; + Tcl_AppendResult (interp, "Bad encoding in file", argv[2], NULL); + fclose (inf); + return TCL_ERROR; + } + offset++; } - setobj->numberOfRecordsReturned = no-1; + setobj->numberOfRecordsReturned = offset - start; fclose (inf); return TCL_OK; } +/* + * do_saveFile: Save result set on file + */ +static int do_saveFile (void *o, Tcl_Interp *interp, + int argc, char **argv) +{ + IrTcl_SetObj *setobj = o; + FILE *outf; + int offset; + int start = 1; + int number = 30000; + IrTcl_RecordList *rl; + + if (argc <= 0) + return TCL_OK; + if (argc < 3) + { + interp->result = "wrong # args"; + return TCL_ERROR; + } + if (argc > 3) + start = atoi (argv[3]); + if (argc > 4) + number = atoi (argv[4]); + offset = start; + + outf = fopen (argv[2], "w"); + if (!outf) + { + Tcl_AppendResult (interp, "Cannot open ", argv[2], NULL); + return TCL_ERROR; + } + while (offset < (start+number) && (rl = find_IR_record (setobj, offset))) + { + if (rl->which == Z_NamePlusRecord_databaseRecord && + rl->u.dbrec.buf && rl->u.dbrec.size) + { + IrTcl_FileRecordHead head; + + head.encoding = IR_TCL_RECORD_ENCODING_RAW; + head.syntax = rl->u.dbrec.type; + head.size = rl->u.dbrec.size; + if (fwrite (&head, sizeof(head), 1, outf) < 1) + { + Tcl_AppendResult (interp, "Cannot write ", argv[2], NULL); + return TCL_ERROR; + } + if (fwrite (rl->u.dbrec.buf, rl->u.dbrec.size, 1, outf) < 1) + { + Tcl_AppendResult (interp, "Cannot write ", argv[2], NULL); + return TCL_ERROR; + } + } + offset++; + } + if (fclose (outf)) + { + Tcl_AppendResult (interp, "Cannot write ", argv[2], NULL); + return TCL_ERROR; + } + return TCL_OK; +} + + static IrTcl_Method ir_set_method_tab[] = { { "search", do_search, NULL}, { "searchResponse", do_searchResponse, NULL}, @@ -2624,11 +2810,13 @@ static IrTcl_Method ir_set_method_tab[] = { { "getMarc", do_getMarc, NULL}, { "getSutrs", do_getSutrs, NULL}, { "getGrs", do_getGrs, NULL}, + { "getExplain", do_getExplain, NULL}, { "recordType", do_recordType, NULL}, { "recordElements", do_recordElements, NULL}, { "diag", do_diag, NULL}, { "responseStatus", do_responseStatus, NULL}, { "loadFile", do_loadFile, NULL}, + { "saveFile", do_saveFile, NULL}, { NULL, NULL} }; @@ -3202,7 +3390,7 @@ static void ir_deleteDiags (IrTcl_Diagnostic **dst_list, int *dst_num) } static void ir_handleDiags (IrTcl_Diagnostic **dst_list, int *dst_num, - Z_DiagRec **list, int num) + Z_DiagRec **list, int num) { int i; char *addinfo; @@ -3231,7 +3419,86 @@ static void ir_handleDiags (IrTcl_Diagnostic **dst_list, int *dst_num, } } -static void ir_handleRecords (void *o, Z_Records *zrs, IrTcl_SetObj *setobj, +static void ir_handleDBRecord (IrTcl_Obj *p, IrTcl_RecordList *rl, + Z_External *oe) +{ + struct oident *ident; + Z_ext_typeent *etype; + + rl->u.dbrec.size = oe->u.octet_aligned->len; + rl->u.dbrec.buf = NULL; + + if ((ident = oid_getentbyoid (oe->direct_reference))) + rl->u.dbrec.type = ident->value; + else + rl->u.dbrec.type = VAL_USMARC; + + if (ident && (oe->which == Z_External_single || + oe->which == Z_External_octet) + && (etype = z_ext_getentbyref (ident->value))) + { + void *rr; + + odr_setbuf (p->odr_in, (char*) oe->u.octet_aligned->buf, + oe->u.octet_aligned->len, 0); + if (!(*etype->fun)(p->odr_in, &rr, 0)) + return; + switch (etype->what) + { + case Z_External_sutrs: + logf (LOG_LOG, "Z_External_sutrs"); + oe->u.sutrs = rr; + if ((rl->u.dbrec.buf = ir_tcl_malloc (oe->u.sutrs->len+1))) + { + memcpy (rl->u.dbrec.buf, oe->u.sutrs->buf, + oe->u.sutrs->len); + rl->u.dbrec.buf[oe->u.sutrs->len] = '\0'; + } + rl->u.dbrec.size = oe->u.sutrs->len; + break; + case Z_External_grs1: + logf (LOG_LOG, "Z_External_grs1"); + oe->u.grs1 = rr; + ir_tcl_grs_mk (oe->u.grs1, &rl->u.dbrec.u.grs1); + break; + case Z_External_explainRecord: + logf (LOG_LOG, "Z_External_explainRecord"); + if ((rl->u.dbrec.buf = ir_tcl_malloc (rl->u.dbrec.size))) + { + memcpy (rl->u.dbrec.buf, oe->u.octet_aligned->buf, + rl->u.dbrec.size); + } + break; + } + } + else + { + if (oe->which == Z_External_octet && rl->u.dbrec.size > 0) + { + char *buf = (char*) oe->u.octet_aligned->buf; + if ((rl->u.dbrec.buf = ir_tcl_malloc (rl->u.dbrec.size))) + memcpy (rl->u.dbrec.buf, buf, rl->u.dbrec.size); + } + else if (rl->u.dbrec.type == VAL_SUTRS && + oe->which == Z_External_sutrs) + { + if ((rl->u.dbrec.buf = ir_tcl_malloc (oe->u.sutrs->len+1))) + { + memcpy (rl->u.dbrec.buf, oe->u.sutrs->buf, + oe->u.sutrs->len); + rl->u.dbrec.buf[oe->u.sutrs->len] = '\0'; + } + rl->u.dbrec.size = oe->u.sutrs->len; + } + else if (rl->u.dbrec.type == VAL_GRS1 && + oe->which == Z_External_grs1) + { + ir_tcl_grs_mk (oe->u.grs1, &rl->u.dbrec.u.grs1); + } + } +} + +static void ir_handleZRecords (void *o, Z_Records *zrs, IrTcl_SetObj *setobj, const char *elements) { IrTcl_Obj *p = o; @@ -3249,64 +3516,21 @@ static void ir_handleRecords (void *o, Z_Records *zrs, IrTcl_SetObj *setobj, setobj->numberOfRecordsReturned = zrs->u.databaseOrSurDiagnostics->num_records; logf (LOG_DEBUG, "Got %d records", setobj->numberOfRecordsReturned); - for (offset = 0; offsetnumberOfRecordsReturned; offset++) + for (offset = 0; offset < setobj->numberOfRecordsReturned; offset++) { - rl = new_IR_record (setobj, setobj->start + offset, - zrs->u.databaseOrSurDiagnostics-> - records[offset]->which, + Z_NamePlusRecord *znpr = zrs->u.databaseOrSurDiagnostics-> + records[offset]; + + rl = new_IR_record (setobj, setobj->start + offset, znpr->which, elements); if (rl->which == Z_NamePlusRecord_surrogateDiagnostic) - { ir_handleDiags (&rl->u.surrogateDiagnostics.list, &rl->u.surrogateDiagnostics.num, - &zrs->u.databaseOrSurDiagnostics-> - records[offset]->u.surrogateDiagnostic, + &znpr->u.surrogateDiagnostic, 1); - } else - { - Z_DatabaseRecord *zr; - Z_External *oe; - struct oident *ident; - - zr = zrs->u.databaseOrSurDiagnostics->records[offset] - ->u.databaseRecord; - oe = (Z_External*) zr; - rl->u.dbrec.size = zr->u.octet_aligned->len; - - if ((ident = oid_getentbyoid (oe->direct_reference))) - rl->u.dbrec.type = ident->value; - else - rl->u.dbrec.type = VAL_USMARC; - - if (oe->which == ODR_EXTERNAL_octet && rl->u.dbrec.size > 0) - { - char *buf = (char*) zr->u.octet_aligned->buf; - if ((rl->u.dbrec.buf = ir_tcl_malloc (rl->u.dbrec.size))) - memcpy (rl->u.dbrec.buf, buf, rl->u.dbrec.size); - } - else if (rl->u.dbrec.type == VAL_SUTRS && - oe->which == Z_External_sutrs) - { - odr_setbuf (p->odr_in, (char*) oe->u.single_ASN1_type->buf, - oe->u.single_ASN1_type->len, 0); - if ((rl->u.dbrec.buf = ir_tcl_malloc (oe->u.sutrs->len+1))) - { - memcpy (rl->u.dbrec.buf, oe->u.sutrs->buf, - oe->u.sutrs->len); - rl->u.dbrec.buf[oe->u.sutrs->len] = '\0'; - } - rl->u.dbrec.size = oe->u.sutrs->len; - } - else if (rl->u.dbrec.type == VAL_GRS1 && - oe->which == Z_External_grs1) - { - ir_tcl_grs_mk (oe->u.grs1, &rl->u.dbrec.u.grs1); - rl->u.dbrec.buf = NULL; - } - else - rl->u.dbrec.buf = NULL; - } + ir_handleDBRecord (p, rl, + (Z_External*) (znpr->u.databaseRecord)); } } else if (zrs->which == Z_Records_multipleNSD) @@ -3358,7 +3582,7 @@ static void ir_searchResponse (void *o, Z_SearchResponse *searchrs, es = setobj->set_inher.smallSetElementSetNames; else es = setobj->set_inher.mediumSetElementSetNames; - ir_handleRecords (o, zrs, setobj, es); + ir_handleZRecords (o, zrs, setobj, es); } else setobj->recordFlag = 0; @@ -3380,7 +3604,7 @@ static void ir_presentResponse (void *o, Z_PresentResponse *presrs, get_referenceId (&setobj->set_inher.referenceId, presrs->referenceId); setobj->nextResultSetPosition = *presrs->nextResultSetPosition; if (zrs) - ir_handleRecords (o, zrs, setobj, setobj->set_inher.elementSetNames); + ir_handleZRecords (o, zrs, setobj, setobj->set_inher.elementSetNames); else { setobj->recordFlag = 0;