2 * Copyright (C) 1997, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.1 1997-09-04 13:54:40 adam
8 * Added MARC filter - type grs.marc.<syntax> where syntax refers
9 * to abstract syntax. New method tellf in retrieve/extract method.
21 data1_node *data1_mk_node_wp (NMEM mem, data1_node *parent)
23 data1_node *res = data1_mk_node (mem);
29 res->root = parent->root;
32 parent->child = parent->last_child = res;
34 parent->last_child->next = res;
35 parent->num_children++;
36 parent->last_child = res;
41 static void destroy_data (struct data1_node *n)
43 assert (n->which == DATA1N_data);
44 xfree (n->u.data.data);
47 data1_node *data1_mk_node_text (NMEM mem, data1_node *parent,
48 const char *buf, size_t len)
50 data1_node *res = data1_mk_node_wp (mem, parent);
51 res->which = DATA1N_data;
52 res->u.data.formatted_text = 0;
53 res->u.data.what = DATA1I_text;
54 res->u.data.len = len;
55 if (res->u.data.len > DATA1_LOCALDATA) {
56 res->u.data.data = xmalloc (res->u.data.len);
57 res->destroy = destroy_data;
60 res->u.data.data = res->lbuf;
61 memcpy (res->u.data.data, buf, res->u.data.len);
65 data1_node *data1_mk_node_tag (NMEM mem, data1_node *parent,
66 const char *tag, size_t len)
68 data1_element *elem = NULL;
69 data1_node *partag = get_parent_tag(parent);
71 data1_element *e = NULL;
74 res = data1_mk_node_wp (mem, parent);
76 res->which = DATA1N_tag;
77 res->u.tag.tag = res->lbuf;
78 res->u.tag.get_bytes = -1;
80 if (len >= DATA1_LOCALDATA)
81 len = DATA1_LOCALDATA-1;
83 memcpy (res->u.tag.tag, tag, len);
84 res->u.tag.tag[len] = '\0';
86 if (parent->which == DATA1N_variant)
89 if (!(e = partag->u.tag.element))
92 elem = data1_getelementbytagname (res->root->u.root.absyn, e,
94 res->u.tag.element = elem;
95 res->u.tag.node_selected = 0;
96 res->u.tag.make_variantlist = 0;
97 res->u.tag.no_data_requested = 0;
103 data1_node *grs_read_marc (struct grs_read_info *p)
108 int indicator_length;
109 int identifier_length;
111 int length_data_entry;
113 int length_implementation;
119 data1_node *res_root;
123 if ((*p->readf)(p->fh, buf, 5) != 5)
125 record_length = atoi_n (buf, 5);
126 if (record_length < 25)
128 logf (LOG_WARN, "MARC record length < 25, is %d", record_length);
131 /* read remaining part - attempt to read one byte furhter... */
132 read_bytes = (*p->readf)(p->fh, buf+5, record_length-4);
133 if (read_bytes < record_length-5)
135 logf (LOG_WARN, "Couldn't read whole MARC record");
138 if (read_bytes == record_length - 4)
140 off_t cur_offset = (*p->tellf)(p->fh);
141 assert (cur_offset > 26);
143 (*p->endf)(p->fh, cur_offset - 1);
146 logf (LOG_DEBUG, "absynName = %s", absynName);
147 if (!(absyn = data1_get_absyn (absynName)))
149 logf (LOG_WARN, "Unknown abstract syntax: %s", absynName);
152 res_root = data1_mk_node_wp (p->mem, NULL);
153 res_root->u.root.type = nmem_malloc (p->mem, strlen(absynName)+1);
154 strcpy (res_root->u.root.type, absynName);
155 res_root->u.root.absyn = absyn;
157 indicator_length = atoi_n (buf+10, 1);
158 identifier_length = atoi_n (buf+11, 1);
159 base_address = atoi_n (buf+12, 4);
161 length_data_entry = atoi_n (buf+20, 1);
162 length_data_entry = atoi_n (buf+20, 1);
163 length_data_entry = atoi_n (buf+20, 1);
164 length_starting = atoi_n (buf+21, 1);
165 length_implementation = atoi_n (buf+22, 1);
167 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
168 entry_p += 3+length_data_entry+length_starting;
169 base_address = entry_p+1;
170 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
178 data1_node *parent = res_root;
180 memcpy (tag, buf+entry_p, 3);
184 /* generate field node */
185 res = data1_mk_node_tag (p->mem, res_root, tag, 3);
188 fprintf (outf, "%s ", tag);
190 data_length = atoi_n (buf+entry_p, length_data_entry);
191 entry_p += length_data_entry;
192 data_offset = atoi_n (buf+entry_p, length_starting);
193 entry_p += length_starting;
194 i = data_offset + base_address;
195 end_offset = i+data_length-1;
197 if (memcmp (tag, "00", 2) && indicator_length)
199 /* generate indicator node */
203 res = data1_mk_node_tag (p->mem, res, buf+i, indicator_length);
205 for (j = 0; j<indicator_length; j++)
206 fprintf (outf, "%c", buf[j+i]);
208 i += indicator_length;
211 /* traverse sub fields */
213 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset)
215 if (memcmp (tag, "00", 2) && identifier_length)
217 data1_node *res = data1_mk_node_tag (p->mem, parent, buf+i+1,
218 identifier_length-1);
220 fprintf (outf, " $");
221 for (j = 1; j<identifier_length; j++)
222 fprintf (outf, "%c", buf[j+i]);
225 i += identifier_length;
227 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_IDFS &&
228 buf[i] != ISO2709_FS && i < end_offset)
231 fprintf (outf, "%c", buf[i]);
235 data1_mk_node_text (p->mem, res, buf + i0, i - i0);
241 fprintf (outf, "%c", buf[i]);
248 data1_node *res = data1_mk_node_tag (p->mem, parent, "@", 1);
249 data1_mk_node_text (p->mem, res, buf + i0, i - i0);
252 fprintf (outf, "\n");
254 fprintf (outf, "-- separator but not at end of field\n");
255 if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
256 fprintf (outf, "-- no separator at end of field\n");