From: Adam Dickmeiss Date: Fri, 27 Sep 2013 13:16:06 +0000 (+0200) Subject: Merge branch 'master' into sru_2_0 X-Git-Tag: v5.0.0~16 X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=commitdiff_plain;h=04a6feeefe28e7f2f9f4701560b3344545a681c6;hp=6d59a642cb7cd71df249fc4ecf5928ea79c7038c Merge branch 'master' into sru_2_0 --- diff --git a/IDMETA b/IDMETA index 5c47833..16d4635 100755 --- a/IDMETA +++ b/IDMETA @@ -1,4 +1,4 @@ DEBIAN_DIST="wheezy squeeze" UBUNTU_DIST="quantal precise oneiric lucid" CENTOS_DIST="centos5 centos6" -VERSION=4.2.68 +VERSION=5.0.0 diff --git a/client/admin.c b/client/admin.c index 14aa281..de29207 100644 --- a/client/admin.c +++ b/client/admin.c @@ -237,9 +237,9 @@ int cmd_adm_import(const char *arg) Z_FragmentSyntax_notExternallyTagged; rec->u.intermediateFragment->u.notExternallyTagged = oct; - oct->len = oct->size = status.st_size; - oct->buf = (unsigned char *) odr_malloc (out, oct->size); - if (fread(oct->buf, 1, oct->size, inf) != (size_t) oct->size) + oct->len = status.st_size; + oct->buf = (char *) odr_malloc (out, oct->len); + if (fread(oct->buf, 1, oct->len, inf) != (size_t) oct->len) { printf("Incomplete read of file %s\n", fname); } diff --git a/client/client.c b/client/client.c index 18c763a..97773d0 100644 --- a/client/client.c +++ b/client/client.c @@ -83,6 +83,7 @@ static file_history_t file_history = 0; static char sru_method[10] = "soap"; static char sru_version[10] = "1.2"; +static char sru_recordPacking[10] = ""; static char *codeset = 0; /* character set for output */ static int hex_dump = 0; static char *dump_file_prefix = 0; @@ -252,9 +253,12 @@ static void add_otherInfos(Z_APDU *a) Z_OtherInformation **oi; int i; - yaz_oi_APDU(a, &oi); - if (facet_list) + if (facet_list && a->which == Z_APDU_searchRequest) + { + oi = &a->u.searchRequest->additionalSearchInfo; yaz_oi_set_facetlist(oi, out, facet_list); + } + yaz_oi_APDU(a, &oi); for (i = 0; i < maxOtherInfosSupported; ++i) { if (oid_oidlen(extraOtherInfos[i].oid) > 0) @@ -317,14 +321,9 @@ static void print_refid(Z_ReferenceId *id) static Z_ReferenceId *set_refid(ODR out) { - Z_ReferenceId *id; if (!refid) return 0; - id = (Z_ReferenceId *) odr_malloc(out, sizeof(*id)); - id->size = id->len = strlen(refid); - id->buf = (unsigned char *) odr_malloc(out, id->len); - memcpy(id->buf, refid, id->len); - return id; + return odr_create_Odr_oct(out, refid, strlen(refid)); } /* INIT SERVICE ------------------------------- */ @@ -1464,12 +1463,12 @@ static int send_SRW_scanRequest(const char *arg, Odr_int *pos, int num) switch (queryType) { case QueryType_CQL: - sr->u.scan_request->query_type = Z_SRW_query_type_cql; - sr->u.scan_request->scanClause.cql = encode_SRW_term(out, arg); + sr->u.scan_request->queryType = "cql"; + sr->u.scan_request->scanClause = encode_SRW_term(out, arg); break; case QueryType_Prefix: - sr->u.scan_request->query_type = Z_SRW_query_type_pqf; - sr->u.scan_request->scanClause.pqf = encode_SRW_term(out, arg); + sr->u.scan_request->queryType = "pqf"; + sr->u.scan_request->scanClause = encode_SRW_term(out, arg); break; default: printf("Only CQL and PQF supported in SRW\n"); @@ -1503,23 +1502,25 @@ static int send_SRW_searchRequest(const char *arg) switch (queryType) { case QueryType_CQL: - srw_sr->u.request->query_type = Z_SRW_query_type_cql; - srw_sr->u.request->query.cql = encode_SRW_term(srw_sr_odr_out, arg); + srw_sr->u.request->queryType = "cql"; + srw_sr->u.request->query = encode_SRW_term(srw_sr_odr_out, arg); - sr->u.request->query_type = Z_SRW_query_type_cql; - sr->u.request->query.cql = encode_SRW_term(srw_sr_odr_out, arg); + sr->u.request->queryType = "cql"; + sr->u.request->query = encode_SRW_term(srw_sr_odr_out, arg); break; case QueryType_Prefix: - srw_sr->u.request->query_type = Z_SRW_query_type_pqf; - srw_sr->u.request->query.pqf = encode_SRW_term(srw_sr_odr_out, arg); + srw_sr->u.request->queryType = "pqf"; + srw_sr->u.request->query = encode_SRW_term(srw_sr_odr_out, arg); - sr->u.request->query_type = Z_SRW_query_type_pqf; - sr->u.request->query.pqf = encode_SRW_term(srw_sr_odr_out, arg); + sr->u.request->queryType = "pqf"; + sr->u.request->query = encode_SRW_term(srw_sr_odr_out, arg); break; default: printf("Only CQL and PQF supported in SRW\n"); return 0; } + if (*sru_recordPacking) + sr->u.request->recordPacking = sru_recordPacking; sru_maximumRecords = 0; sr->u.request->maximumRecords = odr_intdup(out, 0); sr->u.request->facetList = facet_list; @@ -1604,12 +1605,12 @@ static int send_Z3950_searchRequest(const char *arg) req->referenceId = set_refid(out); if (!strcmp(arg, "@big")) /* strictly for troublemaking */ { - static unsigned char big[2100]; + static char big[2100]; static Odr_oct bigo; /* send a very big referenceid to test transport stack etc. */ memset(big, 'A', 2100); - bigo.len = bigo.size = 2100; + bigo.len = 2100; bigo.buf = big; req->referenceId = &bigo; } @@ -1663,7 +1664,7 @@ static int send_Z3950_searchRequest(const char *arg) case QueryType_CCL: query.which = Z_Query_type_2; query.u.type_2 = &ccl_query; - ccl_query.buf = (unsigned char*) arg; + ccl_query.buf = (char *) arg; ccl_query.len = strlen(arg); break; case QueryType_CCL2RPN: @@ -1911,7 +1912,7 @@ static void print_referenceId(int iLevel, Z_ReferenceId *referenceId) int i; print_level(iLevel); - printf("Ref Id (%d, %d): ", referenceId->len, referenceId->size); + printf("Ref Id (%d): ", referenceId->len); for (i = 0; i < referenceId->len; i++) printf("%c", referenceId->buf[i]); printf("\n"); @@ -2173,16 +2174,8 @@ static Z_External *create_external_itemRequest(void) r->indirect_reference = 0; r->descriptor = 0; r->which = Z_External_single; - - r->u.single_ASN1_type = (Odr_oct *) - odr_malloc(out, sizeof(*r->u.single_ASN1_type)); - r->u.single_ASN1_type->buf = (unsigned char *) - odr_malloc(out, item_request_size); - r->u.single_ASN1_type->len = item_request_size; - r->u.single_ASN1_type->size = item_request_size; - memcpy(r->u.single_ASN1_type->buf, item_request_buf, - item_request_size); - + r->u.single_ASN1_type = + odr_create_Odr_oct(out, item_request_buf, item_request_size); do_hex_dump(item_request_buf,item_request_size); } return r; @@ -2226,18 +2219,8 @@ static Z_External *create_external_ILL_APDU(void) r->indirect_reference = 0; r->descriptor = 0; r->which = Z_External_single; - - r->u.single_ASN1_type = (Odr_oct *) - odr_malloc(out, sizeof(*r->u.single_ASN1_type)); - r->u.single_ASN1_type->buf = (unsigned char *) - odr_malloc(out, ill_request_size); - r->u.single_ASN1_type->len = ill_request_size; - r->u.single_ASN1_type->size = ill_request_size; - memcpy(r->u.single_ASN1_type->buf, ill_request_buf, ill_request_size); -/* printf("len = %d\n", ill_request_size); */ -/* do_hex_dump(ill_request_buf,ill_request_size); */ -/* printf("--- end of extenal\n"); */ - + r->u.single_ASN1_type = odr_create_Odr_oct(out, ill_request_buf, + ill_request_size); } return r; } @@ -2526,16 +2509,8 @@ static int send_Z3950_update(int version, int action_no, const char *recid, notToKeep->elements[0] = (Z_IU0SuppliedRecords_elem *) odr_malloc(out, sizeof(**notToKeep->elements)); notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque; - if (recid) - { - notToKeep->elements[0]->u.opaque = (Odr_oct *) - odr_malloc(out, sizeof(Odr_oct)); - notToKeep->elements[0]->u.opaque->buf = (unsigned char *) recid; - notToKeep->elements[0]->u.opaque->size = strlen(recid); - notToKeep->elements[0]->u.opaque->len = strlen(recid); - } - else - notToKeep->elements[0]->u.opaque = 0; + notToKeep->elements[0]->u.opaque = recid ? + odr_create_Odr_oct(out, recid, strlen(recid)) : 0; notToKeep->elements[0]->supplementalId = 0; notToKeep->elements[0]->correlationInfo = 0; notToKeep->elements[0]->record = record_this; @@ -2573,16 +2548,8 @@ static int send_Z3950_update(int version, int action_no, const char *recid, notToKeep->elements[0] = (Z_IUSuppliedRecords_elem *) odr_malloc(out, sizeof(**notToKeep->elements)); notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque; - if (recid) - { - notToKeep->elements[0]->u.opaque = (Odr_oct *) - odr_malloc(out, sizeof(Odr_oct)); - notToKeep->elements[0]->u.opaque->buf = (unsigned char *) recid; - notToKeep->elements[0]->u.opaque->size = strlen(recid); - notToKeep->elements[0]->u.opaque->len = strlen(recid); - } - else - notToKeep->elements[0]->u.opaque = 0; + notToKeep->elements[0]->u.opaque = recid ? + odr_create_Odr_oct(out, recid, strlen(recid)) : 0; notToKeep->elements[0]->supplementalId = 0; notToKeep->elements[0]->correlationInfo = 0; notToKeep->elements[0]->record = record_this; @@ -2626,7 +2593,7 @@ static int cmd_xmles(const char *arg) &ext->u.single_ASN1_type->len) == 0) return 0; - ext->u.single_ASN1_type->buf = (unsigned char *) asn_buf; + ext->u.single_ASN1_type->buf = asn_buf; oid = yaz_string_to_oid_odr(yaz_oid_std(), CLASS_EXTSERV, oid_str, out); @@ -2869,7 +2836,8 @@ static int cmd_sru(const char *arg) } else { - int r = sscanf(arg, "%9s %9s", sru_method, sru_version); + int r = sscanf(arg, "%9s %9s %9s", sru_method, sru_version, + sru_recordPacking); if (r >= 1) { if (!yaz_matchstr(sru_method, "post")) @@ -3212,6 +3180,8 @@ static int send_SRW_presentRequest(const char *arg) return 0; if (!parse_show_args(arg, setstring, &setno, &nos)) return 0; + if (*sru_recordPacking) + sr->u.request->recordPacking = sru_recordPacking; sr->u.request->startRecord = odr_intdup(out, setno); sru_maximumRecords = nos; sr->u.request->maximumRecords = odr_intdup(out, nos); @@ -3428,10 +3398,8 @@ static int send_Z3950_scanrequest(const char *set, const char *query, req->termListAndStartPoint->term->u.general) { req->termListAndStartPoint->term->u.general->buf = - (unsigned char *) odr_strdup(out, term); - req->termListAndStartPoint->term->u.general->len = - req->termListAndStartPoint->term->u.general->size = - strlen(term); + odr_strdup(out, term); + req->termListAndStartPoint->term->u.general->len = strlen(term); } } req->referenceId = set_refid(out); @@ -4499,7 +4467,7 @@ static void http_response(Z_HTTP_Response *hres) Z_SOAP *soap_package = 0; ODR o = odr_createmem(ODR_DECODE); Z_SOAP_Handler soap_handlers[] = { - {YAZ_XMLNS_SRU_v2_response, 0, (Z_SOAP_fun) yaz_srw_codec}, + {YAZ_XMLNS_SRU_v2_mask, 0, (Z_SOAP_fun) yaz_srw_codec}, {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec}, {YAZ_XMLNS_SRU_v1_response, 0, (Z_SOAP_fun) yaz_srw_codec}, {0, 0, 0} diff --git a/debian/changelog b/debian/changelog index 2e1b3e5..7f3b93f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +yaz (5.0.0-1indexdata) unstable; urgency=low + + * Version 5. + + -- Adam Dickmeiss Wed, 11 Sep 2013 09:26:11 +0200 + yaz (4.2.68-1indexdata) unstable; urgency=low * Upstream. diff --git a/debian/compat b/debian/compat index 7ed6ff8..7f8f011 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -5 +7 diff --git a/debian/control b/debian/control index 0a978bf..e39c906 100644 --- a/debian/control +++ b/debian/control @@ -3,7 +3,7 @@ Section: devel Standards-Version: 3.6.2 Maintainer: Adam Dickmeiss Priority: extra -Build-Depends: debhelper (>= 5), +Build-Depends: debhelper (>= 7), pkg-config, libxslt1-dev, libgnutls-dev, @@ -11,7 +11,7 @@ Build-Depends: debhelper (>= 5), libwrap0-dev, libicu-dev -Package: libyaz4 +Package: libyaz5 Section: libs Architecture: any Depends: ${shlibs:Depends} @@ -22,15 +22,15 @@ Description: libraries for the Z39.50 toolkit . This package includes runtime files. -Package: libyaz4-dbg +Package: libyaz5-dbg Section: debug Architecture: any -Depends: libyaz4 (= ${binary:Version}), ${misc:Depends} -Description: debugging symbols for libyaz4 +Depends: libyaz5 (= ${binary:Version}), ${misc:Depends} +Description: debugging symbols for libyaz5 YAZ is a toolkit that allows you to develop software using the ANSI Z39.50/ISO23950 standard for information retrieval. . - This package contains the debugging symbols for libyaz4. + This package contains the debugging symbols for libyaz5. Package: yaz Section: utils @@ -52,8 +52,8 @@ Description: documentation for the Z39.50 toolkit . This package includes HTML documentation for YAZ. -Package: libyaz4-dev -Depends: libyaz4 (= ${Source-Version}), +Package: libyaz5-dev +Depends: libyaz5 (= ${Source-Version}), libxslt1-dev, libicu-dev, tclsh diff --git a/debian/libyaz4-dev.install b/debian/libyaz4-dev.install deleted file mode 100644 index 5e8060d..0000000 --- a/debian/libyaz4-dev.install +++ /dev/null @@ -1,8 +0,0 @@ -debian/tmp/usr/include/yaz -debian/tmp/usr/lib/pkgconfig/yaz.pc -debian/tmp/usr/lib/libyaz*.a -debian/tmp/usr/lib/libyaz*.so -debian/tmp/usr/bin/yaz-config -debian/tmp/usr/bin/yaz-asncomp -debian/tmp/usr/share/aclocal/yaz.m4 -debian/tmp/usr/share/yaz diff --git a/debian/libyaz4-dev.manpages b/debian/libyaz4-dev.manpages deleted file mode 100644 index 5c7701f..0000000 --- a/debian/libyaz4-dev.manpages +++ /dev/null @@ -1,3 +0,0 @@ -debian/tmp/usr/share/man/man1/yaz-asncomp.1 -debian/tmp/usr/share/man/man7/yaz.7 -debian/tmp/usr/share/man/man1/yaz-config.1 diff --git a/debian/libyaz4.install b/debian/libyaz4.install deleted file mode 100644 index c45ebcf..0000000 --- a/debian/libyaz4.install +++ /dev/null @@ -1 +0,0 @@ -debian/tmp/usr/lib/lib*.so.* diff --git a/debian/libyaz5-dev.install b/debian/libyaz5-dev.install new file mode 100644 index 0000000..5e8060d --- /dev/null +++ b/debian/libyaz5-dev.install @@ -0,0 +1,8 @@ +debian/tmp/usr/include/yaz +debian/tmp/usr/lib/pkgconfig/yaz.pc +debian/tmp/usr/lib/libyaz*.a +debian/tmp/usr/lib/libyaz*.so +debian/tmp/usr/bin/yaz-config +debian/tmp/usr/bin/yaz-asncomp +debian/tmp/usr/share/aclocal/yaz.m4 +debian/tmp/usr/share/yaz diff --git a/debian/libyaz5-dev.manpages b/debian/libyaz5-dev.manpages new file mode 100644 index 0000000..5c7701f --- /dev/null +++ b/debian/libyaz5-dev.manpages @@ -0,0 +1,3 @@ +debian/tmp/usr/share/man/man1/yaz-asncomp.1 +debian/tmp/usr/share/man/man7/yaz.7 +debian/tmp/usr/share/man/man1/yaz-config.1 diff --git a/debian/libyaz5.install b/debian/libyaz5.install new file mode 100644 index 0000000..c45ebcf --- /dev/null +++ b/debian/libyaz5.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/lib*.so.* diff --git a/debian/rules b/debian/rules index 5ebb002..68d3716 100755 --- a/debian/rules +++ b/debian/rules @@ -1,106 +1,27 @@ #!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# GNU copyright 1997 to 1999 by Joey Hess. +export DH_VERBOSE=1 -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 +%: + dh $@ --without python-support -# These are used for cross-compiling and for saving the configure script -# from having to guess our platform (since we know it already) -DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) -DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) +override_dh_auto_configure: + dh_auto_configure -- \ + --enable-tcpd --with-xslt --with-gnutls --with-icu +override_dh_strip: + dh_strip --dbg-package=libyaz5-dbg -CPPFLAGS:=$(shell dpkg-buildflags --get CPPFLAGS) -CFLAGS:=$(shell dpkg-buildflags --get CFLAGS) $(CPPFLAGS) -CXXFLAGS:=$(shell dpkg-buildflags --get CXXFLAGS) $(CPPFLAGS) -LDFLAGS:=$(shell dpkg-buildflags --get LDFLAGS) - -config.status: configure - dh_testdir - # Add here commands to configure the package. - CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" \ - LDFLAGS="$(LDFLAGS)" \ - ./configure --host=$(DEB_HOST_GNU_TYPE) \ - --build=$(DEB_BUILD_GNU_TYPE) \ - --mandir=\$${prefix}/share/man \ - --infodir=\$${prefix}/share/info \ - --enable-shared --enable-static --enable-tcpd \ - --with-xslt --with-gnutls --with-icu \ - --prefix=/usr - -build: build-stamp -build-stamp: config.status - dh_testdir - - # Add here commands to compile the package. - $(MAKE) - - touch build-stamp - -clean: - dh_testdir - dh_testroot - rm -f build-stamp - - # Add here commands to clean up after the build process. - -$(MAKE) distclean -ifneq "$(wildcard /usr/share/misc/config.sub)" "" - -cp -f /usr/share/misc/config.sub config.sub -endif -ifneq "$(wildcard /usr/share/misc/config.guess)" "" - -cp -f /usr/share/misc/config.guess config.guess -endif - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - # Add here commands to install the package into debian/tmp - $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp +override_dh_auto_install: + dh_auto_install + mv debian/tmp/usr/share/doc/yaz debian/tmp/usr/share/doc/yaz-doc +override_dh_makeshlibs: + dh_makeshlibs -V 'libyaz5 (>= 5.0.0)' -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. +override_dh_installchangelogs: + dh_installchangelogs NEWS -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot +override_dh_installdocs: cp LICENSE debian/copyright dh_installdocs -A README - dh_installchangelogs - dh_installexamples - mv debian/tmp/usr/share/doc/yaz debian/tmp/usr/share/doc/yaz-doc - dh_install -# dh_installmenu -# dh_installdebconf -# dh_installlogrotate -# dh_installemacsen -# dh_installpam -# dh_installmime -# dh_installinit -# dh_installcron -# dh_installinfo - dh_installman - dh_link - dh_strip --dbg-package=libyaz4-dbg - dh_compress - dh_fixperms -# dh_perl -# dh_python - dh_makeshlibs -V 'libyaz4 (>= 4.2.68)' - dh_installdeb - dh_shlibdeps -l debian/libyaz4/usr/lib - dh_gencontrol - dh_md5sums - dh_builddeb -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install diff --git a/doc/odr.xml b/doc/odr.xml index 770ad9c..6438e6f 100644 --- a/doc/odr.xml +++ b/doc/odr.xml @@ -670,7 +670,6 @@ typedef struct odr_oct { unsigned char *buf; int len; - int size; } Odr_oct; int odr_octetstring(ODR o, Odr_oct **p, int optional, @@ -680,8 +679,7 @@ int odr_octetstring(ODR o, Odr_oct **p, int optional, The buf field should point to the character array that holds the octetstring. The len field holds the - actual length, while the size field gives the size - of the allocated array (not of interest to you, in most cases). + actual length. The character array need not be null terminated. diff --git a/include/yaz/facet.h b/include/yaz/facet.h index 43e1eea..079f371 100644 --- a/include/yaz/facet.h +++ b/include/yaz/facet.h @@ -57,8 +57,9 @@ struct yaz_facet_attr { /* or number converted to a string */ /* defaults to 'any' */ char useattrbuff[30]; /* for converting numbers to strings */ - char *relation; /* @attr 2, defaults to '=' */ - int limit; /* for facet attributes */ + int sortorder; + int limit; + int start; }; YAZ_EXPORT @@ -92,6 +93,11 @@ void yaz_oi_set_facetlist( YAZ_EXPORT Z_FacetList *yaz_oi_get_facetlist(Z_OtherInformation **otherInformation); +YAZ_EXPORT +void yaz_oi_set_facetlist(Z_OtherInformation **otherInformation, ODR odr, + Z_FacetList *facet_list); + + YAZ_END_CDECL #endif diff --git a/include/yaz/odr.h b/include/yaz/odr.h index 20f245b..20d15a4 100644 --- a/include/yaz/odr.h +++ b/include/yaz/odr.h @@ -98,9 +98,8 @@ typedef nmem_bool_t Odr_bool; typedef struct odr_oct { - unsigned char *buf; + char *buf; int len; - int size; } Odr_oct; typedef void Odr_null; @@ -111,7 +110,7 @@ typedef Odr_oct Odr_any; typedef struct odr_bitmask { #define ODR_BITMASK_SIZE 256 - unsigned char bits[ODR_BITMASK_SIZE]; + char bits[ODR_BITMASK_SIZE]; int top; } Odr_bitmask; @@ -128,14 +127,6 @@ struct odr int error; /* current error state (0==OK) */ - unsigned char *buf; /* memory handle */ - int top; /* top of buffer (max pos when encoding) */ - int size; /* current buffer size (encoding+decoding) */ - - int pos; /* current position (encoding) */ - - const unsigned char *bp; /* position in buffer (decoding) */ - NMEM mem; /* memory handle for decoding (primarily) */ struct Odr_private *op; @@ -172,6 +163,7 @@ typedef struct odr_arm extern char *odr_errlist[]; +YAZ_EXPORT int odr_offset(ODR o); YAZ_EXPORT int odr_geterror(ODR o); YAZ_EXPORT int odr_geterrorx(ODR o, int *x); YAZ_EXPORT void odr_seterror(ODR o, int errorno, int errorid); @@ -190,8 +182,7 @@ YAZ_EXPORT char *odr_strdupn(ODR o, const char *str, size_t n); YAZ_EXPORT char *odr_strdup_null(ODR o, const char *str); YAZ_EXPORT Odr_int *odr_intdup(ODR o, Odr_int v); YAZ_EXPORT Odr_bool *odr_booldup(ODR o, Odr_bool v); -YAZ_EXPORT Odr_oct *odr_create_Odr_oct(ODR o, const unsigned char *buf, - int sz); +YAZ_EXPORT Odr_oct *odr_create_Odr_oct(ODR o, const char *buf, int sz); YAZ_EXPORT NMEM odr_extract_mem(ODR o); YAZ_EXPORT Odr_null *odr_nullval(void); #define odr_release_mem(m) nmem_destroy(m) @@ -220,8 +211,6 @@ YAZ_EXPORT Odr_null *odr_nullval(void); ((mask)->bits[(num) >> 3] & (0X80 >> ((num) & 0X07)) ? 1 : 0) : 0) -#define odr_tell(o) ((o)->pos) -#define odr_offset(o) ((o)->bp - (o)->buf) #define odr_ok(o) (!(o)->error) #define odr_getmem(o) ((o)->mem) @@ -231,14 +220,14 @@ YAZ_EXPORT int ber_boolean(ODR o, int *val); YAZ_EXPORT int ber_tag(ODR o, void *p, int zclass, int tag, int *constructed, int opt, const char *name); YAZ_EXPORT int ber_enctag(ODR o, int zclass, int tag, int constructed); -YAZ_EXPORT int ber_dectag(const unsigned char *buf, int *zclass, +YAZ_EXPORT int ber_dectag(const char *buf, int *zclass, int *tag, int *constructed, int max); YAZ_EXPORT int odr_bool(ODR o, Odr_bool **p, int opt, const char *name); YAZ_EXPORT int odr_integer(ODR o, Odr_int **p, int opt, const char *name); YAZ_EXPORT int odr_enum(ODR o, Odr_int **p, int opt, const char *name); YAZ_EXPORT int odr_implicit_settag(ODR o, int zclass, int tag); YAZ_EXPORT int ber_enclen(ODR o, int len, int lenlen, int exact); -YAZ_EXPORT int ber_declen(const unsigned char *buf, int *len, int max); +YAZ_EXPORT int ber_declen(const char *buf, int *len, int max); YAZ_EXPORT void odr_prname(ODR o, const char *name); YAZ_EXPORT int ber_null(ODR o); YAZ_EXPORT int odr_null(ODR o, Odr_null **p, int opt, const char *name); @@ -252,7 +241,7 @@ YAZ_EXPORT int odr_sequence_end(ODR o); YAZ_EXPORT int odr_set_end(ODR o); YAZ_EXPORT int ber_octetstring(ODR o, Odr_oct *p, int cons); YAZ_EXPORT int odr_octetstring(ODR o, Odr_oct **p, int opt, const char *name); -YAZ_EXPORT int odp_more_chunks(ODR o, const unsigned char *base, int len); +YAZ_EXPORT int odp_more_chunks(ODR o, const char *base, int len); YAZ_EXPORT int odr_constructed_more(ODR o); YAZ_EXPORT int odr_bitstring(ODR o, Odr_bitmask **p, int opt, const char *name); @@ -277,15 +266,14 @@ YAZ_EXPORT int ber_any(ODR o, Odr_any **p); \retval 0 package is incomplete \retval >0 package is complete and length is return value */ -YAZ_EXPORT int completeBER(const unsigned char *buf, int len); +YAZ_EXPORT int completeBER(const char *buf, int len); YAZ_EXPORT void odr_begin(ODR o); YAZ_EXPORT void odr_end(ODR o); YAZ_EXPORT Odr_oid *odr_oiddup(ODR odr, const Odr_oid *o); YAZ_EXPORT Odr_oid *odr_oiddup_nmem(NMEM nmem, const Odr_oid *o); YAZ_EXPORT int odr_grow_block(ODR b, int min_bytes); -YAZ_EXPORT int odr_write(ODR o, unsigned char *buf, int bytes); -YAZ_EXPORT int odr_write2(ODR o, const char *buf, int bytes); +YAZ_EXPORT int odr_write(ODR o, const char *buf, int bytes); YAZ_EXPORT int odr_seek(ODR o, int whence, int offset); YAZ_EXPORT int odr_dumpBER(FILE *f, const char *buf, int len); YAZ_EXPORT void odr_choice_bias(ODR o, int what); diff --git a/include/yaz/srw.h b/include/yaz/srw.h index 556d7e7..8e5aa78 100644 --- a/include/yaz/srw.h +++ b/include/yaz/srw.h @@ -37,7 +37,7 @@ #include #include #include -#include "facet.h" +#include YAZ_BEGIN_CDECL @@ -49,10 +49,18 @@ typedef struct { typedef struct { char *recordSchema; - int recordPacking; + + int recordPacking; /* recordXMLEscaping in SRU 2.0 */ #define Z_SRW_recordPacking_string 0 #define Z_SRW_recordPacking_XML 1 #define Z_SRW_recordPacking_URL 2 + +#if 0 + int packing; /* recordPacking in SRU 2.0 */ +#define Z_SRW_packed 0 +#define Z_SRW_unpacked 1 +#endif + char *recordData_buf; int recordData_len; Odr_int *recordPosition; @@ -66,15 +74,8 @@ typedef struct { typedef struct { -#define Z_SRW_query_type_cql 1 -#define Z_SRW_query_type_xcql 2 -#define Z_SRW_query_type_pqf 3 - int query_type; - union { - char *cql; - char *xcql; - char *pqf; - } query; + char *queryType; + char *query; #define Z_SRW_sort_type_none 1 #define Z_SRW_sort_type_sort 2 @@ -88,7 +89,10 @@ typedef struct { Odr_int *startRecord; Odr_int *maximumRecords; char *recordSchema; - char *recordPacking; + + char *recordPacking; /* recordXMLEscaping in SRU 2.0 */ + char *packing; /* recordPacking in SRU 2.0 */ + char *recordXPath; char *database; char *stylesheet; @@ -98,6 +102,7 @@ typedef struct { typedef struct { Odr_int *numberOfRecords; + char *resultCountPrecision; char * resultSetId; Odr_int *resultSetIdleTime; @@ -115,6 +120,7 @@ typedef struct { typedef struct { char *recordPacking; + char *packing; char *database; char *stylesheet; } Z_SRW_explainRequest; @@ -127,12 +133,8 @@ typedef struct { } Z_SRW_explainResponse; typedef struct { - int query_type; - union { - char *cql; - char *xcql; - char *pqf; - } scanClause; + char *queryType; + char *scanClause; Odr_int *responsePosition; Odr_int *maximumTerms; char *stylesheet; @@ -227,7 +229,7 @@ YAZ_EXPORT int yaz_srw_codec(ODR o, void * pptr, YAZ_EXPORT int yaz_ucp_codec(ODR o, void * pptr, Z_SRW_PDU **handler_data, void *client_data, const char *ns); -YAZ_EXPORT Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o); +YAZ_EXPORT Z_SRW_PDU *yaz_srw_get_core_v_2_0(ODR o); YAZ_EXPORT Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version); YAZ_EXPORT Z_SRW_PDU *yaz_srw_get(ODR o, int which); YAZ_EXPORT Z_SRW_recordVersion *yaz_srw_get_record_versions(ODR o, int num); @@ -325,8 +327,6 @@ YAZ_EXPORT int yaz_sru_soap_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, YAZ_EXPORT int yaz_solr_encode_request(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, ODR encode, const char *charset); -YAZ_EXPORT char *yaz_negotiate_sru_version(char *input_ver); - YAZ_EXPORT void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args); @@ -335,7 +335,7 @@ void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args); #define YAZ_XMLNS_SRU_v1_1 "http://www.loc.gov/zing/srw/" #define YAZ_XMLNS_DIAG_v1_1 "http://www.loc.gov/zing/srw/diagnostic/" #define YAZ_XMLNS_UPDATE_v0_9 "http://www.loc.gov/zing/srw/update/" -#define YAZ_XMLNS_SRU_v2_response "http://docs.oasis-open.org/ns/search-ws/sru*esponse" +#define YAZ_XMLNS_SRU_v2_mask "http://docs.oasis-open.org/ns/search-ws/*" #define YAZ_XMLNS_SRU_v1_response "http://www.loc.gov/*" YAZ_EXPORT diff --git a/src/Makefile.am b/src/Makefile.am index 2e7f700..2564e03 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ ## This file is part of the YAZ toolkit. ## Copyright (C) 1995-2013 Index Data -YAZ_VERSION_INFO=4:0:0 +YAZ_VERSION_INFO=5:0:0 lib_LTLIBRARIES = libyaz.la libyaz_server.la libyaz_icu.la @@ -90,9 +90,9 @@ libyaz_la_SOURCES=base64.c version.c options.c log.c \ otherinfo.c pquery.c sortspec.c charneg.c initopt.c init_diag.c \ zoom-c.c zoom-z3950.c zoom-sru.c zoom-query.c zoom-record-cache.c \ zoom-event.c \ - record_render.c zoom-socket.c zoom-opt.c zoom-p.h sru-p.h \ + record_render.c zoom-socket.c zoom-opt.c zoom-p.h sru_facet.c sru-p.h \ grs1disp.c zgdu.c soap.c srw.c srwutil.c uri.c solr.c diag_map.c \ - opac_to_xml.c xml_to_opac.c \ + opac_to_xml.c xml_add.c xml_match.c xml_to_opac.c \ cclfind.c ccltoken.c cclerrms.c cclqual.c cclptree.c cclp.h \ cclqfile.c cclstr.c cclxmlconfig.c ccl_stop_words.c \ cql.y cqlstdio.c cqltransform.c cqlutil.c xcqlutil.c cqlstring.c \ diff --git a/src/ber_any.c b/src/ber_any.c index 3322a02..f12b4ba 100644 --- a/src/ber_any.c +++ b/src/ber_any.c @@ -25,15 +25,15 @@ int ber_any(ODR o, Odr_any **p) switch (o->direction) { case ODR_DECODE: - if ((res = completeBER(o->bp, odr_max(o))) <= 0) /* FIX THIS */ + if ((res = completeBER(o->op->bp, odr_max(o))) <= 0) /* FIX THIS */ { odr_seterror(o, OPROTO, 2); return 0; } - (*p)->buf = (unsigned char *)odr_malloc(o, res); - memcpy((*p)->buf, o->bp, res); - (*p)->len = (*p)->size = res; - o->bp += res; + (*p)->buf = (char *)odr_malloc(o, res); + memcpy((*p)->buf, o->op->bp, res); + (*p)->len = res; + o->op->bp += res; return 1; case ODR_ENCODE: if (odr_write(o, (*p)->buf, (*p)->len) < 0) @@ -45,10 +45,10 @@ int ber_any(ODR o, Odr_any **p) #define BER_ANY_DEBUG 0 -int completeBER_n(const unsigned char *buf, int len, int level) +int completeBER_n(const char *buf, int len, int level) { int res, ll, zclass, tag, cons; - const unsigned char *b = buf; + const char *b = buf; if (level > 1000) { @@ -120,7 +120,7 @@ int completeBER_n(const unsigned char *buf, int len, int level) return (b - buf) + 2; } -int completeBER(const unsigned char *buf, int len) +int completeBER(const char *buf, int len) { int res = completeBER_n(buf, len, 0); #if BER_ANY_DEBUG diff --git a/src/ber_bit.c b/src/ber_bit.c index 00ea535..31e5500 100644 --- a/src/ber_bit.c +++ b/src/ber_bit.c @@ -20,20 +20,20 @@ int ber_bitstring(ODR o, Odr_bitmask *p, int cons) { int res, len; - const unsigned char *base; + const char *base; switch (o->direction) { case ODR_DECODE: - if ((res = ber_declen(o->bp, &len, odr_max(o))) < 0) + if ((res = ber_declen(o->op->bp, &len, odr_max(o))) < 0) { odr_seterror(o, OPROTO, 4); return 0; } - o->bp += res; + o->op->bp += res; if (cons) /* fetch component strings */ { - base = o->bp; + base = o->op->bp; while (odp_more_chunks(o, base, len)) if (!odr_bitstring(o, &p, 0, 0)) return 0; @@ -57,11 +57,11 @@ int ber_bitstring(ODR o, Odr_bitmask *p, int cons) odr_seterror(o, OOTHER, 7); return 0; } - o->bp++; /* silently ignore the unused-bits field */ + o->op->bp++; /* silently ignore the unused-bits field */ len--; - memcpy(p->bits + p->top + 1, o->bp, len); + memcpy(p->bits + p->top + 1, o->op->bp, len); p->top += len; - o->bp += len; + o->op->bp += len; return 1; case ODR_ENCODE: if ((res = ber_enclen(o, p->top + 2, 5, 0)) < 0) diff --git a/src/ber_bool.c b/src/ber_bool.c index ec0a1da..de1ba3a 100644 --- a/src/ber_bool.c +++ b/src/ber_bool.c @@ -31,19 +31,19 @@ int ber_boolean(ODR o, int *val) return 0; return 1; case ODR_DECODE: - if ((res = ber_declen(o->bp, &len, odr_max(o))) < 0) + if ((res = ber_declen(o->op->bp, &len, odr_max(o))) < 0) { odr_seterror(o, OPROTO, 9); return 0; } - o->bp+= res; + o->op->bp+= res; if (len != 1 || odr_max(o) < len) { odr_seterror(o, OPROTO, 10); return 0; } - *val = *o->bp; - o->bp++; + *val = *o->op->bp; + o->op->bp++; return 1; case ODR_PRINT: return 1; diff --git a/src/ber_int.c b/src/ber_int.c index e9b23a2..eb651e2 100644 --- a/src/ber_int.c +++ b/src/ber_int.c @@ -28,7 +28,7 @@ #include "odr-priv.h" static int ber_encinteger(ODR o, Odr_int val); -static int ber_decinteger(const unsigned char *buf, Odr_int *val, int max); +static int ber_decinteger(const char *buf, Odr_int *val, int max); int ber_integer(ODR o, Odr_int *val) { @@ -37,12 +37,12 @@ int ber_integer(ODR o, Odr_int *val) switch (o->direction) { case ODR_DECODE: - if ((res = ber_decinteger(o->bp, val, odr_max(o))) <= 0) + if ((res = ber_decinteger(o->op->bp, val, odr_max(o))) <= 0) { odr_seterror(o, OPROTO, 50); return 0; } - o->bp += res; + o->op->bp += res; return 1; case ODR_ENCODE: if ((res = ber_encinteger(o, *val)) < 0) @@ -77,7 +77,7 @@ int ber_encinteger(ODR o, Odr_int val) len = sizeof(uval) - i; if (ber_enclen(o, len, 1, 1) != 1) return -1; - if (odr_write(o, (unsigned char*) tmp + i, len) < 0) + if (odr_write(o, (const char *) tmp + i, len) < 0) return -1; return 0; } @@ -85,14 +85,14 @@ int ber_encinteger(ODR o, Odr_int val) /* * Returns: Number of bytes read or 0 if no match, -1 if error. */ -int ber_decinteger(const unsigned char *buf, Odr_int *val, int max) +int ber_decinteger(const char *buf, Odr_int *val, int max) { unsigned long long uval = 0; int i, len; int res; - const unsigned char *b = buf; + const unsigned char *b = (const unsigned char *) buf; - if ((res = ber_declen(b, &len, max)) < 0) + if ((res = ber_declen((const char *) b, &len, max)) < 0) return -1; if (len+res > max || len < 0) /* out of bounds or indefinite encoding */ return -1; @@ -107,7 +107,7 @@ int ber_decinteger(const unsigned char *buf, Odr_int *val, int max) uval = (uval << 8) + b[i]; *val = uval; b += len; - return b - buf; + return (const char *) b - buf; } /* * Local variables: diff --git a/src/ber_len.c b/src/ber_len.c index 56674c6..01af404 100644 --- a/src/ber_len.c +++ b/src/ber_len.c @@ -90,9 +90,9 @@ int ber_enclen(ODR o, int len, int lenlen, int exact) * len = -1 indefinite length. * len >= 0 definite length */ -int ber_declen(const unsigned char *buf, int *len, int max) +int ber_declen(const char *buf, int *len, int max) { - const unsigned char *b = buf; + const unsigned char *b = (const unsigned char *) buf; int n; if (max < 1) @@ -122,7 +122,7 @@ int ber_declen(const unsigned char *buf, int *len, int max) } if (*len < 0) return -2; - return (b - buf); + return ((const char *) b - buf); } /* * Local variables: diff --git a/src/ber_null.c b/src/ber_null.c index 1fee4c4..5e3cb94 100644 --- a/src/ber_null.c +++ b/src/ber_null.c @@ -33,7 +33,7 @@ int ber_null(ODR o) odr_seterror(o, OPROTO, 39); return 0; } - if (*(o->bp++) != 0X00) + if (*(o->op->bp++) != 0X00) { odr_seterror(o, OPROTO, 12); return 0; diff --git a/src/ber_oct.c b/src/ber_oct.c index 85242ee..8c60fc7 100644 --- a/src/ber_oct.c +++ b/src/ber_oct.c @@ -16,25 +16,26 @@ #endif #include "odr-priv.h" +#include +#include int ber_octetstring(ODR o, Odr_oct *p, int cons) { int res, len; - const unsigned char *base; - unsigned char *c; + const char *base; switch (o->direction) { case ODR_DECODE: - if ((res = ber_declen(o->bp, &len, odr_max(o))) < 0) + if ((res = ber_declen(o->op->bp, &len, odr_max(o))) < 0) { odr_seterror(o, OPROTO, 14); return 0; } - o->bp += res; + o->op->bp += res; if (cons) /* fetch component strings */ { - base = o->bp; + base = o->op->bp; while (odp_more_chunks(o, base, len)) if (!odr_octetstring(o, &p, 0, 0)) return 0; @@ -51,21 +52,11 @@ int ber_octetstring(ODR o, Odr_oct *p, int cons) odr_seterror(o, OOTHER, 16); return 0; } - if (len + 1 > p->size - p->len) - { - c = (unsigned char *)odr_malloc(o, p->size += len + 1); - if (p->len) - memcpy(c, p->buf, p->len); - p->buf = c; - } - if (len) - memcpy(p->buf + p->len, o->bp, len); - p->len += len; - o->bp += len; - /* the final null is really not part of the buffer, but */ - /* it helps somes applications that assumes C strings */ - if (len) - p->buf[p->len] = '\0'; + p->len = len; + p->buf = odr_malloc(o, len + 1); + memcpy(p->buf, o->op->bp, len); + p->buf[len] = '\0'; + o->op->bp += len; return 1; case ODR_ENCODE: if ((res = ber_enclen(o, p->len, 5, 0)) < 0) diff --git a/src/ber_oid.c b/src/ber_oid.c index 89b8dfa..6e2b595 100644 --- a/src/ber_oid.c +++ b/src/ber_oid.c @@ -25,7 +25,7 @@ int ber_oidc(ODR o, Odr_oid *p, int max_oid_size) switch (o->direction) { case ODR_DECODE: - if ((res = ber_declen(o->bp, &len, odr_max(o))) < 1) + if ((res = ber_declen(o->op->bp, &len, odr_max(o))) < 1) { odr_seterror(o, OPROTO, 18); return 0; @@ -35,7 +35,7 @@ int ber_oidc(ODR o, Odr_oid *p, int max_oid_size) odr_seterror(o, OPROTO, 19); return 0; } - o->bp += res; + o->op->bp += res; if (len > odr_max(o)) { odr_seterror(o, OPROTO, 20); @@ -53,10 +53,10 @@ int ber_oidc(ODR o, Odr_oid *p, int max_oid_size) return 0; } id <<= 7; - id |= *o->bp & 0X7F; + id |= *o->op->bp & 0X7F; len--; } - while (*(o->bp++) & 0X80); + while (*(o->op->bp++) & 0X80); if (id < 0) { diff --git a/src/ber_tag.c b/src/ber_tag.c index 422c74d..7841b8a 100644 --- a/src/ber_tag.c +++ b/src/ber_tag.c @@ -44,8 +44,8 @@ int ber_tag(ODR o, void *p, int zclass, int tag, int *constructed, int opt, if (ODR_STACK_EMPTY(o)) { odr_seek(o, ODR_S_SET, 0); - o->top = 0; - o->bp = o->buf; + o->op->top = 0; + o->op->bp = o->op->buf; odr_ber_tag->lclass = -1; } switch (o->direction) @@ -76,7 +76,7 @@ int ber_tag(ODR o, void *p, int zclass, int tag, int *constructed, int opt, if (odr_ber_tag->lclass < 0) { if ((odr_ber_tag->br = - ber_dectag(o->bp, &odr_ber_tag->lclass, + ber_dectag(o->op->bp, &odr_ber_tag->lclass, &odr_ber_tag->ltag, &odr_ber_tag->lcons, odr_max(o))) <= 0) { @@ -87,7 +87,7 @@ int ber_tag(ODR o, void *p, int zclass, int tag, int *constructed, int opt, } if (zclass == odr_ber_tag->lclass && tag == odr_ber_tag->ltag) { - o->bp += odr_ber_tag->br; + o->op->bp += odr_ber_tag->br; *constructed = odr_ber_tag->lcons; odr_ber_tag->lclass = -1; return 1; @@ -162,9 +162,10 @@ int ber_enctag(ODR o, int zclass, int tag, int constructed) * * Returns number of bytes read or -1 for error. */ -int ber_dectag(const unsigned char *b, int *zclass, int *tag, +int ber_dectag(const char *cp, int *zclass, int *tag, int *constructed, int max) { + const unsigned char *b = (const unsigned char *) cp; int l = 1; if (l > max) diff --git a/src/charneg.c b/src/charneg.c index 951bb37..9986f53 100644 --- a/src/charneg.c +++ b/src/charneg.c @@ -28,17 +28,10 @@ static Z_External* z_ext_record2(ODR o, const char *buf) return 0; p->descriptor = 0; p->indirect_reference = 0; - p->direct_reference = odr_oiddup(o, yaz_oid_negot_charset_id); - p->which = Z_External_octet; - if (!(p->u.octet_aligned = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct)))) - return 0; - if (!(p->u.octet_aligned->buf = (unsigned char *)odr_malloc(o, len))) - return 0; - p->u.octet_aligned->len = p->u.octet_aligned->size = len; - memcpy(p->u.octet_aligned->buf, buf, len); - + p->u.octet_aligned = + odr_create_Odr_oct(o, buf, len); return p; } diff --git a/src/comstack.c b/src/comstack.c index 1755fc7..0c502f8 100644 --- a/src/comstack.c +++ b/src/comstack.c @@ -427,7 +427,7 @@ static int cs_complete_auto_x(const char *buf, int len, int head_only) int r = cs_complete_http(buf, len, head_only); return r; } - return completeBER((const unsigned char *) buf, len); + return completeBER(buf, len); } diff --git a/src/dumpber.c b/src/dumpber.c index 5d49e7f..4a7215f 100644 --- a/src/dumpber.c +++ b/src/dumpber.c @@ -30,7 +30,7 @@ static int do_dumpBER(FILE *f, const char *buf, int len, int level, int offset) return 0; if (!buf[0] && !buf[1]) return 0; - if ((res = ber_dectag((unsigned char*)b, &zclass, &tag, &cons, len)) <= 0) + if ((res = ber_dectag(b, &zclass, &tag, &cons, len)) <= 0) return 0; if (res > len) { @@ -62,7 +62,7 @@ static int do_dumpBER(FILE *f, const char *buf, int len, int level, int offset) b += res; taglen = res; len -= res; - if ((res = ber_declen((unsigned char*)b, &ll, len)) <= 0) + if ((res = ber_declen(b, &ll, len)) <= 0) { fprintf(f, "\n%sBad length\n", level_str); return 0; diff --git a/src/facet.asn b/src/facet.asn index f22eedf..7950bd1 100644 --- a/src/facet.asn +++ b/src/facet.asn @@ -7,8 +7,9 @@ FacetList ::= SEQUENCE OF FacetField; FacetField ::= SEQUENCE { -- attributes will specify: -- 1=use (field name) - -- 2=sortorder 0=most frequent, 1=least frequent, .. + -- 2=sortorder 0=count descending, 1=alpha ascending .. -- 3=limit (integer) + -- 4=start (integer) attributes [1] IMPLICIT AttributeList, terms [2] IMPLICIT SEQUENCE OF FacetTerm OPTIONAL } diff --git a/src/facet.c b/src/facet.c index a9d1ef9..b65091a 100644 --- a/src/facet.c +++ b/src/facet.c @@ -43,17 +43,21 @@ void yaz_oi_set_facetlist( Z_FacetList *yaz_oi_get_facetlist(Z_OtherInformation **otherInformation) { - int categoryValue = 1; - Z_External *z_external = 0; - Z_OtherInformationUnit *oi = - yaz_oi_update(otherInformation, 0, yaz_oid_userinfo_facet_1, - categoryValue, 0); - if (!oi) - return 0; - z_external = oi->information.externallyDefinedInfo; - - if (z_external && z_external->which == Z_External_userFacets) - return z_external->u.facetList; + Z_OtherInformation *oi = *otherInformation; + if (oi) + { + int i; + for (i = 0; i < oi->num_elements; i++) + { + Z_OtherInformationUnit *oiu = oi->list[i]; + if (oiu->which == Z_OtherInfo_externallyDefinedInfo + && oiu->information.externallyDefinedInfo->which == + Z_External_userFacets) + { + return oiu->information.externallyDefinedInfo->u.facetList; + } + } + } return 0; } @@ -65,10 +69,11 @@ void yaz_facet_attr_init(struct yaz_facet_attr *attr_values) { attr_values->errcode = 0; attr_values->errstring = 0; - attr_values->relation = 0; + attr_values->sortorder = 0; attr_values->useattr = 0; attr_values->useattrbuff[0] = 0; attr_values->limit = 0; + attr_values->start = 0; } static const char *stringattr(Z_ComplexAttribute *c) @@ -115,41 +120,17 @@ static void useattr(Z_AttributeElement *ae, struct yaz_facet_attr *av) } -static void sortorderattr(Z_AttributeElement *ae, struct yaz_facet_attr *av) +static void numattr(Z_AttributeElement *ae, struct yaz_facet_attr *av, + int *v) { if (ae->which == Z_AttributeValue_numeric) { - if (*ae->value.numeric == 0) - av->relation = "desc"; - else if (*ae->value.numeric == 1) - av->relation = "asc"; - else if (*ae->value.numeric == 3) - av->relation = "unknown/unordered"; - else - { - av->errcode = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE; - sprintf(av->useattrbuff, ODR_INT_PRINTF, - *ae-> attributeType); - av->errstring = av->useattrbuff; - } - } - else - { - av->errcode = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE; - av->errstring = "non-numeric relation attribute"; - } -} - -static void limitattr(Z_AttributeElement *ae, struct yaz_facet_attr *av) -{ - if (ae->which == Z_AttributeValue_numeric) - { - av->limit = *ae->value.numeric; + *v = *ae->value.numeric; } else { av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE; - av->errstring = "non-numeric limit attribute"; + av->errstring = "non-numeric limit/sort/start attribute"; } } @@ -177,12 +158,16 @@ void yaz_facet_attr_get_z_attributes(const Z_AttributeList *attributes, useattr(ae, av); } else if (*ae->attributeType == 2) - { /* sortorder */ - sortorderattr(ae, av); + { + numattr(ae, av, &av->sortorder); } else if (*ae->attributeType == 3) - { /* limit */ - limitattr(ae, av); + { + numattr(ae, av, &av->limit); + } + else if (*ae->attributeType == 4) + { + numattr(ae, av, &av->start); } else { /* unknown attribute */ diff --git a/src/http.c b/src/http.c index 07005f5..af51c05 100644 --- a/src/http.c +++ b/src/http.c @@ -10,7 +10,7 @@ #include #endif -#include +#include "odr-priv.h" #include #include #include @@ -22,41 +22,43 @@ static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers, { int i = off; int chunked = 0; + const char *buf = o->op->buf; + int size = o->op->size; *headers = 0; - while (i < o->size-1 && o->buf[i] == '\n') + while (i < size-1 && buf[i] == '\n') { int po; i++; - if (o->buf[i] == '\r' && i < o->size-1 && o->buf[i+1] == '\n') + if (buf[i] == '\r' && i < size-1 && buf[i+1] == '\n') { i++; break; } - if (o->buf[i] == '\n') + if (buf[i] == '\n') break; for (po = i; ; i++) { - if (i == o->size) + if (i == size) { o->error = OHTTP; return 0; } - else if (o->buf[i] == ':') + else if (buf[i] == ':') break; } *headers = (Z_HTTP_Header *) odr_malloc(o, sizeof(**headers)); (*headers)->name = (char*) odr_malloc(o, i - po + 1); - memcpy ((*headers)->name, o->buf + po, i - po); + memcpy ((*headers)->name, buf + po, i - po); (*headers)->name[i - po] = '\0'; i++; - while (i < o->size-1 && o->buf[i] == ' ') + while (i < size-1 && buf[i] == ' ') i++; - for (po = i; i < o->size-1 && !strchr("\r\n", o->buf[i]); i++) + for (po = i; i < size-1 && !strchr("\r\n", buf[i]); i++) ; (*headers)->value = (char*) odr_malloc(o, i - po + 1); - memcpy ((*headers)->value, o->buf + po, i - po); + memcpy ((*headers)->value, buf + po, i - po); (*headers)->value[i - po] = '\0'; if (!yaz_strcasecmp((*headers)->name, "Transfer-Encoding") @@ -64,11 +66,11 @@ static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers, !yaz_strcasecmp((*headers)->value, "chunked")) chunked = 1; headers = &(*headers)->next; - if (i < o->size-1 && o->buf[i] == '\r') + if (i < size-1 && buf[i] == '\r') i++; } *headers = 0; - if (o->buf[i] != '\n') + if (buf[i] != '\n') { o->error = OHTTP; return 0; @@ -80,28 +82,28 @@ static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers, int off = 0; /* we know buffer will be smaller than o->size - i*/ - *content_buf = (char*) odr_malloc(o, o->size - i); + *content_buf = (char*) odr_malloc(o, size - i); while (1) { /* chunk length .. */ int chunk_len = 0; - for (; i < o->size-2; i++) - if (yaz_isdigit(o->buf[i])) + for (; i < size-2; i++) + if (yaz_isdigit(buf[i])) chunk_len = chunk_len * 16 + - (o->buf[i] - '0'); - else if (yaz_isupper(o->buf[i])) + (buf[i] - '0'); + else if (yaz_isupper(buf[i])) chunk_len = chunk_len * 16 + - (o->buf[i] - ('A'-10)); - else if (yaz_islower(o->buf[i])) + (buf[i] - ('A'-10)); + else if (yaz_islower(buf[i])) chunk_len = chunk_len * 16 + - (o->buf[i] - ('a'-10)); + (buf[i] - ('a'-10)); else break; /* chunk extension ... */ - while (o->buf[i] != '\r' && o->buf[i+1] != '\n') + while (buf[i] != '\r' && buf[i+1] != '\n') { - if (i >= o->size-2) + if (i >= size-2) { o->error = OHTTP; return 0; @@ -111,13 +113,13 @@ static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers, i += 2; /* skip CRLF */ if (chunk_len == 0) break; - if (chunk_len < 0 || off + chunk_len > o->size) + if (chunk_len < 0 || off + chunk_len > size) { o->error = OHTTP; return 0; } /* copy chunk .. */ - memcpy (*content_buf + off, o->buf + i, chunk_len); + memcpy (*content_buf + off, buf + i, chunk_len); i += chunk_len + 2; /* skip chunk+CRLF */ off += chunk_len; } @@ -127,21 +129,21 @@ static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers, } else { - if (i > o->size) + if (i > size) { o->error = OHTTP; return 0; } - else if (i == o->size) + else if (i == size) { *content_buf = 0; *content_len = 0; } else { - *content_len = o->size - i; + *content_len = size - i; *content_buf = (char*) odr_malloc(o, *content_len + 1); - memcpy(*content_buf, o->buf + i, *content_len); + memcpy(*content_buf, buf + i, *content_len); (*content_buf)[*content_len] = '\0'; } } @@ -483,31 +485,33 @@ int yaz_decode_http_response(ODR o, Z_HTTP_Response **hr_p) { int i, po; Z_HTTP_Response *hr = (Z_HTTP_Response *) odr_malloc(o, sizeof(*hr)); + const char *buf = o->op->buf; + int size = o->op->size; *hr_p = hr; hr->content_buf = 0; hr->content_len = 0; po = i = 5; - while (i < o->size-2 && !strchr(" \r\n", o->buf[i])) + while (i < size-2 && !strchr(" \r\n", buf[i])) i++; hr->version = (char *) odr_malloc(o, i - po + 1); if (i - po) - memcpy(hr->version, o->buf + po, i - po); + memcpy(hr->version, buf + po, i - po); hr->version[i-po] = 0; - if (o->buf[i] != ' ') + if (buf[i] != ' ') { o->error = OHTTP; return 0; } i++; hr->code = 0; - while (i < o->size-2 && o->buf[i] >= '0' && o->buf[i] <= '9') + while (i < size-2 && buf[i] >= '0' && buf[i] <= '9') { - hr->code = hr->code*10 + (o->buf[i] - '0'); + hr->code = hr->code*10 + (buf[i] - '0'); i++; } - while (i < o->size-1 && o->buf[i] != '\n') + while (i < size-1 && buf[i] != '\n') i++; return decode_headers_content(o, i, &hr->headers, &hr->content_buf, &hr->content_len); @@ -517,48 +521,50 @@ int yaz_decode_http_request(ODR o, Z_HTTP_Request **hr_p) { int i, po; Z_HTTP_Request *hr = (Z_HTTP_Request *) odr_malloc(o, sizeof(*hr)); + const char *buf = o->op->buf; + int size = o->op->size; *hr_p = hr; /* method .. */ - for (i = 0; o->buf[i] != ' '; i++) - if (i >= o->size-5 || i > 30) + for (i = 0; buf[i] != ' '; i++) + if (i >= size-5 || i > 30) { o->error = OHTTP; return 0; } hr->method = (char *) odr_malloc(o, i+1); - memcpy (hr->method, o->buf, i); + memcpy (hr->method, buf, i); hr->method[i] = '\0'; /* path */ po = i+1; - for (i = po; o->buf[i] != ' '; i++) - if (i >= o->size-5) + for (i = po; buf[i] != ' '; i++) + if (i >= size-5) { o->error = OHTTP; return 0; } hr->path = (char *) odr_malloc(o, i - po + 1); - memcpy (hr->path, o->buf+po, i - po); + memcpy (hr->path, buf+po, i - po); hr->path[i - po] = '\0'; /* HTTP version */ i++; - if (i > o->size-5 || memcmp(o->buf+i, "HTTP/", 5)) + if (i > size-5 || memcmp(buf+i, "HTTP/", 5)) { o->error = OHTTP; return 0; } i+= 5; po = i; - while (i < o->size && !strchr("\r\n", o->buf[i])) + while (i < size && !strchr("\r\n", buf[i])) i++; hr->version = (char *) odr_malloc(o, i - po + 1); - memcpy(hr->version, o->buf + po, i - po); + memcpy(hr->version, buf + po, i - po); hr->version[i - po] = '\0'; /* headers */ - if (i < o->size-1 && o->buf[i] == '\r') + if (i < size-1 && buf[i] == '\r') i++; - if (o->buf[i] != '\n') + if (buf[i] != '\n') { o->error = OHTTP; return 0; @@ -596,33 +602,33 @@ int yaz_encode_http_response(ODR o, Z_HTTP_Response *hr) { char sbuf[80]; Z_HTTP_Header *h; - int top0 = o->top; + int top0 = o->op->top; sprintf(sbuf, "HTTP/%s %d %s\r\n", hr->version, hr->code, z_HTTP_errmsg(hr->code)); - odr_write2(o, sbuf, strlen(sbuf)); + odr_write(o, sbuf, strlen(sbuf)); /* use content_len for Content-Length */ sprintf(sbuf, "Content-Length: %d\r\n", hr->content_len); - odr_write2(o, sbuf, strlen(sbuf)); + odr_write(o, sbuf, strlen(sbuf)); for (h = hr->headers; h; h = h->next) { if (yaz_strcasecmp(h->name, "Content-Length") && yaz_strcasecmp(h->name, "Transfer-Encoding")) { /* skip Content-Length if given. content_len rules */ - odr_write2(o, h->name, strlen(h->name)); - odr_write2(o, ": ", 2); - odr_write2(o, h->value, strlen(h->value)); - odr_write2(o, "\r\n", 2); + odr_write(o, h->name, strlen(h->name)); + odr_write(o, ": ", 2); + odr_write(o, h->value, strlen(h->value)); + odr_write(o, "\r\n", 2); } } - odr_write(o, (unsigned char *) "\r\n", 2); + odr_write(o, "\r\n", 2); if (hr->content_buf) - odr_write2(o, hr->content_buf, hr->content_len); + odr_write(o, hr->content_buf, hr->content_len); if (o->direction == ODR_PRINT) { odr_printf(o, "-- HTTP response:\n"); - dump_http_package(o, (const char *) o->buf + top0, o->top - top0); + dump_http_package(o, o->op->buf + top0, o->op->top - top0); odr_printf(o, "--\n"); } return 1; @@ -631,14 +637,14 @@ int yaz_encode_http_response(ODR o, Z_HTTP_Response *hr) int yaz_encode_http_request(ODR o, Z_HTTP_Request *hr) { Z_HTTP_Header *h; - int top0 = o->top; - - odr_write2(o, hr->method, strlen(hr->method)); - odr_write2(o, " ", 1); - odr_write2(o, hr->path, strlen(hr->path)); - odr_write2(o, " HTTP/", 6); - odr_write2(o, hr->version, strlen(hr->version)); - odr_write2(o, "\r\n", 2); + int top0 = o->op->top; + + odr_write(o, hr->method, strlen(hr->method)); + odr_write(o, " ", 1); + odr_write(o, hr->path, strlen(hr->path)); + odr_write(o, " HTTP/", 6); + odr_write(o, hr->version, strlen(hr->version)); + odr_write(o, "\r\n", 2); if (hr->content_len && !z_HTTP_header_lookup(hr->headers, "Content-Length")) @@ -646,22 +652,22 @@ int yaz_encode_http_request(ODR o, Z_HTTP_Request *hr) char lstr[60]; sprintf(lstr, "Content-Length: %d\r\n", hr->content_len); - odr_write2(o, lstr, strlen(lstr)); + odr_write(o, lstr, strlen(lstr)); } for (h = hr->headers; h; h = h->next) { - odr_write2(o, h->name, strlen(h->name)); - odr_write2(o, ": ", 2); - odr_write2(o, h->value, strlen(h->value)); - odr_write2(o, "\r\n", 2); + odr_write(o, h->name, strlen(h->name)); + odr_write(o, ": ", 2); + odr_write(o, h->value, strlen(h->value)); + odr_write(o, "\r\n", 2); } - odr_write2(o, "\r\n", 2); + odr_write(o, "\r\n", 2); if (hr->content_buf) - odr_write2(o, hr->content_buf, hr->content_len); + odr_write(o, hr->content_buf, hr->content_len); if (o->direction == ODR_PRINT) { odr_printf(o, "-- HTTP request:\n"); - dump_http_package(o, (const char *) o->buf + top0, o->top - top0); + dump_http_package(o, o->op->buf + top0, o->op->top - top0); odr_printf(o, "--\n"); } return 1; diff --git a/src/odr-priv.h b/src/odr-priv.h index b452d10..cb021ff 100644 --- a/src/odr-priv.h +++ b/src/odr-priv.h @@ -44,8 +44,7 @@ struct Odr_ber_tag { int lcons; }; -#define odr_max(o) ((o)->size - ((o)->bp - (o)->buf)) -#define odr_offset(o) ((o)->bp - (o)->buf) +#define odr_max(o) ((o)->op->size - ((o)->op->bp - (o)->op->buf)) /** * \brief stack for BER constructed items @@ -63,11 +62,11 @@ struct Odr_ber_tag { */ struct odr_constack { - const unsigned char *base; /** starting point of data */ + const char *base; /** starting point of data */ int base_offset; int len; /** length of data, if known, else -1 (decoding only) */ - const unsigned char *lenb; /** where to encode length */ + const char *lenb; /** where to encode length */ int len_offset; int lenlen; /** length of length-field */ const char *name; /** name of stack entry */ @@ -82,6 +81,12 @@ struct odr_constack * \brief ODR private data */ struct Odr_private { + char *buf; /* memory base */ + const char *bp; /* position in buffer (decoding) */ + int pos; /* current position (encoding) */ + int top; /* top of buffer (max pos when encoding) */ + int size; /* current buffer size (encoding+decoding) */ + /* stack for constructed types (we above) */ struct odr_constack *stack_first; /** first member of allocated stack */ struct odr_constack *stack_top; /** top of stack */ @@ -113,6 +118,8 @@ struct Odr_private { #define ODR_STACK_EMPTY(x) (!(x)->op->stack_top) #define ODR_STACK_NOT_EMPTY(x) ((x)->op->stack_top) +#define odr_tell(o) ((o)->op->pos) + /* Private macro. * write a single character at the current position - grow buffer if * necessary. @@ -122,15 +129,15 @@ struct Odr_private { #define odr_putc(o, c) \ ( \ ( \ - (o)->pos < (o)->size ? \ + (o)->op->pos < (o)->op->size ? \ ( \ - (o)->buf[(o)->pos++] = (c), \ + (o)->op->buf[(o)->op->pos++] = (c), \ 0 \ ) : \ ( \ odr_grow_block((o), 1) == 0 ? \ ( \ - (o)->buf[(o)->pos++] = (c), \ + (o)->op->buf[(o)->op->pos++] = (c), \ 0 \ ) : \ ( \ @@ -140,9 +147,9 @@ struct Odr_private { ) \ ) == 0 ? \ ( \ - (o)->pos > (o)->top ? \ + (o)->op->pos > (o)->op->top ? \ ( \ - (o)->top = (o)->pos, \ + (o)->op->top = (o)->op->pos, \ 0 \ ) : \ 0 \ diff --git a/src/odr.c b/src/odr.c index 142249f..25fafb2 100644 --- a/src/odr.c +++ b/src/odr.c @@ -215,8 +215,8 @@ ODR odr_createmem(int direction) return 0; o->op = (struct Odr_private *) xmalloc(sizeof(*o->op)); o->direction = direction; - o->buf = 0; - o->size = o->pos = o->top = 0; + o->op->buf = 0; + o->op->size = o->op->pos = o->op->top = 0; o->op->can_grow = 1; o->mem = nmem_create(); o->op->enable_bias = 1; @@ -237,9 +237,9 @@ void odr_reset(ODR o) } odr_seterror(o, ONONE, 0); - o->bp = o->buf; + o->op->bp = o->op->buf; odr_seek(o, ODR_S_SET, 0); - o->top = 0; + o->op->top = 0; o->op->t_class = -1; o->op->t_tag = -1; o->op->indent = 0; @@ -258,8 +258,8 @@ void odr_reset(ODR o) void odr_destroy(ODR o) { nmem_destroy(o->mem); - if (o->buf && o->op->can_grow) - xfree(o->buf); + if (o->op->buf && o->op->can_grow) + xfree(o->op->buf); if (o->op->stream_close) o->op->stream_close(o->op->print); if (o->op->iconv_handle != 0) @@ -272,19 +272,24 @@ void odr_destroy(ODR o) void odr_setbuf(ODR o, char *buf, int len, int can_grow) { odr_seterror(o, ONONE, 0); - o->bp = (unsigned char *) buf; - o->buf = (unsigned char *) buf; + o->op->bp = buf; + o->op->buf = buf; o->op->can_grow = can_grow; - o->top = o->pos = 0; - o->size = len; + o->op->top = o->op->pos = 0; + o->op->size = len; } char *odr_getbuf(ODR o, int *len, int *size) { - *len = o->top; + *len = o->op->top; if (size) - *size = o->size; - return (char*) o->buf; + *size = o->op->size; + return o->op->buf; +} + +int odr_offset(ODR o) +{ + return o->op->bp - o->op->buf; } void odr_printf(ODR o, const char *fmt, ...) diff --git a/src/odr_choice.c b/src/odr_choice.c index c025157..a3264d9 100644 --- a/src/odr_choice.c +++ b/src/odr_choice.c @@ -56,7 +56,7 @@ int odr_choice(ODR o, Odr_arm arm[], void *p, void *whichp, { if (o->op->stack_top && !odr_constructed_more(o)) return 0; - if (ber_dectag(o->bp, &cl, &tg, &cn, odr_max(o)) <= 0) + if (ber_dectag(o->op->bp, &cl, &tg, &cn, odr_max(o)) <= 0) return 0; } else if (o->direction != ODR_DECODE) diff --git a/src/odr_cons.c b/src/odr_cons.c index fa203d8..5df0fa6 100644 --- a/src/odr_cons.c +++ b/src/odr_cons.c @@ -83,12 +83,12 @@ int odr_constructed_begin(ODR o, void *xxp, int zclass, int tag, o->op->stack_top = o->op->stack_first; assert(o->op->stack_top->prev == 0); } - o->op->stack_top->lenb = o->bp; + o->op->stack_top->lenb = o->op->bp; o->op->stack_top->len_offset = odr_tell(o); o->op->stack_top->name = name ? name : "?"; if (o->direction == ODR_ENCODE) { - static unsigned char dummy[sizeof(int)+1]; + static char dummy[sizeof(int)+1]; o->op->stack_top->lenlen = lenlen; @@ -100,7 +100,7 @@ int odr_constructed_begin(ODR o, void *xxp, int zclass, int tag, } else if (o->direction == ODR_DECODE) { - if ((res = ber_declen(o->bp, &o->op->stack_top->len, + if ((res = ber_declen(o->op->bp, &o->op->stack_top->len, odr_max(o))) < 0) { odr_seterror(o, OOTHER, 31); @@ -108,7 +108,7 @@ int odr_constructed_begin(ODR o, void *xxp, int zclass, int tag, return 0; } o->op->stack_top->lenlen = res; - o->bp += res; + o->op->bp += res; if (o->op->stack_top->len > odr_max(o)) { odr_seterror(o, OOTHER, 32); @@ -128,7 +128,7 @@ int odr_constructed_begin(ODR o, void *xxp, int zclass, int tag, ODR_STACK_POP(o); return 0; } - o->op->stack_top->base = o->bp; + o->op->stack_top->base = o->op->bp; o->op->stack_top->base_offset = odr_tell(o); return 1; } @@ -140,9 +140,9 @@ int odr_constructed_more(ODR o) if (ODR_STACK_EMPTY(o)) return 0; if (o->op->stack_top->len >= 0) - return o->bp - o->op->stack_top->base < o->op->stack_top->len; + return o->op->bp - o->op->stack_top->base < o->op->stack_top->len; else - return (!(*o->bp == 0 && *(o->bp + 1) == 0)); + return (!(*o->op->bp == 0 && *(o->op->bp + 1) == 0)); } int odr_constructed_end(ODR o) @@ -162,7 +162,7 @@ int odr_constructed_end(ODR o) case ODR_DECODE: if (o->op->stack_top->len < 0) { - if (*o->bp++ == 0 && *(o->bp++) == 0) + if (*o->op->bp++ == 0 && *(o->op->bp++) == 0) { ODR_STACK_POP(o); return 1; @@ -173,7 +173,7 @@ int odr_constructed_end(ODR o) return 0; } } - else if (o->bp - o->op->stack_top->base != + else if (o->op->bp - o->op->stack_top->base != o->op->stack_top->len) { odr_seterror(o, OCONLEN, 36); diff --git a/src/odr_mem.c b/src/odr_mem.c index 4309d3d..28181e3 100644 --- a/src/odr_mem.c +++ b/src/odr_mem.c @@ -62,12 +62,11 @@ size_t odr_total(ODR o) return nmem_total(o->mem); } -Odr_oct *odr_create_Odr_oct(ODR o, const unsigned char *buf, int sz) +Odr_oct *odr_create_Odr_oct(ODR o, const char *buf, int sz) { Odr_oct *p = (Odr_oct *) odr_malloc(o, sizeof(Odr_oct)); - p->buf = (unsigned char *) odr_malloc(o, sz); + p->buf = (char *) odr_malloc(o, sz); memcpy(p->buf, buf, sz); - p->size = sz; p->len = sz; return p; } @@ -81,52 +80,47 @@ int odr_grow_block(ODR b, int min_bytes) if (!b->op->can_grow) return -1; - if (!b->size) + if (!b->op->size) togrow = 1024; else - togrow = b->size; + togrow = b->op->size; if (togrow < min_bytes) togrow = min_bytes; - if (b->size && !(b->buf = - (unsigned char *) xrealloc(b->buf, b->size += togrow))) + if (b->op->size && !(b->op->buf = + (char *) xrealloc(b->op->buf, b->op->size += togrow))) abort(); - else if (!b->size && !(b->buf = (unsigned char *) - xmalloc(b->size = togrow))) + else if (!b->op->size && !(b->op->buf = (char *) + xmalloc(b->op->size = togrow))) abort(); return 0; } -int odr_write2(ODR o, const char *buf, int bytes) +int odr_write(ODR o, const char *buf, int bytes) { - if (o->pos + bytes >= o->size && odr_grow_block(o, bytes)) + if (o->op->pos + bytes >= o->op->size && odr_grow_block(o, bytes)) { odr_seterror(o, OSPACE, 40); return -1; } - memcpy(o->buf + o->pos, buf, bytes); - o->pos += bytes; - if (o->pos > o->top) - o->top = o->pos; + memcpy(o->op->buf + o->op->pos, buf, bytes); + o->op->pos += bytes; + if (o->op->pos > o->op->top) + o->op->top = o->op->pos; return 0; } -int odr_write(ODR o, unsigned char *buf, int bytes) -{ - return odr_write2(o, (char *) buf, bytes); -} - int odr_seek(ODR o, int whence, int offset) { if (whence == ODR_S_CUR) - offset += o->pos; + offset += o->op->pos; else if (whence == ODR_S_END) - offset += o->top; - if (offset > o->size && odr_grow_block(o, offset - o->size)) + offset += o->op->top; + if (offset > o->op->size && odr_grow_block(o, offset - o->op->size)) { odr_seterror(o, OSPACE, 41); return -1; } - o->pos = offset; + o->op->pos = offset; return 0; } diff --git a/src/odr_oct.c b/src/odr_oct.c index f359c4c..101f0d2 100644 --- a/src/odr_oct.c +++ b/src/odr_oct.c @@ -45,7 +45,6 @@ int odr_octetstring(ODR o, Odr_oct **p, int opt, const char *name) if (o->direction == ODR_DECODE) { *p = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct)); - (*p)->size= 0; (*p)->len = 0; (*p)->buf = 0; } @@ -84,12 +83,11 @@ int odr_cstring(ODR o, char **p, int opt, const char *name) t = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct)); /* wrapper for octstring */ if (o->direction == ODR_ENCODE) { - t->buf = (unsigned char *) *p; - t->size = t->len = strlen(*p); + t->buf = *p; + t->len = strlen(*p); } else { - t->size= 0; t->len = 0; t->buf = 0; } @@ -142,7 +140,7 @@ int odr_iconv_string(ODR o, char **p, int opt, const char *name) char *outbuf = (char *) odr_malloc (o, outleft); size_t ret; - t->buf = (unsigned char *) outbuf; + t->buf = outbuf; ret = yaz_iconv(o->op->iconv_handle, &inbuf, &inleft, &outbuf, &outleft); @@ -159,17 +157,16 @@ int odr_iconv_string(ODR o, char **p, int opt, const char *name) odr_seterror(o, ODATA, 44); return 0; } - t->size = t->len = outbuf - (char*) t->buf; + t->len = outbuf - (char*) t->buf; } if (!t->buf) { - t->buf = (unsigned char *) *p; - t->size = t->len = strlen(*p); + t->buf = *p; + t->len = strlen(*p); } } else { - t->size= 0; t->len = 0; t->buf = 0; } diff --git a/src/odr_tag.c b/src/odr_tag.c index 9b94781..e696610 100644 --- a/src/odr_tag.c +++ b/src/odr_tag.c @@ -21,7 +21,7 @@ int odr_peektag(ODR o, int *zclass, int *tag, int *cons) } if (ODR_STACK_NOT_EMPTY(o) && !odr_constructed_more(o)) return 0; - if (ber_dectag(o->bp, zclass, tag, cons, odr_max(o)) <= 0) + if (ber_dectag(o->op->bp, zclass, tag, cons, odr_max(o)) <= 0) { odr_seterror(o, OREQUIRED, 49); return 0; diff --git a/src/odr_util.c b/src/odr_util.c index 6efa6c0..0f6c006 100644 --- a/src/odr_util.c +++ b/src/odr_util.c @@ -26,22 +26,22 @@ void odr_prname(ODR o, const char *name) odr_printf(o, "%s ", name); } -int odp_more_chunks(ODR o, const unsigned char *base, int len) +int odp_more_chunks(ODR o, const char *base, int len) { if (!len) return 0; if (len < 0) /* indefinite length */ { - if (*o->bp == 0 && *(o->bp + 1) == 0) + if (*o->op->bp == 0 && *(o->op->bp + 1) == 0) { - o->bp += 2; + o->op->bp += 2; return 0; } else return 1; } else - return o->bp - base < len; + return o->op->bp - base < len; } Odr_oid *odr_oiddup_nmem(NMEM nmem, const Odr_oid *o) diff --git a/src/pquery.c b/src/pquery.c index d4b9958..55eb1d3 100644 --- a/src/pquery.c +++ b/src/pquery.c @@ -310,26 +310,19 @@ static Z_AttributeList *get_attributeList(ODR o, Z_Term *z_Term_create(ODR o, int term_type, const char *buf, size_t len) { Z_Term *term = (Z_Term *)odr_malloc(o, sizeof(*term)); - Odr_oct *term_octet = (Odr_oct *)odr_malloc(o, sizeof(*term_octet)); - term_octet->buf = (unsigned char *)odr_malloc(o, 1 + len); - memcpy(term_octet->buf, buf, len); - term_octet->size = term_octet->len = len; - term_octet->buf[term_octet->size] = 0; /* null terminate */ - switch (term_type) { case Z_Term_general: term->which = Z_Term_general; - term->u.general = term_octet; + term->u.general = odr_create_Odr_oct(o, buf, len); break; case Z_Term_characterString: term->which = Z_Term_characterString; - term->u.characterString = (char*) term_octet->buf; - /* null terminated above */ + term->u.characterString = odr_strdupn(o, buf, len); break; case Z_Term_numeric: term->which = Z_Term_numeric; - term->u.numeric = odr_intdup(o, odr_atoi((const char*) term_octet->buf)); + term->u.numeric = odr_intdup(o, odr_atoi(odr_strdupn(o, buf, len))); break; case Z_Term_null: term->which = Z_Term_null; diff --git a/src/prt-ext.c b/src/prt-ext.c index 6af7c61..7909e98 100644 --- a/src/prt-ext.c +++ b/src/prt-ext.c @@ -13,6 +13,7 @@ #include #include +#include "odr-priv.h" #define PRT_EXT_DEBUG 0 #if PRT_EXT_DEBUG @@ -216,8 +217,8 @@ int z_External(ODR o, Z_External **p, int opt, const char *name) if (zclass == ODR_CONTEXT && tag == 1 && cons == 0) { /* we have an OCTET STRING. decode BER contents from it */ - const unsigned char *o_bp; - unsigned char *o_buf; + const char *o_bp; + char *o_buf; int o_size; char *voidp = 0; Odr_oct *oct; @@ -227,13 +228,13 @@ int z_External(ODR o, Z_External **p, int opt, const char *name) return 0; /* Save our decoding ODR members */ - o_bp = o->bp; - o_buf = o->buf; - o_size = o->size; + o_bp = o->op->bp; + o_buf = o->op->buf; + o_size = o->op->size; /* Set up the OCTET STRING buffer */ - o->bp = o->buf = oct->buf; - o->size = oct->len; + o->op->bp = o->op->buf = oct->buf; + o->op->size = oct->len; /* and decode that */ r = (*type->fun)(o, &voidp, 0, 0); @@ -241,9 +242,9 @@ int z_External(ODR o, Z_External **p, int opt, const char *name) (*p)->u.single_ASN1_type = (Odr_any*) voidp; /* Restore our decoding ODR member */ - o->bp = o_bp; - o->buf = o_buf; - o->size = o_size; + o->op->bp = o_bp; + o->op->buf = o_buf; + o->op->size = o_size; return r && odr_sequence_end(o); } @@ -315,8 +316,8 @@ Z_External *z_ext_record_oid_nmem(NMEM nmem, const Odr_oid *oid, thisext->which = Z_External_sutrs; thisext->u.sutrs = sutrs; - sutrs->buf = (unsigned char *)nmem_malloc(nmem, len); - sutrs->len = sutrs->size = len; + sutrs->buf = (char *)nmem_malloc(nmem, len); + sutrs->len = len; memcpy(sutrs->buf, buf, len); } else @@ -325,11 +326,11 @@ Z_External *z_ext_record_oid_nmem(NMEM nmem, const Odr_oid *oid, if (!(thisext->u.octet_aligned = (Odr_oct *) nmem_malloc(nmem, sizeof(Odr_oct)))) return 0; - if (!(thisext->u.octet_aligned->buf = (unsigned char *) + if (!(thisext->u.octet_aligned->buf = (char *) nmem_malloc(nmem, len))) return 0; memcpy(thisext->u.octet_aligned->buf, buf, len); - thisext->u.octet_aligned->len = thisext->u.octet_aligned->size = len; + thisext->u.octet_aligned->len = len; } return thisext; } @@ -356,12 +357,11 @@ Z_External *z_ext_record_oid_any(ODR o, const Odr_oid *oid, thisext->u.single_ASN1_type = (Odr_any *) odr_malloc(o, sizeof(Odr_any)); if (!thisext->u.single_ASN1_type) return 0; - thisext->u.single_ASN1_type->buf = (unsigned char *) odr_malloc(o, len); + thisext->u.single_ASN1_type->buf = (char *) odr_malloc(o, len); if (!thisext->u.single_ASN1_type->buf) return 0; memcpy(thisext->u.single_ASN1_type->buf, buf, len); - thisext->u.single_ASN1_type->len = thisext->u.single_ASN1_type->size = len; - + thisext->u.single_ASN1_type->len = len; return thisext; } diff --git a/src/seshigh.c b/src/seshigh.c index 24ade48..d357095 100644 --- a/src/seshigh.c +++ b/src/seshigh.c @@ -56,6 +56,7 @@ #include #endif +#include #include #include #include "eventl.h" @@ -933,11 +934,11 @@ static void srw_bend_search(association *assoc, rr.present_number = srw_req->maximumRecords ? *srw_req->maximumRecords : 0; - if (srw_req->query_type == Z_SRW_query_type_cql) + if (!srw_req->queryType || !strcmp(srw_req->queryType, "cql")) { if (assoc->server && assoc->server->cql_transform) { - int srw_errcode = cql2pqf(assoc->encode, srw_req->query.cql, + int srw_errcode = cql2pqf(assoc->encode, srw_req->query, assoc->server->cql_transform, rr.query, &rr.srw_sortKeys); @@ -959,21 +960,20 @@ static void srw_bend_search(association *assoc, ext->indirect_reference = 0; ext->descriptor = 0; ext->which = Z_External_CQL; - ext->u.cql = srw_req->query.cql; + ext->u.cql = srw_req->query; rr.query->which = Z_Query_type_104; rr.query->u.type_104 = ext; } } - else if (srw_req->query_type == Z_SRW_query_type_pqf) + else if (!strcmp(srw_req->queryType, "pqf")) { Z_RPNQuery *RPNquery; YAZ_PQF_Parser pqf_parser; pqf_parser = yaz_pqf_create(); - RPNquery = yaz_pqf_parse(pqf_parser, assoc->decode, - srw_req->query.pqf); + RPNquery = yaz_pqf_parse(pqf_parser, assoc->decode, srw_req->query); if (!RPNquery) { const char *pqf_msg; @@ -1009,6 +1009,11 @@ static void srw_bend_search(association *assoc, rr.errstring = 0; rr.search_info = 0; rr.search_input = 0; + + if (srw_req->facetList) + yaz_oi_set_facetlist(&rr.search_input, assoc->encode, + srw_req->facetList); + yaz_log_zquery_level(log_requestdetail,rr.query); (assoc->init->bend_search)(assoc->backend, &rr); @@ -1047,6 +1052,7 @@ static void srw_bend_search(association *assoc, odr_intdup(assoc->encode, *rr.srw_setnameIdleTime ); } + srw_res->facetList = yaz_oi_get_facetlist(&rr.search_info); if (start > rr.hits || start < 1) { /* if hits<=0 and start=1 we don't return a diagnostic */ @@ -1161,7 +1167,19 @@ static void srw_bend_search(association *assoc, res->extraResponseData_buf = rr.extra_response_data; res->extraResponseData_len = strlen(rr.extra_response_data); } - if (rr.estimated_hit_count || rr.partial_resultset) + if (strcmp(res->srw_version, "2.") > 0) + { + if (rr.estimated_hit_count) + srw_res->resultCountPrecision = + odr_strdup(assoc->encode, "estimate"); + else if (rr.partial_resultset) + srw_res->resultCountPrecision = + odr_strdup(assoc->encode, "minimum"); + else + srw_res->resultCountPrecision = + odr_strdup(assoc->encode, "exact"); + } + else if (rr.estimated_hit_count || rr.partial_resultset) { yaz_add_srw_diagnostic( assoc->encode, @@ -1175,21 +1193,8 @@ static void srw_bend_search(association *assoc, } if (log_request) { - const char *querystr = "?"; - const char *querytype = "?"; WRBUF wr = wrbuf_alloc(); - switch (srw_req->query_type) - { - case Z_SRW_query_type_cql: - querytype = "CQL"; - querystr = srw_req->query.cql; - break; - case Z_SRW_query_type_pqf: - querytype = "PQF"; - querystr = srw_req->query.pqf; - break; - } wrbuf_printf(wr, "SRWSearch %s ", srw_req->database); if (srw_res->num_diagnostics) wrbuf_printf(wr, "ERROR %s", srw_res->diagnostics[0].uri); @@ -1206,7 +1211,8 @@ static void srw_bend_search(association *assoc, srw_res->resultSetId : "-"), (srw_req->startRecord ? *srw_req->startRecord : 1), srw_res->num_records); - yaz_log(log_request, "%s %s: %s", wrbuf_cstr(wr), querytype, querystr); + yaz_log(log_request, "%s %s: %s", wrbuf_cstr(wr), srw_req->queryType, + srw_req->query); wrbuf_destroy(wr); } } @@ -1349,20 +1355,20 @@ static void srw_bend_scan(association *assoc, } save_entries = bsrr->entries; /* save it so we can compare later */ - if (srw_req->query_type == Z_SRW_query_type_pqf && + if (srw_req->queryType && !strcmp(srw_req->queryType, "pqf") && assoc->init->bend_scan) { YAZ_PQF_Parser pqf_parser = yaz_pqf_create(); bsrr->term = yaz_pqf_scan(pqf_parser, assoc->decode, &bsrr->attributeset, - srw_req->scanClause.pqf); + srw_req->scanClause); yaz_pqf_destroy(pqf_parser); bsrr->scanClause = 0; ((int (*)(void *, bend_scan_rr *)) (*assoc->init->bend_scan))(assoc->backend, bsrr); } - else if (srw_req->query_type == Z_SRW_query_type_cql + else if ((!srw_req->queryType || !strcmp(srw_req->queryType, "cql")) && assoc->init->bend_scan && assoc->server && assoc->server->cql_transform) { @@ -1372,7 +1378,7 @@ static void srw_bend_scan(association *assoc, bsrr->term = (Z_AttributesPlusTerm *) odr_malloc(assoc->decode, sizeof(*bsrr->term)); srw_error = cql2pqf_scan(assoc->encode, - srw_req->scanClause.cql, + srw_req->scanClause, assoc->server->cql_transform, bsrr->term); if (srw_error) @@ -1385,12 +1391,12 @@ static void srw_bend_scan(association *assoc, (*assoc->init->bend_scan))(assoc->backend, bsrr); } } - else if (srw_req->query_type == Z_SRW_query_type_cql + else if ((!srw_req->queryType || !strcmp(srw_req->queryType, "cql")) && assoc->init->bend_srw_scan) { bsrr->term = 0; bsrr->attributeset = 0; - bsrr->scanClause = srw_req->scanClause.cql; + bsrr->scanClause = srw_req->scanClause; ((int (*)(void *, bend_scan_rr *)) (*assoc->init->bend_srw_scan))(assoc->backend, bsrr); } @@ -1451,24 +1457,6 @@ static void srw_bend_scan(association *assoc, if (log_request) { WRBUF wr = wrbuf_alloc(); - const char *querytype = 0; - const char *querystr = 0; - - switch(srw_req->query_type) - { - case Z_SRW_query_type_pqf: - querytype = "PQF"; - querystr = srw_req->scanClause.pqf; - break; - case Z_SRW_query_type_cql: - querytype = "CQL"; - querystr = srw_req->scanClause.cql; - break; - default: - querytype = "UNKNOWN"; - querystr = ""; - } - wrbuf_printf(wr, "SRWScan %s ", srw_req->database); if (srw_res->num_diagnostics) @@ -1484,7 +1472,7 @@ static void srw_bend_scan(association *assoc, (srw_req->maximumTerms ? *srw_req->maximumTerms : 1)); /* there is no step size in SRU/W ??? */ - wrbuf_printf(wr, "%s: %s ", querytype, querystr); + wrbuf_printf(wr, "%s: %s ", srw_req->queryType, srw_req->scanClause); yaz_log(log_request, "%s ", wrbuf_cstr(wr) ); wrbuf_destroy(wr); } @@ -3112,7 +3100,6 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb) { Z_Entry *e; Z_TermInfo *t; - Odr_oct *o; tab[i] = e = (Z_Entry *)odr_malloc(assoc->encode, sizeof(*e)); if (bsrr->entries[i].occurrences >= 0) @@ -3139,12 +3126,10 @@ static Z_APDU *process_scanRequest(association *assoc, request *reqb) t->term = (Z_Term *) odr_malloc(assoc->encode, sizeof(*t->term)); t->term->which = Z_Term_general; - t->term->u.general = o = - (Odr_oct *)odr_malloc(assoc->encode, sizeof(Odr_oct)); - o->buf = (unsigned char *) - odr_malloc(assoc->encode, o->len = o->size = - strlen(bsrr->entries[i].term)); - memcpy(o->buf, bsrr->entries[i].term, o->len); + t->term->u.general = + odr_create_Odr_oct(assoc->encode, + bsrr->entries[i].term, + strlen(bsrr->entries[i].term)); yaz_log(YLOG_DEBUG, " term #%d: '%s' (" ODR_INT_PRINTF ")", i, bsrr->entries[i].term, bsrr->entries[i].occurrences); } diff --git a/src/solr.c b/src/solr.c index 088fb63..9897bb1 100644 --- a/src/solr.c +++ b/src/solr.c @@ -397,32 +397,62 @@ static int yaz_solr_encode_facet_field( struct yaz_facet_attr attr_values; yaz_facet_attr_init(&attr_values); yaz_facet_attr_get_z_attributes(attribute_list, &attr_values); - // TODO do we want to support server decided if (attr_values.errcode) return -1; if (attr_values.useattr) { WRBUF wrbuf = wrbuf_alloc(); - wrbuf_puts(wrbuf, (char *) attr_values.useattr); yaz_add_name_value_str(encode, name, value, i, "facet.field", - odr_strdup(encode, wrbuf_cstr(wrbuf))); + odr_strdup(encode, attr_values.useattr)); + if (attr_values.limit > 0) { - WRBUF wrbuf2 = wrbuf_alloc(); - Odr_int olimit; - wrbuf_puts(wrbuf2, "f."); - wrbuf_puts(wrbuf2, wrbuf_cstr(wrbuf)); - wrbuf_puts(wrbuf2, ".facet.limit"); - olimit = attr_values.limit; + Odr_int v = attr_values.limit; + wrbuf_rewind(wrbuf); + wrbuf_printf(wrbuf, "f.%s.facet.limit", attr_values.useattr); yaz_add_name_value_int(encode, name, value, i, - odr_strdup(encode, wrbuf_cstr(wrbuf2)), - &olimit); - wrbuf_destroy(wrbuf2); + odr_strdup(encode, wrbuf_cstr(wrbuf)), + &v); + } + if (attr_values.start > 1) + { + Odr_int v = attr_values.start - 1; + wrbuf_rewind(wrbuf); + wrbuf_printf(wrbuf, "f.%s.facet.offset", attr_values.useattr); + yaz_add_name_value_int(encode, name, value, i, + odr_strdup(encode, wrbuf_cstr(wrbuf)), + &v); + } + if (attr_values.sortorder == 1) + { + wrbuf_rewind(wrbuf); + wrbuf_printf(wrbuf, "f.%s.facet.sort", attr_values.useattr); + yaz_add_name_value_str(encode, name, value, i, + odr_strdup(encode, wrbuf_cstr(wrbuf)), + "index"); } wrbuf_destroy(wrbuf); } + else + { + if (attr_values.limit > 0) + { + Odr_int v = attr_values.limit; + yaz_add_name_value_int(encode, name, value, i, "facet.limit", &v); + } + if (attr_values.start > 1) + { + Odr_int v = attr_values.start - 1; + yaz_add_name_value_int(encode, name, value, i, "facet.offset", &v); + } + if (attr_values.sortorder == 1) + { + yaz_add_name_value_str(encode, name, value, i, "facet.sort", + "index"); + } + } return 0; } @@ -461,19 +491,10 @@ int yaz_solr_encode_request(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, { Z_SRW_searchRetrieveRequest *request = srw_pdu->u.request; solr_op = "select"; - switch (srw_pdu->u.request->query_type) - { - case Z_SRW_query_type_pqf: - yaz_add_name_value_str(encode, name, value, &i, - "q", request->query.pqf); - break; - case Z_SRW_query_type_cql: - yaz_add_name_value_str(encode, name, value, &i, - "q", request->query.cql); - break; - default: + if (!srw_pdu->u.request->query) return -1; - } + /* not considering query type here ! */ + yaz_add_name_value_str(encode, name, value, &i, "q", request->query); if (srw_pdu->u.request->startRecord) { Odr_int start = *request->startRecord - 1; @@ -506,32 +527,33 @@ int yaz_solr_encode_request(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, else if (srw_pdu->which == Z_SRW_scan_request) { Z_SRW_scanRequest *request = srw_pdu->u.scan_request; solr_op = "terms"; - switch (srw_pdu->u.scan_request->query_type) + if (!srw_pdu->u.scan_request->scanClause) + return -1; + if (!strcmp(srw_pdu->u.scan_request->queryType, "pqf")) + { + yaz_add_name_value_str(encode, name, value, &i, + "terms.fl", request->scanClause); + yaz_add_name_value_str(encode, name, value, &i, + "terms.lower", request->scanClause); + } + else if (!strcmp(srw_pdu->u.scan_request->queryType, "cql")) { - case Z_SRW_query_type_pqf: + q = request->scanClause; + pos = strchr(q, ':'); + if (pos != NULL) { yaz_add_name_value_str(encode, name, value, &i, - "terms.fl", request->scanClause.pqf); + "terms.lower", odr_strdup(encode, pos + 1)); + *pos = '\0'; yaz_add_name_value_str(encode, name, value, &i, - "terms.lower", request->scanClause.pqf); - break; - case Z_SRW_query_type_cql: - q = request->scanClause.cql; - pos = strchr(q, ':'); - if (pos != NULL) { - yaz_add_name_value_str(encode, name, value, &i, - "terms.lower", odr_strdup(encode, pos + 1)); - *pos = '\0'; - yaz_add_name_value_str(encode, name, value, &i, - "terms.fl", odr_strdup(encode, q)); - *pos = ':'; - } else { - yaz_add_name_value_str(encode, name, value, &i, - "terms.lower", odr_strdup(encode, q)); - } - break; - default: - return -1; + "terms.fl", odr_strdup(encode, q)); + *pos = ':'; + } else { + yaz_add_name_value_str(encode, name, value, &i, + "terms.lower", odr_strdup(encode, q)); + } } + else + return -1; yaz_add_name_value_str(encode, name, value, &i, "terms.sort", "index"); yaz_add_name_value_int(encode, name, value, &i, diff --git a/src/sortspec.c b/src/sortspec.c index a016496..6cae7d8 100644 --- a/src/sortspec.c +++ b/src/sortspec.c @@ -121,9 +121,7 @@ Z_SortKeySpecList *yaz_sort_spec(ODR out, const char *arg) odr_malloc(out, sizeof(Odr_oct)); i++; sks->u.missingValueData->len = strlen(sort_flags+i); - sks->u.missingValueData->size = sks->u.missingValueData->len; - sks->u.missingValueData->buf = (unsigned char*) - odr_strdup(out, sort_flags+i); + sks->u.missingValueData->buf = odr_strdup(out, sort_flags+i); i += strlen(sort_flags+i) - 1; break; } diff --git a/src/sru-p.h b/src/sru-p.h index b10b858..ea7b3e4 100644 --- a/src/sru-p.h +++ b/src/sru-p.h @@ -37,10 +37,49 @@ void yaz_add_name_value_int(ODR o, char **name, char **value, int *i, Z_AttributeList *yaz_use_attribute_create(ODR o, const char *name); +char *yaz_negotiate_sru_version(char *input_ver); + +void yaz_sru_facet_request(ODR, Z_FacetList **facetList, + const char **limit, const char **start, + const char **sort); + #if YAZ_HAVE_XML2 #include #include -const char *yaz_element_attribute_value_get(xmlNodePtr ptr, const char *node_name, const char *attribute_name); + +int yaz_match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o, + char **val); +int yaz_match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, + Odr_int **val); +int yaz_match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o, + char **val, int *len); +int yaz_match_xsd_string_n_nmem(xmlNodePtr ptr, const char *elem, NMEM nmem, + char **val, int *len); +int yaz_match_xsd_element(xmlNodePtr ptr, const char *elem); + +int yaz_match_xsd_XML_n2(xmlNodePtr ptr, const char *elem, ODR o, + char **val, int *len, int fixup_root); + +int yaz_match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o, + char **val, int *len); + +xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val); + +void add_xsd_integer(xmlNodePtr ptr, const char *elem, const Odr_int *val); + +xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val, + int len); + +void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len, + xmlNsPtr ns_ptr); + +xmlNodePtr add_xsd_string_ns(xmlNodePtr ptr, const char *elem, const char *val, + xmlNsPtr ns_ptr); + +void yaz_sru_facet_response(ODR o, Z_FacetList **facetList, xmlNodePtr n); + +const char *yaz_element_attribute_value_get(xmlNodePtr ptr, + const char *node_name, const char *attribute_name); #endif /* diff --git a/src/sru_facet.c b/src/sru_facet.c new file mode 100644 index 0000000..67e4733 --- /dev/null +++ b/src/sru_facet.c @@ -0,0 +1,367 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2013 Index Data + * See the file LICENSE for details. + */ +/** + * \file sru_facet.c + * \brief Implements SRU 2.0 facets + */ +#if HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#if YAZ_HAVE_XML2 +#include +#include +#include +#endif + +#include "sru-p.h" +#include +#include + +static void insert_field(WRBUF w, const char *field, size_t length, + const char *attr) +{ + const char *cp0 = wrbuf_cstr(w); + const char *cp = cp0; + + while (1) + { + const char *cp2 = strstr(cp, "@attr 1="); + if (!cp2) + break; + cp = cp2 + 8; + if (!strncmp(cp, field, length) && + (cp[length] == ' ' || cp[length] == ',' || cp[length] == '\0')) + { + /* found the field */ + + cp += length; + wrbuf_insert(w, cp - cp0, attr, strlen(attr)); + wrbuf_insert(w, cp - cp0, " ", 1); + return; + } + while (*cp && *cp != ',') + cp++; + } + if (wrbuf_len(w)) + wrbuf_puts(w, ","); + wrbuf_puts(w, "@attr 1="); + wrbuf_write(w, field, length); + wrbuf_puts(w, " "); + wrbuf_puts(w, attr); +} + +void yaz_sru_facet_request(ODR o, Z_FacetList **facetList, const char **limit, + const char **start, const char **sort) +{ + if (o->direction == ODR_ENCODE) + { + Z_FacetList *fl = *facetList; + if (fl) + { + WRBUF w_limit = wrbuf_alloc(); + WRBUF w_start = wrbuf_alloc(); + WRBUF w_sort = wrbuf_alloc(); + int i; + for (i = 0; i < fl->num; i++) + { + struct yaz_facet_attr av; + yaz_facet_attr_init(&av); + yaz_facet_attr_get_z_attributes(fl->elements[i]->attributes, + &av); + if (av.errcode == 0) + { + if (av.limit) + { + wrbuf_printf(w_limit, "%d", av.limit); + if (av.useattr) + wrbuf_printf(w_limit, ":%s", av.useattr); + wrbuf_puts(w_limit, ","); + } + if (av.start || av.useattr) + { + wrbuf_printf(w_start, "%d", + av.start == 0 ? 1 : av.start); + if (av.useattr) + wrbuf_printf(w_start, ":%s", av.useattr); + wrbuf_puts(w_start, ","); + } + if (av.sortorder == 1) + { + /* allow sorting per field */ + /* not really according to spec */ + wrbuf_printf(w_sort, "alphanumeric"); + if (av.useattr) + wrbuf_printf(w_sort, ":%s", av.useattr); + wrbuf_puts(w_sort, ","); + } + } + } + if (wrbuf_len(w_limit) > 1) + { + wrbuf_cut_right(w_limit, 1); /* remove , */ + *limit = odr_strdup(o, wrbuf_cstr(w_limit)); + } + if (wrbuf_len(w_start) > 1) + { + wrbuf_cut_right(w_start, 1); /* remove , */ + *start = odr_strdup(o, wrbuf_cstr(w_start)); + } + if (wrbuf_len(w_sort) > 1) + { + wrbuf_cut_right(w_sort, 1); /* remove , */ + *sort = odr_strdup(o, wrbuf_cstr(w_sort)); + } + wrbuf_destroy(w_limit); + wrbuf_destroy(w_start); + wrbuf_destroy(w_sort); + } + } + else if (o->direction == ODR_DECODE) + { + WRBUF w = wrbuf_alloc(); + + if (*limit) + { + const char *cp = *limit; + int nor = 0; + int val = 0; + while (sscanf(cp, "%d%n", &val, &nor) >= 1 && nor > 0) + { + cp += nor; + if (*cp == ':') /* field name follows */ + { + char tmp[40]; + const char *cp0 = ++cp; + while (*cp && *cp != ',') + cp++; + sprintf(tmp, "@attr 3=%d", val); + insert_field(w, cp0, cp - cp0, tmp); + } + if (*cp != ',') + break; + cp++; + } + } + if (*start) + { + const char *cp = *start; + int nor = 0; + int val = 0; + while (sscanf(cp, "%d%n", &val, &nor) >= 1 && nor > 0) + { + cp += nor; + if (*cp == ':') /* field name follows */ + { + char tmp[40]; + const char *cp0 = ++cp; + while (*cp && *cp != ',') + cp++; + sprintf(tmp, "@attr 4=%d", val); + insert_field(w, cp0, cp - cp0, tmp); + } + if (*cp != ',') + break; + cp++; + } + } + + if (*sort) + { + const char *cp = *sort; + while (1) + { + int val = 0; + const char *cp0 = cp; + while (*cp && *cp != ':' && *cp != ',') + cp++; + if (!strncmp(cp0, "alphanumeric", cp - cp0)) + val = 1; + if (*cp == ':') /* field name follows */ + { + char tmp[40]; + cp0 = ++cp; + while (*cp && *cp != ',') + cp++; + sprintf(tmp, "@attr 2=%d", val); + insert_field(w, cp0, cp - cp0, tmp); + } + if (*cp != ',') + break; + cp++; + } + } + + if (wrbuf_len(w)) + *facetList = yaz_pqf_parse_facet_list(o, wrbuf_cstr(w)); + else + *facetList = 0; + wrbuf_destroy(w); + } +} + +#if YAZ_HAVE_XML2 +void yaz_sru_facet_response(ODR o, Z_FacetList **facetList, xmlNodePtr n) +{ + if (o->direction == ODR_ENCODE) + { + Z_FacetList *fl = *facetList; + if (fl) + { + int i; + const char *ns = + "http://docs.oasis-open.org/ns/search-ws/facetedResults"; + xmlNode *p1 = xmlNewChild(n, 0, BAD_CAST "facetedResults", 0); + xmlNsPtr ns_fr = xmlNewNs(p1, BAD_CAST ns, BAD_CAST "fr"); + xmlSetNs(p1, ns_fr); + for (i = 0; i < fl->num; i++) + { + Z_FacetField *ff = fl->elements[i]; + xmlNode *p2 = xmlNewChild(p1, 0, BAD_CAST "facet", 0); + int j; + xmlNode *p3; + struct yaz_facet_attr av; + yaz_facet_attr_init(&av); + yaz_facet_attr_get_z_attributes(ff->attributes, &av); + add_xsd_string(p2, "index", av.useattr); + p3 = xmlNewChild(p2, 0, BAD_CAST "terms", 0); + for (j = 0; j < ff->num_terms; j++) + { + Z_FacetTerm *ft = ff->terms[j]; + Z_Term *zt = ft->term; + xmlNode *p4 = xmlNewChild(p3, 0, BAD_CAST "term", 0); + if (zt->which == Z_Term_general) + add_xsd_string_n(p4, "actualTerm", + (char *) zt->u.general->buf, + zt->u.general->len); + if (ft->count) + add_xsd_integer(p4, "count", ft->count); + } + } + } + } + else if (o->direction == ODR_DECODE) + { + Z_FacetList *fl = (Z_FacetList *) odr_malloc(o, sizeof(*fl)); + xmlNode *p1; + + fl->num = 0; + for (p1 = n->children; p1; p1 = p1->next) + if (yaz_match_xsd_element(p1, "facet")) + fl->num++; + if (fl->num > 0) + { + int i = 0; + *facetList = fl; + fl->elements = (Z_FacetField **) + odr_malloc(o, sizeof(*fl->elements) * fl->num); + for (p1 = n->children; p1; p1 = p1->next) + if (yaz_match_xsd_element(p1, "facet")) + { + char *index_name = 0; + xmlNode *p_terms = 0; + xmlNode *p2 = p1->children; + Z_FacetField *ff = (Z_FacetField *) + odr_malloc(o, sizeof(*ff)); + fl->elements[i++] = ff; + ff->attributes = 0; + ff->num_terms = 0; + ff->terms = 0; + for (; p2; p2 = p2->next) + { + if (yaz_match_xsd_string(p2, "index", o, &index_name)) + ; + else if (yaz_match_xsd_element(p2, "terms")) + p_terms = p2; + } + if (index_name) + { + Z_AttributeList *al = + (Z_AttributeList*) odr_malloc(o, sizeof(*al)); + Z_ComplexAttribute *ca = + (Z_ComplexAttribute *) odr_malloc(o, sizeof(*ca)); + Z_AttributeElement *ae = + (Z_AttributeElement *) odr_malloc(o, sizeof(*ae)); + al->num_attributes = 1; + al->attributes = (Z_AttributeElement **) + odr_malloc(o, sizeof(*al->attributes)); + al->attributes[0] = ae; + ae->attributeSet = 0; + ae->attributeType = odr_intdup(o, 1); + ae->which = Z_AttributeValue_complex; + ae->value.complex = ca; + ca->num_semanticAction = 0; + ca->semanticAction = 0; + ca->num_list = 1; + ca->list = (Z_StringOrNumeric **) + odr_malloc(o, sizeof(*ca->list)); + ca->list[0] = (Z_StringOrNumeric *) + odr_malloc(o, sizeof(**ca->list)); + ca->list[0]->which = Z_StringOrNumeric_string; + ca->list[0]->u.string = index_name; + ff->attributes = al; + } + if (p_terms) + { + xmlNode *p; + int i = 0; + for (p = p_terms->children; p; p = p->next) + { + if (yaz_match_xsd_element(p, "term")) + ff->num_terms++; + } + if (ff->num_terms) + ff->terms = (Z_FacetTerm **) + odr_malloc(o, + sizeof(*ff->terms) * ff->num_terms); + for (p = p_terms->children; p; p = p->next) + { + if (yaz_match_xsd_element(p, "term")) + { + char *cstr = 0; + Odr_int *count = 0; + xmlNode *p2 = p->children; + for (; p2; p2 = p2->next) + { + if (yaz_match_xsd_string(p2, "actualTerm", o, + &cstr)) + ; + else if (yaz_match_xsd_integer(p2, "count", o, + &count)) + ; + } + if (cstr && count) + { + ff->terms[i++] = + facet_term_create_cstr(o, cstr, *count); + } + } + } + ff->num_terms = i; + if (ff->num_terms == 0) + ff->terms = 0; + } + } + + } + } +} + +#endif + + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/srw.c b/src/srw.c index d4fbfc6..17b7c39 100644 --- a/src/srw.c +++ b/src/srw.c @@ -18,218 +18,25 @@ #include #include #include - +#include #include "sru-p.h" -static void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len, - xmlNsPtr ns_ptr) -{ - if (val) - { - xmlDocPtr doc = xmlParseMemory(val,len); - if (doc) - { - xmlNodePtr c = xmlNewChild(ptr, ns_ptr, BAD_CAST elem, 0); - xmlNodePtr t = xmlDocGetRootElement(doc); - xmlAddChild(c, xmlCopyNode(t,1)); - xmlFreeDoc(doc); - } - } -} - -xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val, - int len) -{ - if (val) - { - xmlNodePtr c = xmlNewChild(ptr, 0, BAD_CAST elem, 0); - xmlNodePtr t = xmlNewTextLen(BAD_CAST val, len); - xmlAddChild(c, t); - return t; - } - return 0; -} - -xmlNodePtr add_xsd_string_ns(xmlNodePtr ptr, const char *elem, const char *val, - xmlNsPtr ns_ptr) -{ - if (val) - { - xmlNodePtr c = xmlNewChild(ptr, ns_ptr, BAD_CAST elem, 0); - xmlNodePtr t = xmlNewText(BAD_CAST val); - xmlAddChild(c, t); - return t; - } - return 0; -} - -xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val) -{ - return add_xsd_string_ns(ptr, elem, val, 0); -} - -static void add_xsd_integer(xmlNodePtr ptr, const char *elem, - const Odr_int *val) -{ - if (val) - { - char str[40]; - sprintf(str, ODR_INT_PRINTF, *val); - xmlNewTextChild(ptr, 0, BAD_CAST elem, BAD_CAST str); - } -} - -static int match_element(xmlNodePtr ptr, const char *elem) -{ - if (ptr->type == XML_ELEMENT_NODE && !xmlStrcmp(ptr->name, BAD_CAST elem)) - { - return 1; - } - return 0; -} - -#define CHECK_TYPE 0 - -static int match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o, - char **val, int *len) -{ -#if CHECK_TYPE - struct _xmlAttr *attr; -#endif - if (!match_element(ptr, elem)) - return 0; -#if CHECK_TYPE - for (attr = ptr->properties; attr; attr = attr->next) - if (!strcmp(attr->name, "type") && - attr->children && attr->children->type == XML_TEXT_NODE) - { - const char *t = strchr(attr->children->content, ':'); - if (t) - t = t + 1; - else - t = attr->children->content; - if (!strcmp(t, "string")) - break; - } - if (!attr) - return 0; -#endif - ptr = ptr->children; - if (!ptr || ptr->type != XML_TEXT_NODE) - { - *val = ""; - return 1; - } - *val = odr_strdup(o, (const char *) ptr->content); - if (len) - *len = xmlStrlen(ptr->content); - return 1; -} - - -static int match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o, - char **val) -{ - return match_xsd_string_n(ptr, elem, o, val, 0); -} - -static int match_xsd_XML_n2(xmlNodePtr ptr, const char *elem, ODR o, - char **val, int *len, int fixup_root) -{ - xmlBufferPtr buf; - int no_root_nodes = 0; - - if (!match_element(ptr, elem)) - return 0; - - buf = xmlBufferCreate(); - - /* Copy each element nodes at top. - In most cases there is only one root node.. At least one server - http://www.theeuropeanlibrary.org/sru/sru.pl - has multiple root nodes in recordData. - */ - for (ptr = ptr->children; ptr; ptr = ptr->next) - { - if (ptr->type == XML_ELEMENT_NODE) - { - /* copy node to get NS right (bug #740). */ - xmlNode *tmp = xmlCopyNode(ptr, 1); - - xmlNodeDump(buf, tmp->doc, tmp, 0, 0); - - xmlFreeNode(tmp); - no_root_nodes++; - } - } - if (no_root_nodes != 1 && fixup_root) - { - /* does not appear to be an XML document. Make it so */ - xmlBufferAddHead(buf, (const xmlChar *) "", -1); - xmlBufferAdd(buf, (const xmlChar *) "", -1); - } - *val = (char *) odr_malloc(o, buf->use + 1); - memcpy(*val, buf->content, buf->use); - (*val)[buf->use] = '\0'; - - if (len) - *len = buf->use; - - xmlBufferFree(buf); - - return 1; -} - -static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o, - char **val, int *len) -{ - return match_xsd_XML_n2(ptr, elem, o, val, len, 0); -} - -static int match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, - Odr_int **val) -{ -#if CHECK_TYPE - struct _xmlAttr *attr; -#endif - if (!match_element(ptr, elem)) - return 0; -#if CHECK_TYPE - for (attr = ptr->properties; attr; attr = attr->next) - if (!strcmp(attr->name, "type") && - attr->children && attr->children->type == XML_TEXT_NODE) - { - const char *t = strchr(attr->children->content, ':'); - if (t) - t = t + 1; - else - t = attr->children->content; - if (!strcmp(t, "integer")) - break; - } - if (!attr) - return 0; -#endif - ptr = ptr->children; - if (!ptr || ptr->type != XML_TEXT_NODE) - return 0; - *val = odr_intdup(o, odr_atoi((const char *) ptr->content)); - return 1; -} - char *yaz_negotiate_sru_version(char *input_ver) { if (!input_ver) - input_ver = "1.1"; - + return "2.0"; if (!strcmp(input_ver, "1.1")) return "1.1"; - return "1.2"; /* our latest supported version */ + if (!strncmp(input_ver, "1.", 2)) + return "1.2"; + if (!strncmp(input_ver, "2.", 2)) + return "2.0"; + return 0; } static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, Z_SRW_extra_record **extra, - void *client_data, const char *ns) + void *client_data, int version2) { if (o->direction == ODR_DECODE) { @@ -237,6 +44,9 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, char *spack = 0; xmlNodePtr ptr; +#ifdef Z_SRW_packed + rec->packing = 0; +#endif rec->recordSchema = 0; rec->recordData_buf = 0; rec->recordData_len = 0; @@ -250,15 +60,15 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, for (ptr = pptr->children; ptr; ptr = ptr->next) { - if (match_xsd_string(ptr, "recordSchema", o, - &rec->recordSchema)) + if (yaz_match_xsd_string(ptr, "recordSchema", o, + &rec->recordSchema)) ; - else if (match_xsd_string(ptr, "recordPacking", o, &spack)) + else if (yaz_match_xsd_string(ptr, "recordPacking", o, &spack)) ; /* can't rely on it: in SRU 2.0 it's different semantics */ - else if (match_xsd_integer(ptr, "recordPosition", o, - &rec->recordPosition)) + else if (yaz_match_xsd_integer(ptr, "recordPosition", o, + &rec->recordPosition)) ; - else if (match_element(ptr, "recordData")) + else if (yaz_match_xsd_element(ptr, "recordData")) { /* we assume XML packing, if any element nodes exist below recordData. Unfortunately, in SRU 2.0 recordPacking @@ -269,26 +79,26 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, break; if (p) { - match_xsd_XML_n2( + yaz_match_xsd_XML_n2( ptr, "recordData", o, &rec->recordData_buf, &rec->recordData_len, 1); rec->recordPacking = Z_SRW_recordPacking_XML; } else { - match_xsd_string_n( + yaz_match_xsd_string_n( ptr, "recordData", o, &rec->recordData_buf, &rec->recordData_len); rec->recordPacking = Z_SRW_recordPacking_string; } } - else if (match_xsd_XML_n(ptr, "extraRecordData", o, - &ex.extraRecordData_buf, - &ex.extraRecordData_len) ) + else if (yaz_match_xsd_XML_n(ptr, "extraRecordData", o, + &ex.extraRecordData_buf, + &ex.extraRecordData_len) ) ; else - match_xsd_string(ptr, "recordIdentifier", o, - &ex.recordIdentifier); + yaz_match_xsd_string(ptr, "recordIdentifier", o, + &ex.recordIdentifier); } if (ex.extraRecordData_buf || ex.recordIdentifier) { @@ -305,7 +115,12 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, add_xsd_string(ptr, "recordSchema", rec->recordSchema); if (spack) - add_xsd_string(ptr, "recordPacking", spack); + { + if (version2) + add_xsd_string(ptr, "recordXMLEscaping", spack); + else + add_xsd_string(ptr, "recordPacking", spack); + } switch (pack) { case Z_SRW_recordPacking_string: @@ -339,7 +154,7 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs, Z_SRW_extra_record ***extra, - int *num, void *client_data, const char *ns) + int *num, void *client_data, int version2) { if (o->direction == ODR_DECODE) { @@ -361,7 +176,7 @@ static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs, if (ptr->type == XML_ELEMENT_NODE && !xmlStrcmp(ptr->name, BAD_CAST "record")) { - yaz_srw_record(o, ptr, *recs + i, *extra + i, client_data, ns); + yaz_srw_record(o, ptr, *recs + i, *extra + i, client_data, 0); i++; } } @@ -374,7 +189,7 @@ static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs, xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "record", 0); yaz_srw_record(o, rptr, (*recs)+i, (*extra ? *extra + i : 0), - client_data, ns); + client_data, version2); } } return 0; @@ -391,11 +206,12 @@ static int yaz_srw_version(ODR o, xmlNodePtr pptr, Z_SRW_recordVersion *rec, for (ptr = pptr->children; ptr; ptr = ptr->next) { - if (match_xsd_string(ptr, "versionType", o, - &rec->versionType)) + if (yaz_match_xsd_string(ptr, "versionType", o, + &rec->versionType)) ; else - match_xsd_string(ptr, "versionValue", o, &rec->versionValue); + yaz_match_xsd_string(ptr, "versionValue", o, + &rec->versionValue); } } else if (o->direction == ODR_ENCODE) @@ -484,14 +300,14 @@ static Z_FacetField *yaz_sru_proxy_decode_facet_field(ODR odr, xmlNodePtr ptr) list = yaz_use_attribute_create(odr, name); for (node = ptr->children; node; node = node->next) { - if (match_element(node, "facetvalue")) + if (yaz_match_xsd_element(node, "facetvalue")) num_terms++; } facet_field = facet_field_create(odr, list, num_terms); index = 0; for (node = ptr->children; node; node = node->next) { - if (match_element(node, "facetvalue")) + if (yaz_match_xsd_element(node, "facetvalue")) { facet_field_term_set(odr, facet_field, yaz_sru_proxy_get_facet_term_count(odr, node), @@ -509,7 +325,7 @@ static int yaz_sru_proxy_decode_facets(ODR o, xmlNodePtr root, for (ptr = root->children; ptr; ptr = ptr->next) { - if (match_element(ptr, "facets")) + if (yaz_match_xsd_element(ptr, "facets")) { xmlNodePtr node; Z_FacetList *facet_list; @@ -523,7 +339,7 @@ static int yaz_sru_proxy_decode_facets(ODR o, xmlNodePtr root, num_facets = 0; for (node = ptr->children; node; node= node->next) { - if (match_element(node, "facet")) + if (yaz_match_xsd_element(node, "facet")) { facet_list_field_set( o, facet_list, @@ -573,14 +389,14 @@ static int yaz_srw_decode_diagnostics(ODR o, xmlNodePtr pptr, (*recs)[i].message = 0; for (rptr = ptr->children; rptr; rptr = rptr->next) { - if (match_xsd_string(rptr, "uri", o, - &(*recs)[i].uri)) + if (yaz_match_xsd_string(rptr, "uri", o, &(*recs)[i].uri)) ; - else if (match_xsd_string(rptr, "details", o, - &(*recs)[i].details)) + else if (yaz_match_xsd_string(rptr, "details", o, + &(*recs)[i].details)) ; else - match_xsd_string(rptr, "message", o, &(*recs)[i].message); + yaz_match_xsd_string(rptr, "message", o, + &(*recs)[i].message); } i++; } @@ -666,16 +482,16 @@ static int yaz_srw_term(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm *term, term->whereInList = 0; for (ptr = pptr->children; ptr; ptr = ptr->next) { - if (match_xsd_string(ptr, "value", o, &term->value)) + if (yaz_match_xsd_string(ptr, "value", o, &term->value)) ; - else if (match_xsd_integer(ptr, "numberOfRecords", o, - &term->numberOfRecords)) + else if (yaz_match_xsd_integer(ptr, "numberOfRecords", o, + &term->numberOfRecords)) ; - else if (match_xsd_string(ptr, "displayTerm", o, - &term->displayTerm)) + else if (yaz_match_xsd_string(ptr, "displayTerm", o, + &term->displayTerm)) ; else - match_xsd_string(ptr, "whereInList", o, &term->whereInList); + yaz_match_xsd_string(ptr, "whereInList", o, &term->whereInList); } } else if (o->direction == ODR_ENCODE) @@ -743,24 +559,30 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, if (method->type != XML_ELEMENT_NODE) return -1; - *p = yaz_srw_get_core_v_1_1(o); + *p = yaz_srw_get_core_v_2_0(o); if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveRequest")) { xmlNodePtr ptr = method->children; Z_SRW_searchRetrieveRequest *req; + char *recordPacking = 0; + char *recordXMLEscaping = 0; + const char *facetLimit = 0; + const char *facetStart = 0; + const char *facetSort = 0; (*p)->which = Z_SRW_searchRetrieve_request; req = (*p)->u.request = (Z_SRW_searchRetrieveRequest *) odr_malloc(o, sizeof(*req)); - req->query_type = Z_SRW_query_type_cql; - req->query.cql = 0; + req->queryType = "cql"; + req->query = 0; req->sort_type = Z_SRW_sort_type_none; req->sort.none = 0; req->startRecord = 0; req->maximumRecords = 0; req->recordSchema = 0; req->recordPacking = 0; + req->packing = 0; req->recordXPath = 0; req->resultSetTTL = 0; req->stylesheet = 0; @@ -768,50 +590,77 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, for (; ptr; ptr = ptr->next) { - if (match_xsd_string(ptr, "version", o, + if (yaz_match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; - else if (match_xsd_string(ptr, "query", o, - &req->query.cql)) - req->query_type = Z_SRW_query_type_cql; - else if (match_xsd_string(ptr, "pQuery", o, - &req->query.pqf)) - req->query_type = Z_SRW_query_type_pqf; - else if (match_xsd_string(ptr, "xQuery", o, - &req->query.xcql)) - req->query_type = Z_SRW_query_type_xcql; - else if (match_xsd_integer(ptr, "startRecord", o, + else if (yaz_match_xsd_string(ptr, "queryType", o, + &req->queryType)) + ; + else if (yaz_match_xsd_string(ptr, "query", o, + &req->query)) + ; + else if (yaz_match_xsd_string(ptr, "pQuery", o, + &req->query)) + req->queryType = "pqf"; + else if (yaz_match_xsd_string(ptr, "xQuery", o, + &req->query)) + req->queryType = "xcql"; + else if (yaz_match_xsd_integer(ptr, "startRecord", o, &req->startRecord)) ; - else if (match_xsd_integer(ptr, "maximumRecords", o, + else if (yaz_match_xsd_integer(ptr, "maximumRecords", o, &req->maximumRecords)) ; - else if (match_xsd_string(ptr, "recordPacking", o, - &req->recordPacking)) + else if (yaz_match_xsd_string(ptr, "recordPacking", o, + &recordPacking)) ; - else if (match_xsd_string(ptr, "recordSchema", o, + else if (yaz_match_xsd_string(ptr, "recordXMLEscaping", o, + &recordXMLEscaping)) + ; + else if (yaz_match_xsd_string(ptr, "recordSchema", o, &req->recordSchema)) ; - else if (match_xsd_string(ptr, "recordXPath", o, + else if (yaz_match_xsd_string(ptr, "recordXPath", o, &req->recordXPath)) ; - else if (match_xsd_integer(ptr, "resultSetTTL", o, + else if (yaz_match_xsd_integer(ptr, "resultSetTTL", o, &req->resultSetTTL)) ; - else if (match_xsd_string(ptr, "sortKeys", o, + else if (yaz_match_xsd_string(ptr, "sortKeys", o, &req->sort.sortKeys)) req->sort_type = Z_SRW_sort_type_sort; - else if (match_xsd_string(ptr, "stylesheet", o, + else if (yaz_match_xsd_string(ptr, "stylesheet", o, &req->stylesheet)) ; - else - match_xsd_string(ptr, "database", o, &req->database); + else if (yaz_match_xsd_string(ptr, "database", o, + &req->database)) + ; + else if (yaz_match_xsd_string(ptr, "facetLimit", o, + (char**) &facetLimit)) + ; + else if (yaz_match_xsd_string(ptr, "facetStart", o, + (char**) &facetStart)) + ; + else if (yaz_match_xsd_string(ptr, "facetSort", o, + (char**) &facetSort)) + ; } - if (!req->query.cql && !req->query.pqf && !req->query.xcql) + if (!req->query) { /* should put proper diagnostic here */ return -1; } + if (!strcmp((*p)->srw_version, "2.0")) + { + req->recordPacking = recordXMLEscaping; + req->packing = recordPacking; + } + else + { + req->recordPacking = recordPacking; + } + yaz_sru_facet_request(o, &req->facetList, &facetLimit, &facetStart, + &facetSort); } else if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveResponse")) { @@ -823,6 +672,7 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, odr_malloc(o, sizeof(*res)); res->numberOfRecords = 0; + res->resultCountPrecision = 0; res->resultSetId = 0; res->resultSetIdleTime = 0; res->records = 0; @@ -835,35 +685,43 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, for (; ptr; ptr = ptr->next) { - if (match_xsd_string(ptr, "version", o, + if (yaz_match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; - else if (match_xsd_XML_n(ptr, "extraResponseData", o, + else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o, &(*p)->extraResponseData_buf, &(*p)->extraResponseData_len)) ; - else if (match_xsd_integer(ptr, "numberOfRecords", o, + else if (yaz_match_xsd_integer(ptr, "numberOfRecords", o, &res->numberOfRecords)) ; - else if (match_xsd_string(ptr, "resultSetId", o, + else if (yaz_match_xsd_string(ptr, "resultCountPrecision", o, + &res->resultCountPrecision)) + ; + else if (yaz_match_xsd_string(ptr, "resultSetId", o, &res->resultSetId)) ; - else if (match_xsd_integer(ptr, "resultSetIdleTime", o, + else if (yaz_match_xsd_integer(ptr, "resultSetIdleTime", o, + &res->resultSetIdleTime)) + ; + else if (yaz_match_xsd_integer(ptr, "resultSetTTL", o, &res->resultSetIdleTime)) ; - else if (match_element(ptr, "records")) + else if (yaz_match_xsd_element(ptr, "records")) yaz_srw_records(o, ptr, &res->records, &res->extra_records, - &res->num_records, client_data, ns); - else if (match_xsd_integer(ptr, "nextRecordPosition", o, + &res->num_records, client_data, 0); + else if (yaz_match_xsd_integer(ptr, "nextRecordPosition", o, &res->nextRecordPosition)) ; - else if (match_element(ptr, "diagnostics")) + else if (yaz_match_xsd_element(ptr, "diagnostics")) yaz_srw_diagnostics(o, ptr, &res->diagnostics, &res->num_diagnostics, client_data, ns); - else if (match_element(ptr, "facet_analysis")) + else if (yaz_match_xsd_element(ptr, "facet_analysis")) yaz_sru_proxy_decode_facets(o, ptr, &res->facetList); + else if (yaz_match_xsd_element(ptr, "facetedResults")) + yaz_sru_facet_response(o, &res->facetList, ptr); } } else if (!xmlStrcmp(method->name, BAD_CAST "explainRequest")) @@ -875,25 +733,26 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, req = (*p)->u.explain_request = (Z_SRW_explainRequest *) odr_malloc(o, sizeof(*req)); req->recordPacking = 0; + req->packing = 0; req->database = 0; req->stylesheet = 0; for (; ptr; ptr = ptr->next) { - if (match_xsd_string(ptr, "version", o, + if (yaz_match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; - else if (match_xsd_XML_n(ptr, "extraResponseData", o, + else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o, &(*p)->extraResponseData_buf, &(*p)->extraResponseData_len)) ; - else if (match_xsd_string(ptr, "stylesheet", o, + else if (yaz_match_xsd_string(ptr, "stylesheet", o, &req->stylesheet)) ; - else if (match_xsd_string(ptr, "recordPacking", o, + else if (yaz_match_xsd_string(ptr, "recordPacking", o, &req->recordPacking)) ; else - match_xsd_string(ptr, "database", o, &req->database); + yaz_match_xsd_string(ptr, "database", o, &req->database); } } else if (!xmlStrcmp(method->name, BAD_CAST "explainResponse")) @@ -913,17 +772,17 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, for (; ptr; ptr = ptr->next) { - if (match_xsd_string(ptr, "version", o, + if (yaz_match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; - else if (match_xsd_XML_n(ptr, "extraResponseData", o, + else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o, &(*p)->extraResponseData_buf, &(*p)->extraResponseData_len)) ; - else if (match_element(ptr, "record")) + else if (yaz_match_xsd_element(ptr, "record")) yaz_srw_record(o, ptr, &res->record, &res->extra_record, - client_data, ns); - else if (match_element(ptr, "diagnostics")) + client_data, 0); + else if (yaz_match_xsd_element(ptr, "diagnostics")) yaz_srw_diagnostics(o, ptr, &res->diagnostics, &res->num_diagnostics, client_data, ns); @@ -938,8 +797,8 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, (*p)->which = Z_SRW_scan_request; req = (*p)->u.scan_request = (Z_SRW_scanRequest *) odr_malloc(o, sizeof(*req)); - req->query_type = Z_SRW_query_type_cql; - req->scanClause.cql = 0; + req->queryType = "cql"; + req->scanClause = 0; req->responsePosition = 0; req->maximumTerms = 0; req->stylesheet = 0; @@ -947,32 +806,32 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, for (; ptr; ptr = ptr->next) { - if (match_xsd_string(ptr, "version", o, + if (yaz_match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; - else if (match_xsd_XML_n(ptr, "extraResponseData", o, + else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o, &(*p)->extraResponseData_buf, &(*p)->extraResponseData_len)) ; - else if (match_xsd_string(ptr, "scanClause", o, - &req->scanClause.cql)) + else if (yaz_match_xsd_string(ptr, "scanClause", o, + &req->scanClause)) ; - else if (match_xsd_string(ptr, "pScanClause", o, - &req->scanClause.pqf)) + else if (yaz_match_xsd_string(ptr, "pScanClause", o, + &req->scanClause)) { - req->query_type = Z_SRW_query_type_pqf; + req->queryType = "pqf"; } - else if (match_xsd_integer(ptr, "responsePosition", o, + else if (yaz_match_xsd_integer(ptr, "responsePosition", o, &req->responsePosition)) ; - else if (match_xsd_integer(ptr, "maximumTerms", o, + else if (yaz_match_xsd_integer(ptr, "maximumTerms", o, &req->maximumTerms)) ; - else if (match_xsd_string(ptr, "stylesheet", o, + else if (yaz_match_xsd_string(ptr, "stylesheet", o, &req->stylesheet)) ; else - match_xsd_string(ptr, "database", o, &req->database); + yaz_match_xsd_string(ptr, "database", o, &req->database); } } else if (!xmlStrcmp(method->name, BAD_CAST "scanResponse")) @@ -990,18 +849,18 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, for (; ptr; ptr = ptr->next) { - if (match_xsd_string(ptr, "version", o, + if (yaz_match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; - else if (match_xsd_XML_n(ptr, "extraResponseData", o, + else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o, &(*p)->extraResponseData_buf, &(*p)->extraResponseData_len)) ; - else if (match_element(ptr, "terms")) + else if (yaz_match_xsd_element(ptr, "terms")) yaz_srw_terms(o, ptr, &res->terms, &res->num_terms, client_data, ns); - else if (match_element(ptr, "diagnostics")) + else if (yaz_match_xsd_element(ptr, "diagnostics")) yaz_srw_diagnostics(o, ptr, &res->diagnostics, &res->num_diagnostics, client_data, ns); @@ -1021,31 +880,43 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, Z_SRW_PDU **p = handler_data; xmlNsPtr ns_srw; xmlNodePtr ptr = 0; - + int version2 = !(*p)->srw_version || + strcmp((*p)->srw_version, "2.") > 0; if ((*p)->which == Z_SRW_searchRetrieve_request) { Z_SRW_searchRetrieveRequest *req = (*p)->u.request; + const char *queryType = req->queryType; + if (version2) + ns = "http://docs.oasis-open.org/ns/search-ws/sruRequest"; ptr = xmlNewChild(pptr, 0, BAD_CAST "searchRetrieveRequest", 0); ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs"); xmlSetNs(ptr, ns_srw); - if ((*p)->srw_version) - add_xsd_string(ptr, "version", (*p)->srw_version); - switch (req->query_type) + add_xsd_string(ptr, "version", (*p)->srw_version); + if (version2) { - case Z_SRW_query_type_cql: - add_xsd_string(ptr, "query", req->query.cql); - break; - case Z_SRW_query_type_xcql: - add_xsd_string(ptr, "xQuery", req->query.xcql); - break; - case Z_SRW_query_type_pqf: - add_xsd_string(ptr, "pQuery", req->query.pqf); - break; + if (queryType) + add_xsd_string(ptr, "queryType", queryType); + add_xsd_string(ptr, "query", req->query); + } + else + { + if (!queryType || !strcmp(queryType, "cql")) + add_xsd_string(ptr, "query", req->query); + else if (!strcmp(queryType, "xcql")) + add_xsd_string(ptr, "xQuery", req->query); + else if (!strcmp(queryType, "pqf")) + add_xsd_string(ptr, "pQuery", req->query); } add_xsd_integer(ptr, "startRecord", req->startRecord); add_xsd_integer(ptr, "maximumRecords", req->maximumRecords); - add_xsd_string(ptr, "recordPacking", req->recordPacking); + if (version2) + { + add_xsd_string(ptr, "recordXMLEscaping", req->recordPacking); + add_xsd_string(ptr, "recordPacking", req->packing); + } + else + add_xsd_string(ptr, "recordPacking", req->recordPacking); add_xsd_string(ptr, "recordSchema", req->recordSchema); add_xsd_string(ptr, "recordXPath", req->recordXPath); add_xsd_integer(ptr, "resultSetTTL", req->resultSetTTL); @@ -1062,25 +933,38 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, } add_xsd_string(ptr, "stylesheet", req->stylesheet); add_xsd_string(ptr, "database", req->database); + { + const char *limit = 0; + const char *start = 0; + const char *sort = 0; + yaz_sru_facet_request(o, &req->facetList, &limit, &start, + &sort); + add_xsd_string(ptr, "facetLimit", limit); + add_xsd_string(ptr, "facetStart", start); + add_xsd_string(ptr, "facetSort", sort); + } } else if ((*p)->which == Z_SRW_searchRetrieve_response) { Z_SRW_searchRetrieveResponse *res = (*p)->u.response; + if (version2) + ns = "http://docs.oasis-open.org/ns/search-ws/sruResponse"; ptr = xmlNewChild(pptr, 0, BAD_CAST "searchRetrieveResponse", 0); ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs"); xmlSetNs(ptr, ns_srw); - if ((*p)->srw_version) - add_xsd_string(ptr, "version", (*p)->srw_version); + add_xsd_string(ptr, "version", (*p)->srw_version); add_xsd_integer(ptr, "numberOfRecords", res->numberOfRecords); add_xsd_string(ptr, "resultSetId", res->resultSetId); - add_xsd_integer(ptr, "resultSetIdleTime", res->resultSetIdleTime); + add_xsd_integer(ptr, + version2 ? "resultSetTTL" : "resultSetIdleTime" , + res->resultSetIdleTime); if (res->num_records) { xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "records", 0); yaz_srw_records(o, rptr, &res->records, &res->extra_records, &res->num_records, - client_data, ns); + client_data, version2); } add_xsd_integer(ptr, "nextRecordPosition", res->nextRecordPosition); @@ -1091,6 +975,10 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, yaz_srw_diagnostics(o, rptr, &res->diagnostics, &res->num_diagnostics, client_data, ns); } + if (res->resultCountPrecision) + add_xsd_string(ptr, "resultCountPrecision", + res->resultCountPrecision); + yaz_sru_facet_response(o, &res->facetList, ptr); } else if ((*p)->which == Z_SRW_explain_request) { @@ -1100,7 +988,13 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, xmlSetNs(ptr, ns_srw); add_xsd_string(ptr, "version", (*p)->srw_version); - add_xsd_string(ptr, "recordPacking", req->recordPacking); + if (version2) + { + add_xsd_string(ptr, "recordXMLEscaping", req->recordPacking); + add_xsd_string(ptr, "recordPacking", req->packing); + } + else + add_xsd_string(ptr, "recordPacking", req->recordPacking); add_xsd_string(ptr, "stylesheet", req->stylesheet); add_xsd_string(ptr, "database", req->database); } @@ -1116,7 +1010,7 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, { xmlNodePtr ptr1 = xmlNewChild(ptr, 0, BAD_CAST "record", 0); yaz_srw_record(o, ptr1, &res->record, &res->extra_record, - client_data, ns); + client_data, version2); } if (res->num_diagnostics) { @@ -1129,19 +1023,27 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if ((*p)->which == Z_SRW_scan_request) { Z_SRW_scanRequest *req = (*p)->u.scan_request; + const char *queryType = req->queryType; + if (version2) + ns = "http://docs.oasis-open.org/ns/search-ws/scan"; ptr = xmlNewChild(pptr, 0, BAD_CAST "scanRequest", 0); ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs"); xmlSetNs(ptr, ns_srw); add_xsd_string(ptr, "version", (*p)->srw_version); - switch (req->query_type) + + if (version2) { - case Z_SRW_query_type_cql: - add_xsd_string(ptr, "scanClause", req->scanClause.cql); - break; - case Z_SRW_query_type_pqf: - add_xsd_string(ptr, "pScanClause", req->scanClause.pqf); - break; + if (queryType && strcmp(queryType, "cql")) + add_xsd_string(ptr, "queryType", queryType); + add_xsd_string(ptr, "scanClause", req->scanClause); + } + else + { + if (!queryType || !strcmp(queryType, "cql")) + add_xsd_string(ptr, "scanClause", req->scanClause); + else if (!strcmp(queryType, "pqf")) + add_xsd_string(ptr, "pScanClause", req->scanClause); } add_xsd_integer(ptr, "responsePosition", req->responsePosition); add_xsd_integer(ptr, "maximumTerms", req->maximumTerms); @@ -1151,12 +1053,13 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, else if ((*p)->which == Z_SRW_scan_response) { Z_SRW_scanResponse *res = (*p)->u.scan_response; + if (version2) + ns = "http://docs.oasis-open.org/ns/search-ws/scan"; ptr = xmlNewChild(pptr, 0, BAD_CAST "scanResponse", 0); ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs"); xmlSetNs(ptr, ns_srw); add_xsd_string(ptr, "version", (*p)->srw_version); - if (res->num_terms) { xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "terms", 0); @@ -1201,7 +1104,7 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, if (method->type != XML_ELEMENT_NODE) return -1; - *p = yaz_srw_get_core_v_1_1(o); + *p = yaz_srw_get_core_v_2_0(o); if (!xmlStrcmp(method->name, BAD_CAST "updateRequest")) { @@ -1225,10 +1128,10 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, for (; ptr; ptr = ptr->next) { - if (match_xsd_string(ptr, "version", o, + if (yaz_match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; - else if (match_xsd_string(ptr, "action", o, + else if (yaz_match_xsd_string(ptr, "action", o, &oper)){ if (oper) { @@ -1240,24 +1143,24 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, req->operation = "insert"; } } - else if (match_xsd_string(ptr, "recordIdentifier", o, + else if (yaz_match_xsd_string(ptr, "recordIdentifier", o, &req->recordId)) ; - else if (match_element(ptr, "recordVersions" ) ) + else if (yaz_match_xsd_element(ptr, "recordVersions" ) ) yaz_srw_versions( o, ptr, &req->recordVersions, &req->num_recordVersions, client_data, ns_ucp_str); - else if (match_element(ptr, "record")) + else if (yaz_match_xsd_element(ptr, "record")) { req->record = yaz_srw_get_record(o); yaz_srw_record(o, ptr, req->record, &req->extra_record, - client_data, ns_ucp_str); + client_data, 0); } - else if (match_xsd_string(ptr, "stylesheet", o, + else if (yaz_match_xsd_string(ptr, "stylesheet", o, &req->stylesheet)) ; else - match_xsd_string(ptr, "database", o, &req->database); + yaz_match_xsd_string(ptr, "database", o, &req->database); } } else if (!xmlStrcmp(method->name, BAD_CAST "updateResponse")) @@ -1282,26 +1185,26 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, for (; ptr; ptr = ptr->next) { - if (match_xsd_string(ptr, "version", o, + if (yaz_match_xsd_string(ptr, "version", o, &(*p)->srw_version)) ; - else if (match_xsd_string(ptr, "operationStatus", o, + else if (yaz_match_xsd_string(ptr, "operationStatus", o, &res->operationStatus )) ; - else if (match_xsd_string(ptr, "recordIdentifier", o, + else if (yaz_match_xsd_string(ptr, "recordIdentifier", o, &res->recordId)) ; - else if (match_element(ptr, "recordVersions" )) + else if (yaz_match_xsd_element(ptr, "recordVersions" )) yaz_srw_versions(o, ptr, &res->recordVersions, &res->num_recordVersions, client_data, ns_ucp_str); - else if (match_element(ptr, "record")) + else if (yaz_match_xsd_element(ptr, "record")) { res->record = yaz_srw_get_record(o); yaz_srw_record(o, ptr, res->record, &res->extra_record, - client_data, ns_ucp_str); + client_data, 0); } - else if (match_element(ptr, "diagnostics")) + else if (yaz_match_xsd_element(ptr, "diagnostics")) yaz_srw_diagnostics(o, ptr, &res->diagnostics, &res->num_diagnostics, client_data, ns_ucp_str); @@ -1344,7 +1247,7 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0); xmlSetNs(rptr, ns_srw); yaz_srw_record(o, rptr, req->record, &req->extra_record, - client_data, ns_ucp_str); + client_data, 0); } if (req->extraRequestData_len) { @@ -1376,7 +1279,7 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data, xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0); xmlSetNs(rptr, ns_srw); yaz_srw_record(o, rptr, res->record, &res->extra_record, - client_data, ns_ucp_str); + client_data, 0); } if (res->num_diagnostics) { diff --git a/src/srwutil.c b/src/srwutil.c index 178d886..83172d5 100644 --- a/src/srwutil.c +++ b/src/srwutil.c @@ -269,11 +269,12 @@ int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, const char *p0 = hreq->path, *p1; int ret = -1; - static Z_SOAP_Handler soap_handlers[4] = { + static Z_SOAP_Handler soap_handlers[5] = { #if YAZ_HAVE_XML2 { YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec }, { YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec }, { YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec }, + { YAZ_XMLNS_SRU_v2_mask, 0, (Z_SOAP_fun) yaz_srw_codec }, #endif {0, 0, 0} }; @@ -295,6 +296,10 @@ int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p; yaz_srw_decodeauth(*srw_pdu, hreq, 0, 0, decode); + /* last entry in handlers - SRU 2.0 - is turned into + offset 0.. due to other pieces relying on it */ + if ((*soap_package)->u.generic->no == 3) + (*soap_package)->u.generic->no = 0; if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request && (*srw_pdu)->u.request->database == 0) (*srw_pdu)->u.request->database = db; @@ -378,20 +383,23 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, const char *operation = 0; char *version = 0; char *query = 0; - char *pQuery = 0; + char *queryType = "cql"; char *username = 0; char *password = 0; char *sortKeys = 0; char *stylesheet = 0; char *scanClause = 0; - char *pScanClause = 0; char *recordXPath = 0; char *recordSchema = 0; - char *recordPacking = "xml"; /* xml packing is default for SRU */ + char *recordXMLEscaping = 0; + char *recordPacking = 0; char *maximumRecords = 0; char *startRecord = 0; char *maximumTerms = 0; char *responsePosition = 0; + const char *facetLimit = 0; + const char *facetStart = 0; + const char *facetSort = 0; Z_SRW_extra_arg *extra_args = 0; #endif char **uri_name; @@ -422,7 +430,12 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, if (!strcmp(n, "query")) query = v; else if (!strcmp(n, "x-pquery")) - pQuery = v; + { + query = v; + queryType = "pqf"; + } + else if (!strcmp(n, "queryType")) + queryType = v; else if (!strcmp(n, "x-username")) username = v; else if (!strcmp(n, "x-password")) @@ -439,12 +452,17 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, recordSchema = v; else if (!strcmp(n, "recordPacking")) recordPacking = v; + else if (!strcmp(n, "recordXMLEscaping")) + recordXMLEscaping = v; else if (!strcmp(n, "version")) version = v; else if (!strcmp(n, "scanClause")) scanClause = v; else if (!strcmp(n, "x-pScanClause")) - pScanClause = v; + { + scanClause = v; + queryType = "pqf"; + } else if (!strcmp(n, "maximumRecords")) maximumRecords = v; else if (!strcmp(n, "startRecord")) @@ -453,6 +471,12 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, maximumTerms = v; else if (!strcmp(n, "responsePosition")) responsePosition = v; + else if (!strcmp(n, "facetLimit")) + facetLimit = v; + else if (!strcmp(n, "facetStart")) + facetStart = v; + else if (!strcmp(n, "facetSort")) + facetSort = v; else if (!strcmp(n, "extraRequestData")) ; /* ignoring extraRequestData */ else if (n[0] == 'x' && n[1] == '-') @@ -473,24 +497,21 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, } } } - if (!version) + if (!operation) { - if (uri_name) - yaz_add_srw_diagnostic( - decode, diag, num_diag, - YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "version"); - version = "1.1"; + if (query) + operation = "searchRetrieve"; + else if (scanClause) + operation = "scan"; } - version = yaz_negotiate_sru_version(version); if (!version) { /* negotiation failed. */ yaz_add_srw_diagnostic(decode, diag, num_diag, - YAZ_SRW_UNSUPP_VERSION, "1.2"); - version = "1.2"; + YAZ_SRW_UNSUPP_VERSION, "2.0"); + version = "2.0"; } - if (!operation) { if (uri_name) @@ -499,6 +520,20 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "operation"); operation = "explain"; } + if (strcmp(version, "2.0")) + { + if (recordXMLEscaping) + { + yaz_add_srw_diagnostic(decode, diag, num_diag, + YAZ_SRW_UNSUPP_PARAMETER, + "recordXMLEscaping"); + + } + recordXMLEscaping = recordPacking; + recordPacking = "packed"; + } + if (!recordXMLEscaping) + recordXMLEscaping = "xml"; if (!strcmp(operation, "searchRetrieve")) { Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request); @@ -507,17 +542,11 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, sr->extra_args = extra_args; *srw_pdu = sr; yaz_srw_decodeauth(sr, hreq, username, password, decode); - if (query) - { - sr->u.request->query_type = Z_SRW_query_type_cql; - sr->u.request->query.cql = query; - } - else if (pQuery) - { - sr->u.request->query_type = Z_SRW_query_type_pqf; - sr->u.request->query.pqf = pQuery; - } - else + + sr->u.request->queryType = queryType; + sr->u.request->query = query; + + if (!query) yaz_add_srw_diagnostic( decode, diag, num_diag, YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "query"); @@ -529,8 +558,11 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, } sr->u.request->recordXPath = recordXPath; sr->u.request->recordSchema = recordSchema; - sr->u.request->recordPacking = recordPacking; + sr->u.request->recordPacking = recordXMLEscaping; + sr->u.request->packing = recordPacking; sr->u.request->stylesheet = stylesheet; + yaz_sru_facet_request(decode , &sr->u.request->facetList, + &facetLimit, &facetStart, &facetSort); yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords, &sr->u.request->maximumRecords, @@ -567,7 +599,8 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, sr->extra_args = extra_args; yaz_srw_decodeauth(sr, hreq, username, password, decode); *srw_pdu = sr; - sr->u.explain_request->recordPacking = recordPacking; + sr->u.explain_request->recordPacking = recordXMLEscaping; + sr->u.explain_request->packing = recordPacking; sr->u.explain_request->database = db; sr->u.explain_request->stylesheet = stylesheet; @@ -598,17 +631,10 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, *srw_pdu = sr; yaz_srw_decodeauth(sr, hreq, username, password, decode); - if (scanClause) - { - sr->u.scan_request->query_type = Z_SRW_query_type_cql; - sr->u.scan_request->scanClause.cql = scanClause; - } - else if (pScanClause) - { - sr->u.scan_request->query_type = Z_SRW_query_type_pqf; - sr->u.scan_request->scanClause.pqf = pScanClause; - } - else + sr->u.scan_request->queryType = queryType; + sr->u.scan_request->scanClause = scanClause; + + if (!scanClause) yaz_add_srw_diagnostic( decode, diag, num_diag, YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, "scanClause"); @@ -724,14 +750,14 @@ static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version) return p; } -Z_SRW_PDU *yaz_srw_get_core_v_1_1(ODR o) +Z_SRW_PDU *yaz_srw_get_core_v_2_0(ODR o) { - return yaz_srw_get_core_ver(o, "1.1"); + return yaz_srw_get_core_ver(o, "2.0"); } Z_SRW_PDU *yaz_srw_get(ODR o, int which) { - return yaz_srw_get_pdu(o, which, "1.1"); + return yaz_srw_get_pdu(o, which, "2.0"); } Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version) @@ -744,14 +770,15 @@ Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version) case Z_SRW_searchRetrieve_request: sr->u.request = (Z_SRW_searchRetrieveRequest *) odr_malloc(o, sizeof(*sr->u.request)); - sr->u.request->query_type = Z_SRW_query_type_cql; - sr->u.request->query.cql = 0; + sr->u.request->queryType = "cql"; + sr->u.request->query = 0; sr->u.request->sort_type = Z_SRW_sort_type_none; sr->u.request->sort.none = 0; sr->u.request->startRecord = 0; sr->u.request->maximumRecords = 0; sr->u.request->recordSchema = 0; sr->u.request->recordPacking = 0; + sr->u.request->packing = 0; sr->u.request->recordXPath = 0; sr->u.request->database = 0; sr->u.request->resultSetTTL = 0; @@ -762,6 +789,7 @@ Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version) sr->u.response = (Z_SRW_searchRetrieveResponse *) odr_malloc(o, sizeof(*sr->u.response)); sr->u.response->numberOfRecords = 0; + sr->u.response->resultCountPrecision = 0; sr->u.response->resultSetId = 0; sr->u.response->resultSetIdleTime = 0; sr->u.response->records = 0; @@ -777,6 +805,7 @@ Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version) sr->u.explain_request = (Z_SRW_explainRequest *) odr_malloc(o, sizeof(*sr->u.explain_request)); sr->u.explain_request->recordPacking = 0; + sr->u.explain_request->packing = 0; sr->u.explain_request->database = 0; sr->u.explain_request->stylesheet = 0; break; @@ -800,8 +829,8 @@ Z_SRW_PDU *yaz_srw_get_pdu(ODR o, int which, const char *version) sr->u.scan_request->stylesheet = 0; sr->u.scan_request->maximumTerms = 0; sr->u.scan_request->responsePosition = 0; - sr->u.scan_request->query_type = Z_SRW_query_type_cql; - sr->u.scan_request->scanClause.cql = 0; + sr->u.scan_request->queryType = "cql"; + sr->u.scan_request->scanClause = 0; break; case Z_SRW_scan_response: sr->u.scan_response = (Z_SRW_scanResponse *) @@ -868,29 +897,44 @@ void yaz_add_name_value_str(ODR o, char **name, char **value, int *i, static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode, char **name, char **value, int max_names) { + int version2 = strcmp(srw_pdu->srw_version, "2.") > 0; int i = 0; - yaz_add_name_value_str(encode, name, value, &i, "version", srw_pdu->srw_version); + char *queryType; + yaz_add_name_value_str(encode, name, value, &i, "version", + srw_pdu->srw_version); name[i] = "operation"; - switch(srw_pdu->which) + switch (srw_pdu->which) { case Z_SRW_searchRetrieve_request: value[i++] = "searchRetrieve"; - switch(srw_pdu->u.request->query_type) + queryType = srw_pdu->u.request->queryType; + if (version2) { - case Z_SRW_query_type_cql: + if (queryType && strcmp(queryType, "cql")) + yaz_add_name_value_str(encode, name, value, &i, "queryType", + queryType); yaz_add_name_value_str(encode, name, value, &i, "query", - srw_pdu->u.request->query.cql); - break; - case Z_SRW_query_type_pqf: - yaz_add_name_value_str(encode, name, value, &i, "x-pquery", - srw_pdu->u.request->query.pqf); - break; - case Z_SRW_query_type_xcql: - yaz_add_name_value_str(encode, name, value, &i, "x-cql", - srw_pdu->u.request->query.xcql); - break; + srw_pdu->u.request->query); } - switch(srw_pdu->u.request->sort_type) + else + { + if (!strcmp(queryType, "cql")) + { + yaz_add_name_value_str(encode, name, value, &i, "query", + srw_pdu->u.request->query); + } + else if (!strcmp(queryType, "pqf")) + { + yaz_add_name_value_str(encode, name, value, &i, "x-pquery", + srw_pdu->u.request->query); + } + else if (!strcmp(queryType, "xcql")) + { + yaz_add_name_value_str(encode, name, value, &i, "x-cql", + srw_pdu->u.request->query); + } + } + switch (srw_pdu->u.request->sort_type) { case Z_SRW_sort_type_none: break; @@ -905,37 +949,75 @@ static int yaz_get_sru_parms(const Z_SRW_PDU *srw_pdu, ODR encode, srw_pdu->u.request->maximumRecords); yaz_add_name_value_str(encode, name, value, &i, "recordSchema", srw_pdu->u.request->recordSchema); - yaz_add_name_value_str(encode, name, value, &i, "recordPacking", - srw_pdu->u.request->recordPacking); + if (version2) + { + yaz_add_name_value_str(encode, name, value, &i, "recordXMLEscaping", + srw_pdu->u.request->recordPacking); + yaz_add_name_value_str(encode, name, value, &i, "recordPacking", + srw_pdu->u.request->packing); + } + else + yaz_add_name_value_str(encode, name, value, &i, "recordPacking", + srw_pdu->u.request->recordPacking); yaz_add_name_value_str(encode, name, value, &i, "recordXPath", srw_pdu->u.request->recordXPath); yaz_add_name_value_str(encode, name, value, &i, "stylesheet", srw_pdu->u.request->stylesheet); yaz_add_name_value_int(encode, name, value, &i, "resultSetTTL", srw_pdu->u.request->resultSetTTL); + { + const char *facetLimit = 0; + const char *facetStart = 0; + const char *facetSort = 0; + yaz_sru_facet_request(encode, &srw_pdu->u.request->facetList, + &facetLimit, &facetStart, &facetSort); + yaz_add_name_value_str(encode, name, value, &i, "facetLimit", + (char *) facetLimit); + yaz_add_name_value_str(encode, name, value, &i, "facetStart", + (char *) facetStart); + yaz_add_name_value_str(encode, name, value, &i, "facetSort", + (char *) facetSort); + } break; case Z_SRW_explain_request: value[i++] = "explain"; + + if (version2) + { + yaz_add_name_value_str(encode, name, value, &i, "recordXMLEscaping", + srw_pdu->u.explain_request->recordPacking); + yaz_add_name_value_str(encode, name, value, &i, "recordPacking", + srw_pdu->u.explain_request->packing); + } + else + yaz_add_name_value_str(encode, name, value, &i, "recordPacking", + srw_pdu->u.explain_request->recordPacking); yaz_add_name_value_str(encode, name, value, &i, "stylesheet", srw_pdu->u.explain_request->stylesheet); break; case Z_SRW_scan_request: value[i++] = "scan"; - - switch(srw_pdu->u.scan_request->query_type) + queryType = srw_pdu->u.scan_request->queryType; + if (version2) { - case Z_SRW_query_type_cql: + if (queryType && strcmp(queryType, "cql")) + yaz_add_name_value_str(encode, name, value, &i, "queryType", + queryType); yaz_add_name_value_str(encode, name, value, &i, "scanClause", - srw_pdu->u.scan_request->scanClause.cql); - break; - case Z_SRW_query_type_pqf: - yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause", - srw_pdu->u.scan_request->scanClause.pqf); - break; - case Z_SRW_query_type_xcql: - yaz_add_name_value_str(encode, name, value, &i, "x-cqlScanClause", - srw_pdu->u.scan_request->scanClause.xcql); - break; + srw_pdu->u.scan_request->scanClause); + } + else + { + if (!queryType || !strcmp(queryType, "cql")) + yaz_add_name_value_str(encode, name, value, &i, "scanClause", + srw_pdu->u.scan_request->scanClause); + else if (!strcmp(queryType, "pqf")) + yaz_add_name_value_str(encode, name, value, &i, "x-pScanClause", + srw_pdu->u.scan_request->scanClause); + else if (!strcmp(queryType, "xcql")) + yaz_add_name_value_str(encode, name, value, &i, + "x-cqlScanClause", + srw_pdu->u.scan_request->scanClause); } yaz_add_name_value_int(encode, name, value, &i, "responsePosition", srw_pdu->u.scan_request->responsePosition); @@ -984,7 +1066,6 @@ int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu, odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4); sprintf(path, "%s?%s", hreq->path, uri_args); - yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path); hreq->path = path; z_HTTP_header_add_content_type(encode, &hreq->headers, diff --git a/src/xml_add.c b/src/xml_add.c new file mode 100644 index 0000000..ebd7a8c --- /dev/null +++ b/src/xml_add.c @@ -0,0 +1,87 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2013 Index Data + * See the file LICENSE for details. + */ +/** + * \file xml_add.c + * \brief XML node creation utilities + */ +#if HAVE_CONFIG_H +#include +#endif + +#include + +#include +#if YAZ_HAVE_XML2 +#include "sru-p.h" + +void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len, + xmlNsPtr ns_ptr) +{ + if (val) + { + xmlDocPtr doc = xmlParseMemory(val,len); + if (doc) + { + xmlNodePtr c = xmlNewChild(ptr, ns_ptr, BAD_CAST elem, 0); + xmlNodePtr t = xmlDocGetRootElement(doc); + xmlAddChild(c, xmlCopyNode(t,1)); + xmlFreeDoc(doc); + } + } +} + +xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val, + int len) +{ + if (val) + { + xmlNodePtr c = xmlNewChild(ptr, 0, BAD_CAST elem, 0); + xmlNodePtr t = xmlNewTextLen(BAD_CAST val, len); + xmlAddChild(c, t); + return t; + } + return 0; +} + +xmlNodePtr add_xsd_string_ns(xmlNodePtr ptr, const char *elem, const char *val, + xmlNsPtr ns_ptr) +{ + if (val) + { + xmlNodePtr c = xmlNewChild(ptr, ns_ptr, BAD_CAST elem, 0); + xmlNodePtr t = xmlNewText(BAD_CAST val); + xmlAddChild(c, t); + return t; + } + return 0; +} + +xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val) +{ + return add_xsd_string_ns(ptr, elem, val, 0); +} + +void add_xsd_integer(xmlNodePtr ptr, const char *elem, + const Odr_int *val) +{ + if (val) + { + char str[40]; + sprintf(str, ODR_INT_PRINTF, *val); + xmlNewTextChild(ptr, 0, BAD_CAST elem, BAD_CAST str); + } +} + +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/xml_match.c b/src/xml_match.c new file mode 100644 index 0000000..dd804db --- /dev/null +++ b/src/xml_match.c @@ -0,0 +1,171 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2013 Index Data + * See the file LICENSE for details. + */ +/** + * \file xml_match.c + * \brief XML node inspection utilities + */ +#if HAVE_CONFIG_H +#include +#endif + +#include +#if YAZ_HAVE_XML2 +#include "sru-p.h" + +int yaz_match_xsd_element(xmlNodePtr ptr, const char *elem) +{ + if (ptr->type == XML_ELEMENT_NODE && !xmlStrcmp(ptr->name, BAD_CAST elem)) + { + return 1; + } + return 0; +} + +#define CHECK_TYPE 0 + +int yaz_match_xsd_string_n_nmem(xmlNodePtr ptr, const char *elem, NMEM nmem, + char **val, int *len) +{ +#if CHECK_TYPE + struct _xmlAttr *attr; +#endif + if (!yaz_match_xsd_element(ptr, elem)) + return 0; +#if CHECK_TYPE + for (attr = ptr->properties; attr; attr = attr->next) + if (!strcmp(attr->name, "type") && + attr->children && attr->children->type == XML_TEXT_NODE) + { + const char *t = strchr(attr->children->content, ':'); + if (t) + t = t + 1; + else + t = attr->children->content; + if (!strcmp(t, "string")) + break; + } + if (!attr) + return 0; +#endif + ptr = ptr->children; + if (!ptr || ptr->type != XML_TEXT_NODE) + { + *val = ""; + return 1; + } + *val = nmem_strdup(nmem, (const char *) ptr->content); + if (len) + *len = xmlStrlen(ptr->content); + return 1; +} + +int yaz_match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o, + char **val, int *len) +{ + return yaz_match_xsd_string_n_nmem(ptr, elem, o->mem, val, len); +} + +int yaz_match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o, char **val) +{ + return yaz_match_xsd_string_n(ptr, elem, o, val, 0); +} + +int yaz_match_xsd_XML_n2(xmlNodePtr ptr, const char *elem, ODR o, + char **val, int *len, int fixup_root) +{ + xmlBufferPtr buf; + int no_root_nodes = 0; + + if (!yaz_match_xsd_element(ptr, elem)) + return 0; + + buf = xmlBufferCreate(); + + /* Copy each element nodes at top. + In most cases there is only one root node.. At least one server + http://www.theeuropeanlibrary.org/sru/sru.pl + has multiple root nodes in recordData. + */ + for (ptr = ptr->children; ptr; ptr = ptr->next) + { + if (ptr->type == XML_ELEMENT_NODE) + { + /* copy node to get NS right (bug #740). */ + xmlNode *tmp = xmlCopyNode(ptr, 1); + + xmlNodeDump(buf, tmp->doc, tmp, 0, 0); + + xmlFreeNode(tmp); + no_root_nodes++; + } + } + if (no_root_nodes != 1 && fixup_root) + { + /* does not appear to be an XML document. Make it so */ + xmlBufferAddHead(buf, (const xmlChar *) "", -1); + xmlBufferAdd(buf, (const xmlChar *) "", -1); + } + *val = (char *) odr_malloc(o, buf->use + 1); + memcpy(*val, buf->content, buf->use); + (*val)[buf->use] = '\0'; + + if (len) + *len = buf->use; + + xmlBufferFree(buf); + + return 1; +} + +int yaz_match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o, + char **val, int *len) +{ + return yaz_match_xsd_XML_n2(ptr, elem, o, val, len, 0); +} + +int yaz_match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, + Odr_int **val) +{ +#if CHECK_TYPE + struct _xmlAttr *attr; +#endif + if (!yaz_match_xsd_element(ptr, elem)) + return 0; +#if CHECK_TYPE + for (attr = ptr->properties; attr; attr = attr->next) + if (!strcmp(attr->name, "type") && + attr->children && attr->children->type == XML_TEXT_NODE) + { + const char *t = strchr(attr->children->content, ':'); + if (t) + t = t + 1; + else + t = attr->children->content; + if (!strcmp(t, "integer")) + break; + } + if (!attr) + return 0; +#endif + ptr = ptr->children; + if (!ptr || ptr->type != XML_TEXT_NODE) + return 0; + *val = odr_intdup(o, odr_atoi((const char *) ptr->content)); + return 1; +} + + +#endif + + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/xml_to_opac.c b/src/xml_to_opac.c index ead47bd..236bf8a 100644 --- a/src/xml_to_opac.c +++ b/src/xml_to_opac.c @@ -20,41 +20,14 @@ #include #if YAZ_HAVE_XML2 -#include -#include - -static int match_element(xmlNode *ptr, const char *elem) -{ - if (ptr->type == XML_ELEMENT_NODE && !xmlStrcmp(ptr->name, BAD_CAST elem)) - { - return 1; - } - return 0; -} - -static int match_xsd_string_n(xmlNodePtr ptr, const char *elem, NMEM nmem, - char **val, int *len) -{ - if (!match_element(ptr, elem)) - return 0; - ptr = ptr->children; - if (!ptr || ptr->type != XML_TEXT_NODE) - { - *val = ""; - return 1; - } - *val = nmem_strdup(nmem, (const char *) ptr->content); - if (len) - *len = xmlStrlen(ptr->content); - return 1; -} +#include "sru-p.h" static int match_element_next(xmlNode **ptr, const char *elem, NMEM nmem, char **val) { while (*ptr && (*ptr)->type != XML_ELEMENT_NODE) (*ptr) = (*ptr)->next; - if (*ptr && match_xsd_string_n(*ptr, elem, nmem, val, 0)) + if (*ptr && yaz_match_xsd_string_n_nmem(*ptr, elem, nmem, val, 0)) { *ptr = (*ptr)->next; return 1; @@ -69,7 +42,7 @@ static int match_v_next(xmlNode **ptr, const char *elem, NMEM nmem, while (*ptr && (*ptr)->type != XML_ELEMENT_NODE) (*ptr) = (*ptr)->next; *val = nmem_booldup(nmem, 0); - if (*ptr && match_element(*ptr, elem)) + if (*ptr && yaz_match_xsd_element(*ptr, elem)) { struct _xmlAttr *attr = (*ptr)->properties; @@ -134,7 +107,7 @@ static int volumes(xmlNode *ptr, Z_Volume ***volp, int *num, NMEM nmem) ptr = ptr->next; if (!ptr) break; - if (!match_element(ptr, "volume")) + if (!yaz_match_xsd_element(ptr, "volume")) return 0; ptr = ptr->next; } @@ -147,7 +120,7 @@ static int volumes(xmlNode *ptr, Z_Volume ***volp, int *num, NMEM nmem) ptr = ptr->next; if (!ptr) break; - if (!match_element(ptr, "volume")) + if (!yaz_match_xsd_element(ptr, "volume")) return 0; volume(ptr->children, (*volp) + i, nmem); ptr = ptr->next; @@ -187,7 +160,7 @@ static int circulations(xmlNode *ptr, Z_CircRecord ***circp, ptr = ptr->next; if (!ptr) break; - if (!match_element(ptr, "circulation")) + if (!yaz_match_xsd_element(ptr, "circulation")) return 0; ptr = ptr->next; } @@ -200,7 +173,7 @@ static int circulations(xmlNode *ptr, Z_CircRecord ***circp, ptr = ptr->next; if (!ptr) break; - if (!match_element(ptr, "circulation")) + if (!yaz_match_xsd_element(ptr, "circulation")) return 0; circulation(ptr->children, (*circp) + i, nmem); ptr = ptr->next; @@ -240,7 +213,7 @@ static int holdingsRecord(xmlNode *ptr, Z_HoldingsRecord **r, NMEM nmem) h->volumes = 0; while (ptr && ptr->type != XML_ELEMENT_NODE) ptr = ptr->next; - if (match_element(ptr, "volumes")) + if (yaz_match_xsd_element(ptr, "volumes")) { volumes(ptr->children, &h->volumes, &h->num_volumes, nmem); ptr = ptr->next; @@ -250,7 +223,7 @@ static int holdingsRecord(xmlNode *ptr, Z_HoldingsRecord **r, NMEM nmem) h->circulationData = 0; while (ptr && ptr->type != XML_ELEMENT_NODE) ptr = ptr->next; - if (match_element(ptr, "circulations")) + if (yaz_match_xsd_element(ptr, "circulations")) { circulations(ptr->children, &h->circulationData, &h->num_circulationData, nmem); @@ -271,12 +244,12 @@ static int yaz_xml_to_opac_ptr(yaz_marc_t mt, xmlNode *ptr, if (!nmem) nmem = yaz_marc_get_nmem(mt); - if (!match_element(ptr, "opacRecord")) + if (!yaz_match_xsd_element(ptr, "opacRecord")) return 0; ptr = ptr->children; while (ptr && ptr->type != XML_ELEMENT_NODE) ptr = ptr->next; - if (!match_element(ptr, "bibliographicRecord")) + if (!yaz_match_xsd_element(ptr, "bibliographicRecord")) return 0; if (!bibliographicRecord(mt, ptr->children, &ext, cd, nmem, syntax)) return 0; @@ -288,7 +261,7 @@ static int yaz_xml_to_opac_ptr(yaz_marc_t mt, xmlNode *ptr, ptr = ptr->next; while (ptr && ptr->type != XML_ELEMENT_NODE) ptr = ptr->next; - if (!match_element(ptr, "holdings")) + if (!yaz_match_xsd_element(ptr, "holdings")) return 0; ptr = ptr->children; @@ -300,7 +273,7 @@ static int yaz_xml_to_opac_ptr(yaz_marc_t mt, xmlNode *ptr, ptr = ptr->next; if (!ptr) break; - if (!match_element(ptr, "holding")) + if (!yaz_match_xsd_element(ptr, "holding")) return 0; ptr = ptr->next; } @@ -314,7 +287,7 @@ static int yaz_xml_to_opac_ptr(yaz_marc_t mt, xmlNode *ptr, ptr = ptr->next; if (!ptr) break; - if (!match_element(ptr, "holding")) + if (!yaz_match_xsd_element(ptr, "holding")) return 0; if (!holdingsRecord(ptr->children, opac->holdingsData + i, nmem)) return 0; diff --git a/src/xmlquery.c b/src/xmlquery.c index e0db8d3..5aff1ae 100644 --- a/src/xmlquery.c +++ b/src/xmlquery.c @@ -565,7 +565,7 @@ static void yaz_xml2query_term(const xmlNode *ptr, Z_Term **term, ODR odr, { (*term)->which = Z_Term_general; (*term)->u.general = - odr_create_Odr_oct(odr, (unsigned char *)cdata, strlen(cdata)); + odr_create_Odr_oct(odr, cdata, strlen(cdata)); } else if (!xmlStrcmp(type, BAD_CAST "numeric")) { diff --git a/src/zgdu.c b/src/zgdu.c index ecdb9e6..8c8222e 100644 --- a/src/zgdu.c +++ b/src/zgdu.c @@ -11,24 +11,25 @@ #endif #include -#include +#include "odr-priv.h" #include int z_GDU(ODR o, Z_GDU **p, int opt, const char *name) { + const char *buf = o->op->buf; if (o->direction == ODR_DECODE) { *p = (Z_GDU *) odr_malloc(o, sizeof(**p)); - if (o->size > 10 && !memcmp(o->buf, "HTTP/", 5)) + if (o->op->size > 10 && !memcmp(buf, "HTTP/", 5)) { (*p)->which = Z_GDU_HTTP_Response; return yaz_decode_http_response(o, &(*p)->u.HTTP_Response); } - else if (o->size > 5 && - o->buf[0] >= 0x20 && o->buf[0] < 0x7f - && o->buf[1] >= 0x20 && o->buf[1] < 0x7f - && o->buf[2] >= 0x20 && o->buf[2] < 0x7f - && o->buf[3] >= 0x20 && o->buf[3] < 0x7f) + else if (o->op->size > 5 && + buf[0] >= 0x20 && buf[0] < 0x7f + && buf[1] >= 0x20 && buf[1] < 0x7f + && buf[2] >= 0x20 && buf[2] < 0x7f + && buf[3] >= 0x20 && buf[3] < 0x7f) { (*p)->which = Z_GDU_HTTP_Request; return yaz_decode_http_request(o, &(*p)->u.HTTP_Request); diff --git a/src/zget.c b/src/zget.c index b44279f..6febde0 100644 --- a/src/zget.c +++ b/src/zget.c @@ -636,10 +636,7 @@ Z_External *zget_init_diagnostics_octet(ODR odr, int error, x->indirect_reference = 0; x->direct_reference = odr_oiddup(odr, yaz_oid_userinfo_userinfo_1); x->which = Z_External_octet; - x->u.octet_aligned = (Odr_oct *) odr_malloc(odr, sizeof(Odr_oct)); - x->u.octet_aligned->buf = (unsigned char *) odr_malloc(odr, octet_len); - memcpy(x->u.octet_aligned->buf, octet_buf, octet_len); - x->u.octet_aligned->len = octet_len; + x->u.octet_aligned = odr_create_Odr_oct(odr, octet_buf, octet_len); odr_destroy(encode); diff --git a/src/zoom-sru.c b/src/zoom-sru.c index 0776057..22ac8c3 100644 --- a/src/zoom-sru.c +++ b/src/zoom-sru.c @@ -108,15 +108,15 @@ zoom_ret ZOOM_connection_srw_send_scan(ZOOM_connection c) /* SRU scan can only carry CQL and PQF */ if (z_query->which == Z_Query_type_104) { - sr->u.scan_request->query_type = Z_SRW_query_type_cql; - sr->u.scan_request->scanClause.cql = + sr->u.scan_request->queryType = "cql"; + sr->u.scan_request->scanClause = odr_strdup(c->odr_out, ZOOM_query_get_query_string(scan->query)); } else if (z_query->which == Z_Query_type_1 || z_query->which == Z_Query_type_101) { - sr->u.scan_request->query_type = Z_SRW_query_type_pqf; - sr->u.scan_request->scanClause.pqf = + sr->u.scan_request->queryType = "pqf"; + sr->u.scan_request->scanClause = odr_strdup(c->odr_out, ZOOM_query_get_query_string(scan->query)); } else @@ -215,13 +215,13 @@ zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c) if (z_query->which == Z_Query_type_104 && z_query->u.type_104->which == Z_External_CQL) { - sr->u.request->query_type = Z_SRW_query_type_cql; - sr->u.request->query.cql = z_query->u.type_104->u.cql; + sr->u.request->queryType = "cql"; + sr->u.request->query = z_query->u.type_104->u.cql; } else if (z_query->which == Z_Query_type_1 && z_query->u.type_1) { - sr->u.request->query_type = Z_SRW_query_type_pqf; - sr->u.request->query.pqf = + sr->u.request->queryType = "pqf"; + sr->u.request->query = odr_strdup(c->odr_out, ZOOM_query_get_query_string(resultset->query)); } @@ -350,14 +350,10 @@ static zoom_ret handle_srw_response(ZOOM_connection c, npr->u.databaseRecord->indirect_reference = 0; npr->u.databaseRecord->which = Z_External_octet; - npr->u.databaseRecord->u.octet_aligned = (Odr_oct *) - odr_malloc(c->odr_in, sizeof(Odr_oct)); - npr->u.databaseRecord->u.octet_aligned->buf = (unsigned char*) - sru_rec->recordData_buf; - npr->u.databaseRecord->u.octet_aligned->len = - npr->u.databaseRecord->u.octet_aligned->size = - sru_rec->recordData_len; - + npr->u.databaseRecord->u.octet_aligned = + odr_create_Odr_oct(c->odr_in, + sru_rec->recordData_buf, + sru_rec->recordData_len); if (sru_rec->recordSchema && !strcmp(sru_rec->recordSchema, "info:srw/schema/1/diagnostics-v1.1")) @@ -441,7 +437,7 @@ int ZOOM_handle_sru(ZOOM_connection c, Z_HTTP_Response *hres, ODR o = c->odr_in; Z_SOAP_Handler soap_handlers[3] = { {YAZ_XMLNS_SRU_v1_response, 0, (Z_SOAP_fun) yaz_srw_codec}, - {YAZ_XMLNS_SRU_v2_response, 0, (Z_SOAP_fun) yaz_srw_codec}, + {YAZ_XMLNS_SRU_v2_mask, 0, (Z_SOAP_fun) yaz_srw_codec}, {0, 0, 0} }; ret = z_soap_codec(o, &soap_package, diff --git a/src/zoom-z3950.c b/src/zoom-z3950.c index 797ffb3..69d6dbe 100644 --- a/src/zoom-z3950.c +++ b/src/zoom-z3950.c @@ -126,9 +126,7 @@ static Z_External *encode_ill_request(ZOOM_package p) r->which = Z_External_single; r->u.single_ASN1_type = - odr_create_Odr_oct(out, - (unsigned char *)illRequest_buf, - illRequest_size); + odr_create_Odr_oct(out, illRequest_buf, illRequest_size); } return r; } @@ -272,8 +270,7 @@ static Z_APDU *create_xmlupdate_package(ZOOM_package p) ext->indirect_reference = 0; ext->which = Z_External_octet; - ext->u.single_ASN1_type = - odr_create_Odr_oct(p->odr_out, (const unsigned char *) doc, len); + ext->u.single_ASN1_type = odr_create_Odr_oct(p->odr_out, doc, len); return apdu; } @@ -417,8 +414,7 @@ static Z_APDU *create_update_package(ZOOM_package p) if (recordIdOpaque) { notToKeep->elements[0]->u.opaque = - odr_create_Odr_oct(p->odr_out, - (const unsigned char *) recordIdOpaque, + odr_create_Odr_oct(p->odr_out, recordIdOpaque, recordIdOpaque_len); } else if (recordIdNumber) @@ -674,8 +670,7 @@ zoom_ret ZOOM_connection_Z3950_send_search(ZOOM_connection c) if (facets) { Z_FacetList *facet_list = yaz_pqf_parse_facet_list(c->odr_out, facets); if (facet_list) { - Z_OtherInformation **oi; - yaz_oi_APDU(apdu, &oi); + Z_OtherInformation **oi = &search_req->additionalSearchInfo; yaz_oi_set_facetlist(oi, c->odr_out, facet_list); } else diff --git a/test/test_odr.c b/test/test_odr.c index bfc237d..1ff12ed 100644 --- a/test/test_odr.c +++ b/test/test_odr.c @@ -25,9 +25,8 @@ void tst_MySequence1(ODR encode, ODR decode) YAZ_CHECK(s); s->first = odr_intdup(encode, 12345); s->second = (Odr_oct *) odr_malloc(encode, sizeof(*s->second)); - s->second->buf = (unsigned char *) "hello"; + s->second->buf = (char *) "hello"; s->second->len = 5; - s->second->size = 0; s->third = odr_booldup(encode, 1); s->fourth = odr_nullval(); s->fifth = odr_intdup(encode, YC_MySequence_enum1); @@ -80,9 +79,8 @@ void tst_MySequence2(ODR encode, ODR decode) YAZ_CHECK(s); s->first = 0; /* deliberately miss this .. */ s->second = (Odr_oct *) odr_malloc(encode, sizeof(*s->second)); - s->second->buf = (unsigned char *) "hello"; + s->second->buf = (char *) "hello"; s->second->len = 5; - s->second->size = 0; s->third = odr_booldup(encode, 1); s->fourth = odr_nullval(); s->fifth = odr_intdup(encode, YC_MySequence_enum1); diff --git a/test/test_soap2.c b/test/test_soap2.c index d371b8c..7b4bc46 100644 --- a/test/test_soap2.c +++ b/test/test_soap2.c @@ -32,9 +32,9 @@ static void tst_srw(void) YAZ_CHECK(sr); YAZ_CHECK(p); #if 0 - sr->u.request->query.cql = "jordb" "\xe6" "r"; + sr->u.request->query = "jordb" "\xe6" "r"; #else - sr->u.request->query.cql = "jordbaer"; + sr->u.request->query = "jordbaer"; #endif p->which = Z_SOAP_generic; diff --git a/test/test_solr.c b/test/test_solr.c index 6b156a2..e4f1c74 100644 --- a/test/test_solr.c +++ b/test/test_solr.c @@ -8,6 +8,7 @@ #include #include +#include #if YAZ_HAVE_XML2 #include #endif @@ -65,9 +66,10 @@ void tst_encoding(void) Z_SRW_PDU *sr = yaz_srw_get_pdu(odr, Z_SRW_searchRetrieve_request, "1.2"); + sr->u.request->query = "title:solr"; YAZ_CHECK(compare_solr_req( odr, sr, 0, - "GET Default/select? HTTP/1.1\r\n" + "GET Default/select?q=title%3Asolr HTTP/1.1\r\n" "User-Agent: YAZ/" YAZ_VERSION "\r\n" "Host: localhost\r\n" "Content-Type: text/xml\r\n\r\n")); @@ -76,9 +78,10 @@ void tst_encoding(void) { Z_SRW_PDU *sr = yaz_srw_get_pdu(odr, Z_SRW_searchRetrieve_request, "1.2"); + sr->u.request->query = "title:solr"; YAZ_CHECK(compare_solr_req( odr, sr, "utf-8", - "GET Default/select? HTTP/1.1\r\n" + "GET Default/select?q=title%3Asolr HTTP/1.1\r\n" "User-Agent: YAZ/" YAZ_VERSION "\r\n" "Host: localhost\r\n" "Content-Type: text/xml; charset=utf-8\r\n\r\n")); @@ -88,8 +91,7 @@ void tst_encoding(void) Z_SRW_PDU *sr = yaz_srw_get_pdu(odr, Z_SRW_searchRetrieve_request, "1.2"); - sr->u.request->query_type = Z_SRW_query_type_cql; - sr->u.request->query.cql = "title:solr"; + sr->u.request->query = "title:solr"; sr->u.request->startRecord = odr_intdup(odr, 3); sr->u.request->maximumRecords = odr_intdup(odr, 10); @@ -106,8 +108,7 @@ void tst_encoding(void) Z_SRW_PDU *sr = yaz_srw_get_pdu(odr, Z_SRW_searchRetrieve_request, "1.2"); - sr->u.request->query_type = Z_SRW_query_type_cql; - sr->u.request->query.cql = "title:solr"; + sr->u.request->query = "title:solr"; sr->u.request->startRecord = odr_intdup(odr, 3); sr->u.request->maximumRecords = odr_intdup(odr, 10); sr->u.request->facetList = yaz_pqf_parse_facet_list( diff --git a/util/srwtst.c b/util/srwtst.c index cd10a51..e62e888 100644 --- a/util/srwtst.c +++ b/util/srwtst.c @@ -53,18 +53,7 @@ int main(int argc, char **argv) if (sr->which == Z_SRW_searchRetrieve_request) { Z_SRW_searchRetrieveRequest *req = sr->u.request; - switch(req->query_type) - { - case Z_SRW_query_type_cql: - fprintf(stderr, "CQL: %s\n", req->query.cql); - break; - case Z_SRW_query_type_xcql: - fprintf(stderr, "XCQL\n"); - break; - case Z_SRW_query_type_pqf: - fprintf(stderr, "PQF: %s\n", req->query.pqf); - break; - } + fprintf(stderr, "%s: %s\n", req->queryType, req->query); } else if (sr->which == Z_SRW_searchRetrieve_response) { diff --git a/util/yaz-illclient.c b/util/yaz-illclient.c index a8bd956..c0383cb 100644 --- a/util/yaz-illclient.c +++ b/util/yaz-illclient.c @@ -364,9 +364,9 @@ ILL_Extension *makepromptextension(struct prog_args *args, ODR odr) { buf= odr_getbuf(odr_ext,&siz,0); ext->u.single_ASN1_type=(Odr_any *) odr_malloc(odr,sizeof(*ext->u.single_ASN1_type)); - ext->u.single_ASN1_type->buf= (unsigned char *) odr_malloc(odr, siz); + ext->u.single_ASN1_type->buf= (char *) odr_malloc(odr, siz); memcpy(ext->u.single_ASN1_type->buf,buf, siz ); - ext->u.single_ASN1_type->len = ext->u.single_ASN1_type->size = siz; + ext->u.single_ASN1_type->len = siz; odr_reset(odr_ext); odr_reset(odr_prt); /*!*/ @@ -380,9 +380,9 @@ ILL_Extension *makepromptextension(struct prog_args *args, ODR odr) { printf("External: \n"); z_External(odr_prt, &ext,0,0); /*!*/ buf= odr_getbuf(odr_ext,&siz,0); - e->item->buf= (unsigned char *) odr_malloc(odr, siz); + e->item->buf= (char *) odr_malloc(odr, siz); memcpy(e->item->buf,buf, siz ); - e->item->len = e->item->size = siz; + e->item->len = siz; odr_destroy(odr_prt); odr_destroy(odr_ext); @@ -423,9 +423,9 @@ ILL_Extension *makeoclcextension(struct prog_args *args, ODR odr) { buf= odr_getbuf(odr_ext,&siz,0); ext->u.single_ASN1_type = (Odr_any*) odr_malloc(odr,sizeof(*ext->u.single_ASN1_type)); - ext->u.single_ASN1_type->buf = (unsigned char *) odr_malloc(odr, siz); + ext->u.single_ASN1_type->buf = (char *) odr_malloc(odr, siz); memcpy(ext->u.single_ASN1_type->buf,buf, siz ); - ext->u.single_ASN1_type->len = ext->u.single_ASN1_type->size = siz; + ext->u.single_ASN1_type->len = siz; odr_reset(odr_ext); odr_reset(odr_prt); /*!*/ @@ -439,9 +439,9 @@ ILL_Extension *makeoclcextension(struct prog_args *args, ODR odr) { printf("External: \n"); z_External(odr_prt, &ext,0,0); /*!*/ buf= odr_getbuf(odr_ext,&siz,0); - e->item->buf= (unsigned char *) odr_malloc(odr, siz); + e->item->buf= (char *) odr_malloc(odr, siz); memcpy(e->item->buf, buf, siz); - e->item->len = e->item->size = siz; + e->item->len = siz; odr_destroy(odr_prt); odr_destroy(odr_ext); diff --git a/win/makefile b/win/makefile index 6204044..6698dc4 100644 --- a/win/makefile +++ b/win/makefile @@ -490,11 +490,14 @@ MISC_OBJS= \ $(OBJDIR)\charneg.obj \ $(OBJDIR)\grs1disp.obj \ $(OBJDIR)\opac_to_xml.obj \ + $(OBJDIR)\xml_add.obj \ + $(OBJDIR)\xml_match.obj \ $(OBJDIR)\xml_to_opac.obj \ $(OBJDIR)\zgdu.obj \ $(OBJDIR)\soap.obj \ $(OBJDIR)\solr.obj \ $(OBJDIR)\solrtransform.obj \ + $(OBJDIR)\sru_facet.obj \ $(OBJDIR)\srw.obj \ $(OBJDIR)\srwutil.obj \ $(OBJDIR)\zoom-c.obj \ diff --git a/yaz.spec b/yaz.spec index 8939cf4..05211a6 100644 --- a/yaz.spec +++ b/yaz.spec @@ -14,7 +14,7 @@ Release: 1indexdata %define is_suse %(test -e /etc/SuSE-release >/dev/null && echo 1 || echo 0) %define is_suse11 %(grep 'VERSION = 11' /etc/SuSE-release >/dev/null 2>&1 && echo 1 || echo 0) %define is_fedora %(test -e /etc/fedora-release && echo 1 || echo 0) -Requires: libxslt, gnutls, readline, libyaz4 = %{version} +Requires: libxslt, gnutls, readline, libyaz5 = %{version} License: BSD Group: Applications/Internet Vendor: Index Data ApS @@ -52,31 +52,31 @@ URL: http://www.indexdata.com/yaz This package contains both a test-server and clients (normal & ssl) for the ANSI/NISO Z39.50 protocol for Information Retrieval. -%package -n libyaz4 +%package -n libyaz5 Summary: Z39.50 Library Group: Libraries Requires: libxslt, gnutls, libicu -%description -n libyaz4 +%description -n libyaz5 YAZ is a library for the ANSI/NISO Z39.50 protocol for Information Retrieval. -%post -n libyaz4 -p /sbin/ldconfig -%postun -n libyaz4 -p /sbin/ldconfig +%post -n libyaz5 -p /sbin/ldconfig +%postun -n libyaz5 -p /sbin/ldconfig -%package -n libyaz4-devel +%package -n libyaz5-devel Summary: Z39.50 Library - development package Group: Development/Libraries -Requires: libyaz4 = %{version}, libxml2-devel, libxslt-devel, libicu-devel -Conflicts: libyaz-devel +Requires: libyaz5 = %{version}, libxml2-devel, libxslt-devel, libicu-devel +Conflicts: libyaz-devel, libyaz4-devel -%description -n libyaz4-devel +%description -n libyaz5-devel Development libraries and includes for the libyaz package. %package -n yaz-illclient Summary: ILL client Group: Applications/Communication -Requires: readline, libyaz4 = %{version} +Requires: readline, libyaz5 = %{version} %description -n yaz-illclient yaz-illclient: an ISO ILL client. @@ -84,7 +84,7 @@ yaz-illclient: an ISO ILL client. %package -n yaz-icu Summary: Command line utility for ICU utilities of YAZ Group: Applications/Communication -Requires: libyaz4 = %{version} +Requires: libyaz5 = %{version} %description -n yaz-icu The yaz-icu program is a command-line based client which exposes the ICU @@ -128,11 +128,11 @@ rm -fr ${RPM_BUILD_ROOT} %{_mandir}/man7/yaz-log.* %{_mandir}/man7/bib1-attr.* -%files -n libyaz4 +%files -n libyaz5 %defattr(-,root,root) %{_libdir}/*.so.* -%files -n libyaz4-devel +%files -n libyaz5-devel %defattr(-,root,root) %{_bindir}/yaz-config %{_bindir}/yaz-asncomp diff --git a/ztest/Makefile.am b/ztest/Makefile.am index fbb19b4..bebd430 100644 --- a/ztest/Makefile.am +++ b/ztest/Makefile.am @@ -12,3 +12,6 @@ EXTRA_DIST=dummy-words dummy-grs ztest.pem config1.xml LDADD=../src/libyaz_server.la ../src/libyaz.la AM_CPPFLAGS=-I$(top_srcdir)/include $(XML2_CFLAGS) + +clean-local: + rm -f socket diff --git a/ztest/ztest.c b/ztest/ztest.c index d92d215..32b8857 100644 --- a/ztest/ztest.c +++ b/ztest/ztest.c @@ -277,7 +277,11 @@ Z_OtherInformation *build_facet_response(ODR odr, Z_FacetList *facet_list) { attrvalues.limit = 10; yaz_facet_attr_get_z_attributes(facet_list->elements[index]->attributes, &attrvalues); - yaz_log(YLOG_LOG, "Attributes: %s %d ", attrvalues.useattr, attrvalues.limit); + yaz_log(YLOG_LOG, "Attributes: %s limit=%d start=%d sort=%d", + attrvalues.useattr, + attrvalues.limit, + attrvalues.start, + attrvalues.sortorder); if (attrvalues.errstring) yaz_log(YLOG_LOG, "Error parsing attributes: %s", attrvalues.errstring); if (attrvalues.limit > 0 && attrvalues.useattr) { @@ -588,13 +592,8 @@ int ztest_esrequest(void *handle, bend_esrequest_rr *rr) rr->taskPackage->retentionTime = 0; rr->taskPackage->permissions = 0; rr->taskPackage->description = 0; - rr->taskPackage->targetReference = (Odr_oct *) - odr_malloc(rr->stream, sizeof(Odr_oct)); - rr->taskPackage->targetReference->buf = - (unsigned char *) odr_strdup(rr->stream, "911"); - rr->taskPackage->targetReference->len = - rr->taskPackage->targetReference->size = - strlen((char *) (rr->taskPackage->targetReference->buf)); + rr->taskPackage->targetReference = + odr_create_Odr_oct(rr->stream, "911", 3); rr->taskPackage->creationDateTime = 0; rr->taskPackage->taskStatus = odr_intdup(rr->stream, 0); rr->taskPackage->packageDiagnostics = 0; @@ -689,13 +688,8 @@ int ztest_esrequest(void *handle, bend_esrequest_rr *rr) rr->taskPackage->retentionTime = 0; rr->taskPackage->permissions = 0; rr->taskPackage->description = 0; - rr->taskPackage->targetReference = (Odr_oct *) - odr_malloc(rr->stream, sizeof(Odr_oct)); - rr->taskPackage->targetReference->buf = - (unsigned char *) odr_strdup(rr->stream, "123"); - rr->taskPackage->targetReference->len = - rr->taskPackage->targetReference->size = - strlen((char *) (rr->taskPackage->targetReference->buf)); + rr->taskPackage->targetReference = + odr_create_Odr_oct(rr->stream, "123", 3); rr->taskPackage->creationDateTime = 0; rr->taskPackage->taskStatus = odr_intdup(rr->stream, 0); rr->taskPackage->packageDiagnostics = 0;