X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fsrwutil.c;h=226b43aae874ebdfdfa904b9199633d1b34b09bc;hb=073195289eb9b73d6793fa283e5a7dca7a24fba8;hp=581c00d53a4008ef5588eb898ec7ee8c7e377daf;hpb=b462b5047a365a76a5be26341e62b69076a33d3a;p=yaz-moved-to-github.git diff --git a/src/srwutil.c b/src/srwutil.c index 581c00d..226b43a 100644 --- a/src/srwutil.c +++ b/src/srwutil.c @@ -2,7 +2,7 @@ * Copyright (c) 2002-2004, Index Data. * See the file LICENSE for details. * - * $Id: srwutil.c,v 1.6 2004-01-07 20:36:44 adam Exp $ + * $Id: srwutil.c,v 1.8 2004-01-09 18:10:32 adam Exp $ */ #include @@ -19,6 +19,65 @@ static int hex_digit (int ch) return 0; } +int yaz_uri_array(const char *path, ODR o, char ***name, char ***val) +{ + int no = 2; + const char *cp; + *name = 0; + if (*path != '?') + return no; + path++; + cp = path; + while ((cp = strchr(cp, '&'))) + { + cp++; + no++; + } + *name = odr_malloc(o, no * sizeof(char**)); + *val = odr_malloc(o, no * sizeof(char**)); + + for (no = 0; *path; no++) + { + const char *p1 = strchr(path, '='); + size_t i = 0; + char *ret; + if (!p1) + break; + + (*name)[no] = odr_malloc(o, (p1-path)+1); + memcpy((*name)[no], path, p1-path); + (*name)[no][p1-path] = '\0'; + + path = p1 + 1; + p1 = strchr(path, '&'); + if (!p1) + p1 = strlen(path) + path; + (*val)[no] = ret = odr_malloc(o, p1 - path + 1); + while (*path && *path != '&') + { + if (*path == '+') + { + ret[i++] = ' '; + path++; + } + else if (*path == '%' && path[1] && path[2]) + { + ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]); + path = path + 3; + } + else + ret[i++] = *path++; + } + ret[i] = '\0'; + + if (*path) + path++; + } + (*name)[no] = 0; + (*val)[no] = 0; + return no; +} + char *yaz_uri_val(const char *path, const char *name, ODR o) { size_t nlen = strlen(name); @@ -72,6 +131,22 @@ void yaz_uri_val_int(const char *path, const char *name, ODR o, int **intp) *intp = odr_intdup(o, atoi(v)); } +void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d, + int *num, int code, const char *addinfo) +{ + Z_SRW_diagnostic *d_new; + d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d)); + if (*num) + memcpy (d_new, *d, *num *sizeof(**d)); + *d = d_new; + (*d + *num)->code = odr_intdup(o, code); + if (addinfo) + (*d + *num)->details = odr_strdup(o, addinfo); + else + (*d + *num)->details = 0; + (*num)++; +} + int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, Z_SOAP **soap_package, ODR decode, char **charset) { @@ -147,7 +222,8 @@ int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, } int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, - Z_SOAP **soap_package, ODR decode, char **charset) + Z_SOAP **soap_package, ODR decode, char **charset, + Z_SRW_diagnostic **diag, int *num_diag) { #if HAVE_XML2 static Z_SOAP_Handler soap_handlers[2] = { @@ -161,10 +237,20 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, char *db = "Default"; const char *p0 = hreq->path, *p1; const char *operation = 0; + char *version = 0; char *query = 0; char *pQuery = 0; + char *sortKeys = 0; char *stylesheet = 0; - + char *scanClause = 0; + char *recordXPath = 0; + char *recordSchema = 0; + char *recordPacking = "xml"; + char *maximumRecords = 0; + char *startRecord = 0; + char **uri_name; + char **uri_val; + if (charset) *charset = 0; if (*p0 == '/') @@ -178,45 +264,87 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, memcpy (db, p0, p1 - p0); db[p1 - p0] = '\0'; } + yaz_uri_array(p1, decode, &uri_name, &uri_val); #if HAVE_XML2 - query = yaz_uri_val(p1, "query", decode); - pQuery = yaz_uri_val(p1, "pQuery", decode); - operation = yaz_uri_val(p1, "operation", decode); - stylesheet = yaz_uri_val(p1, "stylesheet", decode); + if (uri_name) + { + int i; + for (i = 0; uri_name[i]; i++) + { + char *n = uri_name[i]; + char *v = uri_val[i]; + if (!strcmp(n, "query")) + query = v; + else if (!strcmp(n, "x-pquery")) + pQuery = v; + else if (!strcmp(n, "operation")) + operation = v; + else if (!strcmp(n, "stylesheet")) + stylesheet = v; + else if (!strcmp(n, "sortKeys")) + sortKeys = v; + else if (!strcmp(n, "recordXPath")) + recordXPath = v; + else if (!strcmp(n, "recordSchema")) + recordSchema = v; + else if (!strcmp(n, "recordPacking")) + recordPacking = v; + else if (!strcmp(n, "version")) + version = v; + else if (!strcmp(n, "scanClause")) + scanClause = v; + else if (!strcmp(n, "maximumRecords")) + maximumRecords = v; + else if (!strcmp(n, "startRecord")) + startRecord = v; + else + yaz_add_srw_diagnostic(decode, diag, num_diag, 9, n); + } + } + if (!version) + yaz_add_srw_diagnostic(decode, diag, num_diag, 7, "version"); + else if (version && strcmp(version, "1.1")) + yaz_add_srw_diagnostic(decode, diag, num_diag, 5, "1.1"); if (!operation) + { + yaz_add_srw_diagnostic(decode, diag, num_diag, 7, "operation"); operation = "explain"; - if ((operation && !strcmp(operation, "searchRetrieve")) - || pQuery || query) + } + if (!strcmp(operation, "searchRetrieve")) { Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request); - char *sortKeys = yaz_uri_val(p1, "sortKeys", decode); - + + sr->srw_version = version; *srw_pdu = sr; if (query) { sr->u.request->query_type = Z_SRW_query_type_cql; sr->u.request->query.cql = query; } - if (pQuery) + else if (pQuery) { sr->u.request->query_type = Z_SRW_query_type_pqf; sr->u.request->query.pqf = pQuery; } + else + yaz_add_srw_diagnostic(decode, diag, num_diag, 7, "query"); + if (sortKeys) { sr->u.request->sort_type = Z_SRW_sort_type_sort; sr->u.request->sort.sortKeys = sortKeys; } - sr->u.request->recordSchema = yaz_uri_val(p1, "recordSchema", decode); - sr->u.request->recordPacking = yaz_uri_val(p1, "recordPacking", decode); + sr->u.request->recordXPath = recordXPath; + sr->u.request->recordSchema = recordSchema; + sr->u.request->recordPacking = recordPacking; sr->u.request->stylesheet = stylesheet; - if (!sr->u.request->recordPacking) - sr->u.request->recordPacking = "xml"; - yaz_uri_val_int(p1, "maximumRecords", decode, - &sr->u.request->maximumRecords); - yaz_uri_val_int(p1, "startRecord", decode, - &sr->u.request->startRecord); + if (maximumRecords) + sr->u.request->maximumRecords = + odr_intdup(decode, atoi(maximumRecords)); + if (startRecord) + sr->u.request->startRecord = + odr_intdup(decode, atoi(startRecord)); sr->u.request->database = db; @@ -234,15 +362,13 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, return 0; } - else if (p1 && !strcmp(operation, "explain")) + else if (!strcmp(operation, "explain")) { Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request); + sr->srw_version = version; *srw_pdu = sr; - sr->u.explain_request->recordPacking = - yaz_uri_val(p1, "recordPacking", decode); - if (!sr->u.explain_request->recordPacking) - sr->u.explain_request->recordPacking = "xml"; + sr->u.explain_request->recordPacking = recordPacking; sr->u.explain_request->database = db; sr->u.explain_request->stylesheet = stylesheet; @@ -261,6 +387,62 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, return 0; } + else if (!strcmp(operation, "scan")) + { + Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request); + + if (!scanClause) + yaz_add_srw_diagnostic(decode, diag, num_diag, 7, + "scanClause"); + sr->srw_version = version; + *srw_pdu = sr; + sr->u.scan_request->scanClause = scanClause; + sr->u.scan_request->database = db; + sr->u.scan_request->stylesheet = stylesheet; + + (*soap_package) = odr_malloc(decode, sizeof(**soap_package)); + (*soap_package)->which = Z_SOAP_generic; + + (*soap_package)->u.generic = + odr_malloc(decode, sizeof(*(*soap_package)->u.generic)); + + (*soap_package)->u.generic->p = sr; + (*soap_package)->u.generic->ns = soap_handlers[0].ns; + (*soap_package)->u.generic->no = 0; + + (*soap_package)->ns = "SRU"; + + return 0; + } + else + { + /* unsupported operation ... */ + /* Act as if we received a explain request and throw diagnostic. */ + + Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request); + + sr->srw_version = version; + *srw_pdu = sr; + sr->u.explain_request->recordPacking = recordPacking; + sr->u.explain_request->database = db; + + sr->u.explain_request->stylesheet = stylesheet; + + (*soap_package) = odr_malloc(decode, sizeof(**soap_package)); + (*soap_package)->which = Z_SOAP_generic; + + (*soap_package)->u.generic = + odr_malloc(decode, sizeof(*(*soap_package)->u.generic)); + + (*soap_package)->u.generic->p = sr; + (*soap_package)->u.generic->ns = soap_handlers[0].ns; + (*soap_package)->u.generic->no = 0; + + (*soap_package)->ns = "SRU"; + + yaz_add_srw_diagnostic(decode, diag, num_diag, 4, operation); + return 0; + } #endif return 1; } @@ -321,6 +503,23 @@ Z_SRW_PDU *yaz_srw_get(ODR o, int which) Z_SRW_recordPacking_string; sr->u.explain_response->diagnostics = 0; sr->u.explain_response->num_diagnostics = 0; + break; + case Z_SRW_scan_request: + sr->u.scan_request = (Z_SRW_scanRequest *) + odr_malloc(o, sizeof(*sr->u.scan_request)); + sr->u.scan_request->database = 0; + sr->u.scan_request->stylesheet = 0; + sr->u.scan_request->maximumTerms = 0; + sr->u.scan_request->responsePosition = 0; + sr->u.scan_request->scanClause = 0; + break; + case Z_SRW_scan_response: + sr->u.scan_response = (Z_SRW_scanResponse *) + odr_malloc(o, sizeof(*sr->u.scan_response)); + sr->u.scan_response->terms = 0; + sr->u.scan_response->num_terms = 0; + sr->u.scan_response->diagnostics = 0; + sr->u.scan_response->num_diagnostics = 0; } return sr; }