2 * Copyright (C) 1997-2002, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Id: marcread.c,v 1.14 2002-05-13 14:13:43 adam Exp $
13 #include <yaz/yaz-util.h>
14 #include <yaz/marcdisp.h>
19 data1_node *grs_read_marc (struct grs_read_info *p)
25 int identifier_length;
27 int length_data_entry;
29 int length_implementation;
37 data1_marctab *marctab;
39 if ((*p->readf)(p->fh, buf, 5) != 5)
41 record_length = atoi_n (buf, 5);
42 if (record_length < 25)
44 logf (LOG_WARN, "MARC record length < 25, is %d", record_length);
47 /* read remaining part - attempt to read one byte furhter... */
48 read_bytes = (*p->readf)(p->fh, buf+5, record_length-4);
49 if (read_bytes < record_length-5)
51 logf (LOG_WARN, "Couldn't read whole MARC record");
54 if (read_bytes == record_length - 4)
56 off_t cur_offset = (*p->tellf)(p->fh);
60 (*p->endf)(p->fh, cur_offset - 1);
63 res_root = data1_mk_root (p->dh, p->mem, absynName);
66 yaz_log (LOG_WARN, "cannot read MARC without an abstract syntax");
70 marctab = res_root->u.root.absyn->marc;
72 if (marctab && marctab->force_indicator_length >= 0)
73 indicator_length = marctab->force_indicator_length;
75 indicator_length = atoi_n (buf+10, 1);
76 if (marctab && marctab->force_identifier_length >= 0)
77 identifier_length = marctab->force_identifier_length;
79 identifier_length = atoi_n (buf+11, 1);
80 base_address = atoi_n (buf+12, 4);
82 length_data_entry = atoi_n (buf+20, 1);
83 length_starting = atoi_n (buf+21, 1);
84 length_implementation = atoi_n (buf+22, 1);
86 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
87 entry_p += 3+length_data_entry+length_starting;
88 base_address = entry_p+1;
89 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
97 data1_node *parent = res_root;
99 memcpy (tag, buf+entry_p, 3);
104 /* generate field node */
105 res = data1_mk_tag_n (p->dh, p->mem, tag, 3, 0 /* attr */, res_root);
108 fprintf (outf, "%s ", tag);
110 data_length = atoi_n (buf+entry_p, length_data_entry);
111 entry_p += length_data_entry;
112 data_offset = atoi_n (buf+entry_p, length_starting);
113 entry_p += length_starting;
114 i = data_offset + base_address;
115 end_offset = i+data_length-1;
117 if (memcmp (tag, "00", 2) && indicator_length)
119 /* generate indicator node */
123 res = data1_mk_tag_n (p->dh, p->mem,
124 buf+i, indicator_length, 0 /* attr */, res);
126 for (j = 0; j<indicator_length; j++)
127 fprintf (outf, "%c", buf[j+i]);
129 i += indicator_length;
132 /* traverse sub fields */
134 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset)
136 if (memcmp (tag, "00", 2) && identifier_length)
139 data1_mk_tag_n (p->dh, p->mem,
140 buf+i+1, identifier_length-1,
141 0 /* attr */, parent);
143 fprintf (outf, " $");
144 for (j = 1; j<identifier_length; j++)
145 fprintf (outf, "%c", buf[j+i]);
148 i += identifier_length;
150 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_IDFS &&
151 buf[i] != ISO2709_FS && i < end_offset)
154 fprintf (outf, "%c", buf[i]);
158 data1_mk_text_n (p->dh, p->mem, buf + i0, i - i0, res);
164 fprintf (outf, "%c", buf[i]);
171 data1_node *res = data1_mk_tag (p->dh, p->mem, "@", 0 /* attr */,
173 data1_mk_text_n (p->dh, p->mem, buf + i0, i - i0, res);
176 fprintf (outf, "\n");
178 fprintf (outf, "-- separator but not at end of field\n");
179 if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
180 fprintf (outf, "-- no separator at end of field\n");
186 static void *grs_init_marc(void)
191 static void grs_destroy_marc(void *clientData)
195 static struct recTypeGrs marc_type = {
202 RecTypeGrs recTypeGrs_marc = &marc_type;