Using odr_create_Odr_oct
[yaz-moved-to-github.git] / src / zoom-c.c
index 7131b41..6b90468 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2005, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: zoom-c.c,v 1.58 2005-12-20 22:24:05 mike Exp $
+ * $Id: zoom-c.c,v 1.63 2006-02-19 18:36:10 adam Exp $
  */
 /**
  * \file zoom-c.c
@@ -167,7 +167,13 @@ static void set_ZOOM_error (ZOOM_connection c, int error,
 
 static void clear_error (ZOOM_connection c)
 {
-
+    /*
+     * If an error is tied to an operation then it's ok to clear: for
+     * example, a diagnostic returned from a search is cleared by a
+     * subsequent search.  However, problems such as Connection Lost
+     * or Init Refused are not cleared, because they are not
+     * recoverable: doing another search doesn't help.
+     */
     switch (c->error)
     {
     case ZOOM_ERROR_CONNECT:
@@ -524,6 +530,31 @@ ZOOM_query_cql(ZOOM_query s, const char *str)
     return 0;
 }
 
+/*
+ * Translate the CQL string client-side into RPN which is passed to
+ * the server.  This is useful for server's that don't themselves
+ * support CQL, for which ZOOM_query_cql() is useless.  `conn' is used
+ * only as a place to stash diagnostics if compilation fails; if this
+ * information is not needed, a null pointer may be used.
+ */
+ZOOM_API(int)
+ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn)
+{
+    char *rpn;
+    int ret;
+
+    yaz_log(log_details, "%p ZOOM_query_cql2rpn str=%s conn=%p", s, str, conn);
+    if (conn == 0)
+        conn = ZOOM_connection_create(0);
+
+    if ((rpn = cql2pqf(conn, str)) == 0)
+        return -1;
+
+    ret = ZOOM_query_prefix(s, rpn);
+    xfree(rpn);
+    return ret;
+}
+
 ZOOM_API(int)
 ZOOM_query_sortby(ZOOM_query s, const char *criteria)
 {
@@ -1098,7 +1129,7 @@ static zoom_ret ZOOM_connection_send_init (ZOOM_connection c)
         ZOOM_options_get(c->options, "implementationName"),
         odr_prepend(c->odr_out, "ZOOM-C", ireq->implementationName));
 
-    version = odr_strdup(c->odr_out, "$Revision: 1.58 $");
+    version = odr_strdup(c->odr_out, "$Revision: 1.63 $");
     if (strlen(version) > 10)   /* check for unexpanded CVS strings */
         version[strlen(version)-2] = '\0';
     ireq->implementationVersion = odr_prepend(c->odr_out,
@@ -2684,13 +2715,10 @@ static Z_External *encode_ill_request (ZOOM_package p)
         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, illRequest_size);
-        r->u.single_ASN1_type->len = illRequest_size;
-        r->u.single_ASN1_type->size = illRequest_size;
-        memcpy (r->u.single_ASN1_type->buf, illRequest_buf, illRequest_size);
+        r->u.single_ASN1_type =
+            odr_create_Odr_oct(out,
+                               (unsigned char *)illRequest_buf,
+                               illRequest_size);
     }
     return r;
 }
@@ -2812,20 +2840,18 @@ static Z_APDU *create_xmlupdate_package(ZOOM_package p)
     Z_External *ext = (Z_External *) odr_malloc(p->odr_out, sizeof(*ext));
     const char *doc = ZOOM_options_get(p->options, "doc");
 
+    if (!doc)
+        doc = "";
+
     req->taskSpecificParameters = ext;
     ext->direct_reference = req->packageType;
     ext->descriptor = 0;
     ext->indirect_reference = 0;
     
     ext->which = Z_External_octet;
-    ext->u.single_ASN1_type = (Odr_oct *)
-        odr_malloc (p->odr_out, sizeof(Odr_oct));
-
-    if (!doc)
-        doc = "";
-    ext->u.single_ASN1_type->buf = (unsigned char*)
-        odr_strdup(p->odr_out, doc);
-    ext->u.single_ASN1_type->size = ext->u.single_ASN1_type->len = strlen(doc);
+    ext->u.single_ASN1_type =
+        odr_create_Odr_oct(p->odr_out, (const unsigned char *) doc,
+                           strlen(doc));
     return apdu;
 }
 
@@ -2915,12 +2941,10 @@ static Z_APDU *create_update_package(ZOOM_package p)
         notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque;
         if (recordIdOpaque)
         {
-            notToKeep->elements[0]->u.opaque = (Odr_oct *)
-                odr_malloc (p->odr_out, sizeof(Odr_oct));
-            notToKeep->elements[0]->u.opaque->size =
-                notToKeep->elements[0]->u.opaque->len = strlen(recordIdOpaque);
-            notToKeep->elements[0]->u.opaque->buf = (unsigned char*)
-                odr_strdup(p->odr_out, recordIdOpaque);
+            notToKeep->elements[0]->u.opaque = 
+                odr_create_Odr_oct(p->odr_out,
+                                   (const unsigned char *) recordIdOpaque,
+                                   strlen(recordIdOpaque));
         }
         else if (recordIdNumber)
         {
@@ -3393,6 +3417,7 @@ static void handle_srw_response(ZOOM_connection c,
         npr->u.databaseRecord->direct_reference =
             yaz_oidval_to_z3950oid(c->odr_in, CLASS_RECSYN, VAL_TEXT_XML);
         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*)
@@ -4020,7 +4045,6 @@ static char *cql2pqf(ZOOM_connection c, const char *cql)
     char pqfbuf[512];
 
     parser = cql_parser_create();
-    printf("*** got CQL parser %p\n", parser);
     if ((error = cql_parser_string(parser, cql)) != 0) {
         cql_parser_destroy(parser);
         set_ZOOM_error(c, ZOOM_ERROR_CQL_PARSE, cql);
@@ -4028,24 +4052,19 @@ static char *cql2pqf(ZOOM_connection c, const char *cql)
     }
 
     node = cql_parser_result(parser);
-    printf("*** got CQL node %p\n", node);
-    cql_parser_destroy(parser);
-    printf("*** destroyed parser\n");
+    /* ### Do not call cql_parser_destroy() yet: it destroys `node'! */
 
     cqlfile = ZOOM_connection_option_get(c, "cqlfile");
-    printf("*** cqlfile is %p\n", cqlfile);
     if (cqlfile == 0) {
-        printf("*** cqlfile is null\n");
+        cql_parser_destroy(parser);
         cql_node_destroy(node);
-        printf("*** destroyed node\n");
         set_ZOOM_error(c, ZOOM_ERROR_CQL_TRANSFORM, "no CQL transform file");
-        printf("*** set ZOOM_error\n");
         return 0;
     }
-    printf("*** got CQL file %s\n", cqlfile);
 
     if ((trans = cql_transform_open_fname(cqlfile)) == 0) {
         char buf[512];        
+        cql_parser_destroy(parser);
         cql_node_destroy(node);
         sprintf(buf, "can't open CQL transform file '%.200s': %.200s",
                 cqlfile, strerror(errno));
@@ -4054,6 +4073,7 @@ static char *cql2pqf(ZOOM_connection c, const char *cql)
     }
 
     error = cql_transform_buf(trans, node, pqfbuf, sizeof pqfbuf);
+    cql_parser_destroy(parser);
     cql_node_destroy(node);
     if (error != 0) {
         char buf[512];