Treat field as having subfields even if first char is blank/other
[yaz-moved-to-github.git] / src / marcdisp.c
index 1266d25..1b02e11 100644 (file)
@@ -1,8 +1,13 @@
 /*
- * Copyright (c) 1995-2003, Index Data
+ * Copyright (c) 1995-2004, Index Data
  * See the file LICENSE for details.
  *
- * $Id: marcdisp.c,v 1.3 2003-12-17 12:28:07 adam Exp $
+ * $Id: marcdisp.c,v 1.9 2004-11-25 09:43:10 adam Exp $
+ */
+
+/**
+ * \file marcdisp.c
+ * \brief Implements MARC display - and conversion utilities
  */
 
 #if HAVE_CONFIG_H
@@ -43,56 +48,12 @@ void yaz_marc_destroy(yaz_marc_t mt)
 
 static void marc_cdata (yaz_marc_t mt, const char *buf, size_t len, WRBUF wr)
 {
-    size_t i;
     if (mt->xml == YAZ_MARC_ISO2709)
-    {
        wrbuf_iconv_write(wr, mt->iconv_cd, buf, len);
-    }
     else if (mt->xml == YAZ_MARC_LINE)
-    {
        wrbuf_iconv_write(wr, mt->iconv_cd, buf, len);
-    }
     else
-    {
-       int j = 0;
-       for (i = 0; i<len; i++)
-       {
-           switch (buf[i]) {
-           case '<':
-               if (i > j)
-                   wrbuf_iconv_write(wr, mt->iconv_cd, buf+j, i-j);
-               wrbuf_puts(wr, "&lt;");
-               j=i+1;
-               break;
-           case '>':
-               if (i > j)
-                   wrbuf_iconv_write(wr, mt->iconv_cd, buf+j, i-j);
-               wrbuf_puts(wr, "&gt;");
-               j=i+1;
-               break;
-           case '&':
-               if (i > j)
-                   wrbuf_iconv_write(wr, mt->iconv_cd, buf+j, i-j);
-               wrbuf_puts(wr, "&amp;");
-               j=i+1;
-                break;
-           case '"':
-               if (i > j)
-                   wrbuf_iconv_write(wr, mt->iconv_cd, buf+j, i-j);
-               wrbuf_puts(wr, "&quot;");
-               j=i+1;
-               break;
-           case '\'':
-               if (i > j)
-                   wrbuf_iconv_write(wr, mt->iconv_cd, buf+j, i-j);
-               wrbuf_puts(wr, "&apos;");
-               j=i+1;
-               break;
-            }
-       }
-       if (i > j)
-           wrbuf_iconv_write(wr, mt->iconv_cd, buf+j, i-j);
-    }
+       wrbuf_iconv_write_cdata(wr, mt->iconv_cd, buf, len);
 }
 
 int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr)
@@ -177,7 +138,15 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr)
             wrbuf_printf(
                 wr,
                 "<record xmlns=\"http://www.loc.gov/MARC21/slim\">\n"
-                "  <leader>%.24s</leader>\n", buf);
+                "  <leader>");
+#if 1
+           marc_cdata(mt, buf, 9, wr);
+           marc_cdata(mt, "a", 1, wr);  /* set leader to signal unicode */
+           marc_cdata(mt, buf+10, 14, wr);
+#else
+           marc_cdata(mt, buf, 24, wr); /* leave header as is .. */
+#endif
+            wrbuf_printf(wr, "</leader>\n");
             break;
         }
     }
@@ -278,7 +247,7 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr)
        int end_offset;
        int i, j;
        char tag[4];
-        int identifier_flag = 1;
+        int identifier_flag = 0;
 
         memcpy (tag, buf+entry_p, 3);
        entry_p += 3;
@@ -292,11 +261,13 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr)
         
         if (indicator_length < 4 && indicator_length > 0)
         {
-            if (buf[i + indicator_length] != ISO2709_IDFS)
-                identifier_flag = 0;
+           if (buf[i + indicator_length] == ISO2709_IDFS)
+               identifier_flag = 1;
+           else if (buf[i + indicator_length + 1] == ISO2709_IDFS)
+               identifier_flag = 2;
         }
-        else if (!memcmp (tag, "00", 2))
-            identifier_flag = 0;
+        else if (memcmp (tag, "00", 2))
+            identifier_flag = 1;
         
         switch(mt->xml)
         {
@@ -307,23 +278,30 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr)
             wrbuf_puts (wr, " ");
             break;
         case YAZ_MARC_SIMPLEXML:
-            wrbuf_printf (wr, "<field tag=\"%s\"", tag);
+            wrbuf_printf (wr, "<field tag=\"");
+           marc_cdata(mt, tag, strlen(tag), wr);
+           wrbuf_printf(wr, "\"");
             break;
         case YAZ_MARC_OAIMARC:
             if (identifier_flag)
-                wrbuf_printf (wr, "  <varfield id=\"%s\"", tag);
+                wrbuf_printf (wr, "  <varfield id=\"");
             else
-                wrbuf_printf (wr, "  <fixfield id=\"%s\"", tag);
+                wrbuf_printf (wr, "  <fixfield id=\"");
+           marc_cdata(mt, tag, strlen(tag), wr);
+           wrbuf_printf(wr, "\"");
             break;
         case YAZ_MARC_MARCXML:
             if (identifier_flag)
-                wrbuf_printf (wr, "  <datafield tag=\"%s\"", tag);
+                wrbuf_printf (wr, "  <datafield tag=\"");
             else
-                wrbuf_printf (wr, "  <controlfield tag=\"%s\"", tag);
+                wrbuf_printf (wr, "  <controlfield tag=\"");
+           marc_cdata(mt, tag, strlen(tag), wr);
+           wrbuf_printf(wr, "\"");
         }
         
         if (identifier_flag)
        {
+           i += identifier_flag-1;
             for (j = 0; j<indicator_length; j++, i++)
             {
                 switch(mt->xml)
@@ -337,13 +315,19 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr)
                     wrbuf_putc(wr, buf[i]);
                     break;
                 case YAZ_MARC_SIMPLEXML:
-                    wrbuf_printf(wr, " Indicator%d=\"%c\"", j+1, buf[i]);
+                    wrbuf_printf(wr, " Indicator%d=\"", j+1);
+                   marc_cdata(mt, buf+i, 1, wr);
+                    wrbuf_printf(wr, "\"");
                     break;
                 case YAZ_MARC_OAIMARC:
-                    wrbuf_printf(wr, " i%d=\"%c\"", j+1, buf[i]);
+                    wrbuf_printf(wr, " i%d=\"", j+1);
+                   marc_cdata(mt, buf+i, 1, wr);
+                    wrbuf_printf(wr, "\"");
                     break;
                 case YAZ_MARC_MARCXML:
-                    wrbuf_printf(wr, " ind%d=\"%c\"", j+1, buf[i]);
+                    wrbuf_printf(wr, " ind%d=\"", j+1);
+                   marc_cdata(mt, buf+i, 1, wr);
+                    wrbuf_printf(wr, "\"");
                 }
             }
        }
@@ -375,26 +359,26 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr)
                    break;
                 case YAZ_MARC_LINE: 
                     wrbuf_puts (wr, " $"); 
-                    for (j = 1; j<identifier_length; j++, i++)
-                        wrbuf_putc (wr, buf[i]);
+                   marc_cdata(mt, buf+i, identifier_length-1, wr);
+                   i = i+identifier_length-1;
                     wrbuf_putc (wr, ' ');
                     break;
                 case YAZ_MARC_SIMPLEXML:
                     wrbuf_puts (wr, "  <subfield code=\"");
-                    for (j = 1; j<identifier_length; j++, i++)
-                        wrbuf_putc (wr, buf[i]);
+                   marc_cdata(mt, buf+i, identifier_length-1, wr);
+                   i = i+identifier_length-1;
                     wrbuf_puts (wr, "\">");
                     break;
                 case YAZ_MARC_OAIMARC:
                     wrbuf_puts (wr, "    <subfield label=\"");
-                    for (j = 1; j<identifier_length; j++, i++)
-                        wrbuf_putc (wr, buf[i]);
+                   marc_cdata(mt, buf+i, identifier_length-1, wr);
+                   i = i+identifier_length-1;
                     wrbuf_puts (wr, "\">");
                     break;
                 case YAZ_MARC_MARCXML:
                     wrbuf_puts (wr, "    <subfield code=\"");
-                    for (j = 1; j<identifier_length; j++, i++)
-                        wrbuf_putc (wr, buf[i]);
+                   marc_cdata(mt, buf+i, identifier_length-1, wr);
+                   i = i+identifier_length-1;
                     wrbuf_puts (wr, "\">");
                     break;
                 }