+ /* mark end of directory */
+ wrbuf_putc(wr_dir, ISO2709_FS);
+
+ /* base address of data (comes after leader+directory) */
+ base_address = 24 + wrbuf_len(wr_dir);
+
+ wr_head = wrbuf_alloc();
+
+ /* write record length */
+ wrbuf_printf(wr_head, "%05d", base_address + data_offset + 1);
+ /* from "original" leader */
+ wrbuf_write(wr_head, leader+5, 7);
+ /* base address of data */
+ wrbuf_printf(wr_head, "%05d", base_address);
+ /* from "original" leader */
+ wrbuf_write(wr_head, leader+17, 7);
+
+ 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);
+
+ for (n = mt->nodes; n; n = n->next)
+ {
+ struct yaz_marc_subfield *s;
+ switch(n->which)
+ {
+ case YAZ_MARC_DATAFIELD:
+ wrbuf_printf(wr, "%.*s", indicator_length,
+ n->u.datafield.indicator);
+ for (s = n->u.datafield.subfields; s; s = s->next)
+ {
+ wrbuf_printf(wr, "%c", ISO2709_IDFS);
+ wrbuf_iconv_puts(wr, mt->iconv_cd, s->code_data);
+ }
+ wrbuf_printf(wr, "%c", ISO2709_FS);
+ break;
+ case YAZ_MARC_CONTROLFIELD:
+ wrbuf_iconv_puts(wr, mt->iconv_cd, n->u.controlfield.data);
+ wrbuf_printf(wr, "%c", ISO2709_FS);
+ break;
+ case YAZ_MARC_COMMENT:
+ break;
+ case YAZ_MARC_LEADER:
+ break;
+ }
+ }
+ wrbuf_printf(wr, "%c", ISO2709_RS);
+ 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)