Merge branch 'master' into sru_2_0
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 11 Sep 2013 13:29:45 +0000 (15:29 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 11 Sep 2013 13:29:45 +0000 (15:29 +0200)
Conflicts:
IDMETA
debian/changelog

59 files changed:
IDMETA
client/admin.c
client/client.c
debian/changelog
debian/control
debian/libyaz4-dev.install [deleted file]
debian/libyaz4-dev.manpages [deleted file]
debian/libyaz4.install [deleted file]
debian/libyaz5-dev.install [new file with mode: 0644]
debian/libyaz5-dev.manpages [new file with mode: 0644]
debian/libyaz5.install [new file with mode: 0644]
debian/rules
doc/odr.xml
include/yaz/odr.h
include/yaz/srw.h
src/Makefile.am
src/ber_any.c
src/ber_bit.c
src/ber_int.c
src/ber_len.c
src/ber_oct.c
src/ber_tag.c
src/charneg.c
src/comstack.c
src/dumpber.c
src/facet.c
src/http.c
src/odr-priv.h
src/odr.c
src/odr_cons.c
src/odr_mem.c
src/odr_oct.c
src/odr_util.c
src/pquery.c
src/prt-ext.c
src/rpn2solr.c
src/seshigh.c
src/solr.c
src/sortspec.c
src/sru-p.h
src/sru_facet.c [new file with mode: 0644]
src/srw.c
src/srwutil.c
src/xml_add.c [new file with mode: 0644]
src/xml_match.c [new file with mode: 0644]
src/xml_to_opac.c
src/xmlquery.c
src/zget.c
src/zoom-sru.c
src/zoom-z3950.c
test/test_odr.c
test/test_soap2.c
test/test_solr.c
test/test_wrbuf.c
util/srwtst.c
util/yaz-illclient.c
win/makefile
yaz.spec
ztest/ztest.c

diff --git a/IDMETA b/IDMETA
index c012e4f..16d4635 100755 (executable)
--- 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.66
+VERSION=5.0.0
index 14aa281..de29207 100644 (file)
@@ -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);
                 }
index 0147b06..1c5523b 100644 (file)
@@ -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;
@@ -317,14 +318,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 ------------------------------- */
@@ -1417,12 +1413,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");
@@ -1456,23 +1452,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;
@@ -1557,12 +1555,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;
     }
@@ -1616,7 +1614,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:
@@ -1864,7 +1862,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");
@@ -2126,16 +2124,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;
@@ -2179,18 +2169,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;
 }
@@ -2479,16 +2459,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;
@@ -2526,16 +2498,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;
@@ -2579,7 +2543,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);
@@ -2822,7 +2786,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"))
@@ -3165,6 +3130,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);
@@ -3381,10 +3348,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);
@@ -4452,7 +4417,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}
index 5c585f8..c1701b0 100644 (file)
@@ -1,3 +1,9 @@
+yaz (5.0.0-1indexdata) unstable; urgency=low
+
+  * Version 5.
+
+ -- Adam Dickmeiss <adam@indexdata.dk>  Wed, 11 Sep 2013 09:26:11 +0200
+
 yaz (4.2.66-1indexdata) unstable; urgency=low
 
   * Upstream.
index b4fe544..ef506e8 100644 (file)
@@ -11,7 +11,7 @@ Build-Depends: debhelper (>= 5),
        libwrap0-dev,
        libicu36-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,
        libicu36-dev|libicu-dev,
        tcl8.3|tclsh
diff --git a/debian/libyaz4-dev.install b/debian/libyaz4-dev.install
deleted file mode 100644 (file)
index 5e8060d..0000000
+++ /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 (file)
index 5c7701f..0000000
+++ /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 (file)
index c45ebcf..0000000
+++ /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 (file)
index 0000000..5e8060d
--- /dev/null
@@ -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 (file)
index 0000000..5c7701f
--- /dev/null
@@ -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 (file)
index 0000000..c45ebcf
--- /dev/null
@@ -0,0 +1 @@
+debian/tmp/usr/lib/lib*.so.*
index c09b7e7..441f8ab 100755 (executable)
@@ -90,14 +90,14 @@ binary-arch: build install
 #      dh_installinfo
        dh_installman
        dh_link
-       dh_strip --dbg-package=libyaz4-dbg
+       dh_strip --dbg-package=libyaz5-dbg
        dh_compress
        dh_fixperms
 #      dh_perl
 #      dh_python
-       dh_makeshlibs -V 'libyaz4 (>= 4.2.63)'
+       dh_makeshlibs -V 'libyaz5 (>= 5.0.0)'
        dh_installdeb
-       dh_shlibdeps  -l debian/libyaz4/usr/lib
+       dh_shlibdeps  -l debian/libyaz5/usr/lib
        dh_gencontrol
        dh_md5sums
        dh_builddeb
index 770ad9c..6438e6f 100644 (file)
@@ -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,
      <para>
       The <literal>buf</literal> field should point to the character array
       that holds the octetstring. The <literal>len</literal> field holds the
-      actual length, while the <literal>size</literal> 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.
      </para>
 
index 20f245b..865e4d4 100644 (file)
@@ -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,13 +127,13 @@ struct odr
 
     int error;            /* current error state (0==OK) */
 
-    unsigned char *buf;            /* memory handle */
+    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) */
+    const char *bp;       /* position in buffer (decoding) */
 
     NMEM mem;            /* memory handle for decoding (primarily) */
 
@@ -190,8 +189,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)
@@ -231,14 +229,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 +250,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 +275,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);
index 556d7e7..b29562a 100644 (file)
@@ -37,7 +37,7 @@
 #include <yaz/zgdu.h>
 #include <yaz/diagsrw.h>
 #include <yaz/diagsru_update.h>
-#include "facet.h"
+#include <yaz/z-facet-1.h>
 
 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
index 2e7f700..2564e03 100644 (file)
@@ -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 \
index 3322a02..be23946 100644 (file)
@@ -30,9 +30,9 @@ int ber_any(ODR o, Odr_any **p)
             odr_seterror(o, OPROTO, 2);
             return 0;
         }
-        (*p)->buf = (unsigned char *)odr_malloc(o, res);
+        (*p)->buf = (char *)odr_malloc(o, res);
         memcpy((*p)->buf, o->bp, res);
-        (*p)->len = (*p)->size = res;
+        (*p)->len = res;
         o->bp += res;
         return 1;
     case ODR_ENCODE:
@@ -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
index 00ea535..ac3631a 100644 (file)
@@ -20,7 +20,7 @@
 int ber_bitstring(ODR o, Odr_bitmask *p, int cons)
 {
     int res, len;
-    const unsigned char *base;
+    const char *base;
 
     switch (o->direction)
     {
index e9b23a2..cc02d3b 100644 (file)
@@ -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)
 {
@@ -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:
index 56674c6..01af404 100644 (file)
@@ -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:
index 85242ee..5a36482 100644 (file)
 #endif
 
 #include "odr-priv.h"
+#include <yaz/log.h>
+#include <assert.h>
 
 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)
     {
@@ -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;
+        p->len = len;
+        p->buf = odr_malloc(o, len + 1);
+        memcpy(p->buf, o->bp, len);
+        p->buf[len] = '\0';
         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';
         return 1;
     case ODR_ENCODE:
         if ((res = ber_enclen(o, p->len, 5, 0)) < 0)
index 422c74d..f005078 100644 (file)
@@ -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)
index 951bb37..9986f53 100644 (file)
@@ -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;
 }
 
index 1755fc7..0c502f8 100644 (file)
@@ -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);
 }
 
 
index 5d49e7f..4a7215f 100644 (file)
@@ -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;
index a9d1ef9..40b5e1c 100644 (file)
@@ -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;
 }
 
index 746f3e1..683336a 100644 (file)
@@ -595,24 +595,24 @@ int yaz_encode_http_response(ODR o, Z_HTTP_Response *hr)
     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");
@@ -627,12 +627,12 @@ 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);
+    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"))
@@ -640,18 +640,18 @@ 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");
index b452d10..f968edd 100644 (file)
@@ -63,11 +63,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 */
index 142249f..e424b20 100644 (file)
--- a/src/odr.c
+++ b/src/odr.c
@@ -272,8 +272,8 @@ 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->bp = buf;
+    o->buf = buf;
     o->op->can_grow = can_grow;
     o->top = o->pos = 0;
     o->size = len;
index fa203d8..4a18372 100644 (file)
@@ -88,7 +88,7 @@ int odr_constructed_begin(ODR o, void *xxp, int zclass, int tag,
     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;
 
index 4309d3d..33e2bfa 100644 (file)
@@ -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;
 }
@@ -88,15 +87,14 @@ int odr_grow_block(ODR b, int min_bytes)
     if (togrow < min_bytes)
         togrow = min_bytes;
     if (b->size && !(b->buf =
-                     (unsigned char *) xrealloc(b->buf, b->size += togrow)))
+                     (char *) xrealloc(b->buf, b->size += togrow)))
         abort();
-    else if (!b->size && !(b->buf = (unsigned char *)
-                           xmalloc(b->size = togrow)))
+    else if (!b->size && !(b->buf = (char *) xmalloc(b->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))
     {
@@ -110,11 +108,6 @@ int odr_write2(ODR o, const char *buf, int bytes)
     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)
index f359c4c..101f0d2 100644 (file)
@@ -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;
     }
index 6efa6c0..a5c64d6 100644 (file)
@@ -26,7 +26,7 @@ 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;
index d4b9958..55eb1d3 100644 (file)
@@ -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;
index 6af7c61..2f904f1 100644 (file)
@@ -216,8 +216,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;
@@ -315,8 +315,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 +325,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 +356,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;
 }
 
index 5047d4b..4a2c5e4 100644 (file)
@@ -233,7 +233,6 @@ static int rpn2solr_simple(solr_transform_t ct,
         Odr_int trunc = get_truncation(apt);
 
         wrbuf_rewind(w);
-        
         ret = rpn2solr_attr(ct, apt->attributes, w, solr_attr);
 
         if (trunc == 0 || trunc == 1 || trunc == 100 || trunc == 104)
index 3b49190..a9a3cba 100644 (file)
@@ -56,6 +56,7 @@
 #include <libxml/tree.h>
 #endif
 
+#include <yaz/facet.h>
 #include <yaz/xmalloc.h>
 #include <yaz/comstack.h>
 #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);
     }
@@ -3110,7 +3098,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)
@@ -3137,12 +3124,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);
             }
index 088fb63..ca35e56 100644 (file)
@@ -461,19 +461,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 +497,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"))
         {
-            case Z_SRW_query_type_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"))
+        {
+            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,
index a016496..6cae7d8 100644 (file)
@@ -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;
             }
index b10b858..fb6b290 100644 (file)
@@ -37,10 +37,47 @@ 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);
+
 #if YAZ_HAVE_XML2
 #include <libxml/parser.h>
 #include <libxml/tree.h>
-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 (file)
index 0000000..29c5a68
--- /dev/null
@@ -0,0 +1,250 @@
+/* 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 <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <yaz/srw.h>
+#include <yaz/wrbuf.h>
+#if YAZ_HAVE_XML2
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <assert.h>
+#endif
+
+#include "sru-p.h"
+#include <yaz/pquery.h>
+#include <yaz/facet.h>
+
+void yaz_sru_facet_request(ODR o, Z_FacetList **facetList, const char **limit)
+{
+    if (o->direction == ODR_ENCODE)
+    {
+        Z_FacetList *fl = *facetList;
+        if (fl)
+        {
+            int i;
+            WRBUF w = wrbuf_alloc();
+            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)
+                {
+                    wrbuf_printf(w, "%d", av.limit ? av.limit : -1);
+                    if (av.useattr)
+                        wrbuf_printf(w, ":%s,", av.useattr);
+                    /* av.relation not considered yet */
+                }
+            }
+            if (wrbuf_len(w) > 0)
+            {
+                wrbuf_cut_right(w, 1); /* remove , */
+                *limit = odr_strdup(o, wrbuf_cstr(w));
+            }
+            wrbuf_destroy(w);
+        }
+    }
+    else if (o->direction == ODR_DECODE)
+    {
+        const char *cp = *limit;
+        *facetList = 0;
+        if (cp)
+        {
+            int nor = 0;
+            int limit_val = 0;
+            WRBUF w = wrbuf_alloc();
+            while (sscanf(cp, "%d%n", &limit_val, &nor) >= 1 && nor > 0)
+            {
+                cp += nor;
+                if (wrbuf_len(w))
+                    wrbuf_puts(w, ",");
+                if (*cp == ':') /* field name follows */
+                {
+                    wrbuf_puts(w, "@attr 1=");
+                    while (*++cp && *cp != ',')
+                        wrbuf_putc(w, *cp);
+                    wrbuf_puts(w, " ");
+                }
+                if (limit_val != -1)
+                    wrbuf_printf(w, "@attr 3=%d", limit_val);
+                if (*cp != ',')
+                    break;
+                cp++;
+            }
+            if (wrbuf_len(w))
+                *facetList = yaz_pqf_parse_facet_list(o, wrbuf_cstr(w));
+            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
+ */
+
index d4fbfc6..ca46a44 100644 (file)
--- a/src/srw.c
+++ b/src/srw.c
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 #include <assert.h>
-
+#include <yaz/facet.h>
 #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 *) "<yaz_record>", -1);
-        xmlBufferAdd(buf, (const xmlChar *) "</yaz_record>", -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,28 @@ 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;
 
             (*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 +588,69 @@ 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 (yaz_match_xsd_string(ptr, "recordXMLEscaping", o,
+                                          &recordXMLEscaping))
                     ;
-                else if (match_xsd_string(ptr, "recordSchema", o,
+                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))
+                    ;
             }
-            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);
         }
         else if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveResponse"))
         {
@@ -823,6 +662,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 +675,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 +723,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 +762,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 +787,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 +796,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 +839,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 +870,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 +923,33 @@ 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;
+                yaz_sru_facet_request(o, &req->facetList, &limit);
+                add_xsd_string(ptr, "facetLimit", limit);
+            }
         }
         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 +960,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 +973,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 +995,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 +1008,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 +1038,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 +1089,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 +1113,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 +1128,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 +1170,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 +1232,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 +1264,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)
            {
index 38ee0d0..1937a77 100644 (file)
@@ -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,21 @@ 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;
         Z_SRW_extra_arg *extra_args = 0;
 #endif
         char **uri_name;
@@ -422,7 +428,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 +450,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 +469,8 @@ 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, "extraRequestData"))
                     ; /* ignoring extraRequestData */
                 else if (n[0] == 'x' && n[1] == '-')
@@ -473,24 +491,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 +514,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 +536,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 +552,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);
 
             yaz_sru_decode_integer(decode, "maximumRecords", maximumRecords,
                                    &sr->u.request->maximumRecords,
@@ -567,7 +593,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 +625,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 +744,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 +764,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 +783,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 +799,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 +823,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 +891,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 +943,69 @@ 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;
+            yaz_sru_facet_request(encode, &srw_pdu->u.request->facetList,
+                                  &facetLimit);
+            yaz_add_name_value_str(encode, name, value, &i, "facetLimit",
+                                   (char *) facetLimit);
+        }
         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 +1054,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 (file)
index 0000000..ebd7a8c
--- /dev/null
@@ -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 <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <yaz/srw.h>
+#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 (file)
index 0000000..dd804db
--- /dev/null
@@ -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 <config.h>
+#endif
+
+#include <yaz/srw.h>
+#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 *) "<yaz_record>", -1);
+        xmlBufferAdd(buf, (const xmlChar *) "</yaz_record>", -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
+ */
+
index ead47bd..236bf8a 100644 (file)
 #include <yaz/oid_db.h>
 
 #if YAZ_HAVE_XML2
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-
-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;
index e0db8d3..5aff1ae 100644 (file)
@@ -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"))
     {
index b44279f..6febde0 100644 (file)
@@ -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);
 
index b829738..b3c34cb 100644 (file)
@@ -87,15 +87,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
@@ -194,13 +194,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));
     }
@@ -329,14 +329,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"))
@@ -420,7 +416,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,
index 797ffb3..fe86050 100644 (file)
@@ -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)
index bfc237d..1ff12ed 100644 (file)
@@ -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);
index d371b8c..7b4bc46 100644 (file)
@@ -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;
index 6b156a2..e4f1c74 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <stdlib.h>
 #include <yaz/srw.h>
+#include <yaz/log.h>
 #if YAZ_HAVE_XML2
 #include <libxml/parser.h>
 #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(
index defdc34..7c27fe5 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 
 #include <yaz/wrbuf.h>
 #include <yaz/test.h>
index cd10a51..e62e888 100644 (file)
@@ -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)
             {
index a8bd956..c0383cb 100644 (file)
@@ -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);
index 6204044..6698dc4 100644 (file)
@@ -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 \
index 8939cf4..05211a6 100644 (file)
--- 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 <info@indexdata.dk>
@@ -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
index d92d215..aa91186 100644 (file)
@@ -588,13 +588,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 +684,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;