From: Adam Dickmeiss Date: Sun, 11 Nov 2001 22:25:25 +0000 (+0000) Subject: Protocol behavior sections. record_get raw returning Z External *. X-Git-Tag: YAZ.1.8.2~5 X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=commitdiff_plain;h=49218d3cab22778f7460f1099d0534e057be629f Protocol behavior sections. record_get raw returning Z External *. --- diff --git a/doc/zoom.xml b/doc/zoom.xml index c350599..2937474 100644 --- a/doc/zoom.xml +++ b/doc/zoom.xml @@ -1,4 +1,4 @@ - + Building clients with ZOOM @@ -40,6 +40,11 @@ that because of typedefs. All destroy methods should gracefully ignore a NULL pointer. + + In each of the sections below you'll find a sub section called + protocol behavior, that descries how the API maps to the Z39.50 + protocol. + Connections The Connection object is a session with a target. @@ -122,7 +127,8 @@ asyncIf true (1) the connection operates in asynchronous operation which means that all calls are non-blocking - except Z3950_event. + except + Z3950_event. 0 maximumRecordSize Maximum size of single record. @@ -153,6 +159,44 @@ holds messages for the error and additional-info if passed as non-NULL. + Protocol behavior + + The calls Z3950_connection_new and + Z3950_connection_connect establises a TCP/IP + connection and sends an Initialize Request to the target if + possible. In addition, the calls waits for an Initialize Response + from the target and the result is inspected (OK or rejected). + + + If proxy is set then the client will establish + a TCP/IP connection with the peer as specified by the + proxy host and the hostname as part of the + connect calls will be set as part of the Initialize Request. + The proxy server will then "forward" the PDU's transparently + to the target behind the proxy. + + + For the authentication parameters, if option user + is set and both options group and + pass are unset, then Open style + authentication is used (Version 2/3) in which case the username + is usually followed by a slash, then by a password. + If either group + or pass is set then idPass authentication + (Version 3 only) is used. If none of the options are set, no + authentication parameters are set as part of the Initialize Request + (obviously). + + + When option async is 1, it really means that + all network operations are postponed (and queued) until the + function Z3950_event is invoked. When doing so + it doesn't make sense to check for errors after + Z3950_connection_new is called since that + operation "connecting - and init" is still incomplete and the + API cannot tell the outcome (yet). + + Queries @@ -180,6 +224,13 @@ sort criteria using the same string notation for sort as offered by the YAZ client. + Protocol behavior + + The query object is just an interface for the member Query + in the SearchRequest. The sortby-function is an interface to the + sortSequence member of the SortRequest. + + Result sets @@ -269,8 +320,8 @@ value, then target will return all records using small element set name 0 - largeSetLowerBoundIf hits is greator than this value, the target - will return no records. + largeSetLowerBoundIf hits is greator than this + value, the target will return no records. 1 mediumSetPresentNumberThis value represents @@ -293,6 +344,57 @@ + + Protocol behavior + + The creation of a result set involves at least a SearchRequest + - SearchResponse protocol handshake. Following that, if a sort + critieria was specified as part of the query, a sortRequest - + SortResponse handshake takes place. Note that it is necessary to + perform sorting before any retrieval takes place, so no records will + be returned from the target as part of the SearchResponse because these + would be unsorted. Hence, piggyback is disabled when sort critieria + is set. Following Search - and a Possible sort, Retrieval takes + place - as one or more Present Requests - Present Response being + transferred. + + + The API allows for two different modes for retrieval. A high level + mode which is somewhat more powerful and a low level one. + The low level is "enabled" when the settings + smallSetUpperBound, + mediumSetPresentNumber and + largeSetLowerBound are set. The low level mode + thus allows you to precisely set how records are returned as part + of a search response as offered by the Z39.50 protocol. + Since the client may be retrieving records as part of the + search response, this mode doesn't work well if sorting is used. + + + The high-level mode allows you to fetch a range of records from + the result set with a given start offset. When you use this mode + the client will automatically use piggyback if that is possible + with the target and perform one or more present requests as needed. + Even if the target returns fewer records as part of a present response + because of a record size limit, etc. the client will repeat sending + present requests. As an example, if option start + is 0 (default) and count is 4, and + piggyback is 1 (default) and no sorting critieria + is specified, then the client will attempt to retrieve the 4 + records as part the search response (using piggyback). On the other + hand, if either start is positive or if + a sorting criteria is set, or if piggyback + is 0, then the client will not perform piggyback but send Present + Requests instead. + + + If either of the options mediumSetElementSetName and + smallSetElementSetName are unset, the value + of option elementSetName is used for piggyback + searches. This means that for the high-level mode you only have + to specify one elementSetName option rather than three. + + Records @@ -326,7 +428,8 @@ Function Z3950_resultset_records retrieves a number of records from a result set. Parameter start and count specifies the range of records to - be returned. Upon completion array recs[0], ..recs[count-1] + be returned. Upon completion array + recs[0], ..recs[count-1] holds record objects for the records. The array of records recs should be allocate prior to calling Z3950_resultset_records. Note that for those @@ -340,14 +443,47 @@ nature (type) of the pointer depends on the type given. In addition for certain types, the length len passed will be set to the size in bytes of - the returned information. The types database, - syntax and render are - supported. More will be added later. + the returned information. + + database + The database that holds the record is returned + as a C string. Return type char *. + + + syntax + The transfer syntax (OID) of the record is returned + as a C string. Return type char *. + + + render + The record is returned in a display friendly + format. Upon completion buffer is returned + (type char *) and length is stored in + *len. + + + raw + The record is returned in the internal + YAZ specific format. The raw data is returned as type + Z_External * is just the type for + the member retrievalRecord in + type NamePlusRecord. + + + + Protocol behavior + + The functions Z3950_resultset_record and + Z3950_resultset_records inspects the client-side + record cache. If the records(s) were not found, i.e. not yet retrieved + from, they are fetched using Present Requests. + + Options - Most &zoom; objects provide a way to specify options to default behaviour. + Most &zoom; objects provide a way to specify options to default behavior. From an implementation point of view a set of options is just like an associate array / hash array, etc. @@ -394,7 +530,7 @@ occurred for connection cs[n-1]. When no events are pending for the connections, a value of zero is returned. - To make sure all outstanding requests are performed call this function + To ensure that all outstanding requests are performed call this function repeatedly until zero is returned. diff --git a/zoom/zoom-c.c b/zoom/zoom-c.c index 8b38ce3..21ae004 100644 --- a/zoom/zoom-c.c +++ b/zoom/zoom-c.c @@ -1,5 +1,5 @@ /* - * $Id: zoom-c.c,v 1.3 2001-11-06 17:05:19 adam Exp $ + * $Id: zoom-c.c,v 1.4 2001-11-11 22:25:25 adam Exp $ * * ZOOM layer for C, connections, result sets, queries. */ @@ -12,6 +12,12 @@ #include "zoom-p.h" +#define USE_POLL 0 + +#if USE_POLL +#include +#endif + static Z3950_record record_cache_lookup (Z3950_resultset r, int pos, const char *elementSetName); @@ -434,7 +440,8 @@ static void do_connect (Z3950_connection c) if (ret >= 0) { c->state = STATE_CONNECTING; - c->mask = Z3950_SELECT_READ | Z3950_SELECT_WRITE | Z3950_SELECT_EXCEPT; + c->mask = Z3950_SELECT_READ | Z3950_SELECT_WRITE | + Z3950_SELECT_EXCEPT; return; } } @@ -820,6 +827,15 @@ void *Z3950_record_get (Z3950_record rec, const char *type, size_t *len) } return 0; } + else if (!strcmp (type, "raw")) + { + if (npr->which == Z_NamePlusRecord_databaseRecord) + { + *len = -1; + return (Z_External *) npr->u.databaseRecord; + } + return 0; + } return 0; } @@ -1192,12 +1208,12 @@ static int do_write_ex (Z3950_connection c, char *buf_out, int len_out) else if (r == 1) { c->state = STATE_ESTABLISHED; - c->mask = Z3950_SELECT_READ|Z3950_SELECT_WRITE; + c->mask = Z3950_SELECT_READ|Z3950_SELECT_WRITE|Z3950_SELECT_EXCEPT; } else { c->state = STATE_ESTABLISHED; - c->mask = Z3950_SELECT_READ; + c->mask = Z3950_SELECT_READ|Z3950_SELECT_EXCEPT; } return 0; } @@ -1293,7 +1309,7 @@ int Z3950_connection_do_io(Z3950_connection c, int mask) { #if 0 int r = cs_look(c->cs); - yaz_log (LOG_DEBUG, "Z3950_connection_do_io c=%p mask=%d cs_look=%d", + yaz_log (LOG_LOG, "Z3950_connection_do_io c=%p mask=%d cs_look=%d", c, mask, r); if (r == CS_NONE) @@ -1303,7 +1319,7 @@ int Z3950_connection_do_io(Z3950_connection c, int mask) } else if (r == CS_CONNECT) { - yaz_log (LOG_DEBUG, "calling rcvconnect"); + yaz_log (LOG_LOG, "calling rcvconnect"); if (cs_rcvconnect (c->cs) < 0) { c->error = Z3950_ERROR_CONNECT; @@ -1350,9 +1366,14 @@ int Z3950_connection_do_io(Z3950_connection c, int mask) int Z3950_event (int no, Z3950_connection *cs) { +#if USE_POLL + struct pollfd pollfds[1024]; + Z3950_connection poll_cs[1024]; +#else struct timeval tv; fd_set input, output, except; - int i, r; +#endif + int i, r, nfds; int max_fd = 0; for (i = 0; imask) + { + int mask = 0; + if (pollfds[i].revents & POLLIN) + mask += Z3950_SELECT_READ; + if (pollfds[i].revents & POLLOUT) + mask += Z3950_SELECT_WRITE; + if (pollfds[i].revents & POLLERR) + mask += Z3950_SELECT_EXCEPT; + if (mask) + Z3950_connection_do_io(c, mask); + } + else if (r == 0 && c->mask) + { + /* timeout and this connection was waiting */ + c->error = Z3950_ERROR_TIMEOUT; + c->event_pending = 1; + } + } +#else yaz_log (LOG_DEBUG, "select start"); r = select (max_fd+1, &input, &output, &except, &tv); yaz_log (LOG_DEBUG, "select stop, returned r=%d", r); - for (i = 0; ievent_pending = 1; } } +#endif + for (i = 0; i