Support for turbo marcxml
[yaz-moved-to-github.git] / src / zoom-c.c
index fe7971d..44a5646 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2008 Index Data
+ * Copyright (C) 1995-2010 Index Data
  * See the file LICENSE for details.
  */
 /**
@@ -406,6 +406,7 @@ ZOOM_API(ZOOM_connection)
 
     c->odr_in = odr_createmem(ODR_DECODE);
     c->odr_out = odr_createmem(ODR_ENCODE);
+    c->odr_print = 0;
 
     c->async = 0;
     c->support_named_resultsets = 0;
@@ -479,6 +480,11 @@ ZOOM_API(void)
     set_ZOOM_error(c, ZOOM_ERROR_NONE, 0);
     ZOOM_connection_remove_tasks(c);
 
+    if (c->odr_print)
+    {
+        odr_setprint(c->odr_print, 0); /* prevent destroy from fclose'ing */
+        odr_destroy(c->odr_print);
+    }
     if (ZOOM_options_get_bool(c->options, "apdulog", 0))
     {
         c->odr_print = odr_createmem(ODR_PRINT);
@@ -1005,6 +1011,20 @@ ZOOM_API(int)
     return 0;
 }
 
+static void ZOOM_record_release(ZOOM_record rec)
+{
+    if (!rec)
+        return;
+    if (rec->wrbuf)
+        wrbuf_destroy(rec->wrbuf);
+#if YAZ_HAVE_XML2
+    if (rec->xml_mem)
+        xmlFree(rec->xml_mem);
+#endif
+    if (rec->odr)
+        odr_destroy(rec->odr);
+}
+
 ZOOM_API(void)
     ZOOM_resultset_cache_reset(ZOOM_resultset r)
 {
@@ -1014,12 +1034,7 @@ ZOOM_API(void)
         ZOOM_record_cache rc;
         for (rc = r->record_hash[i]; rc; rc = rc->next)
         {
-            if (rc->rec.wrbuf_marc)
-                wrbuf_destroy(rc->rec.wrbuf_marc);
-            if (rc->rec.wrbuf_iconv)
-                wrbuf_destroy(rc->rec.wrbuf_iconv);
-            if (rc->rec.wrbuf_opac)
-                wrbuf_destroy(rc->rec.wrbuf_opac);
+            ZOOM_record_release(&rc->rec);
         }
         r->record_hash[i] = 0;
     }
@@ -1069,7 +1084,7 @@ static void resultset_destroy(ZOOM_resultset r)
 ZOOM_API(size_t)
     ZOOM_resultset_size(ZOOM_resultset r)
 {
-    yaz_log(log_details, "ZOOM_resultset_size r=%p count=%d",
+    yaz_log(log_details, "ZOOM_resultset_size r=%p count=" ODR_INT_PRINTF,
             r, r->size);
     return r->size;
 }
@@ -1211,14 +1226,14 @@ static zoom_ret do_connect(ZOOM_connection c)
     if (c->cs && c->cs->protocol == PROTO_HTTP)
     {
 #if YAZ_HAVE_XML2
-        const char *path = 0;
+        const char *db = 0;
 
         c->proto = PROTO_HTTP;
-        cs_get_host_args(c->host_port, &path);
+        cs_get_host_args(c->host_port, &db);
         xfree(c->path);
-        c->path = (char*) xmalloc(strlen(path)+2);
-        c->path[0] = '/';
-        strcpy(c->path+1, path);
+
+        c->path = xmalloc(strlen(db) * 3 + 2);
+        yaz_encode_sru_dbpath_buf(c->path, db);
 #else
         set_ZOOM_error(c, ZOOM_ERROR_UNSUPPORTED_PROTOCOL, "SRW");
         do_close(c);
@@ -1443,11 +1458,7 @@ static zoom_ret send_srw(ZOOM_connection c, Z_SRW_PDU *sr)
     char *fdatabase = 0;
     
     if (database)
-    {
-        fdatabase = (char *) odr_malloc(c->odr_out, strlen(database)+2);
-        strcpy(fdatabase, "/");
-        strcat(fdatabase, database);
-    }
+        fdatabase = yaz_encode_sru_dbpath_odr(c->odr_out, database);
     gdu = z_get_HTTP_Request_host_path(c->odr_out, c->host_port,
                                        fdatabase ? fdatabase : c->path);
 
@@ -1633,12 +1644,19 @@ static zoom_ret ZOOM_connection_send_search(ZOOM_connection c)
             yaz_iconv_t cd = yaz_iconv_open(cp, "UTF-8");
             if (cd)
             {
+                int r;
                 search_req->query = yaz_copy_Z_Query(search_req->query,
                                                      c->odr_out);
                 
-                yaz_query_charset_convert_rpnquery(search_req->query->u.type_1,
-                                                   c->odr_out, cd);
+                r = yaz_query_charset_convert_rpnquery_check(
+                    search_req->query->u.type_1,
+                    c->odr_out, cd);
                 yaz_iconv_close(cd);
+                if (r)
+                {  /* query could not be char converted */
+                    set_ZOOM_error(c, ZOOM_ERROR_INVALID_QUERY, 0);
+                    return zoom_complete;
+                }
             }
         }
     }
@@ -1774,9 +1792,11 @@ ZOOM_API(ZOOM_record)
     
     nrec = (ZOOM_record) xmalloc(sizeof(*nrec));
     nrec->odr = odr_createmem(ODR_DECODE);
-    nrec->wrbuf_marc = 0;
-    nrec->wrbuf_iconv = 0;
-    nrec->wrbuf_opac = 0;
+    nrec->wrbuf = 0;
+#if YAZ_HAVE_XML2
+    nrec->xml_mem = 0;
+    nrec->xml_size = 0;
+#endif
     odr_setbuf(nrec->odr, buf, size, 0);
     z_NamePlusRecord(nrec->odr, &nrec->npr, 0, 0);
     
@@ -1824,27 +1844,16 @@ ZOOM_API(ZOOM_record)
 ZOOM_API(void)
     ZOOM_record_destroy(ZOOM_record rec)
 {
-    if (!rec)
-        return;
-    if (rec->wrbuf_marc)
-        wrbuf_destroy(rec->wrbuf_marc);
-    if (rec->wrbuf_iconv)
-        wrbuf_destroy(rec->wrbuf_iconv);
-    if (rec->wrbuf_opac)
-        wrbuf_destroy(rec->wrbuf_opac);
-    odr_destroy(rec->odr);
+    ZOOM_record_release(rec);
     xfree(rec);
 }
 
-static const char *marc_iconv_return(ZOOM_record rec, int marc_type,
-                                     int *len,
-                                     const char *buf, int sz,
-                                     const char *record_charset)
+
+static yaz_iconv_t iconv_create_charset(const char *record_charset)
 {
     char to[40];
     char from[40];
     yaz_iconv_t cd = 0;
-    yaz_marc_t mt = yaz_marc_create();
 
     *from = '\0';
     strcpy(to, "UTF-8");
@@ -1852,7 +1861,7 @@ static const char *marc_iconv_return(ZOOM_record rec, int marc_type,
     {
         /* Use "from,to" or just "from" */
         const char *cp = strchr(record_charset, ',');
-        int clen = strlen(record_charset);
+        size_t clen = strlen(record_charset);
         if (cp && cp[1])
         {
             strncpy( to, cp+1, sizeof(to)-1);
@@ -1866,74 +1875,82 @@ static const char *marc_iconv_return(ZOOM_record rec, int marc_type,
             strncpy(from, record_charset, clen);
         from[clen] = '\0';
     }
-
     if (*from && *to)
-    {
         cd = yaz_iconv_open(to, from);
-        yaz_marc_iconv(mt, cd);
-    }
+    return cd;
+}
 
+static const char *return_marc_record(ZOOM_record rec, int marc_type,
+                                      int *len,
+                                      const char *buf, int sz,
+                                      const char *record_charset)
+{
+    yaz_iconv_t cd = iconv_create_charset(record_charset);
+    yaz_marc_t mt = yaz_marc_create();
+    const char *ret_string = 0;
+
+    if (cd)
+        yaz_marc_iconv(mt, cd);
     yaz_marc_xml(mt, marc_type);
-    if (!rec->wrbuf_marc)
-        rec->wrbuf_marc = wrbuf_alloc();
-    wrbuf_rewind(rec->wrbuf_marc);
-    if (yaz_marc_decode_wrbuf(mt, buf, sz, rec->wrbuf_marc) > 0)
-    {
-        yaz_marc_destroy(mt);
-        if (cd)
-            yaz_iconv_close(cd);
+    if (!rec->wrbuf)
+        rec->wrbuf = wrbuf_alloc();
+    wrbuf_rewind(rec->wrbuf);
+    if (yaz_marc_decode_wrbuf(mt, buf, sz, rec->wrbuf) > 0)
+    {
         if (len)
-            *len = wrbuf_len(rec->wrbuf_marc);
-        return wrbuf_cstr(rec->wrbuf_marc);
+            *len = wrbuf_len(rec->wrbuf);
+        ret_string = wrbuf_cstr(rec->wrbuf);
     }
     yaz_marc_destroy(mt);
     if (cd)
         yaz_iconv_close(cd);
-    return 0;
+    return ret_string;
 }
 
-static const char *record_iconv_return(ZOOM_record rec, int *len,
-                                       const char *buf, int sz,
-                                       const char *record_charset)
+static const char *return_opac_record(ZOOM_record rec, int marc_type,
+                                      int *len,
+                                      Z_OPACRecord *opac_rec,
+                                      const char *record_charset)
 {
-    char to[40];
-    char from[40];
-    yaz_iconv_t cd = 0;
+    yaz_iconv_t cd = iconv_create_charset(record_charset);
+    yaz_marc_t mt = yaz_marc_create();
 
-    *from = '\0';
-    strcpy(to, "UTF-8");
+    if (cd)
+        yaz_marc_iconv(mt, cd);
+    yaz_marc_xml(mt, marc_type);
 
-    if (record_charset && *record_charset)
-    {
-        /* Use "from,to" or just "from" */
-        const char *cp = strchr(record_charset, ',');
-        int clen = strlen(record_charset);
-        if (cp && cp[1])
-        {
-            strncpy( to, cp+1, sizeof(to)-1);
-            to[sizeof(to)-1] = '\0';
-            clen = cp - record_charset;
-        }
-        if (clen > sizeof(from)-1)
-            clen = sizeof(from)-1;
-        
-        if (clen)
-            strncpy(from, record_charset, clen);
-        from[clen] = '\0';
-    }
+    if (!rec->wrbuf)
+        rec->wrbuf = wrbuf_alloc();
+    wrbuf_rewind(rec->wrbuf);
+
+    yaz_opac_decode_wrbuf(mt, opac_rec, rec->wrbuf);
+    yaz_marc_destroy(mt);
+
+    if (cd)
+        yaz_iconv_close(cd);
+    if (len)
+        *len = wrbuf_len(rec->wrbuf);
+    return wrbuf_cstr(rec->wrbuf);
+}
 
-    if (*from && *to && (cd = yaz_iconv_open(to, from)))
+static const char *return_string_record(ZOOM_record rec, int *len,
+                                        const char *buf, int sz,
+                                        const char *record_charset)
+{
+    yaz_iconv_t cd = iconv_create_charset(record_charset);
+
+    if (cd)
     {
-        if (!rec->wrbuf_iconv)
-            rec->wrbuf_iconv = wrbuf_alloc();
+        if (!rec->wrbuf)
+            rec->wrbuf = wrbuf_alloc();
 
-        wrbuf_rewind(rec->wrbuf_iconv);
+        wrbuf_rewind(rec->wrbuf);
 
-        wrbuf_iconv_write(rec->wrbuf_iconv, cd, buf, sz);
-        wrbuf_iconv_reset(rec->wrbuf_iconv, cd);
+        wrbuf_iconv_write(rec->wrbuf, cd, buf, sz);
+        wrbuf_iconv_reset(rec->wrbuf, cd);
 
-        buf = wrbuf_cstr(rec->wrbuf_iconv);
-        sz = wrbuf_len(rec->wrbuf_iconv);
+        buf = wrbuf_cstr(rec->wrbuf);
+        sz = wrbuf_len(rec->wrbuf);
         yaz_iconv_close(cd);
     }
     if (len)
@@ -1941,6 +1958,58 @@ static const char *record_iconv_return(ZOOM_record rec, int *len,
     return buf;
 }
 
+static const char *return_record(ZOOM_record rec, int *len,
+                                 Z_NamePlusRecord *npr,
+                                 int marctype, const char *charset)
+{
+    Z_External *r = (Z_External *) npr->u.databaseRecord;
+    const Odr_oid *oid = r->direct_reference;
+    
+    /* render bibliographic record .. */
+    if (r->which == Z_External_OPAC)
+    {
+        return return_opac_record(rec, marctype, len,
+                                  r->u.opac, charset);
+    }
+    if (r->which == Z_External_sutrs)
+        return return_string_record(rec, len,
+                                    (char*) r->u.sutrs->buf,
+                                    r->u.sutrs->len,
+                                    charset);
+    else if (r->which == Z_External_octet)
+    {
+        if (yaz_oid_is_iso2709(oid))
+        {
+            const char *ret_buf = return_marc_record(
+                rec, marctype, len,
+                (const char *) r->u.octet_aligned->buf,
+                r->u.octet_aligned->len,
+                charset);
+            if (ret_buf)
+                return ret_buf;
+            /* bad ISO2709. Return fail unless raw (ISO2709) is wanted */
+            if (marctype != YAZ_MARC_ISO2709)
+                return 0;
+        }
+        return return_string_record(rec, len,
+                                    (const char *) r->u.octet_aligned->buf,
+                                    r->u.octet_aligned->len,
+                                    charset);
+    }
+    else if (r->which == Z_External_grs1)
+    {
+        if (!rec->wrbuf)
+            rec->wrbuf = wrbuf_alloc();
+        wrbuf_rewind(rec->wrbuf);
+        yaz_display_grs1(rec->wrbuf, r->u.grs1, 0);
+        return return_string_record(rec, len,
+                                    wrbuf_buf(rec->wrbuf),
+                                    wrbuf_len(rec->wrbuf),
+                                    charset);
+    }
+    return 0;
+}
+    
 
 ZOOM_API(int)
     ZOOM_record_error(ZOOM_record rec, const char **cp,
@@ -2002,14 +2071,42 @@ ZOOM_API(int)
     return 0;
 }
 
+static const char *get_record_format(ZOOM_record rec, int *len,
+                                     Z_NamePlusRecord *npr,
+                                     int marctype, const char *charset,
+                                     const char *format)
+{
+    const char *res = return_record(rec, len, npr, marctype, charset);
+#if YAZ_HAVE_XML2
+    if (*format == '1' && len)
+    {
+        /* try to XML format res */
+        xmlDocPtr doc;
+        xmlKeepBlanksDefault(0); /* get get xmlDocFormatMemory to work! */
+        doc = xmlParseMemory(res, *len);
+        if (doc)
+        {
+            if (rec->xml_mem)
+                xmlFree(rec->xml_mem);
+            xmlDocDumpFormatMemory(doc, &rec->xml_mem, &rec->xml_size, 1);
+            xmlFreeDoc(doc);
+            res = (char *) rec->xml_mem;
+            *len = rec->xml_size;
+        } 
+    }
+#endif
+    return res;
+}
+
+
 ZOOM_API(const char *)
     ZOOM_record_get(ZOOM_record rec, const char *type_spec, int *len)
 {
     char type[40];
     char charset[40];
-    char xpath[512];
+    char format[3];
     const char *cp;
-    int i;
+    size_t i;
     Z_NamePlusRecord *npr;
     
     if (len)
@@ -2022,41 +2119,43 @@ ZOOM_API(const char *)
         return 0;
 
     cp = type_spec;
-    for (i = 0; cp[i] && i < sizeof(type)-1; i++)
-    {
-        if (cp[i] == ';' || cp[i] == ' ')
-            break;
+    for (i = 0; cp[i] && cp[i] != ';' && cp[i] != ' ' && i < sizeof(type)-1;
+         i++)
         type[i] = cp[i];
-    }
     type[i] = '\0';
     charset[0] = '\0';
-    while (type_spec[i] == ';')
+    format[0] = '\0';
+    while (1)
     {
+        while (cp[i] == ' ')
+            i++;
+        if (cp[i] != ';')
+            break;
         i++;
-        while (type_spec[i] == ' ')
+        while (cp[i] == ' ')
             i++;
-        if (!strncmp(type_spec+i, "charset=", 8))
+        if (!strncmp(cp + i, "charset=", 8))
         {
-            int j = 0;
+            size_t j = 0;
             i = i + 8; /* skip charset= */
-            for (j = 0; type_spec[i]  && j < sizeof(charset)-1; i++, j++)
+            for (j = 0; cp[i] && cp[i] != ';' && cp[i] != ' '; i++)
             {
-                if (type_spec[i] == ';' || type_spec[i] == ' ')
-                    break;
-                charset[j] = cp[i];
+                if (j < sizeof(charset)-1)
+                    charset[j++] = cp[i];
             }
             charset[j] = '\0';
         }
-        else if (!strncmp(type_spec+i, "xpath=", 6))
+        else if (!strncmp(cp + i, "format=", 7))
         {
-            int j = 0; 
-            i = i + 6;
-            for (j = 0; type_spec[i] && j < sizeof(xpath)-1; i++, j++)
-                xpath[j] = cp[i];
-            xpath[j] = '\0';
+            size_t j = 0; 
+            i = i + 7;
+            for (j = 0; cp[i] && cp[i] != ';' && cp[i] != ' '; i++)
+            {
+                if (j < sizeof(format)-1)
+                    format[j++] = cp[i];
+            }
+            format[j] = '\0';
         } 
-        while (type_spec[i] == ' ')
-            i++;
     }
     if (!strcmp(type, "database"))
     {
@@ -2090,137 +2189,33 @@ ZOOM_API(const char *)
     /* from now on - we have a database record .. */
     if (!strcmp(type, "render"))
     {
-        Z_External *r = (Z_External *) npr->u.databaseRecord;
-        const Odr_oid *oid = r->direct_reference;
-
-        /* render bibliographic record .. */
-        if (r->which == Z_External_OPAC)
-        {
-            r = r->u.opac->bibliographicRecord;
-            if (!r)
-                return 0;
-            oid = r->direct_reference;
-        }
-        if (r->which == Z_External_sutrs)
-            return record_iconv_return(rec, len,
-                                       (char*) r->u.sutrs->buf,
-                                       r->u.sutrs->len,
-                                       charset);
-        else if (r->which == Z_External_octet)
-        {
-            if (yaz_oid_is_iso2709(oid))
-            {
-                const char *ret_buf = marc_iconv_return(
-                    rec, YAZ_MARC_LINE, len,
-                    (const char *) r->u.octet_aligned->buf,
-                    r->u.octet_aligned->len,
-                    charset);
-                if (ret_buf)
-                    return ret_buf;
-            }
-            return record_iconv_return(rec, len,
-                                       (const char *) r->u.octet_aligned->buf,
-                                       r->u.octet_aligned->len,
-                                       charset);
-        }
-        else if (r->which == Z_External_grs1)
-        {
-            if (!rec->wrbuf_marc)
-                rec->wrbuf_marc = wrbuf_alloc();
-            wrbuf_rewind(rec->wrbuf_marc);
-            yaz_display_grs1(rec->wrbuf_marc, r->u.grs1, 0);
-            return record_iconv_return(rec, len,
-                                       wrbuf_buf(rec->wrbuf_marc),
-                                       wrbuf_len(rec->wrbuf_marc),
-                                       charset);
-        }
-        return 0;
+        return get_record_format(rec, len, npr, YAZ_MARC_LINE, charset, format);
     }
     else if (!strcmp(type, "xml"))
     {
-        Z_External *r = (Z_External *) npr->u.databaseRecord;
-        const Odr_oid *oid = r->direct_reference;
-
-        /* render bibliographic record .. */
-        if (r->which == Z_External_OPAC)
-        {
-            r = r->u.opac->bibliographicRecord;
-            if (!r)
-                return 0;
-            oid = r->direct_reference;
-        }
-        
-        if (r->which == Z_External_sutrs)
-            return record_iconv_return(rec, len,
-                                       (const char *) r->u.sutrs->buf,
-                                       r->u.sutrs->len,
-                                       charset);
-        else if (r->which == Z_External_octet)
-        {
-            int marc_decode_type = YAZ_MARC_MARCXML;
-            if (yaz_oid_is_iso2709(oid))
-            {
-                const char *ret_buf = marc_iconv_return(
-                    rec, marc_decode_type, len,
-                    (const char *) r->u.octet_aligned->buf,
-                    r->u.octet_aligned->len,
-                    charset);
-                if (ret_buf)
-                    return ret_buf;
-            }
-            return record_iconv_return(rec, len,
-                                       (const char *) r->u.octet_aligned->buf,
-                                       r->u.octet_aligned->len,
-                                       charset);
-        }
-        else if (r->which == Z_External_grs1)
-        {
-            if (len) *len = 5;
-            return "GRS-1";
-        }
-        return 0;
+        return get_record_format(rec, len, npr, YAZ_MARC_MARCXML, charset,
+                                 format);
+    }
+    else if (!strcmp(type, "txml"))
+    {
+        return get_record_format(rec, len, npr, YAZ_MARC_TMARCXML, charset,
+                                 format);
     }
     else if (!strcmp(type, "raw"))
     {
-        Z_External *r = (Z_External *) npr->u.databaseRecord;
-        
-        if (r->which == Z_External_sutrs)
-        {
-            if (len) *len = r->u.sutrs->len;
-            return (const char *) r->u.sutrs->buf;
-        }
-        else if (r->which == Z_External_octet)
-        {
-            if (len) *len = r->u.octet_aligned->len;
-            return (const char *) r->u.octet_aligned->buf;
-        }
-        else /* grs-1, explain, OPAC, ... */
-        {
-            if (len) *len = -1;
-            return (const char *) npr->u.databaseRecord;
-        }
-        return 0;
+        return get_record_format(rec, len, npr, YAZ_MARC_ISO2709, charset,
+            format);
     }
-    else if (!strcmp (type, "ext"))
+    else if (!strcmp(type, "ext"))
     {
         if (len) *len = -1;
         return (const char *) npr->u.databaseRecord;
     }
-    else if (!strcmp (type, "opac"))
-             
+    else if (!strcmp(type, "opac"))
     {
-        Z_External *r = (Z_External *) npr->u.databaseRecord;
-        if (r->which == Z_External_OPAC)
-        {
-            if (!rec->wrbuf_opac)
-                rec->wrbuf_opac = wrbuf_alloc();
-            wrbuf_rewind(rec->wrbuf_opac);
-            yaz_display_OPAC(rec->wrbuf_opac, r->u.opac, 0);
-            return record_iconv_return(rec, len,
-                                       wrbuf_buf(rec->wrbuf_opac),
-                                       wrbuf_len(rec->wrbuf_opac),
-                                       charset);
-        }
+        if (npr->u.databaseRecord->which == Z_External_OPAC)
+            return get_record_format(rec, len, npr, YAZ_MARC_MARCXML, charset,
+                format);
     }
     return 0;
 }
@@ -2264,9 +2259,10 @@ static void record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr,
     {
         rc = (ZOOM_record_cache) odr_malloc(r->odr, sizeof(*rc));
         rc->rec.odr = 0;
-        rc->rec.wrbuf_marc = 0;
-        rc->rec.wrbuf_iconv = 0;
-        rc->rec.wrbuf_opac = 0;
+        rc->rec.wrbuf = 0;
+#if YAZ_HAVE_XML2
+        rc->rec.xml_mem = 0;
+#endif
         rc->elementSetName = odr_strdup_null(r->odr, elementSetName);
         
         rc->syntax = odr_strdup_null(r->odr, syntax);
@@ -2969,7 +2965,7 @@ ZOOM_API(size_t)
 }
 
 static void ZOOM_scanset_term_x(ZOOM_scanset scan, size_t pos,
-                                int *occ,
+                                size_t *occ,
                                 const char **value_term, size_t *value_len,
                                 const char **disp_term, size_t *disp_len)
 {
@@ -2982,7 +2978,7 @@ static void ZOOM_scanset_term_x(ZOOM_scanset scan, size_t pos,
     *disp_len = 0;
 
     *occ = 0;
-    if (pos >= noent || pos < 0)
+    if (pos >= noent)
         return;
     if (scan->scan_response)
     {
@@ -3027,7 +3023,7 @@ static void ZOOM_scanset_term_x(ZOOM_scanset scan, size_t pos,
 
 ZOOM_API(const char *)
     ZOOM_scanset_term(ZOOM_scanset scan, size_t pos,
-                      int *occ, int *len)
+                      size_t *occ, size_t *len)
 {
     const char *value_term = 0;
     size_t value_len = 0;
@@ -3043,7 +3039,7 @@ ZOOM_API(const char *)
 
 ZOOM_API(const char *)
     ZOOM_scanset_display_term(ZOOM_scanset scan, size_t pos,
-                              int *occ, int *len)
+                              size_t *occ, size_t *len)
 {
     const char *value_term = 0;
     size_t value_len = 0;
@@ -3207,7 +3203,7 @@ static Z_ItemOrder *encode_item_order(ZOOM_package p)
         req->u.esRequest->notToKeep->resultSetItem->resultSetId =
             odr_strdup(p->odr_out, str);
         req->u.esRequest->notToKeep->resultSetItem->item =
-            (int *) odr_malloc(p->odr_out, sizeof(int));
+            odr_intdup(p->odr_out, 0);
         
         str = ZOOM_options_get(p->options, "itemorder-item");
         *req->u.esRequest->notToKeep->resultSetItem->item =
@@ -4141,6 +4137,8 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres)
             Z_SRW_PDU *sr = (Z_SRW_PDU*) soap_package->u.generic->p;
 
             ZOOM_options_set(c->options, "sru_version", sr->srw_version);
+            ZOOM_options_setl(c->options, "sru_extra_response_data",
+                sr->extraResponseData_buf, sr->extraResponseData_len);
             if (sr->which == Z_SRW_searchRetrieve_response)
                 cret = handle_srw_response(c, sr->u.response);
             else if (sr->which == Z_SRW_scan_response)
@@ -4677,9 +4675,15 @@ ZOOM_API(int) ZOOM_connection_get_timeout(ZOOM_connection c)
     return ZOOM_options_get_int(c->options, "timeout", 30);
 }
 
+ZOOM_API(void) ZOOM_connection_close(ZOOM_connection c)
+{
+    do_close(c);
+}
+
 /*
  * Local variables:
  * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
  * indent-tabs-mode: nil
  * End:
  * vim: shiftwidth=4 tabstop=8 expandtab