1 /* $Id: marcread.c,v 1.17 2002-08-02 19:26:56 adam Exp $
2 Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
29 #include <yaz/yaz-util.h>
30 #include <yaz/marcdisp.h>
35 data1_node *grs_read_marc (struct grs_read_info *p)
41 int identifier_length;
43 int length_data_entry;
45 int length_implementation;
50 data1_node *res_root, *res_top;
52 data1_marctab *marctab;
54 if ((*p->readf)(p->fh, buf, 5) != 5)
56 record_length = atoi_n (buf, 5);
57 if (record_length < 25)
59 logf (LOG_WARN, "MARC record length < 25, is %d", record_length);
62 /* read remaining part - attempt to read one byte furhter... */
63 read_bytes = (*p->readf)(p->fh, buf+5, record_length-4);
64 if (read_bytes < record_length-5)
66 logf (LOG_WARN, "Couldn't read whole MARC record");
69 if (read_bytes == record_length - 4)
71 off_t cur_offset = (*p->tellf)(p->fh);
75 (*p->endf)(p->fh, cur_offset - 1);
78 res_root = data1_mk_root (p->dh, p->mem, absynName);
81 yaz_log (LOG_WARN, "cannot read MARC without an abstract syntax");
84 res_top = data1_mk_tag (p->dh, p->mem, absynName, 0, res_root);
86 marctab = res_root->u.root.absyn->marc;
88 if (marctab && marctab->force_indicator_length >= 0)
89 indicator_length = marctab->force_indicator_length;
91 indicator_length = atoi_n (buf+10, 1);
92 if (marctab && marctab->force_identifier_length >= 0)
93 identifier_length = marctab->force_identifier_length;
95 identifier_length = atoi_n (buf+11, 1);
96 base_address = atoi_n (buf+12, 4);
98 length_data_entry = atoi_n (buf+20, 1);
99 length_starting = atoi_n (buf+21, 1);
100 length_implementation = atoi_n (buf+22, 1);
102 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
103 entry_p += 3+length_data_entry+length_starting;
104 base_address = entry_p+1;
105 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
113 data1_node *parent = res_top;
115 memcpy (tag, buf+entry_p, 3);
120 /* generate field node */
121 res = data1_mk_tag_n (p->dh, p->mem, tag, 3, 0 /* attr */, parent);
124 fprintf (outf, "%s ", tag);
126 data_length = atoi_n (buf+entry_p, length_data_entry);
127 entry_p += length_data_entry;
128 data_offset = atoi_n (buf+entry_p, length_starting);
129 entry_p += length_starting;
130 i = data_offset + base_address;
131 end_offset = i+data_length-1;
133 if (memcmp (tag, "00", 2) && indicator_length)
135 /* generate indicator node */
139 res = data1_mk_tag_n (p->dh, p->mem,
140 buf+i, indicator_length, 0 /* attr */, res);
142 for (j = 0; j<indicator_length; j++)
143 fprintf (outf, "%c", buf[j+i]);
145 i += indicator_length;
148 /* traverse sub fields */
150 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset)
152 if (memcmp (tag, "00", 2) && identifier_length)
155 data1_mk_tag_n (p->dh, p->mem,
156 buf+i+1, identifier_length-1,
157 0 /* attr */, parent);
159 fprintf (outf, " $");
160 for (j = 1; j<identifier_length; j++)
161 fprintf (outf, "%c", buf[j+i]);
164 i += identifier_length;
166 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_IDFS &&
167 buf[i] != ISO2709_FS && i < end_offset)
170 fprintf (outf, "%c", buf[i]);
174 data1_mk_text_n (p->dh, p->mem, buf + i0, i - i0, res);
180 fprintf (outf, "%c", buf[i]);
187 data1_mk_text_n (p->dh, p->mem, buf + i0, i - i0, parent);
190 fprintf (outf, "\n");
192 fprintf (outf, "-- separator but not at end of field\n");
193 if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
194 fprintf (outf, "-- no separator at end of field\n");
200 static void *grs_init_marc(void)
205 static void grs_destroy_marc(void *clientData)
209 static struct recTypeGrs marc_type = {
216 RecTypeGrs recTypeGrs_marc = &marc_type;