2 * Copyright (C) 1995-2007, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: marc_read_line.c,v 1.3 2007-01-03 08:42:15 adam Exp $
9 * \file marc_read_line.c
10 * \brief Implements reading of MARC in line format
26 #include <yaz/marcdisp.h>
27 #include <yaz/wrbuf.h>
28 #include <yaz/yaz-util.h>
30 int yaz_gets(int (*getbyte)(void *client_data),
31 void (*ungetbyte)(int b, void *client_data),
33 char *buf, size_t len)
36 int ch = getbyte(client_data);
37 while (ch != '\0' && ch != '\r' && ch != '\n')
41 ch = getbyte(client_data);
45 ch = getbyte(client_data);
46 if (ch != '\n' && ch != '\0')
47 ungetbyte(ch, client_data);
51 ch = getbyte(client_data);
52 if (ch != '\r' && ch != '\0')
53 ungetbyte(ch, client_data);
61 int yaz_marc_read_line(yaz_marc_t mt,
62 int (*getbyte)(void *client_data),
63 void (*ungetbyte)(int b, void *client_data),
67 int identifier_length;
69 int length_data_entry;
71 int length_implementation;
74 int header_created = 0;
79 while (yaz_gets(getbyte, ungetbyte, client_data, line, sizeof(line)))
82 size_t line_len = strlen(line);
83 /* see if have leader lines of the form:
84 00366nam 22001698a 4500
86 if (line_len == 0) /* empty line indicates end of record */
91 else if (line[0] == '$') /* indicates beginning/end of record */
96 else if (line[0] == '(') /* annotation, skip it */
98 else if (line_len == 24 && atoi_n_check(line, 5, &val) && val >= 24)
102 yaz_marc_set_leader(mt, line,
108 &length_implementation);
111 else if (line_len > 5 && memcmp(line, " ", 4) == 0)
112 { /* continuation line */
115 else if (line_len > 5 && line[3] == ' ')
118 char *datafield_start = line+6;
122 memcpy(tag, line, 3);
124 if (line_len >= 8) /* control - or datafield ? */
126 if (*datafield_start == ' ')
127 datafield_start++; /* skip blank after indicator */
129 if (strchr("$_*", *datafield_start))
131 marker_ch = *datafield_start;
132 if (datafield_start[2] == ' ')
133 marker_skip = 1; /* subfields has blank before data */
138 const char *leader = "01000cam 2200265 i 4500";
140 yaz_marc_set_leader(mt, leader,
146 &length_implementation);
151 { /* control field */
152 yaz_marc_add_controlfield(mt, tag, line+4, strlen(line+4));
156 const char *indicator = line+4;
157 int indicator_len = 2;
158 char *cp = datafield_start;
160 yaz_marc_add_datafield(mt, tag, indicator, indicator_len);
166 assert(cp[0] == marker_ch);
169 while ((next = strchr(next, marker_ch)))
171 if ((next[1] >= 'A' && next[1] <= 'Z')
172 ||(next[1] >= 'a' && next[1] <= 'z'))
176 else if (next[2] == ' ')
183 len = next - cp - marker_skip;
187 /* remove ' ' after subfield marker */
188 char *cp_blank = strchr(cp, ' ');
192 while (cp_blank != cp)
194 cp_blank[0] = cp_blank[-1];
202 yaz_marc_add_subfield(mt, cp, len);
218 * indent-tabs-mode: nil
220 * vim: shiftwidth=4 tabstop=8 expandtab