Simplify in a lot of places using odr_strdupn
[yaz-moved-to-github.git] / src / srw.c
index 33452e2..17b7c39 100644 (file)
--- a/src/srw.c
+++ b/src/srw.c
 #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);
-}
-
-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);
-    }
-}
-
-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(xmlNodePtr ptr, const char *elem, ODR o,
-                           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 = odr_strdup(o, (const char *) ptr->content);
-    if (len)
-        *len = xmlStrlen(ptr->content);
-    return 1;
-}
-
-
-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);
-}
-
-static 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;
-}
-
-static 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;
-}
-
 char *yaz_negotiate_sru_version(char *input_ver)
 {
     if (!input_ver)
@@ -763,6 +568,8 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
             char *recordPacking = 0;
             char *recordXMLEscaping = 0;
             const char *facetLimit = 0;
+            const char *facetStart = 0;
+            const char *facetSort = 0;
 
             (*p)->which = Z_SRW_searchRetrieve_request;
             req = (*p)->u.request = (Z_SRW_searchRetrieveRequest *)
@@ -825,10 +632,17 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
                 else if (yaz_match_xsd_string(ptr, "stylesheet", o,
                                           &req->stylesheet))
                     ;
-                else if (yaz_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))
+                                              (char**) &facetLimit))
+                    ;
+                else if (yaz_match_xsd_string(ptr, "facetStart", o,
+                                              (char**) &facetStart))
+                    ;
+                else if (yaz_match_xsd_string(ptr, "facetSort", o,
+                                              (char**) &facetSort))
                     ;
             }
             if (!req->query)
@@ -845,7 +659,8 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
             {
                 req->recordPacking = recordPacking;
             }
-            yaz_sru_facet_request(o, &req->facetList, &facetLimit);
+            yaz_sru_facet_request(o, &req->facetList, &facetLimit, &facetStart,
+                                  &facetSort);
         }
         else if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveResponse"))
         {
@@ -1120,8 +935,13 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
             add_xsd_string(ptr, "database", req->database);
             {
                 const char *limit = 0;
-                yaz_sru_facet_request(o, &req->facetList, &limit);
+                const char *start = 0;
+                const char *sort = 0;
+                yaz_sru_facet_request(o, &req->facetList, &limit, &start,
+                                      &sort);
                 add_xsd_string(ptr, "facetLimit", limit);
+                add_xsd_string(ptr, "facetStart", start);
+                add_xsd_string(ptr, "facetSort", sort);
             }
         }
         else if ((*p)->which == Z_SRW_searchRetrieve_response)