2 * Copyright (C) 1997-2002, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Id: marcread.c,v 1.16 2002-07-05 12:43:30 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;
34 data1_node *res_root, *res_top;
36 data1_marctab *marctab;
38 if ((*p->readf)(p->fh, buf, 5) != 5)
40 record_length = atoi_n (buf, 5);
41 if (record_length < 25)
43 logf (LOG_WARN, "MARC record length < 25, is %d", record_length);
46 /* read remaining part - attempt to read one byte furhter... */
47 read_bytes = (*p->readf)(p->fh, buf+5, record_length-4);
48 if (read_bytes < record_length-5)
50 logf (LOG_WARN, "Couldn't read whole MARC record");
53 if (read_bytes == record_length - 4)
55 off_t cur_offset = (*p->tellf)(p->fh);
59 (*p->endf)(p->fh, cur_offset - 1);
62 res_root = data1_mk_root (p->dh, p->mem, absynName);
65 yaz_log (LOG_WARN, "cannot read MARC without an abstract syntax");
68 res_top = data1_mk_tag (p->dh, p->mem, absynName, 0, res_root);
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_top;
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 */, parent);
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_mk_text_n (p->dh, p->mem, buf + i0, i - i0, parent);
174 fprintf (outf, "\n");
176 fprintf (outf, "-- separator but not at end of field\n");
177 if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
178 fprintf (outf, "-- no separator at end of field\n");
184 static void *grs_init_marc(void)
189 static void grs_destroy_marc(void *clientData)
193 static struct recTypeGrs marc_type = {
200 RecTypeGrs recTypeGrs_marc = &marc_type;