2 * Copyright (c) 1995-2002, Index Data
3 * See the file LICENSE for details.
5 * $Id: marcdisp.c,v 1.24 2002-12-03 10:03:27 adam Exp $
15 #include <yaz/marcdisp.h>
16 #include <yaz/wrbuf.h>
17 #include <yaz/yaz-util.h>
19 int yaz_marc_decode (const char *buf, WRBUF wr, int debug, int bsize, int xml)
24 int identifier_length;
26 int length_data_entry;
28 int length_implementation;
30 record_length = atoi_n (buf, 5);
31 if (record_length < 25)
37 sprintf (str, "Record length %d - aborting\n", record_length);
42 /* ballout if bsize is known and record_length is than that */
43 if (bsize != -1 && record_length > bsize)
46 indicator_length = atoi_n (buf+10, 1);
50 identifier_length = atoi_n (buf+11, 1);
52 identifier_length = 2;
53 base_address = atoi_n (buf+12, 5);
55 length_data_entry = atoi_n (buf+20, 1);
56 length_starting = atoi_n (buf+21, 1);
57 length_implementation = atoi_n (buf+22, 1);
66 wrbuf_puts (wr, "<iso2709\n");
67 sprintf (str, " RecordStatus=\"%c\"\n", buf[5]);
69 sprintf (str, " TypeOfRecord=\"%c\"\n", buf[6]);
71 for (i = 1; i<=19; i++)
73 sprintf (str, " ImplDefined%d=\"%c\"\n", i, buf[6+i]);
76 wrbuf_puts (wr, ">\n");
78 case YAZ_MARC_OAIMARC:
81 "<oai_marc xmlns=\"http://www.openarchives.org/OIA/oai_marc\""
83 " xmlns:xsi=\"http://www.w3.org/2000/10/XMLSchema-instance\""
85 " xsi:schemaLocation=\"http://www.openarchives.org/OAI/oai_marc.xsd\""
89 sprintf (str, " status=\"%c\" type=\"%c\" catForm=\"%c\">\n",
90 buf[5], buf[6], buf[7]);
93 case YAZ_MARC_MARCXML:
96 "<collection xmlns=\"http://www.loc.gov/MARC21/slim\">\n"
98 " <leader>%.24s</leader>\n", buf);
107 wrbuf_puts (wr, "<!--\n");
108 sprintf (str, "Record length %5d\n", record_length);
109 wrbuf_puts (wr, str);
110 sprintf (str, "Indicator length %5d\n", indicator_length);
111 wrbuf_puts (wr, str);
112 sprintf (str, "Identifier length %5d\n", identifier_length);
113 wrbuf_puts (wr, str);
114 sprintf (str, "Base address %5d\n", base_address);
115 wrbuf_puts (wr, str);
116 sprintf (str, "Length data entry %5d\n", length_data_entry);
117 wrbuf_puts (wr, str);
118 sprintf (str, "Length starting %5d\n", length_starting);
119 wrbuf_puts (wr, str);
120 sprintf (str, "Length implementation %5d\n", length_implementation);
121 wrbuf_puts (wr, str);
123 wrbuf_puts (wr, "-->\n");
126 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
128 entry_p += 3+length_data_entry+length_starting;
129 if (entry_p >= record_length)
132 base_address = entry_p+1;
133 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
140 int identifier_flag = 1;
142 memcpy (tag, buf+entry_p, 3);
145 data_length = atoi_n (buf+entry_p, length_data_entry);
146 entry_p += length_data_entry;
147 data_offset = atoi_n (buf+entry_p, length_starting);
148 entry_p += length_starting;
149 i = data_offset + base_address;
150 end_offset = i+data_length-1;
152 if (indicator_length < 4 && indicator_length > 0)
154 if (buf[i + indicator_length] != ISO2709_IDFS)
157 else if (!memcmp (tag, "00", 2))
164 wrbuf_puts (wr, "Tag: ");
165 wrbuf_puts (wr, tag);
166 wrbuf_puts (wr, " ");
169 wrbuf_printf (wr, "<field tag=\"%s\"", tag);
171 case YAZ_MARC_OAIMARC:
173 wrbuf_printf (wr, " <varfield id=\"%s\"", tag);
175 wrbuf_printf (wr, " <fixfield id=\"%s\"", tag);
177 case YAZ_MARC_MARCXML:
179 wrbuf_printf (wr, " <datafield tag=\"%s\"", tag);
181 wrbuf_printf (wr, " <controlfield tag=\"%s\"", tag);
186 for (j = 0; j<indicator_length; j++, i++)
192 wrbuf_puts (wr, " Ind: ");
193 wrbuf_putc (wr, buf[i]);
196 wrbuf_printf (wr, " Indicator%d=\"%c\"", j+1, buf[i]);
198 case YAZ_MARC_OAIMARC:
199 wrbuf_printf (wr, " i%d=\"%c\"", j+1, buf[i]);
201 case YAZ_MARC_MARCXML:
202 wrbuf_printf (wr, " ind%d=\"%c\"", j+1, buf[i]);
208 wrbuf_puts (wr, ">");
210 wrbuf_puts (wr, "\n");
215 wrbuf_puts (wr, " Fields: ");
217 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset)
225 wrbuf_puts (wr, " $");
226 for (j = 1; j<identifier_length; j++, i++)
227 wrbuf_putc (wr, buf[i]);
228 wrbuf_putc (wr, ' ');
231 wrbuf_puts (wr, " <subfield code=\"");
232 for (j = 1; j<identifier_length; j++, i++)
233 wrbuf_putc (wr, buf[i]);
234 wrbuf_puts (wr, "\">");
236 case YAZ_MARC_OAIMARC:
237 wrbuf_puts (wr, " <subfield label=\"");
238 for (j = 1; j<identifier_length; j++, i++)
239 wrbuf_putc (wr, buf[i]);
240 wrbuf_puts (wr, "\">");
242 case YAZ_MARC_MARCXML:
243 wrbuf_puts (wr, " <subfield code=\"");
244 for (j = 1; j<identifier_length; j++, i++)
245 wrbuf_putc (wr, buf[i]);
246 wrbuf_puts (wr, "\">");
249 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_IDFS &&
250 buf[i] != ISO2709_FS && i < end_offset)
252 if (xml && buf[i] == '<')
253 wrbuf_puts(wr, "<");
254 else if (xml && buf[i] == '&')
255 wrbuf_puts(wr, "&");
257 wrbuf_putc (wr, buf[i]);
261 wrbuf_puts (wr, "</subfield>\n");
265 if (xml && buf[i] == '<')
266 wrbuf_puts(wr, "<");
267 else if (xml && buf[i] == '&')
268 wrbuf_puts(wr, "&");
269 else if (xml && buf[i] == '"')
270 wrbuf_puts(wr, """);
272 wrbuf_putc (wr, buf[i]);
277 wrbuf_putc (wr, '\n');
279 wrbuf_puts (wr, " <!-- separator but not at end of field -->\n");
280 if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
281 wrbuf_puts (wr, " <!-- no separator at end of field -->\n");
287 wrbuf_puts (wr, "</field>\n");
289 case YAZ_MARC_OAIMARC:
291 wrbuf_puts (wr, " </varfield>\n");
293 wrbuf_puts (wr, " </fixfield>\n");
295 case YAZ_MARC_MARCXML:
297 wrbuf_puts (wr, " </datafield>\n");
299 wrbuf_puts (wr, " </controlfield>\n");
309 wrbuf_puts (wr, "</iso2709>\n");
311 case YAZ_MARC_OAIMARC:
312 wrbuf_puts (wr, "</oai_marc>\n");
314 case YAZ_MARC_MARCXML:
315 wrbuf_puts (wr, " </record>\n</collection>\n");
318 return record_length;
321 int marc_display_wrbuf (const char *buf, WRBUF wr, int debug,
324 return yaz_marc_decode (buf, wr, debug, bsize, 0);
327 int marc_display_exl (const char *buf, FILE *outf, int debug, int length)
331 WRBUF wrbuf = wrbuf_alloc ();
332 record_length = marc_display_wrbuf (buf, wrbuf, debug, length);
335 if (record_length > 0)
336 fwrite (wrbuf_buf(wrbuf), 1, wrbuf_len(wrbuf), outf);
337 wrbuf_free (wrbuf, 1);
338 return record_length;
341 int marc_display_ex (const char *buf, FILE *outf, int debug)
343 return marc_display_exl (buf, outf, debug, -1);
346 int marc_display (const char *buf, FILE *outf)
348 return marc_display_ex (buf, outf, 0);