Net-Z3950
view release on metacpan or search on metacpan
yazwrap/send.c view on Meta::CPAN
*req->numberOfRecordsRequested = numberOfRecordsRequested;
req->num_ranges = 0; /* ### would be nice to support this */
req->recordComposition = &rcomp;
rcomp.which = Z_RecordComp_simple; /* ### espec suppport would be nice */
rcomp.u.simple = &esname;
esname.which = Z_ElementSetNames_generic;
esname.u.generic = elementSetName;
if ((req->preferredRecordSyntax =
record_syntax(odr, preferredRecordSyntax)) == 0)
return nodata(*errmsgp = "can't convert record syntax");
return encode_apdu(odr, apdu, errmsgp);
}
databuf makeDeleteRSRequest(databuf referenceId,
char *resultSetId,
char **errmsgp)
{
static ODR odr = 0;
Z_APDU *apdu;
Z_DeleteResultSetRequest *req;
Z_ReferenceId zr;
Z_ResultSetId *rsList[1];
int x;
if (!prepare_odr(&odr, errmsgp))
return nodata((char*) 0);
apdu = zget_APDU(odr, Z_APDU_deleteResultSetRequest);
req = apdu->u.deleteResultSetRequest;
req->referenceId = make_ref_id(&zr, referenceId);
req->deleteFunction = &x;
x = Z_DeleteResultSetRequest_list;
req->num_resultSetList = 1;
req->resultSetList = &rsList[0];
rsList[0] = resultSetId;
return encode_apdu(odr, apdu, errmsgp);
}
/*
* If refId is non-null, copy it into the provided buffer, and return
* a pointer to it; otherwise, return a null pointer. Either way, the
* result is suitable to by plugged into an APDU structure.
*/
Z_ReferenceId *make_ref_id(Z_ReferenceId *buf, databuf refId)
{
if (refId.data == 0)
return 0;
buf->buf = (unsigned char*) refId.data;
buf->len = (int) refId.len;
return buf;
}
static Odr_oid *record_syntax(ODR odr, int preferredRecordSyntax)
{
oident prefsyn;
int oidbuf[20]; /* more than enough */
int *oid;
prefsyn.proto = PROTO_Z3950;
prefsyn.oclass = CLASS_RECSYN;
prefsyn.value = (oid_value) preferredRecordSyntax;
if ((oid = oid_ent_to_oid(&prefsyn, oidbuf)) == 0)
return 0;
return odr_oiddup(odr, oid);
}
/*
* Memory management strategy: every APDU we're asked to allocate
* obliterates the previous one by overwriting our static ODR buffer,
* so the caller _must_ ensure that it copies or otherwise consumes
* the return value before the next call is made. (This strategy
* would normally stink, but it's actually not error-prone in this
* context, since we know that the Perl XS code is about to copy the
* data onto its stack.)
*/
static databuf encode_apdu(ODR odr, Z_APDU *apdu, char **errmsgp)
{
databuf res;
int len;
res.len = 0; /* Not needed, but prevents compiler warning */
res.data = 0;
if (!z_APDU(odr, &apdu, 0, (char*) 0)) {
*errmsgp = odr_errmsg(odr_geterror(odr));
return res;
}
res.data = odr_getbuf(odr, &len, (int*) 0);
res.len = len;
return res;
}
static int prepare_odr(ODR *odrp, char **errmsgp)
{
if (*odrp != 0) {
odr_reset(*odrp);
} else if ((*odrp = odr_createmem(ODR_ENCODE)) == 0) {
*errmsgp = "can't create ODR stream";
return 0;
}
return 1;
}
/*
* Return a databuf with a null pointer (used as an error indicator)
* (In passing, we also report to stderr what the problem was.)
*/
static databuf nodata(char *msg)
{
databuf buf;
#ifndef NDEBUG
if (msg != 0) {
fprintf(stderr, "DEBUG nodata(): %s\n", msg);
}
#endif
buf.len = 0; /* Not needed, but prevents compiler warning */
( run in 1.915 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )