Update headers and omit CVS Ids.
[yaz-moved-to-github.git] / src / zoom-c.c
index d724047..b59c14a 100644 (file)
@@ -1,8 +1,6 @@
-/*
- * Copyright (C) 1995-2007, Index Data ApS
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) 1995-2008 Index Data
  * See the file LICENSE for details.
- *
- * $Id: zoom-c.c,v 1.147 2007-09-09 05:54:45 adam Exp $
  */
 /**
  * \file zoom-c.c
@@ -49,7 +47,7 @@ static char *cql2pqf(ZOOM_connection c, const char *cql);
  * if it could cause failure when a lookup fails, but that's hard.
  */
 static Odr_oid *zoom_yaz_str_to_z3950oid(ZOOM_connection c,
-                                     int oid_class, const char *str) {
+                                     oid_class oid_class, const char *str) {
     Odr_oid *res = yaz_string_to_oid_odr(yaz_oid_std(), oid_class, str,
                                      c->odr_out);
     if (res == 0)
@@ -174,13 +172,6 @@ static void set_dset_error(ZOOM_connection c, int error,
     }
 }
 
-#if YAZ_HAVE_XML2
-static void set_HTTP_error(ZOOM_connection c, int error,
-                           const char *addinfo, const char *addinfo2)
-{
-    set_dset_error(c, error, "HTTP", addinfo, addinfo2);
-}
-
 static int uri_to_code(const char *uri)
 {
     int code = 0;       
@@ -190,6 +181,13 @@ static int uri_to_code(const char *uri)
     return code;
 }
 
+#if YAZ_HAVE_XML2
+static void set_HTTP_error(ZOOM_connection c, int error,
+                           const char *addinfo, const char *addinfo2)
+{
+    set_dset_error(c, error, "HTTP", addinfo, addinfo2);
+}
+
 static void set_SRU_error(ZOOM_connection c, Z_SRW_diagnostic *d)
 {
     const char *uri = d->uri;
@@ -399,7 +397,7 @@ ZOOM_API(ZOOM_connection)
     c->m_queue_front = 0;
     c->m_queue_back = 0;
 
-    c->sru_version = xstrdup("1.1");
+    c->sru_version = 0;
     return c;
 }
 
@@ -548,7 +546,7 @@ ZOOM_API(void)
 
     xfree(c->sru_version);
     val = ZOOM_options_get(c->options, "sru_version");
-    c->sru_version = xstrdup(val ? val : "1.1");
+    c->sru_version = xstrdup(val ? val : "1.2");
 
     ZOOM_options_set(c->options, "host", c->host_port);
 
@@ -1356,7 +1354,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.147 $");
+    version = odr_strdup(c->odr_out, "$Revision: 1.154 $");
     if (strlen(version) > 10)   /* check for unexpanded CVS strings */
         version[strlen(version)-2] = '\0';
     ireq->implementationVersion = 
@@ -1371,15 +1369,9 @@ static zoom_ret ZOOM_connection_send_init(ZOOM_connection c)
     if (c->group || c->password)
     {
         Z_IdPass *pass = (Z_IdPass *) odr_malloc(c->odr_out, sizeof(*pass));
-        pass->groupId = 0;
-        if (c->group)
-            pass->groupId = odr_strdup(c->odr_out, c->group);
-        pass->userId = 0;
-        if (c->user)
-            pass->userId = odr_strdup(c->odr_out, c->user);
-        pass->password = 0;
-        if (c->password)
-            pass->password = odr_strdup(c->odr_out, c->password);
+        pass->groupId = odr_strdup_null(c->odr_out, c->group);
+        pass->userId = odr_strdup_null(c->odr_out, c->user);
+        pass->password = odr_strdup_null(c->odr_out, c->password);
         auth->which = Z_IdAuthentication_idPass;
         auth->u.idPass = pass;
         ireq->idAuthentication = auth;
@@ -1454,7 +1446,6 @@ static Z_SRW_PDU *ZOOM_srw_get_pdu(ZOOM_connection c, int type) {
     return sr;
 }
 
-
 #if YAZ_HAVE_XML2
 static zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
 {
@@ -1540,8 +1531,7 @@ static zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c)
         sr->u.request->recordPacking = odr_strdup(c->odr_out, option_val);
 
     option_val = ZOOM_resultset_option_get(resultset, "extraArgs");
-    if (option_val)
-        sr->extra_args = odr_strdup(c->odr_out, option_val);
+    yaz_encode_sru_extra(sr, c->odr_out, option_val);
     return send_srw(c, sr);
 }
 #else
@@ -1748,6 +1738,11 @@ ZOOM_API(ZOOM_record)
     odr_setbuf(nrec->odr, buf, size, 0);
     z_NamePlusRecord(nrec->odr, &nrec->npr, 0, 0);
     
+    nrec->schema = odr_strdup_null(nrec->odr, srec->schema);
+    nrec->diag_uri = odr_strdup_null(nrec->odr, srec->diag_uri);
+    nrec->diag_message = odr_strdup_null(nrec->odr, srec->diag_message);
+    nrec->diag_details = odr_strdup_null(nrec->odr, srec->diag_details);
+    nrec->diag_set = odr_strdup_null(nrec->odr, srec->diag_set);
     odr_destroy(odr_enc);
     return nrec;
 }
@@ -1915,15 +1910,15 @@ ZOOM_API(int)
         return 0;
 
     npr = rec->npr;
-    if (rec->diag)
+    if (rec->diag_uri)
     {
         if (cp)
-            *cp = rec->diag[0].message;
+            *cp = rec->diag_message;
         if (addinfo)
-            *addinfo = rec->diag[0].details;
+            *addinfo = rec->diag_details;
         if (diagset)
-            *diagset = rec->diagset;
-        return uri_to_code(rec->diag[0].uri);
+            *diagset = rec->diag_set;
+        return uri_to_code(rec->diag_uri);
     }
     if (npr && npr->which == Z_NamePlusRecord_surrogateDiagnostic)
     {
@@ -2208,65 +2203,57 @@ static void record_cache_add(ZOOM_resultset r, Z_NamePlusRecord *npr,
                              int pos,
                              const char *syntax, const char *elementSetName,
                              const char *schema,
-                             Z_SRW_diagnostic *diag, int num_diag)
+                             Z_SRW_diagnostic *diag)
 {
-    ZOOM_record_cache rc;
+    ZOOM_record_cache rc = 0;
     
     ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_RECV_RECORD);
     ZOOM_connection_put_event(r->connection, event);
 
     for (rc = r->record_hash[record_hash(pos)]; rc; rc = rc->next)
     {
-        if (pos == rc->pos)
-        {
-            if (strcmp_null(r->schema, rc->schema))
-                continue;
-            if (strcmp_null(elementSetName,rc->elementSetName))
-                continue;
-            if (strcmp_null(syntax, rc->syntax))
-                continue;
-            /* not destroying rc->npr (it's handled by nmem )*/
-            rc->rec.npr = npr;
-            /* keeping wrbuf_marc too */
-            return;
-        }
+        if (pos == rc->pos 
+            && strcmp_null(r->schema, rc->schema) == 0
+            && strcmp_null(elementSetName,rc->elementSetName) == 0
+            && strcmp_null(syntax, rc->syntax) == 0)
+            break;
+    }
+    if (!rc)
+    {
+        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->elementSetName = odr_strdup_null(r->odr, elementSetName);
+        
+        rc->syntax = odr_strdup_null(r->odr, syntax);
+        
+        rc->schema = odr_strdup_null(r->odr, r->schema);
+
+        rc->pos = pos;
+        rc->next = r->record_hash[record_hash(pos)];
+        r->record_hash[record_hash(pos)] = rc;
     }
-    rc = (ZOOM_record_cache) odr_malloc(r->odr, sizeof(*rc));
     rc->rec.npr = npr;
-    rc->rec.schema = schema ? odr_strdup(r->odr, schema) : 0;
-    rc->rec.odr = 0;
-    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';
+    rc->rec.schema = odr_strdup_null(r->odr, schema);
+    rc->rec.diag_set = 0;
+    rc->rec.diag_uri = 0;
+    rc->rec.diag_message = 0;
+    rc->rec.diag_details = 0;
+    if (diag)
+    {
+        if (diag->uri)
+        {
+            char *cp;
+            rc->rec.diag_set = odr_strdup(r->odr, diag->uri);
+            if ((cp = strrchr(rc->rec.diag_set, '/')))
+                *cp = '\0';
+            rc->rec.diag_uri = odr_strdup(r->odr, diag->uri);
+        }
+        rc->rec.diag_message = odr_strdup_null(r->odr, diag->message);            
+        rc->rec.diag_details = odr_strdup_null(r->odr, diag->details);
     }
-
-    if (elementSetName)
-        rc->elementSetName = odr_strdup(r->odr, elementSetName);
-    else
-        rc->elementSetName = 0;
-
-    if (syntax)
-        rc->syntax = odr_strdup(r->odr, syntax);
-    else
-        rc->syntax = 0;
-
-    if (r->schema)
-        rc->schema = odr_strdup(r->odr, r->schema);
-    else
-        rc->schema = 0;
-
-
-    rc->pos = pos;
-    rc->next = r->record_hash[record_hash(pos)];
-    r->record_hash[record_hash(pos)] = rc;
 }
 
 static ZOOM_record record_cache_lookup(ZOOM_resultset r, int pos,
@@ -2344,7 +2331,7 @@ static void handle_records(ZOOM_connection c, Z_Records *sr,
             {
                 record_cache_add(resultset, p->records[i], i + *start,
                                  syntax, elementSetName,
-                                 elementSetName, 0, 0);
+                                 elementSetName, 0);
             }
             *count -= i;
             if (*count < 0)
@@ -2363,7 +2350,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);
+                                 syntax, elementSetName, 0, 0);
             }
         }
         else if (present_phase)
@@ -2372,7 +2359,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, 0);
         }
     }
 }
@@ -2911,8 +2898,7 @@ static zoom_ret ZOOM_connection_srw_send_scan(ZOOM_connection c)
         c->odr_out, ZOOM_options_get_int(scan->options, "position", 1));
     
     option_val = ZOOM_options_get(scan->options, "extraArgs");
-    if (option_val)
-        sr->extra_args = odr_strdup(c->odr_out, option_val);
+    yaz_encode_sru_extra(sr, c->odr_out, option_val);
     return send_srw(c, sr);
 }
 #else
@@ -3050,7 +3036,7 @@ static Z_APDU *create_es_package(ZOOM_package p, const Odr_oid *oid)
     
     str = ZOOM_options_get(p->options, "user-id");
     if (str)
-        req->userId = odr_strdup(p->odr_out, str);
+        req->userId = odr_strdup_null(p->odr_out, str);
     
     req->packageType = odr_oiddup(p->odr_out, oid);
 
@@ -3130,6 +3116,7 @@ static Z_ItemOrder *encode_item_order(ZOOM_package p)
 {
     Z_ItemOrder *req = (Z_ItemOrder *) odr_malloc(p->odr_out, sizeof(*req));
     const char *str;
+    int len;
     
     req->which = Z_IOItemOrder_esRequest;
     req->u.esRequest = (Z_IORequest *) 
@@ -3143,16 +3130,16 @@ static Z_ItemOrder *encode_item_order(ZOOM_package p)
         odr_malloc(p->odr_out, sizeof(*req->u.esRequest->toKeep->contact));
         
     str = ZOOM_options_get(p->options, "contact-name");
-    req->u.esRequest->toKeep->contact->name = str ?
-        odr_strdup(p->odr_out, str) : 0;
+    req->u.esRequest->toKeep->contact->name =
+        odr_strdup_null(p->odr_out, str);
         
     str = ZOOM_options_get(p->options, "contact-phone");
-    req->u.esRequest->toKeep->contact->phone = str ?
-        odr_strdup(p->odr_out, str) : 0;
+    req->u.esRequest->toKeep->contact->phone =
+        odr_strdup_null(p->odr_out, str);
         
     str = ZOOM_options_get(p->options, "contact-email");
-    req->u.esRequest->toKeep->contact->email = str ?
-        odr_strdup(p->odr_out, str) : 0;
+    req->u.esRequest->toKeep->contact->email =
+        odr_strdup_null(p->odr_out, str);
         
     req->u.esRequest->toKeep->addlBilling = 0;
         
@@ -3181,11 +3168,11 @@ static Z_ItemOrder *encode_item_order(ZOOM_package p)
             (str ? atoi(str) : 1);
     }
 
-    str = ZOOM_options_get(p->options, "doc");
+    str = ZOOM_options_getl(p->options, "doc", &len);
     if (str)
     {
         req->u.esRequest->notToKeep->itemRequest =
-            z_ext_record_xml(p->odr_out, str, strlen(str));
+            z_ext_record_xml(p->odr_out, str, len);
     }
     else
         req->u.esRequest->notToKeep->itemRequest = encode_ill_request(p);
@@ -3248,10 +3235,14 @@ static Z_APDU *create_xmlupdate_package(ZOOM_package p)
     Z_APDU *apdu = create_es_package(p, yaz_oid_extserv_xml_es);
     Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
     Z_External *ext = (Z_External *) odr_malloc(p->odr_out, sizeof(*ext));
-    const char *doc = ZOOM_options_get(p->options, "doc");
+    int len;
+    const char *doc = ZOOM_options_getl(p->options, "doc", &len);
 
     if (!doc)
+    {
         doc = "";
+        len = 0;
+    }
 
     req->taskSpecificParameters = ext;
     ext->direct_reference = req->packageType;
@@ -3260,8 +3251,7 @@ static Z_APDU *create_xmlupdate_package(ZOOM_package p)
     
     ext->which = Z_External_octet;
     ext->u.single_ASN1_type =
-        odr_create_Odr_oct(p->odr_out, (const unsigned char *) doc,
-                           strlen(doc));
+        odr_create_Odr_oct(p->odr_out, (const unsigned char *) doc, len);
     return apdu;
 }
 
@@ -3272,9 +3262,13 @@ static Z_APDU *create_update_package(ZOOM_package p)
     int num_db;
     char **db = set_DatabaseNames(p->connection, p->options, &num_db, p->odr_out);
     const char *action = ZOOM_options_get(p->options, "action");
-    const char *recordIdOpaque = ZOOM_options_get(p->options, "recordIdOpaque");
+    int recordIdOpaque_len;
+    const char *recordIdOpaque = ZOOM_options_getl(p->options, "recordIdOpaque",
+        &recordIdOpaque_len);
     const char *recordIdNumber = ZOOM_options_get(p->options, "recordIdNumber");
-    const char *record_buf = ZOOM_options_get(p->options, "record");
+    int record_len;
+    const char *record_buf = ZOOM_options_getl(p->options, "record",
+        &record_len);
     const char *syntax_str = ZOOM_options_get(p->options, "syntax");
     const char *version = ZOOM_options_get(p->options, "updateVersion");
 
@@ -3293,6 +3287,7 @@ static Z_APDU *create_update_package(ZOOM_package p)
     if (!record_buf)
     {
         record_buf = "void";
+        record_len = 4;
         syntax_str = "SUTRS";
     }
 
@@ -3372,9 +3367,7 @@ static Z_APDU *create_update_package(ZOOM_package p)
         toKeep->databaseName = odr_strdup(p->odr_out, first_db);
         toKeep->schema = 0;
         
-        toKeep->elementSetName = 0;
-        if (elementSetName)
-            toKeep->elementSetName = odr_strdup(p->odr_out, elementSetName);
+        toKeep->elementSetName = odr_strdup_null(p->odr_out, elementSetName);
             
         toKeep->actionQualifier = 0;
         toKeep->action = odr_intdup(p->odr_out, action_no);
@@ -3393,7 +3386,7 @@ static Z_APDU *create_update_package(ZOOM_package p)
             notToKeep->elements[0]->u.opaque = 
                 odr_create_Odr_oct(p->odr_out,
                                    (const unsigned char *) recordIdOpaque,
-                                   strlen(recordIdOpaque));
+                                   recordIdOpaque_len);
         }
         else if (recordIdNumber)
         {
@@ -3409,9 +3402,8 @@ static Z_APDU *create_update_package(ZOOM_package p)
         {
             Z_IUCorrelationInfo *ci;
             ci = notToKeep->elements[0]->correlationInfo =
-                odr_malloc(p->odr_out, sizeof(*ci));
-            ci->note = correlationInfo_note ?
-                odr_strdup(p->odr_out, correlationInfo_note) : 0;
+                (Z_IUCorrelationInfo *) odr_malloc(p->odr_out, sizeof(*ci));
+            ci->note = odr_strdup_null(p->odr_out, correlationInfo_note);
             ci->id = correlationInfo_id ?
                 odr_intdup(p->odr_out, atoi(correlationInfo_id)) : 0;
         }
@@ -3419,7 +3411,7 @@ static Z_APDU *create_update_package(ZOOM_package p)
             notToKeep->elements[0]->correlationInfo = 0;
         notToKeep->elements[0]->record =
             z_ext_record_oid(p->odr_out, syntax_oid,
-                             record_buf, strlen(record_buf));
+                             record_buf, record_len);
     }
     if (0 && apdu)
     {
@@ -3540,6 +3532,11 @@ ZOOM_API(const char *)
     return ZOOM_options_get(p->options, key);
 }
 
+ZOOM_API(const char *)
+    ZOOM_package_option_getl(ZOOM_package p, const char *key, int *lenp)
+{
+    return ZOOM_options_getl(p->options, key, lenp);
+}
 
 ZOOM_API(void)
     ZOOM_package_option_set(ZOOM_package p, const char *key,
@@ -3548,6 +3545,13 @@ ZOOM_API(void)
     ZOOM_options_set(p->options, key, val);
 }
 
+ZOOM_API(void)
+    ZOOM_package_option_setl(ZOOM_package p, const char *key,
+                             const char *val, int len)
+{
+    ZOOM_options_setl(p->options, key, val, len);
+}
+
 static int ZOOM_connection_exec_task(ZOOM_connection c)
 {
     ZOOM_task task = c->tasks;
@@ -3926,7 +3930,7 @@ static void handle_srw_response(ZOOM_connection c,
                                              resultset->odr);
         }
         record_cache_add(resultset, npr, pos, syntax, elementSetName,
-                         sru_rec->recordSchema, diag, num_diag);
+                         sru_rec->recordSchema, diag);
     }
     if (res->num_diagnostics > 0)
         set_SRU_error(c, &res->diagnostics[0]);