2 * Copyright (c) 1995-2003, Index Data
3 * See the file LICENSE for details.
5 * $Id: marcdisp.c,v 1.1 2003-10-27 12:21:30 adam Exp $
15 #include <yaz/marcdisp.h>
16 #include <yaz/wrbuf.h>
17 #include <yaz/yaz-util.h>
25 yaz_marc_t yaz_marc_create(void)
27 yaz_marc_t mt = (yaz_marc_t) xmalloc(sizeof(*mt));
28 mt->xml = YAZ_MARC_LINE;
30 mt->m_wr = wrbuf_alloc();
34 void yaz_marc_destroy(yaz_marc_t mt)
38 wrbuf_free (mt->m_wr, 1);
42 static void marc_cdata (yaz_marc_t mt, const char *buf, size_t len, WRBUF wr)
45 for (i = 0; i<len; i++)
51 wrbuf_puts(wr, "<");
54 wrbuf_puts(wr, ">");
57 wrbuf_puts(wr, "&");
60 wrbuf_puts(wr, """);
63 wrbuf_puts(wr, "'");
66 wrbuf_putc(wr, buf[i]);
70 wrbuf_putc(wr, buf[i]);
75 static void marc_cdata (yaz_marc_t mt, const char *buf, size_t len)
78 marc_cdata2 (mt, buf, len);
82 size_t inbytesleft = len;
83 const char *inp = buf;
87 size_t outbytesleft = sizeof(outbuf);
89 size_t r = yaz_iconv (mt->cd, (char**) &inp, &inbytesleft,
90 &outp, &outbytesleft);
91 if (r == (size_t) (-1))
93 int e = yaz_iconv_error(mt->cd);
94 if (e != YAZ_ICONV_E2BIG)
97 marc_cdata2 (mt, outbuf, outp - outbuf);
103 int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr)
107 int indicator_length;
108 int identifier_length;
110 int length_data_entry;
112 int length_implementation;
116 record_length = atoi_n (buf, 5);
117 if (record_length < 25)
123 sprintf (str, "Record length %d - aborting\n", record_length);
124 wrbuf_puts (wr, str);
128 /* ballout if bsize is known and record_length is than that */
129 if (bsize != -1 && record_length > bsize)
131 if (isdigit(buf[10]))
132 indicator_length = atoi_n (buf+10, 1);
134 indicator_length = 2;
135 if (isdigit(buf[11]))
136 identifier_length = atoi_n (buf+11, 1);
138 identifier_length = 2;
139 base_address = atoi_n (buf+12, 5);
141 length_data_entry = atoi_n (buf+20, 1);
142 length_starting = atoi_n (buf+21, 1);
143 length_implementation = atoi_n (buf+22, 1);
151 case YAZ_MARC_SIMPLEXML:
152 wrbuf_puts (wr, "<iso2709\n");
153 sprintf (str, " RecordStatus=\"%c\"\n", buf[5]);
154 wrbuf_puts (wr, str);
155 sprintf (str, " TypeOfRecord=\"%c\"\n", buf[6]);
156 wrbuf_puts (wr, str);
157 for (i = 1; i<=19; i++)
159 sprintf (str, " ImplDefined%d=\"%c\"\n", i, buf[6+i]);
160 wrbuf_puts (wr, str);
162 wrbuf_puts (wr, ">\n");
164 case YAZ_MARC_OAIMARC:
167 "<oai_marc xmlns=\"http://www.openarchives.org/OIA/oai_marc\""
169 " xmlns:xsi=\"http://www.w3.org/2000/10/XMLSchema-instance\""
171 " xsi:schemaLocation=\"http://www.openarchives.org/OAI/oai_marc.xsd\""
175 sprintf (str, " status=\"%c\" type=\"%c\" catForm=\"%c\">\n",
176 buf[5], buf[6], buf[7]);
177 wrbuf_puts (wr, str);
179 case YAZ_MARC_MARCXML:
182 "<record xmlns=\"http://www.loc.gov/MARC21/slim\">\n"
183 " <leader>%.24s</leader>\n", buf);
192 wrbuf_puts (wr, "<!--\n");
193 sprintf (str, "Record length %5d\n", record_length);
194 wrbuf_puts (wr, str);
195 sprintf (str, "Indicator length %5d\n", indicator_length);
196 wrbuf_puts (wr, str);
197 sprintf (str, "Identifier length %5d\n", identifier_length);
198 wrbuf_puts (wr, str);
199 sprintf (str, "Base address %5d\n", base_address);
200 wrbuf_puts (wr, str);
201 sprintf (str, "Length data entry %5d\n", length_data_entry);
202 wrbuf_puts (wr, str);
203 sprintf (str, "Length starting %5d\n", length_starting);
204 wrbuf_puts (wr, str);
205 sprintf (str, "Length implementation %5d\n", length_implementation);
206 wrbuf_puts (wr, str);
208 wrbuf_puts (wr, "-->\n");
211 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
213 entry_p += 3+length_data_entry+length_starting;
214 if (entry_p >= record_length)
217 base_address = entry_p+1;
218 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
225 int identifier_flag = 1;
227 memcpy (tag, buf+entry_p, 3);
230 data_length = atoi_n (buf+entry_p, length_data_entry);
231 entry_p += length_data_entry;
232 data_offset = atoi_n (buf+entry_p, length_starting);
233 entry_p += length_starting;
234 i = data_offset + base_address;
235 end_offset = i+data_length-1;
237 if (indicator_length < 4 && indicator_length > 0)
239 if (buf[i + indicator_length] != ISO2709_IDFS)
242 else if (!memcmp (tag, "00", 2))
249 wrbuf_puts (wr, "Tag: ");
250 wrbuf_puts (wr, tag);
251 wrbuf_puts (wr, " ");
253 case YAZ_MARC_SIMPLEXML:
254 wrbuf_printf (wr, "<field tag=\"%s\"", tag);
256 case YAZ_MARC_OAIMARC:
258 wrbuf_printf (wr, " <varfield id=\"%s\"", tag);
260 wrbuf_printf (wr, " <fixfield id=\"%s\"", tag);
262 case YAZ_MARC_MARCXML:
264 wrbuf_printf (wr, " <datafield tag=\"%s\"", tag);
266 wrbuf_printf (wr, " <controlfield tag=\"%s\"", tag);
271 for (j = 0; j<indicator_length; j++, i++)
277 wrbuf_puts (wr, " Ind: ");
278 wrbuf_putc (wr, buf[i]);
280 case YAZ_MARC_SIMPLEXML:
281 wrbuf_printf (wr, " Indicator%d=\"%c\"", j+1, buf[i]);
283 case YAZ_MARC_OAIMARC:
284 wrbuf_printf (wr, " i%d=\"%c\"", j+1, buf[i]);
286 case YAZ_MARC_MARCXML:
287 wrbuf_printf (wr, " ind%d=\"%c\"", j+1, buf[i]);
293 wrbuf_puts (wr, ">");
295 wrbuf_puts (wr, "\n");
299 if (mt->debug && !mt->xml)
300 wrbuf_puts (wr, " Fields: ");
304 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset)
311 wrbuf_puts (wr, " $");
312 for (j = 1; j<identifier_length; j++, i++)
313 wrbuf_putc (wr, buf[i]);
314 wrbuf_putc (wr, ' ');
316 case YAZ_MARC_SIMPLEXML:
317 wrbuf_puts (wr, " <subfield code=\"");
318 for (j = 1; j<identifier_length; j++, i++)
319 wrbuf_putc (wr, buf[i]);
320 wrbuf_puts (wr, "\">");
322 case YAZ_MARC_OAIMARC:
323 wrbuf_puts (wr, " <subfield label=\"");
324 for (j = 1; j<identifier_length; j++, i++)
325 wrbuf_putc (wr, buf[i]);
326 wrbuf_puts (wr, "\">");
328 case YAZ_MARC_MARCXML:
329 wrbuf_puts (wr, " <subfield code=\"");
330 for (j = 1; j<identifier_length; j++, i++)
331 wrbuf_putc (wr, buf[i]);
332 wrbuf_puts (wr, "\">");
336 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_IDFS &&
337 buf[i] != ISO2709_FS && i < end_offset)
339 marc_cdata(mt, buf + i0, i - i0, wr);
342 wrbuf_puts (wr, "</subfield>\n");
348 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset)
350 marc_cdata(mt, buf + i0, i - i0, wr);
353 wrbuf_putc (wr, '\n');
355 wrbuf_puts (wr, " <!-- separator but not at end of field -->\n");
356 if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
357 wrbuf_puts (wr, " <!-- no separator at end of field -->\n");
360 case YAZ_MARC_SIMPLEXML:
361 wrbuf_puts (wr, "</field>\n");
363 case YAZ_MARC_OAIMARC:
365 wrbuf_puts (wr, " </varfield>\n");
367 wrbuf_puts (wr, " </fixfield>\n");
369 case YAZ_MARC_MARCXML:
371 wrbuf_puts (wr, " </datafield>\n");
373 wrbuf_puts (wr, " </controlfield>\n");
382 case YAZ_MARC_SIMPLEXML:
383 wrbuf_puts (wr, "</iso2709>\n");
385 case YAZ_MARC_OAIMARC:
386 wrbuf_puts (wr, "</oai_marc>\n");
388 case YAZ_MARC_MARCXML:
389 wrbuf_puts (wr, "</record>\n");
392 return record_length;
395 int yaz_marc_decode_buf (yaz_marc_t mt, const char *buf, int bsize,
396 char **result, int *rsize)
398 int r = yaz_marc_decode_wrbuf(mt, buf, bsize, mt->m_wr);
402 *result = wrbuf_buf(mt->m_wr);
404 *rsize = wrbuf_len(mt->m_wr);
409 void yaz_marc_xml(yaz_marc_t mt, int xmlmode)
415 void yaz_marc_debug(yaz_marc_t mt, int level)
422 int yaz_marc_decode(const char *buf, WRBUF wr, int debug, int bsize, int xml)
424 yaz_marc_t mt = yaz_marc_create();
429 r = yaz_marc_decode_wrbuf(mt, buf, bsize, wr);
430 yaz_marc_destroy(mt);
435 int marc_display_wrbuf (const char *buf, WRBUF wr, int debug, int bsize)
437 return yaz_marc_decode(buf, wr, debug, bsize, 0);
441 int marc_display_exl (const char *buf, FILE *outf, int debug, int bsize)
443 yaz_marc_t mt = yaz_marc_create();
447 r = yaz_marc_decode_wrbuf (mt, buf, bsize, mt->m_wr);
451 fwrite (wrbuf_buf(mt->m_wr), 1, wrbuf_len(mt->m_wr), outf);
452 yaz_marc_destroy(mt);
457 int marc_display_ex (const char *buf, FILE *outf, int debug)
459 return marc_display_exl (buf, outf, debug, -1);
463 int marc_display (const char *buf, FILE *outf)
465 return marc_display_ex (buf, outf, 0);