Use term Windows rather than win32
[yaz-moved-to-github.git] / src / record_conv.c
index 34a3cc3..9ab5b71 100644 (file)
@@ -317,6 +317,38 @@ static void destroy_xslt(void *vinfo)
 /* YAZ_HAVE_XSLT */
 #endif
 
+static void *construct_solrmarc(const xmlNode *ptr,
+                                const char *path, WRBUF wr_error)
+{
+    if (strcmp((const char *) ptr->name, "solrmarc"))
+        return 0;
+    return wr_error; /* any non-null ptr will do; we don't use it later*/
+}
+
+static int convert_solrmarc(void *info, WRBUF record, WRBUF wr_error)
+{
+    WRBUF w = wrbuf_alloc();
+    const char *buf = wrbuf_buf(record);
+    size_t i, sz = wrbuf_len(record);
+    for (i = 0; i < sz; i++)
+    {
+        int ch;
+        if (buf[i] == '#' && i < sz - 3 && buf[i+3] == ';'
+            && atoi_n_check(buf+i+1, 2, &ch))
+            i += 3;
+        else
+            ch = buf[i];
+        wrbuf_putc(w, ch);
+    }
+    wrbuf_rewind(record);
+    wrbuf_write(record, wrbuf_buf(w), wrbuf_len(w));
+    wrbuf_destroy(w);
+    return 0;
+}
+
+static void destroy_solrmarc(void *info)
+{
+}
 
 static void *construct_marc(const xmlNode *ptr,
                             const char *path, WRBUF wr_error)
@@ -332,7 +364,6 @@ static void *construct_marc(const xmlNode *ptr,
         nmem_destroy(nmem);
         return 0;
     }
-
     info->nmem = nmem;
     info->input_charset = 0;
     info->output_charset = 0;
@@ -488,23 +519,25 @@ static void *construct_marc(const xmlNode *ptr,
 static int convert_marc(void *info, WRBUF record, WRBUF wr_error)
 {
     struct marc_info *mi = info;
+    const char *input_charset = mi->input_charset;
     int ret = 0;
-
-    yaz_iconv_t cd = yaz_iconv_open(mi->output_charset, mi->input_charset);
     yaz_marc_t mt = yaz_marc_create();
 
     yaz_marc_xml(mt, mi->output_format_mode);
     if (mi->leader_spec)
         yaz_marc_leader_spec(mt, mi->leader_spec);
 
-    if (cd)
-        yaz_marc_iconv(mt, cd);
     if (mi->input_format_mode == YAZ_MARC_ISO2709)
     {
         int sz = yaz_marc_read_iso2709(mt, wrbuf_buf(record),
                                        wrbuf_len(record));
         if (sz > 0)
+        {
+            if (yaz_marc_check_marc21_coding(input_charset, wrbuf_buf(record),
+                                             wrbuf_len(record)))
+                input_charset = "utf-8";
             ret = 0;
+        }
         else
             ret = -1;
     }
@@ -533,13 +566,18 @@ static int convert_marc(void *info, WRBUF record, WRBUF wr_error)
     }
     if (ret == 0)
     {
+        yaz_iconv_t cd = yaz_iconv_open(mi->output_charset, input_charset);
+
+        if (cd)
+            yaz_marc_iconv(mt, cd);
+
         wrbuf_rewind(record);
         ret = yaz_marc_write_mode(mt, record);
         if (ret)
             wrbuf_printf(wr_error, "yaz_marc_write_mode failed");
+        if (cd)
+            yaz_iconv_close(cd);
     }
-    if (cd)
-        yaz_iconv_close(cd);
     yaz_marc_destroy(mt);
     return ret;
 }
@@ -554,24 +592,28 @@ static void destroy_marc(void *info)
 int yaz_record_conv_configure_t(yaz_record_conv_t p, const xmlNode *ptr,
                                 struct yaz_record_conv_type *types)
 {
-    struct yaz_record_conv_type bt[2];
+    struct yaz_record_conv_type bt[3];
+    size_t i = 0;
 
     /* register marc */
-    bt[0].construct = construct_marc;
-    bt[0].convert = convert_marc;
-    bt[0].destroy = destroy_marc;
+    bt[i].construct = construct_marc;
+    bt[i].convert = convert_marc;
+    bt[i++].destroy = destroy_marc;
+
+    bt[i-1].next = &bt[i];
+    bt[i].construct = construct_solrmarc;
+    bt[i].convert = convert_solrmarc;
+    bt[i++].destroy = destroy_solrmarc;
 
 #if YAZ_HAVE_XSLT
     /* register xslt */
-    bt[0].next = &bt[1];
-    bt[1].next = types;
-    bt[1].construct = construct_xslt;
-    bt[1].convert = convert_xslt;
-    bt[1].destroy = destroy_xslt;
-#else
-    bt[0].next = types;
+    bt[i-1].next = &bt[i];
+    bt[i].construct = construct_xslt;
+    bt[i].convert = convert_xslt;
+    bt[i++].destroy = destroy_xslt;
 #endif
 
+    bt[i-1].next = types;
     yaz_record_conv_reset(p);
 
     /* parsing element children */
@@ -645,11 +687,15 @@ int yaz_record_conv_opac_record(yaz_record_conv_t p,
     else
     {
         struct marc_info *mi = r->info;
+        const char *input_charset = mi->input_charset;
+        yaz_iconv_t cd;
 
         WRBUF res = wrbuf_alloc();
         yaz_marc_t mt = yaz_marc_create();
-        yaz_iconv_t cd = yaz_iconv_open(mi->output_charset,
-                                        mi->input_charset);
+
+        if (yaz_opac_check_marc21_coding(input_charset, input_record))
+            input_charset = "utf-8";
+        cd = yaz_iconv_open(mi->output_charset, input_charset);
 
         wrbuf_rewind(p->wr_error);
         yaz_marc_xml(mt, mi->output_format_mode);
@@ -702,9 +748,6 @@ yaz_record_conv_t yaz_record_conv_create()
     p->wr_error = wrbuf_alloc();
     p->rules = 0;
     p->path = 0;
-#if YAZ_HAVE_EXSLT
-    exsltRegisterAll();
-#endif
     return p;
 }