Handle surrogate diagnostics for SRU
authorAdam Dickmeiss <adam@indexdata.dk>
Sun, 9 Sep 2007 05:54:45 +0000 (05:54 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Sun, 9 Sep 2007 05:54:45 +0000 (05:54 +0000)
include/yaz/srw.h
src/srw.c
src/zoom-c.c
src/zoom-p.h

index a81581b..7662818 100644 (file)
@@ -24,7 +24,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-/* $Id: srw.h,v 1.35 2007-08-23 14:23:23 adam Exp $ */
+/* $Id: srw.h,v 1.36 2007-09-09 05:54:45 adam Exp $ */
 
 /**
  * \file srw.h
@@ -277,6 +277,13 @@ YAZ_EXPORT char *yaz_negotiate_sru_version(char *input_ver);
 YAZ_EXPORT
 int yaz_srw_check_content_type(Z_HTTP_Response *hres);
 
+YAZ_EXPORT
+int sru_decode_surrogate_diagnostics(const char *buf, size_t len,
+                                     Z_SRW_diagnostic **diag,
+                                     int *num, ODR odr);
+
+    
+
 YAZ_END_CDECL
 
 #endif
index 54aa7ba..93037e9 100644 (file)
--- a/src/srw.c
+++ b/src/srw.c
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2007, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: srw.c,v 1.57 2007-08-23 14:23:23 adam Exp $
+ * $Id: srw.c,v 1.58 2007-09-09 05:54:45 adam Exp $
  */
 /**
  * \file srw.c
@@ -439,53 +439,85 @@ static int yaz_srw_versions(ODR o, xmlNodePtr pptr,
     return 0;
 }
 
-static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,
-                               int *num, void *client_data, const char *ns)
+
+static int yaz_srw_decode_diagnostics(ODR o, xmlNodePtr pptr,
+                                      Z_SRW_diagnostic **recs, int *num,
+                                      void *client_data, const char *ns)
+    
 {
-    if (o->direction == ODR_DECODE)
+    int i;
+    xmlNodePtr ptr;
+    *num = 0;
+    for (ptr = pptr; ptr; ptr = ptr->next)
     {
-        int i;
-        xmlNodePtr ptr;
-        *num = 0;
-        for (ptr = pptr->children; ptr; ptr = ptr->next)
-        {
             if (ptr->type == XML_ELEMENT_NODE &&
                 !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
                 (*num)++;
-        }
-        if (!*num)
-            return 1;
-        *recs = (Z_SRW_diagnostic *) odr_malloc(o, *num * sizeof(**recs));
-        for (i = 0; i < *num; i++)
+    }
+    if (!*num)
+        return 1;
+    *recs = (Z_SRW_diagnostic *) odr_malloc(o, *num * sizeof(**recs));
+    for (i = 0; i < *num; i++)
         {
             (*recs)[i].uri = 0;
             (*recs)[i].details = 0;
             (*recs)[i].message = 0;
         } 
-        for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
+    for (i = 0, ptr = pptr; ptr; ptr = ptr->next)
+    {
+        if (ptr->type == XML_ELEMENT_NODE &&
+            !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
         {
-            if (ptr->type == XML_ELEMENT_NODE &&
-                !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
+            xmlNodePtr rptr;
+            (*recs)[i].uri = 0;
+            (*recs)[i].details = 0;
+            (*recs)[i].message = 0;
+            for (rptr = ptr->children; rptr; rptr = rptr->next)
             {
-                xmlNodePtr rptr;
-                (*recs)[i].uri = 0;
-                (*recs)[i].details = 0;
-                (*recs)[i].message = 0;
-                for (rptr = ptr->children; rptr; rptr = rptr->next)
-                {
-                    if (match_xsd_string(rptr, "uri", o, 
-                                         &(*recs)[i].uri))
-                        ;
-                    else if (match_xsd_string(rptr, "details", o, 
-                                              &(*recs)[i].details))
-                        ;
-                    else if (match_xsd_string(rptr, "message", o, 
-                                              &(*recs)[i].message))
-                        ;
-                }
-                i++;
+                if (match_xsd_string(rptr, "uri", o, 
+                                     &(*recs)[i].uri))
+                    ;
+                else if (match_xsd_string(rptr, "details", o, 
+                                          &(*recs)[i].details))
+                    ;
+                else if (match_xsd_string(rptr, "message", o, 
+                                          &(*recs)[i].message))
+                    ;
             }
+            i++;
+        }
+    }
+    return 0;
+}
+
+int sru_decode_surrogate_diagnostics(const char *buf, size_t len,
+                                     Z_SRW_diagnostic **diag,
+                                     int *num, ODR odr)
+{
+    int ret = 0;
+    xmlDocPtr doc = xmlParseMemory(buf, len);
+    if (doc)
+    {
+        xmlNodePtr ptr = xmlDocGetRootElement(doc);
+        while (ptr && ptr->type != XML_ELEMENT_NODE)
+            ptr = ptr->next;
+        if (ptr && ptr->ns 
+            && !xmlStrcmp(ptr->ns->href,
+                          BAD_CAST "http://www.loc.gov/zing/srw/diagnostic/"))
+        {
+            ret = yaz_srw_decode_diagnostics(odr, ptr, diag, num, 0, 0);
         }
+        xmlFreeDoc(doc);
+    }
+    return ret;
+}
+
+static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,
+                               int *num, void *client_data, const char *ns)
+{
+    if (o->direction == ODR_DECODE)
+    {
+        return yaz_srw_decode_diagnostics(o, pptr->children, recs, num, client_data, ns);
     }
     else if (o->direction == ODR_ENCODE)
     {
index d96d1f5..d724047 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2007, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: zoom-c.c,v 1.146 2007-09-08 06:17:45 adam Exp $
+ * $Id: zoom-c.c,v 1.147 2007-09-09 05:54:45 adam Exp $
  */
 /**
  * \file zoom-c.c
@@ -181,17 +181,20 @@ static void set_HTTP_error(ZOOM_connection c, int error,
     set_dset_error(c, error, "HTTP", addinfo, addinfo2);
 }
 
+static int uri_to_code(const char *uri)
+{
+    int code = 0;       
+    const char *cp;
+    if ((cp = strrchr(uri, '/')))
+        code = atoi(cp+1);
+    return code;
+}
+
 static void set_SRU_error(ZOOM_connection c, Z_SRW_diagnostic *d)
 {
     const char *uri = d->uri;
     if (uri)
-    {
-        int code = 0;       
-        const char *cp;
-        if ((cp = strrchr(uri, '/')))
-            code = atoi(cp+1);
-        set_dset_error(c, code, uri, d->details, 0);
-    }
+        set_dset_error(c, uri_to_code(uri), uri, d->details, 0);
 }
 
 #endif
@@ -1353,7 +1356,7 @@ static zoom_ret ZOOM_connection_send_init(ZOOM_connection c)
                     odr_prepend(c->odr_out, "ZOOM-C",
                                 ireq->implementationName));
     
-    version = odr_strdup(c->odr_out, "$Revision: 1.146 $");
+    version = odr_strdup(c->odr_out, "$Revision: 1.147 $");
     if (strlen(version) > 10)   /* check for unexpanded CVS strings */
         version[strlen(version)-2] = '\0';
     ireq->implementationVersion = 
@@ -1901,6 +1904,7 @@ static const char *record_iconv_return(ZOOM_record rec, int *len,
     return buf;
 }
 
+
 ZOOM_API(int)
     ZOOM_record_error(ZOOM_record rec, const char **cp,
                       const char **addinfo, const char **diagset)
@@ -1909,7 +1913,18 @@ ZOOM_API(int)
     
     if (!rec)
         return 0;
+
     npr = rec->npr;
+    if (rec->diag)
+    {
+        if (cp)
+            *cp = rec->diag[0].message;
+        if (addinfo)
+            *addinfo = rec->diag[0].details;
+        if (diagset)
+            *diagset = rec->diagset;
+        return uri_to_code(rec->diag[0].uri);
+    }
     if (npr && npr->which == Z_NamePlusRecord_surrogateDiagnostic)
     {
         Z_DiagRec *diag_rec = npr->u.surrogateDiagnostic;
@@ -2192,7 +2207,8 @@ static size_t record_hash(int pos)
 static void record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr, 
                              int pos,
                              const char *syntax, const char *elementSetName,
-                             const char *schema)
+                             const char *schema,
+                             Z_SRW_diagnostic *diag, int num_diag)
 {
     ZOOM_record_cache rc;
     
@@ -2222,6 +2238,16 @@ static void record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr,
     rc->rec.wrbuf_marc = 0;
     rc->rec.wrbuf_iconv = 0;
     rc->rec.wrbuf_opac = 0;
+    rc->rec.diag = diag;
+    rc->rec.diagset = 0;
+    if (diag && diag[0].uri)
+    {
+        char *cp;
+        rc->rec.diagset = odr_strdup(r->odr, diag[0].uri);
+        if ((cp = strrchr(rc->rec.diagset, '/')))
+            *cp = '\0';
+    }
+
     if (elementSetName)
         rc->elementSetName = odr_strdup(r->odr, elementSetName);
     else
@@ -2237,6 +2263,7 @@ static void record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr,
     else
         rc->schema = 0;
 
+
     rc->pos = pos;
     rc->next = r->record_hash[record_hash(pos)];
     r->record_hash[record_hash(pos)] = rc;
@@ -2317,7 +2344,7 @@ static void handle_records(ZOOM_connection c, Z_Records *sr,
             {
                 record_cache_add(resultset, p->records[i], i + *start,
                                  syntax, elementSetName,
-                                 elementSetName);
+                                 elementSetName, 0, 0);
             }
             *count -= i;
             if (*count < 0)
@@ -2336,7 +2363,7 @@ static void handle_records(ZOOM_connection c, Z_Records *sr,
                 Z_NamePlusRecord *myrec = 
                     zget_surrogateDiagRec(resultset->odr, 0, 14, 0);
                 record_cache_add(resultset, myrec, *start,
-                                 syntax, elementSetName, 0);
+                                 syntax, elementSetName, 0, 0, 0);
             }
         }
         else if (present_phase)
@@ -2345,7 +2372,7 @@ static void handle_records(ZOOM_connection c, Z_Records *sr,
             Z_NamePlusRecord *myrec = 
                 zget_surrogateDiagRec(resultset->odr, 0, 14, 0);
             record_cache_add(resultset, myrec, *start, syntax, elementSetName,
-                             0);
+                             0, 0, 0);
         }
     }
 }
@@ -3857,7 +3884,10 @@ static void handle_srw_response(ZOOM_connection c,
     for (i = 0; i<res->num_records; i++)
     {
         int pos;
-
+        Z_SRW_record *sru_rec;
+        Z_SRW_diagnostic *diag = 0;
+        int num_diag;
         Z_NamePlusRecord *npr = (Z_NamePlusRecord *)
             odr_malloc(c->odr_in, sizeof(Z_NamePlusRecord));
 
@@ -3867,6 +3897,8 @@ static void handle_srw_response(ZOOM_connection c,
         else
             pos = *start + i;
         
+        sru_rec = &res->records[i];
+
         npr->databaseName = 0;
         npr->which = Z_NamePlusRecord_databaseRecord;
         npr->u.databaseRecord = (Z_External *)
@@ -3879,12 +3911,22 @@ static void handle_srw_response(ZOOM_connection c,
         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*)
-            res->records[i].recordData_buf;
+            sru_rec->recordData_buf;
         npr->u.databaseRecord->u.octet_aligned->len = 
             npr->u.databaseRecord->u.octet_aligned->size = 
-            res->records[i].recordData_len;
+            sru_rec->recordData_len;
+        
+        if (sru_rec->recordSchema 
+            && !strcmp(sru_rec->recordSchema,
+                       "info:srw/schema/1/diagnostics-v1.1"))
+        {
+            sru_decode_surrogate_diagnostics(sru_rec->recordData_buf,
+                                             sru_rec->recordData_len,
+                                             &diag, &num_diag,
+                                             resultset->odr);
+        }
         record_cache_add(resultset, npr, pos, syntax, elementSetName,
-                         res->records[i].recordSchema);
+                         sru_rec->recordSchema, diag, num_diag);
     }
     if (res->num_diagnostics > 0)
         set_SRU_error(c, &res->diagnostics[0]);
index 28a3de3..87b5fb6 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2005, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: zoom-p.h,v 1.23 2007-09-08 06:17:45 adam Exp $
+ * $Id: zoom-p.h,v 1.24 2007-09-09 05:54:45 adam Exp $
  */
 /**
  * \file zoom-p.h
@@ -130,6 +130,8 @@ struct ZOOM_record_p {
     WRBUF wrbuf_opac;
     Z_NamePlusRecord *npr;
     const char *schema;
+    Z_SRW_diagnostic *diag;
+    const char *diagset;
 };
 
 struct ZOOM_record_cache_p {