* Sebastian Hammer, Adam Dickmeiss
*
* $Log: seshigh.c,v $
- * Revision 1.38 1995-06-19 12:39:11 quinn
+ * Revision 1.45 1995-08-21 09:11:00 quinn
+ * Smallish fixes to suppport new formats.
+ *
+ * Revision 1.44 1995/08/17 12:45:25 quinn
+ * Fixed minor problems with GRS-1. Added support in c&s.
+ *
+ * Revision 1.43 1995/08/15 12:00:31 quinn
+ * Updated External
+ *
+ * Revision 1.42 1995/08/15 11:16:50 quinn
+ * CV:e ----------------------------------------------------------------------
+ * CV:e ----------------------------------------------------------------------
+ *
+ * Revision 1.41 1995/08/02 10:23:06 quinn
+ * Smallish
+ *
+ * Revision 1.40 1995/07/31 14:34:26 quinn
+ * Fixed bug in process_searchResponse (numberOfRecordsReturned).
+ *
+ * Revision 1.39 1995/06/27 13:21:00 quinn
+ * SUTRS support
+ *
+ * Revision 1.38 1995/06/19 12:39:11 quinn
* Fixed bug in timeout code. Added BER dumper.
*
* Revision 1.37 1995/06/16 13:16:14 quinn
static Z_Records *pack_records(association *a, char *setname, int start,
int *num, Z_ElementSetNames *esn,
- int *next, int *pres)
+ int *next, int *pres, oid_value format)
{
int recno, total_length = 0, toget = *num;
static Z_Records records;
static Z_NamePlusRecordList reclist;
static Z_NamePlusRecord *list[MAX_RECORDS];
oident recform;
- Odr_oid *oid;
records.which = Z_Records_DBOSD;
records.u.databaseOrSurDiagnostics = &reclist;
*num = 0;
*next = 0;
- recform.proto = a->proto;
- recform.class = CLASS_RECSYN;
- recform.value = VAL_USMARC;
- if (!(oid = odr_oiddup(a->encode, oid_getoidbyent(&recform))))
- return 0;
-
logf(LOG_DEBUG, "Request to pack %d+%d", start, toget);
logf(LOG_DEBUG, "pms=%d, mrs=%d", a->preferredMessageSize,
a->maximumRecordSize);
bend_fetchresult *fres;
Z_NamePlusRecord *thisrec;
Z_DatabaseRecord *thisext;
+ int this_length;
+ /*
+ * we get the number of bytes allocated on the stream before any
+ * allocation done by the backend - this should give us a reasonable
+ * idea of the total size of the data so far.
+ */
+ total_length = odr_total(a->encode);
if (reclist.num_records == MAX_RECORDS - 1)
{
*pres = Z_PRES_PARTIAL_2;
}
freq.setname = setname;
freq.number = recno;
+ freq.format = format;
+ freq.stream = a->encode;
if (!(fres = bend_fetch(a->backend, &freq, 0)))
{
*pres = Z_PRES_FAILURE;
*pres = Z_PRES_FAILURE;
return diagrec(a->proto, fres->errcode, fres->errstring);
}
+ if (fres->len >= 0)
+ this_length = fres->len;
+ else
+ this_length = odr_total(a->encode) - total_length;
logf(LOG_DEBUG, " fetched record, len=%d, total=%d",
- fres->len, total_length);
- if (fres->len + total_length > a->preferredMessageSize)
+ this_length, total_length);
+ if (this_length + total_length > a->preferredMessageSize)
{
/* record is small enough, really */
- if (fres->len <= a->preferredMessageSize)
+ if (this_length <= a->preferredMessageSize)
{
logf(LOG_DEBUG, " Dropped last normal-sized record");
*pres = Z_PRES_PARTIAL_2;
break;
}
/* record can only be fetched by itself */
- if (fres->len < a->maximumRecordSize)
+ if (this_length < a->maximumRecordSize)
{
logf(LOG_DEBUG, " Record > prefmsgsz");
if (toget > 1)
reclist.records[reclist.num_records] =
surrogatediagrec(a->proto, fres->basename, 16, 0);
reclist.num_records++;
- total_length += 10; /* totally arbitrary */
continue;
}
}
reclist.records[reclist.num_records] =
surrogatediagrec(a->proto, fres->basename, 17, 0);
reclist.num_records++;
- total_length += 10; /* totally arbitrary */
continue;
}
}
if (!(thisrec->u.databaseRecord = thisext = odr_malloc(a->encode,
sizeof(Z_DatabaseRecord))))
return 0;
- thisext->direct_reference = oid; /* should be OID for current MARC */
+ recform.proto = a->proto;
+ recform.class = CLASS_RECSYN;
+ recform.value = fres->format;
+ thisext->direct_reference = odr_oiddup(a->encode,
+ oid_getoidbyent(&recform));
thisext->indirect_reference = 0;
thisext->descriptor = 0;
- thisext->which = ODR_EXTERNAL_octet;
- if (!(thisext->u.octet_aligned = odr_malloc(a->encode,
- sizeof(Odr_oct))))
- return 0;
- if (!(thisext->u.octet_aligned->buf = odr_malloc(a->encode, fres->len)))
- return 0;
- memcpy(thisext->u.octet_aligned->buf, fres->record, fres->len);
- thisext->u.octet_aligned->len = thisext->u.octet_aligned->size =
- fres->len;
+ if (fres->len < 0) /* Structured data */
+ {
+ switch (fres->format)
+ {
+ case VAL_SUTRS: thisext->which = Z_External_sutrs; break;
+ case VAL_GRS1: thisext->which = Z_External_grs1; break;
+ case VAL_EXPLAIN: thisext->which = Z_External_explainRecord;
+ break;
+
+ default:
+ logf(LOG_FATAL, "Unknown structured format from backend.");
+ return 0;
+ }
+
+ /*
+ * We cheat on the pointers here. Obviously, the record field
+ * of the backend-fetch structure should have been a union for
+ * correctness, but we're stuck with this for backwards
+ * compatibility.
+ */
+ thisext->u.grs1 = (Z_GenericRecord*) fres->record;
+ }
+ else if (fres->format == VAL_SUTRS) /* SUTRS is a single-ASN.1-type */
+ {
+ Odr_oct *sutrs = odr_malloc(a->encode, sizeof(*sutrs));
+
+ thisext->which = Z_External_sutrs;
+ thisext->u.sutrs = sutrs;
+ sutrs->buf = odr_malloc(a->encode, fres->len);
+ sutrs->len = sutrs->size = fres->len;
+ memcpy(sutrs->buf, fres->record, fres->len);
+ }
+ else /* octet-aligned record. */
+ {
+ thisext->which = Z_External_octet;
+ if (!(thisext->u.octet_aligned = odr_malloc(a->encode,
+ sizeof(Odr_oct))))
+ return 0;
+ if (!(thisext->u.octet_aligned->buf = odr_malloc(a->encode,
+ fres->len)))
+ return 0;
+ memcpy(thisext->u.octet_aligned->buf, fres->record, fres->len);
+ thisext->u.octet_aligned->len = thisext->u.octet_aligned->size =
+ fres->len;
+ }
reclist.records[reclist.num_records] = thisrec;
reclist.num_records++;
- total_length += fres->len;
*next = fres->last_in_set ? 0 : recno + 1;
}
*num = reclist.num_records;
}
else
{
- int toget;
+ static int toget;
Z_ElementSetNames *setnames;
- int presst = 0;
+ static int presst = 0;
resp.records = 0;
resp.resultCount = &bsrt->hits;
if (toget && !resp.records)
{
+ oident *prefformat;
+ oid_value form;
+
+ if (!(prefformat = oid_getentbyoid(req->preferredRecordSyntax)) ||
+ prefformat->class != CLASS_RECSYN)
+ form = VAL_NONE;
+ else
+ form = prefformat->value;
resp.records = pack_records(assoc, req->resultSetName, 1,
- &toget, setnames, &next, &presst);
+ &toget, setnames, &next, &presst, form);
if (!resp.records)
return 0;
resp.numberOfRecordsReturned = &toget;
}
else
{
+ if (*resp.resultCount)
+ next = 1;
resp.numberOfRecordsReturned = &nulint;
resp.nextResultSetPosition = &next;
resp.searchStatus = &sr;
static Z_APDU apdu;
static Z_PresentResponse resp;
static int presst, next, num;
+ oident *prefformat;
+ oid_value form;
+
logf(LOG_LOG, "Got PresentRequest.");
apdu.which = Z_APDU_presentResponse;
resp.otherInfo = 0;
#endif
+ if (!(prefformat = oid_getentbyoid(req->preferredRecordSyntax)) ||
+ prefformat->class != CLASS_RECSYN)
+ form = VAL_NONE;
+ else
+ form = prefformat->value;
num = *req->numberOfRecordsRequested;
resp.records = pack_records(assoc, req->resultSetId,
- *req->resultSetStartPoint, &num, 0, &next, &presst);
+ *req->resultSetStartPoint, &num, 0, &next, &presst, form);
if (!resp.records)
return 0;
resp.numberOfRecordsReturned = #