+/*
+ * 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)
+ {
+ Tcl_AppendResult (interp, wrongArgs, *argv, " ", argv[1],
+ " filename ?start? ?number?\"", NULL);
+ 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 file", NULL);
+ return ir_tcl_error_exec (interp, argc, argv);
+ }
+ 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", NULL);
+ return ir_tcl_error_exec (interp, argc, argv);
+ }
+ if (fwrite (rl->u.dbrec.buf, rl->u.dbrec.size, 1, outf) < 1)
+ {
+ Tcl_AppendResult (interp, "cannot write", NULL);
+ return ir_tcl_error_exec (interp, argc, argv);
+ }
+ }
+ offset++;
+ }
+ if (fclose (outf))
+ {
+ Tcl_AppendResult (interp, "cannot write ", NULL);
+ return ir_tcl_error_exec (interp, argc, argv);
+ }
+ return TCL_OK;
+}
+
+
+/* ------------------------------------------------------- */
+/*
+ * do_sort: Do sort request
+ */
+static int do_sort (void *o, Tcl_Interp *interp, int argc, char **argv)
+{
+ Z_SortRequest *req;
+ Z_APDU *apdu;
+ IrTcl_SetObj *obj = o;
+ IrTcl_Obj *p;
+ char sort_string[64], sort_flags[64];
+ char *arg;
+ int off;
+ Z_SortKeySpecList *sksl;
+ int oid[OID_SIZE];
+ oident bib1;
+
+ if (argc <= 0)
+ return TCL_OK;
+
+ p = obj->parent;
+ assert (argc > 1);
+ if (argc != 3)
+ {
+ Tcl_AppendResult (interp, wrongArgs, *argv, " ", argv[1], "query\"",
+ NULL);
+ return TCL_ERROR;
+ }
+ logf (LOG_DEBUG, "sort %s %s", *argv, argv[2]);
+ if (!p->cs_link)
+ {
+ Tcl_AppendResult (interp, "not connected", NULL);
+ return ir_tcl_error_exec (interp, argc, argv);
+ }
+ apdu = zget_APDU (p->odr_out, Z_APDU_sortRequest);
+ sksl = (Z_SortKeySpecList *) odr_malloc (p->odr_out, sizeof(*sksl));
+ req = apdu->u.sortRequest;
+
+ set_referenceId (p->odr_out, &req->referenceId,
+ obj->set_inher.referenceId);
+
+#ifdef ASN_COMPILED
+ req->num_inputResultSetNames = 1;
+ req->inputResultSetNames = (Z_InternationalString **)
+ odr_malloc (p->odr_out, sizeof(*req->inputResultSetNames));
+ req->inputResultSetNames[0] = obj->setName;
+#else
+ req->inputResultSetNames =
+ (Z_StringList *)odr_malloc (p->odr_out,
+ sizeof(*req->inputResultSetNames));
+ req->inputResultSetNames->num_strings = 1;
+ req->inputResultSetNames->strings =
+ (char **)odr_malloc (p->odr_out,
+ sizeof(*req->inputResultSetNames->strings));
+ req->inputResultSetNames->strings[0] = obj->setName;
+#endif
+
+ req->sortedResultSetName = (char *) obj->setName;
+
+
+ req->sortSequence = sksl;
+ sksl->num_specs = 0;
+ sksl->specs = (Z_SortKeySpec **)
+ odr_malloc (p->odr_out, sizeof(sksl->specs) * 20);
+
+ bib1.proto = PROTO_Z3950;
+ bib1.oclass = CLASS_ATTSET;
+ bib1.value = VAL_BIB1;
+ arg = argv[2];
+ while ((sscanf (arg, "%63s %63s%n", sort_string, sort_flags, &off)) == 2
+ && off > 1)
+ {
+ int i;
+ char *sort_string_sep;
+ Z_SortKeySpec *sks = (Z_SortKeySpec *)
+ odr_malloc (p->odr_out, sizeof(*sks));
+ Z_SortKey *sk = (Z_SortKey *)
+ odr_malloc (p->odr_out, sizeof(*sk));
+
+ arg += off;
+ sksl->specs[sksl->num_specs++] = sks;
+ sks->sortElement = (Z_SortElement *)
+ odr_malloc (p->odr_out, sizeof(*sks->sortElement));
+ sks->sortElement->which = Z_SortElement_generic;
+ sks->sortElement->u.generic = sk;
+
+ if ((sort_string_sep = strchr (sort_string, '=')))
+ {
+ Z_AttributeElement *el = (Z_AttributeElement *)
+ odr_malloc (p->odr_out, sizeof(*el));
+ sk->which = Z_SortKey_sortAttributes;
+ sk->u.sortAttributes =
+ (Z_SortAttributes *)
+ odr_malloc (p->odr_out, sizeof(*sk->u.sortAttributes));
+ sk->u.sortAttributes->id = oid_ent_to_oid(&bib1, oid);
+ sk->u.sortAttributes->list =
+ (Z_AttributeList *)
+ odr_malloc (p->odr_out, sizeof(*sk->u.sortAttributes->list));
+ sk->u.sortAttributes->list->num_attributes = 1;
+ sk->u.sortAttributes->list->attributes =
+ (Z_AttributeElement **)odr_malloc (p->odr_out,
+ sizeof(*sk->u.sortAttributes->list->attributes));
+ sk->u.sortAttributes->list->attributes[0] = el;
+ el->attributeSet = 0;
+ el->attributeType = (int *)
+ odr_malloc (p->odr_out, sizeof(*el->attributeType));
+ *el->attributeType = atoi (sort_string);
+ el->which = Z_AttributeValue_numeric;
+ el->value.numeric = (int *)
+ odr_malloc (p->odr_out, sizeof(*el->value.numeric));
+ *el->value.numeric = atoi (sort_string_sep + 1);
+ }
+ else
+ {
+ sk->which = Z_SortKey_sortField;
+ sk->u.sortField = (char *)odr_malloc (p->odr_out, strlen(sort_string)+1);
+ strcpy (sk->u.sortField, sort_string);
+ }
+ sks->sortRelation = (int *)
+ odr_malloc (p->odr_out, sizeof(*sks->sortRelation));
+ *sks->sortRelation = Z_SortKeySpec_ascending;
+ sks->caseSensitivity = (int *)
+ odr_malloc (p->odr_out, sizeof(*sks->caseSensitivity));
+ *sks->caseSensitivity = Z_SortKeySpec_caseSensitive;
+
+#ifdef ASN_COMPILED
+ sks->which = Z_SortKeySpec_null;
+ sks->u.null = odr_nullval ();
+#else
+ sks->missingValueAction = NULL;
+#endif
+
+ for (i = 0; sort_flags[i]; i++)
+ {
+ switch (sort_flags[i])
+ {
+ case 'a':
+ case 'A':
+ case '>':
+ *sks->sortRelation = Z_SortKeySpec_descending;
+ break;
+ case 'd':
+ case 'D':
+ case '<':
+ *sks->sortRelation = Z_SortKeySpec_ascending;
+ break;
+ case 'i':
+ case 'I':
+ *sks->caseSensitivity = Z_SortKeySpec_caseInsensitive;
+ break;
+ case 'S':
+ case 's':
+ *sks->caseSensitivity = Z_SortKeySpec_caseSensitive;
+ break;
+ }
+ }
+ }
+ if (!sksl->num_specs)
+ {
+ printf ("Missing sort specifications\n");
+ return -1;
+ }
+ return ir_tcl_send_APDU (interp, p, apdu, "sort", *argv);
+}
+