Character set negotiation updates
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 25 Jul 2002 12:52:52 +0000 (12:52 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 25 Jul 2002 12:52:52 +0000 (12:52 +0000)
13 files changed:
CHANGELOG
buildconf.sh
client/client.c
include/yaz/backend.h
include/yaz/data1.h
retrieval/d1_absyn.c
retrieval/d1_expat.c
retrieval/d1_grs.c
retrieval/d1_marc.c
retrieval/d1_read.c
retrieval/d1_write.c
server/seshigh.c
win/yaz.nsi

index 7042b21..690c9f8 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,28 @@ Possible compatibility problems with earlier versions marked with '*'.
 
 --- 1.8.8 2002/MM/DD
 
+Added three members in bend_initrequest structure to facilitate
+character set negotiation.
+
+Fixed a bug in frontend server that could cause indefinite
+loops under rare conditions. 
+
+Revised character set utilities (charneg.h) so that encoding
+UCS-4, UCSA-4, UTF-16 and UTF-8 are encoded non-privately.
+
+For PQF, directive @term <type> sets term type for Scan/Search.
+Here <type> is general, string, numeric, null. The term type
+is inherited - just like @attr.
+
+New call odr_set_charset that sets character set conversion for
+international-strings on a ODR stream. Prototype is:
+ int odr_set_charset(ODR o, const char *to, const char *from);
+The InternationalString is still represented as C string in YAZ 
+so native strings of type UTF-8, ASCII, etc. will work (UTF-16
+won't). On the protocol level, you can use any encoding.
+
+Support for UNIX sockets in ZOOM.
+
 Solaris recv sometimes returns errno == ENOENT. It is treated as
 EINPROGRESS. COMSTACK patch by Ko van der Sloot.
 
index bcf0d28..440077e 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
-# $Id: buildconf.sh,v 1.12 2002-05-13 18:34:53 adam Exp $
-aclocal 
+# $Id: buildconf.sh,v 1.13 2002-07-25 12:52:52 adam Exp $
+aclocal
 libtoolize --automake --force 
 automake -a 
 autoconf
index 8a7424f..ed14f02 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1995-2002, Index Data
  * See the file LICENSE for details.
  *
- * $Id: client.c,v 1.161 2002-07-12 12:20:34 ja7 Exp $
+ * $Id: client.c,v 1.162 2002-07-25 12:52:53 adam Exp $
  */
 
 #include <stdio.h>
@@ -306,10 +306,11 @@ static int process_initResponse(Z_InitResponse *res)
                char *charset=NULL, *lang=NULL;
                int selected;
                
-               yaz_get_response_charneg(session_mem, p, &charset, &lang, &selected);
+               yaz_get_response_charneg(session_mem, p, &charset, &lang,
+                                     &selected);
                
-               printf("Accepted character set : `%s'\n", charset);
-               printf("Accepted code language : `%s'\n", lang);
+               printf("Accepted character set : %s\n", charset);
+               printf("Accepted code language : %s\n", lang ? lang : "none");
                printf("Accepted records in ...: %d\n", selected );
        }
     }
@@ -901,11 +902,23 @@ static void display_queryExpression (Z_QueryExpression *qe)
         if (qe->u.term->queryTerm)
         {
             Z_Term *term = qe->u.term->queryTerm;
-            if (term->which == Z_Term_general)
+            switch (term->which)
+            {
+            case Z_Term_general:
                 printf (" %.*s", term->u.general->len, term->u.general->buf);
+                break;
+            case Z_Term_characterString:
+                printf (" %s", term->u.characterString);
+                break;
+            case Z_Term_numeric:
+                printf (" %d", *term->u.numeric);
+                break;
+            case Z_Term_null:
+                printf (" null");
+                break;
+            }
         }
     }
-
 }
 
 /* see if we can find USR:SearchResult-1 */
@@ -2114,17 +2127,24 @@ int cmd_proxy(char* arg)
 
 int cmd_charset(char* arg)
 {
-    if (*arg == '\0') {
-       printf("Current character set is `%s'\n", (yazCharset)?yazCharset:NULL);
+    char l1[30], l2[30];
+
+    *l1 = *l2 = 0;
+    if (sscanf(arg, "%29s %29s", l1, l2) < 1)
+    {
+       printf("Current character set is `%s'\n", (yazCharset) ?
+               yazCharset:NULL);
        return 1;
     }
     xfree (yazCharset);
     yazCharset = NULL;
-    if (*arg)
+    if (*l1)
+        yazCharset = xstrdup(l1);
+    if (*l2)
     {
-        yazCharset = (char *) xmalloc (strlen(arg)+1);
-        strcpy (yazCharset, arg);
-    } 
+        odr_set_charset (out, l1, l2);
+        odr_set_charset (in, l2, l1);
+    }
     return 1;
 }
 
index e8d8bc2..a8e6c81 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995-2001, Index Data.
+ * Copyright (c) 1995-2002, Index Data.
  *
  * Permission to use, copy, modify, distribute, and sell this software and
  * its documentation, in whole or in part, for any purpose, is hereby granted,
  * OF THIS SOFTWARE.
  *
  * $Log: backend.h,v $
- * Revision 1.14  2002-03-20 14:36:00  adam
+ * Revision 1.15  2002-07-25 12:52:53  adam
+ * Character set negotiation updates
+ *
+ * Revision 1.14  2002/03/20 14:36:00  adam
  * Additional Search Info for GFS
  *
  * Revision 1.13  2002/03/05 12:45:49  mike
@@ -285,6 +288,12 @@ typedef struct bend_initrequest
     int (*bend_delete)(void *handle, bend_delete_rr *rr);
     int (*bend_scan)(void *handle, bend_scan_rr *rr);
     int (*bend_segment)(void *handle, bend_segment_rr *rr);
+
+    ODR decode;                 /* decoding stream */
+    /* character set and language negotiation - see include/yaz/z-charneg.h */
+    Z_CharSetandLanguageNegotiation *charneg_request;
+    Z_External *charneg_response;
+
 } bend_initrequest;
 
 typedef struct bend_initresult
index 3c6ada6..b8c78a5 100644 (file)
@@ -23,7 +23,7 @@
  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  * OF THIS SOFTWARE.
  *
- * $Id: data1.h,v 1.13 2002-07-05 16:04:28 adam Exp $
+ * $Id: data1.h,v 1.14 2002-07-25 12:52:53 adam Exp $
  */
 
 #ifndef DATA1_H
@@ -211,6 +211,7 @@ typedef struct data1_absyn
     data1_marctab *marc;
     data1_sub_elements *sub_elements;
     data1_element *main_elements;
+    char *encoding;
 } data1_absyn;
 
 /*
@@ -473,6 +474,8 @@ YAZ_EXPORT int data1_iconv (data1_handle dh, NMEM m, data1_node *n,
                             const char *tocode, 
                             const char *fromcode);
 
+YAZ_EXPORT const char *data1_get_encoding (data1_handle dh, data1_node *n);
+
 YAZ_END_CDECL
 
 #endif
index 6d9bb23..9e4d41b 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: d1_absyn.c,v $
- * Revision 1.31  2002-04-04 20:49:46  adam
+ * Revision 1.32  2002-07-25 12:52:53  adam
+ * Character set negotiation updates
+ *
+ * Revision 1.31  2002/04/04 20:49:46  adam
  * New functions yaz_is_abspath, yaz_path_fopen_base
  *
  * Revision 1.30  2000/12/05 19:07:24  adam
@@ -429,6 +432,7 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
     res->name = 0;
     res->reference = VAL_NONE;
     res->tagset = 0;
+    res->encoding = 0;
     tagset_childp = &res->tagset;
 
     res->attset = data1_empty_attset (dh);
@@ -769,6 +773,16 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
            }
            marcp = &(*marcp)->next;
        }
+       else if (!strcmp(cmd, "encoding"))
+       {
+           if (argc != 2)
+           {
+               yaz_log(LOG_WARN, "%s:%d: Bad # or args for encoding",
+                    file, lineno);
+               continue;
+           }
+            res->encoding = nmem_strdup (data1_nmem_get(dh), argv[1]);
+       }
        else
        {
            yaz_log(LOG_WARN, "%s:%d: Unknown directive '%s'", file, lineno, cmd);
index 556f006..4d09049 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 2002, Index Data.
  * See the file LICENSE for details.
  *
- * $Id: d1_expat.c,v 1.5 2002-07-11 10:39:49 adam Exp $
+ * $Id: d1_expat.c,v 1.6 2002-07-25 12:52:53 adam Exp $
  */
 
 #if HAVE_EXPAT_H
@@ -79,7 +79,7 @@ static void cb_decl (void *user, const char *version, const char*encoding,
     attr_list[1] = version;
 
     attr_list[2] = "encoding";
-    attr_list[3] = encoding;
+    attr_list[3] = "UTF-8"; /* encoding */
 
     attr_list[4] = "standalone";
     attr_list[5] = standalone  ? "yes" : "no";
index cea1dba..5432b0f 100644 (file)
@@ -3,7 +3,7 @@
  * See the file LICENSE for details.
  * Sebastian Hammer, Adam Dickmeiss
  *
- * $Id: d1_grs.c,v 1.23 2002-07-11 10:40:34 adam Exp $
+ * $Id: d1_grs.c,v 1.24 2002-07-25 12:52:53 adam Exp $
  *
  */
 
@@ -125,7 +125,7 @@ static Z_ElementData *nodetoelementdata(data1_handle dh, data1_node *n,
        res->which = Z_ElementData_elementNotThere;
        res->u.elementNotThere = odr_nullval();
     }
-    else if (n->which == DATA1N_data && (leaf || n->next == NULL))
+    else if (n->which == DATA1N_data && leaf)
     {
        char str[512];
        int toget;
@@ -144,8 +144,6 @@ static Z_ElementData *nodetoelementdata(data1_handle dh, data1_node *n,
             break;
         case DATA1I_text:
             toget = n->u.data.len;
-            if (p && p->u.tag.get_bytes > 0 && p->u.tag.get_bytes < toget)
-                toget = p->u.tag.get_bytes;
             res->which = Z_ElementData_string;
             res->u.string = (char *)odr_malloc(o, toget+1);
             memcpy(res->u.string, n->u.data.data, toget);
@@ -173,6 +171,21 @@ static Z_ElementData *nodetoelementdata(data1_handle dh, data1_node *n,
     return res;
 }
 
+static int is_empty_data (data1_node *n)
+{
+    if (n && n->which == DATA1N_data && n->u.data.what == DATA1I_text)
+    {
+        int i = n->u.data.len;
+        
+        while (i > 0 && n->u.data.data[i-1] == '\n')
+            i--;
+        if (i == 0)
+            return 1;
+    }
+    return 0;
+}
+
+
 static Z_TaggedElement *nodetotaggedelement(data1_handle dh, data1_node *n,
                                            int select, ODR o,
                                            int *len)
@@ -187,7 +200,20 @@ static Z_TaggedElement *nodetotaggedelement(data1_handle dh, data1_node *n,
        if (n->u.tag.element)
            tag = n->u.tag.element->tag;
        data = n->child;
-       leaf = 0;
+
+        /* skip empty data children */
+        while (is_empty_data(data))
+            data = data->next;
+        if (!data)
+            data = n->child;
+        else
+        {   /* got one. see if this is the only non-empty one */
+            data1_node *sub = data->next;
+            while (sub && is_empty_data(sub))
+                sub = sub->next;
+            if (!sub)
+                leaf = 1;  /* all empty. 'data' is the only child */
+        }
     }
     /*
      * If we're a data element at this point, we need to insert a
@@ -204,6 +230,8 @@ static Z_TaggedElement *nodetotaggedelement(data1_handle dh, data1_node *n,
        }
        data = n;
        leaf = 1;
+        if (is_empty_data(data))
+            return 0;
     }
     else
     {
index fc0127a..bb054ac 100644 (file)
@@ -3,7 +3,7 @@
  * See the file LICENSE for details.
  * Sebastian Hammer, Adam Dickmeiss
  *
- * $Id: d1_marc.c,v 1.20 2002-07-03 14:09:34 adam Exp $
+ * $Id: d1_marc.c,v 1.21 2002-07-25 12:52:53 adam Exp $
  */
 
 
@@ -144,6 +144,7 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file)
     return res;
 }
 
+
 /*
  * Locate some data under this node. This routine should handle variants
  * prettily.
@@ -151,21 +152,30 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file)
 static char *get_data(data1_node *n, int *len)
 {
     char *r;
+    data1_node *np = 0;
 
-    while (n->which != DATA1N_data && n->child)
-       n = n->child;
-    if (n->which != DATA1N_data || 
-       (n->u.data.what != DATA1I_text && n->u.data.what != DATA1I_num))
+    while (n)
     {
-       r = "[Structured/included data]";
-       *len = strlen(r);
-       return r;
+        if (n->which == DATA1N_data)
+        {
+            *len = n->u.data.len;
+            while (*len && d1_isspace(n->u.data.data[*len - 1]))
+                (*len)--;
+            if (*len != 0)
+                return n->u.data.data;
+        }
+        if (n->which == DATA1N_tag)
+            np = n->child;
+        n = n->next;
+        if (!n)
+        {
+            n = np;
+            np = 0;
+        }
     }
-
-    *len = n->u.data.len;
-    while (*len && d1_isspace(n->u.data.data[*len - 1]))
-       (*len)--;
-    return n->u.data.data;
+    r = "";
+    *len = strlen(r);
+    return r;
 }
 
 static void memint (char *p, int val, int len)
index e79ad72..4926ec1 100644 (file)
@@ -3,7 +3,7 @@
  * See the file LICENSE for details.
  * Sebastian Hammer, Adam Dickmeiss
  *
- * $Id: d1_read.c,v 1.45 2002-07-05 16:04:28 adam Exp $
+ * $Id: d1_read.c,v 1.46 2002-07-25 12:52:53 adam Exp $
  */
 
 #include <assert.h>
@@ -834,7 +834,7 @@ static int conv_item (NMEM m, iconv_t t,
 }
 
 static void data1_iconv_s (data1_handle dh, NMEM m, data1_node *n,
-                           iconv_t t, WRBUF wrbuf)
+                           iconv_t t, WRBUF wrbuf, const char *tocode)
 {
     for (; n; n = n->next)
     {
@@ -872,24 +872,55 @@ static void data1_iconv_s (data1_handle dh, NMEM m, data1_node *n,
                 }
             }
             break;
+        case DATA1N_preprocess:
+            if (strcmp(n->u.preprocess.target, "xml") == 0)
+            {
+                data1_xattr *p = n->u.preprocess.attributes;
+                for (; p; p = p->next)
+                    if (strcmp (p->name, "encoding") == 0)
+                        p->value = nmem_strdup (m, tocode);
+            }
+            break;
         }
-        data1_iconv_s (dh, m, n->child, t, wrbuf);
+        data1_iconv_s (dh, m, n->child, t, wrbuf, tocode);
     }
 }
 #endif
 
+const char *data1_get_encoding (data1_handle dh, data1_node *n)
+{
+    /* see if we have an xml header that specifies encoding */
+    if (n && n->child && n->child->which == DATA1N_preprocess &&
+        strcmp (n->child->u.preprocess.target, "xml") == 0)
+    {
+        data1_xattr *xp = n->child->u.preprocess.attributes;
+        for (; xp; xp = xp->next)
+            if (!strcmp (xp->name, "encoding") == 0)
+                return xp->value;
+    }
+    /* no encoding in header, so see if "encoding" was specified for abs */
+    if (n && n->which == DATA1N_root &&
+        n->u.root.absyn && n->u.root.absyn->encoding)
+        return n->u.root.absyn->encoding;
+    /* none of above, return a hard coded default */
+    return "ISO-8859-1";
+}
+
 int data1_iconv (data1_handle dh, NMEM m, data1_node *n,
                   const char *tocode, 
                   const char *fromcode)
 {
 #if HAVE_ICONV_H
-    WRBUF wrbuf = wrbuf_alloc();
-    iconv_t t = iconv_open (tocode, fromcode);
-    if (t == (iconv_t) (-1))
-        return -1;
-    data1_iconv_s (dh, m, n, t, wrbuf);
-    iconv_close (t);
-    wrbuf_free (wrbuf, 1);
+    if (strcmp (tocode, fromcode))
+    {
+        WRBUF wrbuf = wrbuf_alloc();
+        iconv_t t = iconv_open (tocode, fromcode);
+        if (t == (iconv_t) (-1))
+            return -1;
+        data1_iconv_s (dh, m, n, t, wrbuf, tocode);
+        iconv_close (t);
+        wrbuf_free (wrbuf, 1);
+    }
     return 0;
 #else
     return -2;
index 1e80c6b..69d8db6 100644 (file)
@@ -3,7 +3,7 @@
  * See the file LICENSE for details.
  * Sebastian Hammer, Adam Dickmeiss
  *
- * $Id: d1_write.c,v 1.14 2002-07-05 12:42:52 adam Exp $
+ * $Id: d1_write.c,v 1.15 2002-07-25 12:52:53 adam Exp $
  */
 
 #include <string.h>
@@ -24,10 +24,50 @@ static int wordlen(char *b, int max)
     return l;
 }
 
-static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col)
+static void indent (WRBUF b, int col)
+{
+    int i;
+    for (i = 0; i<col; i++)
+        wrbuf_putc (b, ' ');
+}
+
+static void wrbuf_write_cdata(WRBUF b, const char *msg, int len)
+{
+    int i;
+
+    for (i = 0; i < len; i++)
+    {
+        switch (msg[i])
+        {
+        case '"':
+            wrbuf_puts (b, "&quot;");
+            break;
+        case '>':
+            wrbuf_puts (b, "&gt;");
+            break;
+        case '<':
+            wrbuf_puts (b, "&lt;");
+            break;
+#if 0
+        case '&':
+            wrbuf_puts (b, "&amp;");
+            break;
+#endif
+        default:
+            wrbuf_putc(b, msg[i]);
+        }
+    }
+}
+
+static void wrbuf_put_cdata(WRBUF b, const char *msg)
+{
+    wrbuf_write_cdata (b, msg, strlen(msg));
+}
+
+static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col,
+                        int pretty_format)
 {
     data1_node *c;
-    char line[1024];
 
     for (c = n->child; c; c = c->next)
     {
@@ -36,25 +76,24 @@ static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col)
         if (c->which == DATA1N_preprocess)
         {
             data1_xattr *p;
-           
-#if PRETTY_FORMAT
-            sprintf (line, "%*s", col, "");
-            wrbuf_puts (b, line);
-#endif
+
+            if (pretty_format)
+                indent (b, col);
            wrbuf_puts (b, "<?");
-            wrbuf_puts (b, c->u.preprocess.target);
+            wrbuf_put_cdata (b, c->u.preprocess.target);
             for (p = c->u.preprocess.attributes; p; p = p->next)
             {
                 wrbuf_putc (b, ' ');
-                wrbuf_puts (b, p->name);
+                wrbuf_put_cdata (b, p->name);
                 wrbuf_putc (b, '=');
                 wrbuf_putc (b, '"');
-                wrbuf_puts (b, p->value);
+                wrbuf_put_cdata (b, p->value);
                 wrbuf_putc (b, '"');
             }
             if (c->child)
                 wrbuf_puts(b, " ");
-            if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2) < 0)
+            if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2,
+                             pretty_format) < 0)
                 return -1;
             wrbuf_puts (b, "?>\n");
         }
@@ -65,44 +104,39 @@ static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col)
             tag = c->u.tag.tag;
            if (!data1_matchstr(tag, "wellknown")) /* skip wellknown */
            {
-               if (nodetoidsgml(c, select, b, col) < 0)
+               if (nodetoidsgml(c, select, b, col, pretty_format) < 0)
                    return -1;
            }
            else
            {
                data1_xattr *p;
 
-#if PRETTY_FORMAT
-               sprintf (line, "%*s", col, "");
-               wrbuf_puts (b, line);
-#endif
+                if (pretty_format)
+                    indent (b, col);
                wrbuf_puts (b, "<");    
-               wrbuf_puts (b, tag);
+               wrbuf_put_cdata (b, tag);
                for (p = c->u.tag.attributes; p; p = p->next)
                {
                    wrbuf_putc (b, ' ');
-                   wrbuf_puts (b, p->name);
+                   wrbuf_put_cdata (b, p->name);
                    wrbuf_putc (b, '=');
                    wrbuf_putc (b, '"');
-                   wrbuf_puts (b, p->value);
+                   wrbuf_put_cdata (b, p->value);
                    wrbuf_putc (b, '"');
                }
                wrbuf_puts(b, ">");
-#if PRETTY_FORMAT
-               wrbuf_puts(b, "\n");
-#endif
-               if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2) < 0)
+                if (pretty_format)
+                    wrbuf_puts(b, "\n");
+               if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2,
+                                 pretty_format) < 0)
                    return -1;
-#if PRETTY_FORMAT
-               sprintf (line, "%*s", col);
-               wrbuf_puts(b, line);
-#endif
+                if (pretty_format)
+                    indent (b, col);
                wrbuf_puts(b, "</");
-               wrbuf_puts(b, tag);
+               wrbuf_put_cdata(b, tag);
                wrbuf_puts(b, ">");
-#if PRETTY_FORMAT
-               wrbuf_puts (b, "\n");
-#endif
+                if (pretty_format)
+                    wrbuf_puts (b, "\n");
            }
        }
        else if (c->which == DATA1N_data || c->which == DATA1N_comment)
@@ -112,24 +146,16 @@ static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col)
            int first = 1;
            int lcol = col;
 
-#if PRETTY_FORMAT
-            if (!c->u.data.formatted_text)
-            {
-                sprintf(line, "%*s", col, "");
-                wrbuf_write(b, line, strlen(line));
-            }
-#endif
+            if (pretty_format && !c->u.data.formatted_text)
+                indent (b, col);
             if (c->which == DATA1N_comment)
-            {
-                wrbuf_write (b, "<!--", 4);
-            }
+                wrbuf_puts (b, "<!--");
            switch (c->u.data.what)
            {
            case DATA1I_text:
-#if PRETTY_FORMAT
-                if (c->u.data.formatted_text)
+                if (!pretty_format || c->u.data.formatted_text)
                 {
-                    wrbuf_write (b, p, l);
+                    wrbuf_write_cdata (b, p, l);
                 }
                 else
                 {
@@ -145,9 +171,9 @@ static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col)
                         if (lcol + (wlen = wordlen(p, l)) > IDSGML_MARGIN &&
                             wlen < IDSGML_MARGIN)
                         {
-                            sprintf(line, "\n%*s", col, "");
+                            wrbuf_puts (b, "\n");
+                            indent (b, col);
                             lcol = col;
-                            wrbuf_write(b, line, strlen(line));
                             first = 1;
                         }
                         if (!first)
@@ -164,30 +190,24 @@ static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col)
                         }
                         first = 0;
                     }
-                    wrbuf_write(b, "\n", 1);
+                    wrbuf_puts(b, "\n");
                 }
-#else
-                wrbuf_write (b, p, l);
-#endif
                break;
            case DATA1I_num:
-               wrbuf_write(b, c->u.data.data, c->u.data.len);
-#if PRETTY_FORMAT
-                wrbuf_puts(b, "\n");
-#endif
+               wrbuf_write_cdata(b, c->u.data.data, c->u.data.len);
+                if (pretty_format)
+                    wrbuf_puts(b, "\n");
                break;
            case DATA1I_oid:
-               wrbuf_write(b, c->u.data.data, c->u.data.len);
-#if PRETTY_FORMAT
-                wrbuf_puts(b, "\n");
-#endif
+               wrbuf_write_cdata(b, c->u.data.data, c->u.data.len);
+                if (pretty_format)
+                    wrbuf_puts(b, "\n");
            }
             if (c->which == DATA1N_comment)
             {
                 wrbuf_puts(b, "-->");
-#if PRETTY_FORMAT
-                wrbuf_puts(b, "\n");
-#endif
+                if (pretty_format)
+                    wrbuf_puts(b, "\n");
             }
        }
     }
@@ -200,7 +220,7 @@ char *data1_nodetoidsgml (data1_handle dh, data1_node *n, int select, int *len)
     
     wrbuf_rewind(b);
     
-    if (nodetoidsgml(n, select, b, 0))
+    if (nodetoidsgml(n, select, b, 0, 0 /* no pretty format */))
        return 0;
     *len = wrbuf_len(b);
     return wrbuf_buf(b);
index 2be36c1..a9e17fa 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1995-2002, Index Data
  * See the file LICENSE for details.
  *
- * $Id: seshigh.c,v 1.130 2002-06-18 21:30:39 adam Exp $
+ * $Id: seshigh.c,v 1.131 2002-07-25 12:52:54 adam Exp $
  */
 
 /*
@@ -46,6 +46,8 @@
 #include <yaz/logrpn.h>
 #include <yaz/statserv.h>
 #include <yaz/diagbib1.h>
+#include <yaz/charneg.h>
+#include <yaz/otherinfo.h>
 
 #include <yaz/backend.h>
 
@@ -358,6 +360,8 @@ void ir_session(IOCHAN h, int event)
                iochan_clearflag(h, EVENT_OUTPUT|EVENT_INPUT);
                iochan_setflag(h, assoc->cs_get_mask);
            }
+            else
+                assoc->cs_put_mask = EVENT_OUTPUT;
            break;
        default:
            if (conn->io_pending & CS_WANT_WRITE)
@@ -574,7 +578,8 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
     Z_APDU *apdu = zget_APDU(assoc->encode, Z_APDU_initResponse);
     Z_InitResponse *resp = apdu->u.initResponse;
     bend_initresult *binitres;
-    char options[100];
+
+    char options[140];
 
     xfree (assoc->init);
     assoc->init = (bend_initrequest *) xmalloc (sizeof(*assoc->init));
@@ -602,6 +607,17 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
     assoc->init->bend_scan = NULL;
     assoc->init->bend_segment = NULL;
     assoc->init->bend_fetch = NULL;
+    assoc->init->charneg_request = NULL;
+    assoc->init->charneg_response = NULL;
+    assoc->init->decode = assoc->decode;
+
+    if (ODR_MASK_GET(req->options, Z_Options_negotiationModel))
+    {
+        Z_CharSetandLanguageNegotiation *negotiation =
+            yaz_get_charneg_record (req->otherInfo);
+        if (negotiation->which == Z_CharSetandLanguageNegotiation_proposal)
+            assoc->init->charneg_request = negotiation;
+    }
     
     assoc->init->peer_name =
        odr_strdup (assoc->encode, cs_addrstr(assoc->client_link));
@@ -665,13 +681,33 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
     if (ODR_MASK_GET(req->options, Z_Options_concurrentOperations))
     {
        ODR_MASK_SET(resp->options, Z_Options_concurrentOperations);
-       strcat(options, " concurop");
+       strcat(options, " concurrop");
     }
     if (ODR_MASK_GET(req->options, Z_Options_sort) && assoc->init->bend_sort)
     {
        ODR_MASK_SET(resp->options, Z_Options_sort);
        strcat(options, " sort");
     }
+
+    if (ODR_MASK_GET(req->options, Z_Options_negotiationModel)
+        && assoc->init->charneg_response)
+    {
+       Z_OtherInformation **p;
+       Z_OtherInformationUnit *p0;
+       
+       yaz_oi_APDU(apdu, &p);
+       
+       if ((p0=yaz_oi_update(p, assoc->encode, NULL, 0, 0))) {
+            ODR_MASK_SET(resp->options, Z_Options_negotiationModel);
+            
+            p0->which = Z_OtherInfo_externallyDefinedInfo;
+            p0->information.externallyDefinedInfo =
+                assoc->init->charneg_response;
+        }
+       ODR_MASK_SET(resp->options, Z_Options_negotiationModel);
+       strcat(options, " negotiation");
+    }
+
     if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_1))
     {
        ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_1);
@@ -687,6 +723,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
        ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_3);
        assoc->version = 3;
     }
+
     yaz_log(LOG_LOG, "Negotiated to v%d: %s", assoc->version, options);
     assoc->maximumRecordSize = *req->maximumRecordSize;
     if (assoc->maximumRecordSize > control_block->maxrecordsize)
index 8eb4fa5..3e37755 100644 (file)
@@ -1,4 +1,4 @@
-; $Id: yaz.nsi,v 1.8 2002-06-05 21:10:16 adam Exp $
+; $Id: yaz.nsi,v 1.9 2002-07-25 12:52:54 adam Exp $
 
 !define VERSION "1.8.8"
 
@@ -98,6 +98,7 @@ Section "YAZ Source"
        File ..\util\*.tcl
        SetOutPath $INSTDIR\odr
        File ..\odr\*.c
+       File ..\odr\*.h
        SetOutPath $INSTDIR\z39.50
        File ..\z39.50\*.c
        File ..\z39.50\*.asn