2 * Copyright (C) 1997, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.4 1997-10-27 14:34:26 adam
8 * Fixed bug - data1 root node wasn't tagged at all!
10 * Revision 1.3 1997/09/24 13:36:51 adam
11 * *** empty log message ***
13 * Revision 1.2 1997/09/17 12:19:21 adam
14 * Zebra version corresponds to YAZ version 1.4.
15 * Changed Zebra server so that it doesn't depend on global common_resource.
17 * Revision 1.1 1997/09/04 13:54:40 adam
18 * Added MARC filter - type grs.marc.<syntax> where syntax refers
19 * to abstract syntax. New method tellf in retrieve/extract method.
31 data1_node *data1_mk_node_wp (data1_handle dh, NMEM mem, data1_node *parent)
33 data1_node *res = data1_mk_node (dh, mem);
39 res->root = parent->root;
42 parent->child = parent->last_child = res;
44 parent->last_child->next = res;
45 parent->num_children++;
46 parent->last_child = res;
51 static void destroy_data (struct data1_node *n)
53 assert (n->which == DATA1N_data);
54 xfree (n->u.data.data);
57 data1_node *data1_mk_node_text (data1_handle dh, NMEM mem, data1_node *parent,
58 const char *buf, size_t len)
60 data1_node *res = data1_mk_node_wp (dh, mem, parent);
61 res->which = DATA1N_data;
62 res->u.data.formatted_text = 0;
63 res->u.data.what = DATA1I_text;
64 res->u.data.len = len;
65 if (res->u.data.len > DATA1_LOCALDATA) {
66 res->u.data.data = xmalloc (res->u.data.len);
67 res->destroy = destroy_data;
70 res->u.data.data = res->lbuf;
71 memcpy (res->u.data.data, buf, res->u.data.len);
75 data1_node *data1_mk_node_tag (data1_handle dh, NMEM mem, data1_node *parent,
76 const char *tag, size_t len)
78 data1_element *elem = NULL;
79 data1_node *partag = get_parent_tag(dh, parent);
81 data1_element *e = NULL;
84 res = data1_mk_node_wp (dh, mem, parent);
86 res->which = DATA1N_tag;
87 res->u.tag.tag = res->lbuf;
88 res->u.tag.get_bytes = -1;
90 if (len >= DATA1_LOCALDATA)
91 len = DATA1_LOCALDATA-1;
93 memcpy (res->u.tag.tag, tag, len);
94 res->u.tag.tag[len] = '\0';
96 if (parent->which == DATA1N_variant)
99 if (!(e = partag->u.tag.element))
102 elem = data1_getelementbytagname (dh, res->root->u.root.absyn, e,
104 res->u.tag.element = elem;
105 res->u.tag.node_selected = 0;
106 res->u.tag.make_variantlist = 0;
107 res->u.tag.no_data_requested = 0;
113 data1_node *grs_read_marc (struct grs_read_info *p)
118 int indicator_length;
119 int identifier_length;
121 int length_data_entry;
123 int length_implementation;
129 data1_node *res_root;
132 data1_marctab *marctab;
134 if ((*p->readf)(p->fh, buf, 5) != 5)
136 record_length = atoi_n (buf, 5);
137 if (record_length < 25)
139 logf (LOG_WARN, "MARC record length < 25, is %d", record_length);
142 /* read remaining part - attempt to read one byte furhter... */
143 read_bytes = (*p->readf)(p->fh, buf+5, record_length-4);
144 if (read_bytes < record_length-5)
146 logf (LOG_WARN, "Couldn't read whole MARC record");
149 if (read_bytes == record_length - 4)
151 off_t cur_offset = (*p->tellf)(p->fh);
152 assert (cur_offset > 26);
154 (*p->endf)(p->fh, cur_offset - 1);
157 logf (LOG_DEBUG, "absynName = %s", absynName);
158 if (!(absyn = data1_get_absyn (p->dh, absynName)))
160 logf (LOG_WARN, "Unknown abstract syntax: %s", absynName);
163 res_root = data1_mk_node_wp (p->dh, p->mem, NULL);
164 res_root->which = DATA1N_root;
165 res_root->u.root.type = nmem_malloc (p->mem, strlen(absynName)+1);
166 strcpy (res_root->u.root.type, absynName);
167 res_root->u.root.absyn = absyn;
169 marctab = absyn->marc;
171 if (marctab && marctab->force_indicator_length >= 0)
172 indicator_length = marctab->force_indicator_length;
174 indicator_length = atoi_n (buf+10, 1);
175 if (marctab && marctab->force_identifier_length >= 0)
176 identifier_length = marctab->force_identifier_length;
178 identifier_length = atoi_n (buf+11, 1);
179 base_address = atoi_n (buf+12, 4);
182 length_data_entry = atoi_n (buf+20, 1);
183 length_starting = atoi_n (buf+21, 1);
184 length_implementation = atoi_n (buf+22, 1);
186 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
187 entry_p += 3+length_data_entry+length_starting;
188 base_address = entry_p+1;
189 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
197 data1_node *parent = res_root;
199 memcpy (tag, buf+entry_p, 3);
203 /* generate field node */
204 res = data1_mk_node_tag (p->dh, p->mem, res_root, tag, 3);
207 fprintf (outf, "%s ", tag);
209 data_length = atoi_n (buf+entry_p, length_data_entry);
210 entry_p += length_data_entry;
211 data_offset = atoi_n (buf+entry_p, length_starting);
212 entry_p += length_starting;
213 i = data_offset + base_address;
214 end_offset = i+data_length-1;
216 if (memcmp (tag, "00", 2) && indicator_length)
218 /* generate indicator node */
222 res = data1_mk_node_tag (p->dh, p->mem, res, buf+i,
225 for (j = 0; j<indicator_length; j++)
226 fprintf (outf, "%c", buf[j+i]);
228 i += indicator_length;
231 /* traverse sub fields */
233 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset)
235 if (memcmp (tag, "00", 2) && identifier_length)
238 data1_mk_node_tag (p->dh, p->mem, parent,
239 buf+i+1, identifier_length-1);
241 fprintf (outf, " $");
242 for (j = 1; j<identifier_length; j++)
243 fprintf (outf, "%c", buf[j+i]);
246 i += identifier_length;
248 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_IDFS &&
249 buf[i] != ISO2709_FS && i < end_offset)
252 fprintf (outf, "%c", buf[i]);
256 data1_mk_node_text (p->dh, p->mem, res, buf + i0, i - i0);
262 fprintf (outf, "%c", buf[i]);
269 data1_node *res = data1_mk_node_tag (p->dh, p->mem,
271 data1_mk_node_text (p->dh, p->mem, res, buf + i0, i - i0);
274 fprintf (outf, "\n");
276 fprintf (outf, "-- separator but not at end of field\n");
277 if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
278 fprintf (outf, "-- no separator at end of field\n");