-/*
- * 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: marcdisp.c,v 1.48 2007-03-19 14:40:07 adam Exp $
*/
/**
#include <libxml/tree.h>
#endif
+enum yaz_collection_state {
+ no_collection,
+ collection_first,
+ collection_second
+};
+
/** \brief node types for yaz_marc_node */
enum YAZ_MARC_NODE_TYPE
{
int xml;
int debug;
int write_using_libxml2;
+ enum yaz_collection_state enable_collection;
yaz_iconv_t iconv_cd;
char subfield_str[8];
char endline_str[8];
mt->xml = YAZ_MARC_LINE;
mt->debug = 0;
mt->write_using_libxml2 = 0;
+ mt->enable_collection = no_collection;
mt->m_wr = wrbuf_alloc();
mt->iconv_cd = 0;
mt->leader_spec = 0;
static void marc_iconv_reset(yaz_marc_t mt, WRBUF wr)
{
- if (mt->iconv_cd)
- {
- char outbuf[12];
- size_t outbytesleft = sizeof(outbuf);
- char *outp = outbuf;
- size_t r = yaz_iconv(mt->iconv_cd, 0, 0, &outp, &outbytesleft);
- if (r != (size_t) (-1))
- wrbuf_write(wr, outbuf, outp - outbuf);
- }
+ wrbuf_iconv_reset(wr, mt->iconv_cd);
}
static int marc_exec_leader(const char *leader_spec, char *leader,
static struct yaz_marc_node *yaz_marc_add_node(yaz_marc_t mt)
{
- struct yaz_marc_node *n = nmem_malloc(mt->nmem, sizeof(*n));
+ struct yaz_marc_node *n = (struct yaz_marc_node *)
+ nmem_malloc(mt->nmem, sizeof(*n));
n->next = 0;
*mt->nodes_pp = n;
mt->nodes_pp = &n->next;
if (mt->subfield_pp)
{
- struct yaz_marc_subfield *n = nmem_malloc(mt->nmem, sizeof(*n));
+ struct yaz_marc_subfield *n = (struct yaz_marc_subfield *)
+ nmem_malloc(mt->nmem, sizeof(*n));
n->code_data = nmem_strdupn(mt->nmem, code_data, code_data_len);
n->next = 0;
/* mark subfield_pp to point to this one, so we append here next */
wrbuf_puts(wr, "(");
wrbuf_iconv_write(wr, mt->iconv_cd,
n->u.comment, strlen(n->u.comment));
+ marc_iconv_reset(mt, wr);
wrbuf_puts(wr, ")\n");
break;
case YAZ_MARC_LEADER:
return 0;
}
+int yaz_marc_write_trailer(yaz_marc_t mt, WRBUF wr)
+{
+ if (mt->enable_collection == collection_second)
+ {
+ switch(mt->xml)
+ {
+ case YAZ_MARC_MARCXML:
+ wrbuf_printf(wr, "</collection>\n");
+ break;
+ case YAZ_MARC_XCHANGE:
+ wrbuf_printf(wr, "</collection>\n");
+ break;
+ }
+ }
+ return 0;
+}
+
+void yaz_marc_enable_collection(yaz_marc_t mt)
+{
+ mt->enable_collection = collection_first;
+}
+
int yaz_marc_write_mode(yaz_marc_t mt, WRBUF wr)
{
switch(mt->xml)
return -1;
if (!atoi_n_check(leader+11, 1, &identifier_length))
return -1;
-
- wrbuf_printf(wr, "<record xmlns=\"%s\"", ns);
+
+ if (mt->enable_collection != no_collection)
+ {
+ if (mt->enable_collection == collection_first)
+ wrbuf_printf(wr, "<collection xmlns=\"%s\">\n", ns);
+ mt->enable_collection = collection_second;
+ wrbuf_printf(wr, "<record");
+ }
+ else
+ {
+ wrbuf_printf(wr, "<record xmlns=\"%s\"", ns);
+ }
if (format)
wrbuf_printf(wr, " format=\"%.80s\"", format);
if (type)
wrbuf_iconv_write_cdata(wr, mt->iconv_cd, n->u.controlfield.tag,
strlen(n->u.controlfield.tag));
wrbuf_iconv_puts(wr, mt->iconv_cd, "\">");
- wrbuf_iconv_puts(wr, mt->iconv_cd, n->u.controlfield.data);
+ wrbuf_iconv_write_cdata(wr, mt->iconv_cd,
+ n->u.controlfield.data,
+ strlen(n->u.controlfield.data));
marc_iconv_reset(mt, wr);
wrbuf_iconv_puts(wr, mt->iconv_cd, "</controlfield>");
int yaz_marc_write_marcxml(yaz_marc_t mt, WRBUF wr)
{
+ /* set leader 09 to 'a' for UNICODE */
+ /* http://www.loc.gov/marc/bibliographic/ecbdldrd.html#mrcblea */
if (!mt->leader_spec)
yaz_marc_modify_leader(mt, 9, "a");
return yaz_marc_write_marcxml_ns(mt, wr, "http://www.loc.gov/MARC21/slim",
}
/* write dummy FS (makes MARC-8 to become ASCII) */
wrbuf_iconv_putchar(wr_data_tmp, mt->iconv_cd, ' ');
+ marc_iconv_reset(mt, wr_data_tmp);
data_length += wrbuf_len(wr_data_tmp);
break;
case YAZ_MARC_CONTROLFIELD:
n->u.controlfield.data);
marc_iconv_reset(mt, wr_data_tmp);
wrbuf_iconv_putchar(wr_data_tmp, mt->iconv_cd, ' ');/* field sep */
+ marc_iconv_reset(mt, wr_data_tmp);
data_length += wrbuf_len(wr_data_tmp);
break;
case YAZ_MARC_COMMENT:
mt->iconv_cd = cd;
}
+yaz_iconv_t yaz_marc_get_iconv(yaz_marc_t mt)
+{
+ return mt->iconv_cd;
+}
+
void yaz_marc_modify_leader(yaz_marc_t mt, size_t off, const char *str)
{
struct yaz_marc_node *n;