2 * Copyright (C) 1997-1999, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.12 2002-04-09 14:36:53 adam
8 * Fix XML attributes for MARC reader
10 * Revision 1.11 2000/05/15 15:32:51 adam
11 * Added support for 64 bit input file support.
13 * Revision 1.10 1999/11/30 13:48:04 adam
14 * Improved installation. Updated for inclusion of YAZ header files.
16 * Revision 1.9 1999/06/25 13:47:25 adam
17 * Minor change that prevents MSVC warning.
19 * Revision 1.8 1999/05/26 07:49:14 adam
22 * Revision 1.7 1999/05/20 12:57:18 adam
23 * Implemented TCL filter. Updated recctrl system.
25 * Revision 1.6 1999/02/02 14:51:27 adam
26 * Updated WIN32 code specific sections. Changed header.
28 * Revision 1.5 1997/11/18 10:03:24 adam
29 * Member num_children removed from data1_node.
31 * Revision 1.4 1997/10/27 14:34:26 adam
32 * Fixed bug - data1 root node wasn't tagged at all!
34 * Revision 1.3 1997/09/24 13:36:51 adam
35 * *** empty log message ***
37 * Revision 1.2 1997/09/17 12:19:21 adam
38 * Zebra version corresponds to YAZ version 1.4.
39 * Changed Zebra server so that it doesn't depend on global common_resource.
41 * Revision 1.1 1997/09/04 13:54:40 adam
42 * Added MARC filter - type grs.marc.<syntax> where syntax refers
43 * to abstract syntax. New method tellf in retrieve/extract method.
51 #include <yaz/yaz-util.h>
52 #include <yaz/marcdisp.h>
55 data1_node *data1_mk_node_wp (data1_handle dh, NMEM mem, data1_node *parent)
57 data1_node *res = data1_mk_node (dh, mem);
63 res->root = parent->root;
66 parent->child = parent->last_child = res;
68 parent->last_child->next = res;
69 parent->last_child = res;
74 static void destroy_data (struct data1_node *n)
76 assert (n->which == DATA1N_data);
77 xfree (n->u.data.data);
80 data1_node *data1_mk_node_text (data1_handle dh, NMEM mem, data1_node *parent,
81 const char *buf, size_t len)
83 data1_node *res = data1_mk_node_wp (dh, mem, parent);
84 res->which = DATA1N_data;
85 res->u.data.formatted_text = 0;
86 res->u.data.what = DATA1I_text;
87 res->u.data.len = len;
88 if (res->u.data.len > DATA1_LOCALDATA) {
89 res->u.data.data = (char *) xmalloc (res->u.data.len);
90 res->destroy = destroy_data;
93 res->u.data.data = res->lbuf;
94 memcpy (res->u.data.data, buf, res->u.data.len);
98 data1_node *data1_mk_node_tag (data1_handle dh, NMEM mem, data1_node *parent,
99 const char *tag, size_t len)
101 data1_element *elem = NULL;
102 data1_node *partag = get_parent_tag(dh, parent);
104 data1_element *e = NULL;
107 res = data1_mk_node_wp (dh, mem, parent);
109 res->which = DATA1N_tag;
110 res->u.tag.tag = res->lbuf;
111 res->u.tag.get_bytes = -1;
112 #if DATA1_USING_XATTR
113 res->u.tag.attributes = 0;
116 if (len >= DATA1_LOCALDATA)
117 len = DATA1_LOCALDATA-1;
119 memcpy (res->u.tag.tag, tag, len);
120 res->u.tag.tag[len] = '\0';
122 if (parent->which == DATA1N_variant)
125 if (!(e = partag->u.tag.element))
128 elem = data1_getelementbytagname (dh, res->root->u.root.absyn, e,
130 res->u.tag.element = elem;
131 res->u.tag.node_selected = 0;
132 res->u.tag.make_variantlist = 0;
133 res->u.tag.no_data_requested = 0;
139 data1_node *grs_read_marc (struct grs_read_info *p)
144 int indicator_length;
145 int identifier_length;
147 int length_data_entry;
149 int length_implementation;
155 data1_node *res_root;
158 data1_marctab *marctab;
160 if ((*p->readf)(p->fh, buf, 5) != 5)
162 record_length = atoi_n (buf, 5);
163 if (record_length < 25)
165 logf (LOG_WARN, "MARC record length < 25, is %d", record_length);
168 /* read remaining part - attempt to read one byte furhter... */
169 read_bytes = (*p->readf)(p->fh, buf+5, record_length-4);
170 if (read_bytes < record_length-5)
172 logf (LOG_WARN, "Couldn't read whole MARC record");
175 if (read_bytes == record_length - 4)
177 off_t cur_offset = (*p->tellf)(p->fh);
178 if (cur_offset <= 27)
181 (*p->endf)(p->fh, cur_offset - 1);
184 logf (LOG_DEBUG, "absynName = %s", absynName);
185 if (!(absyn = data1_get_absyn (p->dh, absynName)))
187 logf (LOG_WARN, "Unknown abstract syntax: %s", absynName);
190 res_root = data1_mk_node_wp (p->dh, p->mem, NULL);
191 res_root->which = DATA1N_root;
192 res_root->u.root.type = (char *) nmem_malloc (p->mem, strlen(absynName)+1);
193 strcpy (res_root->u.root.type, absynName);
194 res_root->u.root.absyn = absyn;
196 marctab = absyn->marc;
198 if (marctab && marctab->force_indicator_length >= 0)
199 indicator_length = marctab->force_indicator_length;
201 indicator_length = atoi_n (buf+10, 1);
202 if (marctab && marctab->force_identifier_length >= 0)
203 identifier_length = marctab->force_identifier_length;
205 identifier_length = atoi_n (buf+11, 1);
206 base_address = atoi_n (buf+12, 4);
209 length_data_entry = atoi_n (buf+20, 1);
210 length_starting = atoi_n (buf+21, 1);
211 length_implementation = atoi_n (buf+22, 1);
213 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
214 entry_p += 3+length_data_entry+length_starting;
215 base_address = entry_p+1;
216 for (entry_p = 24; buf[entry_p] != ISO2709_FS; )
224 data1_node *parent = res_root;
226 memcpy (tag, buf+entry_p, 3);
230 /* generate field node */
231 res = data1_mk_node_tag (p->dh, p->mem, res_root, tag, 3);
234 fprintf (outf, "%s ", tag);
236 data_length = atoi_n (buf+entry_p, length_data_entry);
237 entry_p += length_data_entry;
238 data_offset = atoi_n (buf+entry_p, length_starting);
239 entry_p += length_starting;
240 i = data_offset + base_address;
241 end_offset = i+data_length-1;
243 if (memcmp (tag, "00", 2) && indicator_length)
245 /* generate indicator node */
249 res = data1_mk_node_tag (p->dh, p->mem, res, buf+i,
252 for (j = 0; j<indicator_length; j++)
253 fprintf (outf, "%c", buf[j+i]);
255 i += indicator_length;
258 /* traverse sub fields */
260 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset)
262 if (memcmp (tag, "00", 2) && identifier_length)
265 data1_mk_node_tag (p->dh, p->mem, parent,
266 buf+i+1, identifier_length-1);
268 fprintf (outf, " $");
269 for (j = 1; j<identifier_length; j++)
270 fprintf (outf, "%c", buf[j+i]);
273 i += identifier_length;
275 while (buf[i] != ISO2709_RS && buf[i] != ISO2709_IDFS &&
276 buf[i] != ISO2709_FS && i < end_offset)
279 fprintf (outf, "%c", buf[i]);
283 data1_mk_node_text (p->dh, p->mem, res, buf + i0, i - i0);
289 fprintf (outf, "%c", buf[i]);
296 data1_node *res = data1_mk_node_tag (p->dh, p->mem,
298 data1_mk_node_text (p->dh, p->mem, res, buf + i0, i - i0);
301 fprintf (outf, "\n");
303 fprintf (outf, "-- separator but not at end of field\n");
304 if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS)
305 fprintf (outf, "-- no separator at end of field\n");
311 static void *grs_init_marc(void)
316 static void grs_destroy_marc(void *clientData)
320 static struct recTypeGrs marc_type = {
327 RecTypeGrs recTypeGrs_marc = &marc_type;