-/*
- * Copyright (C) 1995-2006, Index Data ApS
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) 1995-2010 Index Data
* See the file LICENSE for details.
- *
- * $Id: marcdisp.c,v 1.34 2006-08-28 14:18:22 adam Exp $
*/
/**
#include <stdarg.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <yaz/marcdisp.h>
#include <yaz/wrbuf.h>
#include <yaz/yaz-util.h>
+#include <yaz/nmem_xml.h>
+#include <yaz/snprintf.h>
#if YAZ_HAVE_XML2
#include <libxml/parser.h>
#include <libxml/tree.h>
#endif
-static void yaz_marc_reset(yaz_marc_t mt);
-
+enum yaz_collection_state {
+ no_collection,
+ collection_first,
+ collection_second
+};
+
/** \brief node types for yaz_marc_node */
enum YAZ_MARC_NODE_TYPE
{
struct yaz_marc_t_ {
WRBUF m_wr;
NMEM nmem;
- int xml;
+ int output_format;
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];
yaz_marc_t yaz_marc_create(void)
{
yaz_marc_t mt = (yaz_marc_t) xmalloc(sizeof(*mt));
- mt->xml = YAZ_MARC_LINE;
+ mt->output_format = 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;
if (!mt)
return ;
nmem_destroy(mt->nmem);
- wrbuf_free(mt->m_wr, 1);
+ wrbuf_destroy(mt->m_wr);
xfree(mt->leader_spec);
xfree(mt);
}
+NMEM yaz_marc_get_nmem(yaz_marc_t mt)
+{
+ return mt->nmem;
+}
+
+static void marc_iconv_reset(yaz_marc_t mt, WRBUF wr)
+{
+ wrbuf_iconv_reset(wr, mt->iconv_cd);
+}
+
static int marc_exec_leader(const char *leader_spec, char *leader,
size_t size);
+static int yaz_marc_write_xml_turbo_xml(yaz_marc_t mt, xmlNode **root_ptr,
+ const char *ns,
+ const char *format,
+ const char *type);
-
-struct yaz_marc_node *yaz_marc_add_node(yaz_marc_t mt)
+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;
return n;
}
+#if YAZ_HAVE_XML2
+void yaz_marc_add_controlfield_xml(yaz_marc_t mt, const xmlNode *ptr_tag,
+ const xmlNode *ptr_data)
+{
+ struct yaz_marc_node *n = yaz_marc_add_node(mt);
+ n->which = YAZ_MARC_CONTROLFIELD;
+ n->u.controlfield.tag = nmem_text_node_cdata(ptr_tag, mt->nmem);
+ n->u.controlfield.data = nmem_text_node_cdata(ptr_data, mt->nmem);
+}
+
+void yaz_marc_add_controlfield_xml2(yaz_marc_t mt, char *tag,
+ const xmlNode *ptr_data)
+{
+ struct yaz_marc_node *n = yaz_marc_add_node(mt);
+ n->which = YAZ_MARC_CONTROLFIELD;
+ n->u.controlfield.tag = tag;
+ n->u.controlfield.data = nmem_text_node_cdata(ptr_data, mt->nmem);
+}
+
+#endif
+
+
void yaz_marc_add_comment(yaz_marc_t mt, char *comment)
{
struct yaz_marc_node *n = yaz_marc_add_node(mt);
{
va_list ap;
char buf[200];
- va_start(ap, fmt);
-#ifdef WIN32
- _vsnprintf(buf, sizeof(buf)-1, fmt, ap);
-#else
-/* !WIN32 */
-#if HAVE_VSNPRINTF
- vsnprintf(buf, sizeof(buf), fmt, ap);
-#else
- vsprintf(buf, fmt, ap);
-#endif
-#endif
-/* WIN32 */
+ va_start(ap, fmt);
+ yaz_vsnprintf(buf, sizeof(buf)-1, fmt, ap);
yaz_marc_add_comment(mt, buf);
va_end (ap);
}
+int yaz_marc_get_debug(yaz_marc_t mt)
+{
+ return mt->debug;
+}
+
void yaz_marc_add_leader(yaz_marc_t mt, const char *leader, size_t leader_len)
{
struct yaz_marc_node *n = yaz_marc_add_node(mt);
}
}
-#if YAZ_HAVE_XML2
-void yaz_marc_add_controlfield_xml(yaz_marc_t mt, const xmlNode *ptr_tag,
- const xmlNode *ptr_data)
-{
- struct yaz_marc_node *n = yaz_marc_add_node(mt);
- n->which = YAZ_MARC_CONTROLFIELD;
- n->u.controlfield.tag = nmem_text_node_cdata(ptr_tag, mt->nmem);
- n->u.controlfield.data = nmem_text_node_cdata(ptr_data, mt->nmem);
-}
-#endif
-
void yaz_marc_add_datafield(yaz_marc_t mt, const char *tag,
const char *indicator, size_t indicator_len)
{
mt->subfield_pp = &n->u.datafield.subfields;
}
+// Magic function: adds a attribute value to the element name if it is plain characters.
+// if not, and if the attribute name is not null, it will append a attribute element with the value
+// if attribute name is null it will return a non-zero value meaning it couldnt handle the value.
+
+int element_name_append_attribute_value(yaz_marc_t mt, WRBUF buffer, const char *attribute_name, char *code_data, size_t code_len)
+{
+ // TODO Map special codes to something possible for XML ELEMENT names
+
+ int encode = 0;
+ int index = 0;
+ int success = 0;
+ for (index = 0; index < code_len; index++)
+ {
+ if (!((code_data[index] >= '0' && code_data[index] <= '9') ||
+ (code_data[index] >= 'a' && code_data[index] <= 'z') ||
+ (code_data[index] >= 'A' && code_data[index] <= 'Z')))
+ encode = 1;
+ }
+ // Add as attribute
+ if (encode && attribute_name)
+ wrbuf_printf(buffer, " %s=\"", attribute_name);
+
+ if (!encode || attribute_name)
+ wrbuf_iconv_write_cdata(buffer, mt->iconv_cd, code_data, code_len);
+ else
+ success = -1;
+
+ if (encode && attribute_name)
+ wrbuf_printf(buffer, "\""); // return error if we couldn't handle it.
+ return success;
+}
+
#if YAZ_HAVE_XML2
void yaz_marc_add_datafield_xml(yaz_marc_t mt, const xmlNode *ptr_tag,
const char *indicator, size_t indicator_len)
/* make subfield_pp the current (last one) */
mt->subfield_pp = &n->u.datafield.subfields;
}
+
+void yaz_marc_add_datafield_xml2(yaz_marc_t mt, char *tag_value, char *indicators)
+{
+ struct yaz_marc_node *n = yaz_marc_add_node(mt);
+ n->which = YAZ_MARC_DATAFIELD;
+ n->u.datafield.tag = tag_value;
+ n->u.datafield.indicator = indicators;
+ n->u.datafield.subfields = 0;
+
+ // make subfield_pp the current (last one)
+ mt->subfield_pp = &n->u.datafield.subfields;
+}
+
+void yaz_marc_datafield_set_indicators(struct yaz_marc_node *n, char *indicator)
+{
+ n->u.datafield.indicator = indicator;
+}
+
#endif
void yaz_marc_add_subfield(yaz_marc_t mt,
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 */
}
}
-static int atoi_n_check(const char *buf, int size, int *val)
-{
- if (!isdigit(*(const unsigned char *) buf))
- return 0;
- *val = atoi_n(buf, size);
- return 1;
-}
-
-/** \brief reads the MARC 24 bytes leader and checks content
- \param mt handle
- \param leader of the 24 byte leader
- \param indicator_length indicator length
- \param identifier_length identifier length
- \param base_address base address
- \param length_data_entry length of data entry
- \param length_starting length of starting
- \param length_implementation length of implementation defined data
-*/
-static void yaz_marc_read_leader(yaz_marc_t mt, const char *leader_c,
- int *indicator_length,
- int *identifier_length,
- int *base_address,
- int *length_data_entry,
- int *length_starting,
- int *length_implementation)
+void yaz_marc_set_leader(yaz_marc_t mt, const char *leader_c,
+ int *indicator_length,
+ int *identifier_length,
+ int *base_address,
+ int *length_data_entry,
+ int *length_starting,
+ int *length_implementation)
{
char leader[24];
return 1; /* we don't know */
}
-static void yaz_marc_reset(yaz_marc_t mt)
+void yaz_marc_reset(yaz_marc_t mt)
{
nmem_reset(mt->nmem);
mt->nodes = 0;
mt->subfield_pp = 0;
}
+int yaz_marc_write_check(yaz_marc_t mt, WRBUF wr)
+{
+ struct yaz_marc_node *n;
+ int identifier_length;
+ const char *leader = 0;
+
+ for (n = mt->nodes; n; n = n->next)
+ if (n->which == YAZ_MARC_LEADER)
+ {
+ leader = n->u.leader;
+ break;
+ }
+
+ if (!leader)
+ return -1;
+ if (!atoi_n_check(leader+11, 1, &identifier_length))
+ return -1;
+
+ for (n = mt->nodes; n; n = n->next)
+ {
+ switch(n->which)
+ {
+ case YAZ_MARC_COMMENT:
+ wrbuf_iconv_write(wr, mt->iconv_cd,
+ n->u.comment, strlen(n->u.comment));
+ wrbuf_puts(wr, "\n");
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+static size_t get_subfield_len(yaz_marc_t mt, const char *data,
+ int identifier_length)
+{
+ /* if identifier length is 2 (most MARCs) or less (probably an error),
+ the code is a single character .. However we've
+ seen multibyte codes, so see how big it really is */
+ if (identifier_length > 2)
+ return identifier_length - 1;
+ else
+ return cdata_one_character(mt, data);
+}
+
int yaz_marc_write_line(yaz_marc_t mt, WRBUF wr)
{
struct yaz_marc_node *n;
n->u.datafield.indicator);
for (s = n->u.datafield.subfields; s; s = s->next)
{
- /* if identifier length is 2 (most MARCs),
- the code is a single character .. However we've
- seen multibyte codes, so see how big it really is */
- size_t using_code_len =
- (identifier_length != 2) ? identifier_length - 1
- :
- cdata_one_character(mt, s->code_data);
+ size_t using_code_len = get_subfield_len(mt, s->code_data,
+ identifier_length);
wrbuf_puts (wr, mt->subfield_str);
wrbuf_iconv_write(wr, mt->iconv_cd, s->code_data,
wrbuf_iconv_puts(wr, mt->iconv_cd, " ");
wrbuf_iconv_puts(wr, mt->iconv_cd,
s->code_data + using_code_len);
- wrbuf_iconv_puts(wr, mt->iconv_cd, " ");
- wr->pos--;
+ marc_iconv_reset(mt, wr);
}
wrbuf_puts (wr, mt->endline_str);
break;
wrbuf_printf(wr, "%s", n->u.controlfield.tag);
wrbuf_iconv_puts(wr, mt->iconv_cd, " ");
wrbuf_iconv_puts(wr, mt->iconv_cd, n->u.controlfield.data);
- wrbuf_iconv_puts(wr, mt->iconv_cd, " ");
- wr->pos--;
+ marc_iconv_reset(mt, wr);
wrbuf_puts (wr, mt->endline_str);
break;
case YAZ_MARC_COMMENT:
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:
wrbuf_printf(wr, "%s\n", n->u.leader);
}
}
+ wrbuf_puts(wr, "\n");
+ return 0;
+}
+
+int yaz_marc_write_trailer(yaz_marc_t mt, WRBUF wr)
+{
+ if (mt->enable_collection == collection_second)
+ {
+ switch(mt->output_format)
+ {
+ case YAZ_MARC_MARCXML:
+ case YAZ_MARC_TURBOMARC:
+ 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)
+ switch(mt->output_format)
{
case YAZ_MARC_LINE:
return yaz_marc_write_line(mt, wr);
case YAZ_MARC_MARCXML:
return yaz_marc_write_marcxml(mt, wr);
+ case YAZ_MARC_TURBOMARC:
+ return yaz_marc_write_turbomarc(mt, wr);
case YAZ_MARC_XCHANGE:
return yaz_marc_write_marcxchange(mt, wr, 0, 0); /* no format, type */
case YAZ_MARC_ISO2709:
return yaz_marc_write_iso2709(mt, wr);
+ case YAZ_MARC_CHECK:
+ return yaz_marc_write_check(mt, wr);
}
return -1;
}
-/** \brief common MARC XML/Xchange writer
+static const char *record_name[2] = { "record", "r"};
+static const char *leader_name[2] = { "leader", "l"};
+static const char *controlfield_name[2] = { "controlfield", "c"};
+static const char *datafield_name[2] = { "datafield", "d"};
+static const char *indicator_name[2] = { "ind", "i"};
+static const char *subfield_name[2] = { "subfield", "s"};
+
+/** \brief common MARC XML/Xchange/turbomarc writer
\param mt handle
\param wr WRBUF output
\param ns XMLNS for the elements
\param format record format (e.g. "MARC21")
\param type record type (e.g. "Bibliographic")
+ \param turbo =1 for turbomarc
+ \retval 0 OK
+ \retval -1 failure
*/
-static int yaz_marc_write_marcxml_ns(yaz_marc_t mt, WRBUF wr,
- const char *ns,
- const char *format,
- const char *type)
+static int yaz_marc_write_marcxml_wrbuf(yaz_marc_t mt, WRBUF wr,
+ const char *ns,
+ const char *format,
+ const char *type,
+ int turbo)
{
struct yaz_marc_node *n;
int identifier_length;
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, "<%s", record_name[turbo]);
+ }
+ else
+ {
+ wrbuf_printf(wr, "<%s xmlns=\"%s\"", record_name[turbo], ns);
+ }
if (format)
wrbuf_printf(wr, " format=\"%.80s\"", format);
if (type)
switch(n->which)
{
case YAZ_MARC_DATAFIELD:
- wrbuf_printf(wr, " <datafield tag=\"");
+
+ wrbuf_printf(wr, " <%s", datafield_name[turbo]);
+ if (!turbo)
+ wrbuf_printf(wr, " tag=\"");
wrbuf_iconv_write_cdata(wr, mt->iconv_cd, n->u.datafield.tag,
strlen(n->u.datafield.tag));
- wrbuf_printf(wr, "\"");
- if (n->u.datafield.indicator)
- {
- int i;
- for (i = 0; n->u.datafield.indicator[i]; i++)
- {
- wrbuf_printf(wr, " ind%d=\"", i+1);
+ if (!turbo)
+ wrbuf_printf(wr, "\"");
+ if (n->u.datafield.indicator)
+ {
+ int i;
+ for (i = 0; n->u.datafield.indicator[i]; i++)
+ {
+ wrbuf_printf(wr, " %s%d=\"", indicator_name[turbo], i+1);
wrbuf_iconv_write_cdata(wr, mt->iconv_cd,
- n->u.datafield.indicator+i, 1);
+ n->u.datafield.indicator+i, 1);
wrbuf_iconv_puts(wr, mt->iconv_cd, "\"");
}
}
wrbuf_printf(wr, ">\n");
for (s = n->u.datafield.subfields; s; s = s->next)
{
- /* if identifier length is 2 (most MARCs),
- the code is a single character .. However we've
- seen multibyte codes, so see how big it really is */
- size_t using_code_len =
- (identifier_length != 2) ? identifier_length - 1
- :
- cdata_one_character(mt, s->code_data);
-
- wrbuf_iconv_puts(wr, mt->iconv_cd, " <subfield code=\"");
- wrbuf_iconv_write_cdata(wr, mt->iconv_cd,
- s->code_data, using_code_len);
- wrbuf_iconv_puts(wr, mt->iconv_cd, "\">");
+ size_t using_code_len = get_subfield_len(mt, s->code_data,
+ identifier_length);
+ wrbuf_printf(wr, " <%s", subfield_name[turbo]);
+ if (!turbo)
+ {
+ wrbuf_printf(wr, " code=\"");
+ wrbuf_iconv_write_cdata(wr, mt->iconv_cd,
+ s->code_data, using_code_len);
+ wrbuf_iconv_puts(wr, mt->iconv_cd, "\">");
+ }
+ else
+ {
+ element_name_append_attribute_value(mt, wr, "code", s->code_data, using_code_len);
+ wrbuf_puts(wr, ">");
+ }
wrbuf_iconv_write_cdata(wr, mt->iconv_cd,
s->code_data + using_code_len,
strlen(s->code_data + using_code_len));
- wrbuf_iconv_puts(wr, mt->iconv_cd, "</subfield>");
- wrbuf_puts(wr, "\n");
+ marc_iconv_reset(mt, wr);
+ wrbuf_printf(wr, "</%s", subfield_name[turbo]);
+ if (turbo)
+ element_name_append_attribute_value(mt, wr, 0, s->code_data, using_code_len);
+ wrbuf_puts(wr, ">\n");
}
- wrbuf_printf(wr, " </datafield>\n");
+ wrbuf_printf(wr, " </%s", datafield_name[turbo]);
+ //TODO Not CDATA
+ if (turbo)
+ wrbuf_iconv_write_cdata(wr, mt->iconv_cd, n->u.datafield.tag,
+ strlen(n->u.datafield.tag));
+ wrbuf_printf(wr, ">\n");
break;
case YAZ_MARC_CONTROLFIELD:
- wrbuf_printf(wr, " <controlfield tag=\"");
- 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_puts(wr, mt->iconv_cd, "</controlfield>");
- wrbuf_puts(wr, "\n");
+ wrbuf_printf(wr, " <%s", controlfield_name[turbo]);
+ if (!turbo)
+ {
+ wrbuf_printf(wr, " tag=\"");
+ wrbuf_iconv_write_cdata(wr, mt->iconv_cd, n->u.controlfield.tag,
+ strlen(n->u.controlfield.tag));
+ wrbuf_iconv_puts(wr, mt->iconv_cd, "\">");
+ }
+ else
+ {
+ //TODO convert special
+ 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_write_cdata(wr, mt->iconv_cd,
+ n->u.controlfield.data,
+ strlen(n->u.controlfield.data));
+ marc_iconv_reset(mt, wr);
+ wrbuf_printf(wr, "</%s", controlfield_name[turbo]);
+ //TODO convert special
+ if (turbo)
+ wrbuf_iconv_write_cdata(wr, mt->iconv_cd, n->u.controlfield.tag,
+ strlen(n->u.controlfield.tag));
+ wrbuf_puts(wr, ">\n");
break;
case YAZ_MARC_COMMENT:
wrbuf_printf(wr, "<!-- ");
wrbuf_printf(wr, " -->\n");
break;
case YAZ_MARC_LEADER:
- wrbuf_printf(wr, " <leader>");
- wrbuf_iconv_write_cdata(wr,
- 0 /* no charset conversion for leader */,
+ wrbuf_printf(wr, " <%s>", leader_name[turbo]);
+ wrbuf_iconv_write_cdata(wr,
+ 0 , /* no charset conversion for leader */
n->u.leader, strlen(n->u.leader));
- wrbuf_printf(wr, "</leader>\n");
+ wrbuf_printf(wr, "</%s>\n", leader_name[turbo]);
}
}
- wrbuf_puts(wr, "</record>\n");
+ wrbuf_printf(wr, "</%s>\n", record_name[turbo]);
return 0;
}
+static int yaz_marc_write_marcxml_ns(yaz_marc_t mt, WRBUF wr,
+ const char *ns,
+ const char *format,
+ const char *type,
+ int turbo)
+{
+ if (mt->write_using_libxml2)
+ {
+#if YAZ_HAVE_XML2
+ int ret;
+ xmlNode *root_ptr;
+
+ if (!turbo)
+ ret = yaz_marc_write_xml(mt, &root_ptr, ns, format, type);
+ else
+ ret = yaz_marc_write_xml_turbo_xml(mt, &root_ptr, ns, format, type);
+ if (ret == 0)
+ {
+ xmlChar *buf_out;
+ xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
+ int len_out;
+
+ xmlDocSetRootElement(doc, root_ptr);
+ xmlDocDumpMemory(doc, &buf_out, &len_out);
+
+ wrbuf_write(wr, (const char *) buf_out, len_out);
+ wrbuf_puts(wr, "");
+ xmlFree(buf_out);
+ xmlFreeDoc(doc);
+ }
+ return ret;
+#else
+ return -1;
+#endif
+ }
+ else
+ return yaz_marc_write_marcxml_wrbuf(mt, wr, ns, format, type, turbo);
+}
+
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",
- 0, 0);
+ return yaz_marc_write_marcxml_ns(mt, wr,
+ "http://www.loc.gov/MARC21/slim",
+ 0, 0, 0);
+}
+
+int yaz_marc_write_turbomarc(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.indexdata.com/turbomarc", 0, 0, 1);
}
int yaz_marc_write_marcxchange(yaz_marc_t mt, WRBUF wr,
const char *type)
{
return yaz_marc_write_marcxml_ns(mt, wr,
- "http://www.bs.dk/standards/MarcXchange",
- 0, 0);
+ "info:lc/xmlns/marcxchange-v1",
+ 0, 0, 0);
+}
+
+#if YAZ_HAVE_XML2
+
+void add_marc_datafield_turbo_xml(yaz_marc_t mt, struct yaz_marc_node *n,
+ xmlNode *record_ptr,
+ xmlNsPtr ns_record, WRBUF wr_cdata,
+ int identifier_length)
+{
+ xmlNode *ptr;
+ struct yaz_marc_subfield *s;
+ WRBUF subfield_name = wrbuf_alloc();
+
+ //TODO consider if safe
+ char field[10];
+ field[0] = 'd';
+ strncpy(field + 1, n->u.datafield.tag, 3);
+ field[4] = '\0';
+ ptr = xmlNewChild(record_ptr, ns_record, BAD_CAST field, 0);
+
+ if (n->u.datafield.indicator)
+ {
+ int i;
+ for (i = 0; n->u.datafield.indicator[i]; i++)
+ {
+ char ind_str[6];
+ char ind_val[2];
+
+ ind_val[0] = n->u.datafield.indicator[i];
+ ind_val[1] = '\0';
+ sprintf(ind_str, "%s%d", indicator_name[1], i+1);
+ xmlNewProp(ptr, BAD_CAST ind_str, BAD_CAST ind_val);
+ }
+ }
+ for (s = n->u.datafield.subfields; s; s = s->next)
+ {
+ int not_written;
+ xmlNode *ptr_subfield;
+ size_t using_code_len = get_subfield_len(mt, s->code_data,
+ identifier_length);
+ wrbuf_rewind(wr_cdata);
+ wrbuf_iconv_puts(wr_cdata, mt->iconv_cd, s->code_data + using_code_len);
+ marc_iconv_reset(mt, wr_cdata);
+
+ wrbuf_rewind(subfield_name);
+ wrbuf_puts(subfield_name, "s");
+ not_written = element_name_append_attribute_value(mt, subfield_name, 0, s->code_data, using_code_len) != 0;
+ ptr_subfield = xmlNewTextChild(ptr, ns_record,
+ BAD_CAST wrbuf_cstr(subfield_name),
+ BAD_CAST wrbuf_cstr(wr_cdata));
+ if (not_written)
+ {
+ // Generate code attribute value and add
+ wrbuf_rewind(wr_cdata);
+ wrbuf_iconv_write(wr_cdata, mt->iconv_cd,s->code_data, using_code_len);
+ xmlNewProp(ptr_subfield, BAD_CAST "code", BAD_CAST wrbuf_cstr(wr_cdata));
+ }
+ }
+ wrbuf_destroy(subfield_name);
}
+static int yaz_marc_write_xml_turbo_xml(yaz_marc_t mt, xmlNode **root_ptr,
+ const char *ns,
+ const char *format,
+ const char *type)
+{
+ struct yaz_marc_node *n;
+ int identifier_length;
+ const char *leader = 0;
+ xmlNode *record_ptr;
+ xmlNsPtr ns_record;
+ WRBUF wr_cdata = 0;
+
+ for (n = mt->nodes; n; n = n->next)
+ if (n->which == YAZ_MARC_LEADER)
+ {
+ leader = n->u.leader;
+ break;
+ }
+
+ if (!leader)
+ return -1;
+ if (!atoi_n_check(leader+11, 1, &identifier_length))
+ return -1;
+
+ wr_cdata = wrbuf_alloc();
+
+ record_ptr = xmlNewNode(0, BAD_CAST "r");
+ *root_ptr = record_ptr;
+
+ ns_record = xmlNewNs(record_ptr, BAD_CAST ns, 0);
+ xmlSetNs(record_ptr, ns_record);
+
+ if (format)
+ xmlNewProp(record_ptr, BAD_CAST "format", BAD_CAST format);
+ if (type)
+ xmlNewProp(record_ptr, BAD_CAST "type", BAD_CAST type);
+ for (n = mt->nodes; n; n = n->next)
+ {
+ xmlNode *ptr;
+
+ char field[10];
+ field[0] = 'c';
+ field[4] = '\0';
+
+ switch(n->which)
+ {
+ case YAZ_MARC_DATAFIELD:
+ add_marc_datafield_turbo_xml(mt, n, record_ptr, ns_record, wr_cdata, identifier_length);
+ break;
+ case YAZ_MARC_CONTROLFIELD:
+ wrbuf_rewind(wr_cdata);
+ wrbuf_iconv_puts(wr_cdata, mt->iconv_cd, n->u.controlfield.data);
+ marc_iconv_reset(mt, wr_cdata);
+
+ strncpy(field + 1, n->u.controlfield.tag, 3);
+ ptr = xmlNewTextChild(record_ptr, ns_record,
+ BAD_CAST field,
+ BAD_CAST wrbuf_cstr(wr_cdata));
+ break;
+ case YAZ_MARC_COMMENT:
+ ptr = xmlNewComment(BAD_CAST n->u.comment);
+ xmlAddChild(record_ptr, ptr);
+ break;
+ case YAZ_MARC_LEADER:
+ {
+ char *field = "leader";
+ field = "l";
+ xmlNewTextChild(record_ptr, ns_record, BAD_CAST field,
+ BAD_CAST n->u.leader);
+ }
+ break;
+ }
+ }
+ wrbuf_destroy(wr_cdata);
+ return 0;
+}
+
+
+int yaz_marc_write_xml(yaz_marc_t mt, xmlNode **root_ptr,
+ const char *ns,
+ const char *format,
+ const char *type)
+{
+ struct yaz_marc_node *n;
+ int identifier_length;
+ const char *leader = 0;
+ xmlNode *record_ptr;
+ xmlNsPtr ns_record;
+ WRBUF wr_cdata = 0;
+
+ for (n = mt->nodes; n; n = n->next)
+ if (n->which == YAZ_MARC_LEADER)
+ {
+ leader = n->u.leader;
+ break;
+ }
+
+ if (!leader)
+ return -1;
+ if (!atoi_n_check(leader+11, 1, &identifier_length))
+ return -1;
+
+ wr_cdata = wrbuf_alloc();
+
+ record_ptr = xmlNewNode(0, BAD_CAST "record");
+ *root_ptr = record_ptr;
+
+ ns_record = xmlNewNs(record_ptr, BAD_CAST ns, 0);
+ xmlSetNs(record_ptr, ns_record);
+
+ if (format)
+ xmlNewProp(record_ptr, BAD_CAST "format", BAD_CAST format);
+ if (type)
+ xmlNewProp(record_ptr, BAD_CAST "type", BAD_CAST type);
+ for (n = mt->nodes; n; n = n->next)
+ {
+ struct yaz_marc_subfield *s;
+ xmlNode *ptr;
+
+ switch(n->which)
+ {
+ case YAZ_MARC_DATAFIELD:
+ ptr = xmlNewChild(record_ptr, ns_record, BAD_CAST "datafield", 0);
+ xmlNewProp(ptr, BAD_CAST "tag", BAD_CAST n->u.datafield.tag);
+ if (n->u.datafield.indicator)
+ {
+ int i;
+ for (i = 0; n->u.datafield.indicator[i]; i++)
+ {
+ char ind_str[6];
+ char ind_val[2];
+
+ sprintf(ind_str, "ind%d", i+1);
+ ind_val[0] = n->u.datafield.indicator[i];
+ ind_val[1] = '\0';
+ xmlNewProp(ptr, BAD_CAST ind_str, BAD_CAST ind_val);
+ }
+ }
+ for (s = n->u.datafield.subfields; s; s = s->next)
+ {
+ xmlNode *ptr_subfield;
+ size_t using_code_len = get_subfield_len(mt, s->code_data,
+ identifier_length);
+ wrbuf_rewind(wr_cdata);
+ wrbuf_iconv_puts(wr_cdata, mt->iconv_cd,
+ s->code_data + using_code_len);
+ marc_iconv_reset(mt, wr_cdata);
+ ptr_subfield = xmlNewTextChild(
+ ptr, ns_record,
+ BAD_CAST "subfield", BAD_CAST wrbuf_cstr(wr_cdata));
+
+ wrbuf_rewind(wr_cdata);
+ wrbuf_iconv_write(wr_cdata, mt->iconv_cd,
+ s->code_data, using_code_len);
+ xmlNewProp(ptr_subfield, BAD_CAST "code",
+ BAD_CAST wrbuf_cstr(wr_cdata));
+ }
+ break;
+ case YAZ_MARC_CONTROLFIELD:
+ wrbuf_rewind(wr_cdata);
+ wrbuf_iconv_puts(wr_cdata, mt->iconv_cd, n->u.controlfield.data);
+ marc_iconv_reset(mt, wr_cdata);
+
+ ptr = xmlNewTextChild(record_ptr, ns_record,
+ BAD_CAST "controlfield",
+ BAD_CAST wrbuf_cstr(wr_cdata));
+
+ xmlNewProp(ptr, BAD_CAST "tag", BAD_CAST n->u.controlfield.tag);
+ break;
+ case YAZ_MARC_COMMENT:
+ ptr = xmlNewComment(BAD_CAST n->u.comment);
+ xmlAddChild(record_ptr, ptr);
+ break;
+ case YAZ_MARC_LEADER:
+ xmlNewTextChild(record_ptr, ns_record, BAD_CAST "leader",
+ BAD_CAST n->u.leader);
+ break;
+ }
+ }
+ wrbuf_destroy(wr_cdata);
+ return 0;
+}
+
+#endif
+
int yaz_marc_write_iso2709(yaz_marc_t mt, WRBUF wr)
{
struct yaz_marc_node *n;
/* write dummy IDFS + content */
wrbuf_iconv_putchar(wr_data_tmp, mt->iconv_cd, ' ');
wrbuf_iconv_puts(wr_data_tmp, mt->iconv_cd, s->code_data);
+ marc_iconv_reset(mt, wr_data_tmp);
}
/* 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:
wrbuf_rewind(wr_data_tmp);
wrbuf_iconv_puts(wr_data_tmp, mt->iconv_cd,
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:
wrbuf_write(wr, wrbuf_buf(wr_head), 24);
wrbuf_write(wr, wrbuf_buf(wr_dir), wrbuf_len(wr_dir));
- wrbuf_free(wr_head, 1);
- wrbuf_free(wr_dir, 1);
- wrbuf_free(wr_data_tmp, 1);
+ wrbuf_destroy(wr_head);
+ wrbuf_destroy(wr_dir);
+ wrbuf_destroy(wr_data_tmp);
for (n = mt->nodes; n; n = n->next)
{
{
wrbuf_putc(wr, ISO2709_IDFS);
wrbuf_iconv_puts(wr, mt->iconv_cd, s->code_data);
- /* write dummy blank - makes MARC-8 to become ASCII */
- wrbuf_iconv_putchar(wr, mt->iconv_cd, ' ');
- wr->pos--;
+ marc_iconv_reset(mt, wr);
}
wrbuf_putc(wr, ISO2709_FS);
break;
case YAZ_MARC_CONTROLFIELD:
wrbuf_iconv_puts(wr, mt->iconv_cd, n->u.controlfield.data);
- /* write dummy blank - makes MARC-8 to become ASCII */
- wrbuf_iconv_putchar(wr, mt->iconv_cd, ' ');
- wr->pos--;
+ marc_iconv_reset(mt, wr);
wrbuf_putc(wr, ISO2709_FS);
break;
case YAZ_MARC_COMMENT:
return 0;
}
-#if YAZ_HAVE_XML2
-int yaz_marc_read_xml_subfields(yaz_marc_t mt, const xmlNode *ptr)
-{
- for (; ptr; ptr = ptr->next)
- {
- if (ptr->type == XML_ELEMENT_NODE)
- {
- if (!strcmp((const char *) ptr->name, "subfield"))
- {
- size_t ctrl_data_len = 0;
- char *ctrl_data_buf = 0;
- const xmlNode *p = 0, *ptr_code = 0;
- struct _xmlAttr *attr;
- for (attr = ptr->properties; attr; attr = attr->next)
- if (!strcmp((const char *)attr->name, "code"))
- ptr_code = attr->children;
- else
- {
- yaz_marc_cprintf(
- mt, "Bad attribute '%.80s' for 'subfield'",
- attr->name);
- return -1;
- }
- if (!ptr_code)
- {
- yaz_marc_cprintf(
- mt, "Missing attribute 'code' for 'subfield'" );
- return -1;
- }
- if (ptr_code->type == XML_TEXT_NODE)
- {
- ctrl_data_len =
- strlen((const char *)ptr_code->content);
- }
- else
- {
- yaz_marc_cprintf(
- mt, "Missing value for 'code' in 'subfield'" );
- return -1;
- }
- for (p = ptr->children; p ; p = p->next)
- if (p->type == XML_TEXT_NODE)
- ctrl_data_len += strlen((const char *)p->content);
- ctrl_data_buf = nmem_malloc(mt->nmem, ctrl_data_len+1);
- strcpy(ctrl_data_buf, (const char *)ptr_code->content);
- for (p = ptr->children; p ; p = p->next)
- if (p->type == XML_TEXT_NODE)
- strcat(ctrl_data_buf, (const char *)p->content);
- yaz_marc_add_subfield(mt, ctrl_data_buf, ctrl_data_len);
- }
- else
- {
- yaz_marc_cprintf(
- mt, "Expected element 'subfield', got '%.80s'", ptr->name);
- return -1;
- }
- }
- }
- return 0;
-}
-
-static int yaz_marc_read_xml_leader(yaz_marc_t mt, const xmlNode **ptr_p)
-{
- int indicator_length;
- int identifier_length;
- int base_address;
- int length_data_entry;
- int length_starting;
- int length_implementation;
- const char *leader = 0;
- const xmlNode *ptr = *ptr_p;
-
- for(; ptr; ptr = ptr->next)
- if (ptr->type == XML_ELEMENT_NODE)
- {
- if (!strcmp((const char *) ptr->name, "leader"))
- {
- xmlNode *p = ptr->children;
- for(; p; p = p->next)
- if (p->type == XML_TEXT_NODE)
- leader = (const char *) p->content;
- break;
- }
- else
- {
- yaz_marc_cprintf(
- mt, "Expected element 'leader', got '%.80s'", ptr->name);
- return -1;
- }
- }
- if (!leader)
- {
- yaz_marc_cprintf(mt, "Missing element 'leader'");
- return -1;
- }
- if (strlen(leader) != 24)
- {
- yaz_marc_cprintf(mt, "Bad length %d of leader data."
- " Must have length of 24 characters", strlen(leader));
- return -1;
- }
- yaz_marc_read_leader(mt, leader,
- &indicator_length,
- &identifier_length,
- &base_address,
- &length_data_entry,
- &length_starting,
- &length_implementation);
- *ptr_p = ptr;
- return 0;
-}
-
-static int yaz_marc_read_xml_fields(yaz_marc_t mt, const xmlNode *ptr)
-{
- for(; ptr; ptr = ptr->next)
- if (ptr->type == XML_ELEMENT_NODE)
- {
- if (!strcmp((const char *) ptr->name, "controlfield"))
- {
- const xmlNode *ptr_tag = 0;
- struct _xmlAttr *attr;
- for (attr = ptr->properties; attr; attr = attr->next)
- if (!strcmp((const char *)attr->name, "tag"))
- ptr_tag = attr->children;
- else
- {
- yaz_marc_cprintf(
- mt, "Bad attribute '%.80s' for 'controlfield'",
- attr->name);
- return -1;
- }
- if (!ptr_tag)
- {
- yaz_marc_cprintf(
- mt, "Missing attribute 'tag' for 'controlfield'" );
- return -1;
- }
- yaz_marc_add_controlfield_xml(mt, ptr_tag, ptr->children);
- }
- else if (!strcmp((const char *) ptr->name, "datafield"))
- {
- char indstr[11]; /* 0(unused), 1,....9, + zero term */
- const xmlNode *ptr_tag = 0;
- struct _xmlAttr *attr;
- int i;
- for (i = 0; i<11; i++)
- indstr[i] = '\0';
- for (attr = ptr->properties; attr; attr = attr->next)
- if (!strcmp((const char *)attr->name, "tag"))
- ptr_tag = attr->children;
- else if (strlen((const char *)attr->name) == 4 &&
- !memcmp(attr->name, "ind", 3))
- {
- int no = atoi((const char *)attr->name+3);
- if (attr->children
- && attr->children->type == XML_TEXT_NODE)
- indstr[no] = attr->children->content[0];
- }
- else
- {
- yaz_marc_cprintf(
- mt, "Bad attribute '%.80s' for 'datafield'",
- attr->name);
- return -1;
- }
- if (!ptr_tag)
- {
- yaz_marc_cprintf(
- mt, "Missing attribute 'tag' for 'datafield'" );
- return -1;
- }
- /* note that indstr[0] is unused so we use indstr[1..] */
- yaz_marc_add_datafield_xml(mt, ptr_tag,
- indstr+1, strlen(indstr+1));
-
- if (yaz_marc_read_xml_subfields(mt, ptr->children))
- return -1;
- }
- else
- {
- yaz_marc_cprintf(mt,
- "Expected element controlfield or datafield,"
- " got %.80s", ptr->name);
- return -1;
- }
- }
- return 0;
-}
-
-int yaz_marc_read_xml(yaz_marc_t mt, const void *xmlnode)
-{
- const xmlNode *ptr = xmlnode;
- for(; ptr; ptr = ptr->next)
- if (ptr->type == XML_ELEMENT_NODE)
- {
- if (!strcmp((const char *) ptr->name, "record"))
- break;
- else
- {
- yaz_marc_cprintf(
- mt, "Unknown element '%.80s' in MARC XML reader",
- ptr->name);
- return -1;
- }
- }
- if (!ptr)
- {
- yaz_marc_cprintf(mt, "Missing element 'record' in MARC XML record");
- return -1;
- }
- /* ptr points to record node now */
- ptr = ptr->children;
- if (yaz_marc_read_xml_leader(mt, &ptr))
- return -1;
- return yaz_marc_read_xml_fields(mt, ptr->next);
-}
-#else
-int yaz_marc_read_xml(yaz_marc_t mt, const void *xmlnode)
-{
- return -1;
-}
-#endif
-
-int yaz_marc_read_iso2709(yaz_marc_t mt, const char *buf, int bsize)
-{
- int entry_p;
- int record_length;
- int indicator_length;
- int identifier_length;
- int end_of_directory;
- int base_address;
- int length_data_entry;
- int length_starting;
- int length_implementation;
-
- yaz_marc_reset(mt);
-
- record_length = atoi_n (buf, 5);
- if (record_length < 25)
- {
- yaz_marc_cprintf(mt, "Record length %d < 24", record_length);
- return -1;
- }
- /* ballout if bsize is known and record_length is less than that */
- if (bsize != -1 && record_length > bsize)
- {
- yaz_marc_cprintf(mt, "Record appears to be larger than buffer %d < %d",
- record_length, bsize);
- return -1;
- }
- if (mt->debug)
- yaz_marc_cprintf(mt, "Record length %5d", record_length);
-
- yaz_marc_read_leader(mt, buf,
- &indicator_length,
- &identifier_length,
- &base_address,
- &length_data_entry,
- &length_starting,
- &length_implementation);
-
- /* First pass. determine length of directory & base of data */
- for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
- {
- /* length of directory entry */
- int l = 3 + length_data_entry + length_starting;
- if (entry_p + l >= record_length)
- {
- yaz_marc_cprintf(mt, "Directory offset %d: end of record."
- " Missing FS char", entry_p);
- return -1;
- }
- if (mt->debug)
- {
- yaz_marc_cprintf(mt, "Directory offset %d: Tag %.3s",
- entry_p, buf+entry_p);
- }
- /* Check for digits in length info */
- while (--l >= 3)
- if (!isdigit(*(const unsigned char *) (buf + entry_p+l)))
- break;
- if (l >= 3)
- {
- /* Not all digits, so stop directory scan */
- yaz_marc_cprintf(mt, "Directory offset %d: Bad value for data"
- " length and/or length starting", entry_p);
- break;
- }
- entry_p += 3 + length_data_entry + length_starting;
- }
- end_of_directory = entry_p;
- if (base_address != entry_p+1)
- {
- yaz_marc_cprintf(mt, "Base address not at end of directory,"
- " base %d, end %d", base_address, entry_p+1);
- }
-
- /* Second pass. parse control - and datafields */
- for (entry_p = 24; entry_p != end_of_directory; )
- {
- int data_length;
- int data_offset;
- int end_offset;
- int i;
- char tag[4];
- int identifier_flag = 0;
- int entry_p0 = entry_p;
-
- memcpy (tag, buf+entry_p, 3);
- entry_p += 3;
- tag[3] = '\0';
- data_length = atoi_n(buf+entry_p, length_data_entry);
- entry_p += length_data_entry;
- data_offset = atoi_n(buf+entry_p, length_starting);
- entry_p += length_starting;
- i = data_offset + base_address;
- end_offset = i+data_length-1;
-
- if (data_length <= 0 || data_offset < 0)
- break;
-
- if (mt->debug)
- {
- yaz_marc_cprintf(mt, "Tag: %s. Directory offset %d: data-length %d,"
- " data-offset %d",
- tag, entry_p0, data_length, data_offset);
- }
- if (end_offset >= record_length)
- {
- yaz_marc_cprintf(mt, "Directory offset %d: Data out of bounds %d >= %d",
- entry_p0, end_offset, record_length);
- break;
- }
-
- if (memcmp (tag, "00", 2))
- identifier_flag = 1; /* if not 00X assume subfields */
- else if (indicator_length < 4 && indicator_length > 0)
- {
- /* Danmarc 00X have subfields */
- if (buf[i + indicator_length] == ISO2709_IDFS)
- identifier_flag = 1;
- else if (buf[i + indicator_length + 1] == ISO2709_IDFS)
- identifier_flag = 2;
- }
-
- if (identifier_flag)
- {
- /* datafield */
- i += identifier_flag-1;
- yaz_marc_add_datafield(mt, tag, buf+i, indicator_length);
- i += indicator_length;
-
- while (i < end_offset &&
- buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
- {
- int code_offset = i+1;
-
- i ++;
- while (i < end_offset &&
- buf[i] != ISO2709_RS && buf[i] != ISO2709_IDFS &&
- buf[i] != ISO2709_FS)
- i++;
- yaz_marc_add_subfield(mt, buf+code_offset, i - code_offset);
- }
- }
- else
- {
- /* controlfield */
- int i0 = i;
- while (i < end_offset &&
- buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
- i++;
- yaz_marc_add_controlfield(mt, tag, buf+i0, i-i0);
- }
- if (i < end_offset)
- {
- yaz_marc_cprintf(mt, "Separator but not at end of field length=%d",
- data_length);
- }
- if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
- {
- yaz_marc_cprintf(mt, "No separator at end of field length=%d",
- data_length);
- }
- }
- return record_length;
-}
int yaz_marc_decode_wrbuf(yaz_marc_t mt, const char *buf, int bsize, WRBUF wr)
{
}
int yaz_marc_decode_buf (yaz_marc_t mt, const char *buf, int bsize,
- char **result, int *rsize)
+ const char **result, size_t *rsize)
{
int r;
wrbuf_rewind(mt->m_wr);
r = yaz_marc_decode_wrbuf(mt, buf, bsize, mt->m_wr);
if (result)
- *result = wrbuf_buf(mt->m_wr);
+ *result = wrbuf_cstr(mt->m_wr);
if (rsize)
*rsize = wrbuf_len(mt->m_wr);
return r;
void yaz_marc_xml(yaz_marc_t mt, int xmlmode)
{
- if (mt)
- mt->xml = xmlmode;
+ mt->output_format = xmlmode;
}
void yaz_marc_debug(yaz_marc_t mt, int level)
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;
}
}
-/* deprecated */
-int yaz_marc_decode(const char *buf, WRBUF wr, int debug, int bsize, int xml)
-{
- yaz_marc_t mt = yaz_marc_create();
- int r;
-
- mt->debug = debug;
- mt->xml = xml;
- r = yaz_marc_decode_wrbuf(mt, buf, bsize, wr);
- yaz_marc_destroy(mt);
- return r;
-}
-
-/* deprecated */
-int marc_display_wrbuf (const char *buf, WRBUF wr, int debug, int bsize)
-{
- return yaz_marc_decode(buf, wr, debug, bsize, 0);
-}
-
-/* deprecated */
-int marc_display_exl (const char *buf, FILE *outf, int debug, int bsize)
-{
- yaz_marc_t mt = yaz_marc_create();
- int r;
-
- mt->debug = debug;
- r = yaz_marc_decode_wrbuf (mt, buf, bsize, mt->m_wr);
- if (!outf)
- outf = stdout;
- if (r > 0)
- fwrite (wrbuf_buf(mt->m_wr), 1, wrbuf_len(mt->m_wr), outf);
- yaz_marc_destroy(mt);
- return r;
-}
-
-/* deprecated */
-int marc_display_ex (const char *buf, FILE *outf, int debug)
-{
- return marc_display_exl (buf, outf, debug, -1);
-}
-
-/* deprecated */
-int marc_display (const char *buf, FILE *outf)
-{
- return marc_display_ex (buf, outf, 0);
-}
-
int yaz_marc_leader_spec(yaz_marc_t mt, const char *leader_spec)
{
xfree(mt->leader_spec);
no = sscanf(cp, "%d=%20[^,]%n", &pos, val, &no_read);
if (no < 2 || no_read < 3)
return -1;
- if (pos < 0 || pos >= size)
+ if (pos < 0 || (size_t) pos >= size)
return -1;
if (*val == '\'')
return 0;
}
+int yaz_marc_decode_formatstr(const char *arg)
+{
+ int mode = -1;
+ if (!strcmp(arg, "marc"))
+ mode = YAZ_MARC_ISO2709;
+ if (!strcmp(arg, "marcxml"))
+ mode = YAZ_MARC_MARCXML;
+ if (!strcmp(arg, "turbomarc"))
+ mode = YAZ_MARC_TURBOMARC;
+ if (!strcmp(arg, "marcxchange"))
+ mode = YAZ_MARC_XCHANGE;
+ if (!strcmp(arg, "line"))
+ mode = YAZ_MARC_LINE;
+ return mode;
+}
+
+void yaz_marc_write_using_libxml2(yaz_marc_t mt, int enable)
+{
+ mt->write_using_libxml2 = enable;
+}
/*
* Local variables:
* c-basic-offset: 4
+ * c-file-style: "Stroustrup"
* indent-tabs-mode: nil
* End:
* vim: shiftwidth=4 tabstop=8 expandtab