1 /* $Id: csvread.c,v 1.5 2006-05-10 08:13:28 adam Exp $
2 Copyright (C) 1995-2005
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 #include <yaz/yaz-util.h>
29 /* #include <d1_absyn.h> */
30 #include <idzebra/data1.h>
31 #include <idzebra/recgrs.h>
33 /* #include <assert.h> */
37 struct csv_getc_info {
44 int (*readf)(void *, char *, size_t);
64 /* char *field_names; */
69 static ZEBRA_RES grs_config_csv(void *clientData, Res res, const char *args)
72 struct csv_t *csvp = (struct csv_t*) clientData;
74 yaz_log (YLOG_LOG, "Called CSV filter grs_config_csv");
75 yaz_log (YLOG_LOG, "'%s'", args);
78 csvp->buf = nmem_malloc(csvp->nmem, csvp->buf_size);
79 csvp->name_size = 256;
80 csvp->value_size = 4096;
81 csvp->value = nmem_malloc(csvp->nmem, csvp->value_size);
83 csvp->field_char = '|';
84 csvp->record_char = '\n';
85 csvp->string_char = 0;
86 csvp->root_element = nmem_strdup(csvp->nmem, "csv");
89 csvp->max_nr_fields = 512;
91 /* csvp->field_names = 0; */ /*nmem_strdup(csvp->nmem, "a|b|c|d|e");*/
94 = nmem_malloc(csvp->nmem,
95 sizeof(*(csvp->field_name)) * csvp->max_nr_fields);
96 for (i = 0; i < csvp->max_nr_fields; i++){
97 csvp->field_name[i] = 0;
100 /* know field names from config file */
101 /*if (strlen(csvp->field_names))
102 yaz_log (YLOG_LOG, "CSV filter grs_config_csv field names");
105 yaz_log (YLOG_LOG, "Ended CSV filter grs_config_csv");
110 static data1_node *grs_read_csv (struct grs_read_info *gri)
112 data1_node *root_node = 0;
113 data1_node *node = 0;
114 struct csv_t *csvp = (struct csv_t *)gri->clientData;
116 int end_of_record = 0;
119 char *cb = csvp->buf;
120 char *cv = csvp->value;
122 yaz_log (YLOG_LOG, "Called CSV filter grs_read_csv");
124 /* if on start of first line, read header line for dynamic configure */
125 if(csvp->field_line && gri->offset == 0)
128 while (!end_of_record){
131 /* configure grs.csv filter with first line in file containing field
134 yaz_log (YLOG_LOG, "CSV filter grs_read_csv reading header line");
136 /* create new memory for fieldname and value */
137 if (old_nr_fields < csvp->nr_fields){
139 "CSV filter grs_read_csv name:'%d' ", csvp->nr_fields);
140 old_nr_fields = csvp->nr_fields;
141 csvp->field_name[csvp->nr_fields]
142 = nmem_malloc(csvp->nmem, csvp->name_size);
143 csvp->field_value[csvp->nr_fields]
144 = nmem_malloc(csvp->nmem, csvp->value_size);
146 /* read buf and copy values to field_name[] */
147 read_bytes = (*gri->readf)(gri->fh, csvp->buf, csvp->buf_size);
148 gri-> offset = (*gri->tellf)(gri->fh);
149 /* yaz_log(YLOG_LOG, "CSV filter grs_read_csv offset:'%d' ", offset); */
153 /* read buf and copy values to field_value[] */
154 read_bytes = (*gri->readf)(gri->fh, csvp->buf, csvp->buf_size);
155 gri->offset = (*gri->tellf)(gri->fh);
156 yaz_log(YLOG_LOG, "CSV filter grs_read_csv offset:'%d' ", offset);
162 /* read new buffer from file */
163 read_bytes = (*gri->readf)(gri->fh, csvp->buf, csvp->buf_size);
165 yaz_log (YLOG_LOG, "CSV filter grs_read_csv read_bytes %d", read_bytes);
166 yaz_log (YLOG_LOG, "CSV filter grs_read_csv csvp->buf %s", csvp->buf);
168 gri->offset = (*gri->tellf)(gri->fh);
169 yaz_log(YLOG_LOG, "CSV filter grs_read_csv gri->offset:'%d' ",
174 while ((cb - csvp->buf < read_bytes)
175 && (cv - csvp->value < csvp->value_size)
178 if (*cb == csvp->field_char){
179 /* if field finished */
182 /* read field names from header line */
183 if (csvp->nr_fields < csvp->max_nr_fields){
184 csvp->field_name[csvp->nr_fields]
185 = nmem_strdup(csvp->nmem, csvp->value);
188 yaz_log (YLOG_LOG, "CSV filter grs_read_csv field %d name '%s'",
189 field_nr, csvp->value);
191 yaz_log (YLOG_WARN, "CSV filter grs_read_csv field %d name '%s' "
192 "exceeds configured max number of fields %d",
193 field_nr, csvp->value, csvp->max_nr_fields);
196 /* process following value line fields */
197 if (field_nr < csvp->nr_fields){
198 /* less or qual fields number */
199 yaz_log (YLOG_LOG, "CSV filter grs_read_csv field %d %s: '%s'",
200 field_nr, csvp->field_name[field_nr], csvp->value);
202 /* too many fields */
203 yaz_log (YLOG_WARN, "CSV filter grs_read_csv field value %d %s "
204 "exceeds dynamic configured number of fields %d",
205 field_nr, csvp->value, csvp->nr_fields);
209 /* advance buffer and proceed to next field */
213 } else if (*cb == csvp->record_char){
214 /* if record finished */
215 /* advance buffer and proceed to record */
222 yaz_log (YLOG_LOG, "CSV filter grs_read_csv header end");
225 yaz_log (YLOG_LOG, "CSV filter grs_read_csv record end");
228 /* just plain char to be stored in value, no special action at all */
229 if (csvp->lower_case && read_header){
241 (*gri->endf)(gri->fh, offset - 1); */
244 /* try to build GRS node and document */
246 root_node = data1_mk_root(gri->dh, gri->mem, csvp->root_element);
247 node = data1_mk_node2(gri->dh, gri->mem, DATA1N_data, root_node);
248 node = data1_mk_tag(gri->dh, gri->mem, "pr_name_gn", 0, node);
249 data1_mk_text_n(gri->dh, gri->mem, csvp->buf, read_bytes, node);
252 yaz_log (YLOG_WARN, "empty CSV record of type '%s' "
253 "near file offset %d "
254 "or missing abstract syntax file '%s.abs'",
255 csvp->root_element, (int)gri->offset, csvp->root_element);
259 yaz_log (YLOG_LOG, "Ended CSV filter grs_read_csv");
263 static void *grs_init_csv(Res res, RecType recType)
265 NMEM m = nmem_create();
266 struct csv_t *csvp = (struct csv_t *) nmem_malloc(m, sizeof(*csvp));
267 yaz_log (YLOG_LOG, "Called CSV filter grs_init_csv");
269 yaz_log (YLOG_LOG, "Ended CSV filter grs_init_csv");
273 static void grs_destroy_csv(void *clientData)
275 struct csv_t *csvp = (struct csv_t*) clientData;
277 yaz_log (YLOG_LOG, "Called CSV filter grs_destroy_csv");
279 nmem_destroy(csvp->nmem);
282 yaz_log (YLOG_LOG, "Ended CSV filter grs_destroy_csv");
285 static int grs_extract_csv(void *clientData, struct recExtractCtrl *ctrl)
288 /* struct csv_t *csvp = (struct csv_t*) clientData; */
290 yaz_log (YLOG_LOG, "Called CSV filter grs_extract_csv");
291 yaz_log (YLOG_LOG, "recExtractCtr fh %d", (int)ctrl->fh);
292 yaz_log (YLOG_LOG, "recExtractCtr offset %d", (int)ctrl->offset);
294 res = zebra_grs_extract(clientData, ctrl, grs_read_csv);
296 yaz_log (YLOG_LOG, "recExtractCtr fh %d", (int)ctrl->fh);
297 yaz_log (YLOG_LOG, "recExtractCtr offset %d", (int)ctrl->offset);
298 yaz_log (YLOG_LOG, "Ended CSV filter grs_extract_csv");
303 static int grs_retrieve_csv(void *clientData, struct recRetrieveCtrl *ctrl)
306 /* struct csv_t *csvp = (struct csv_t*) clientData; */
308 yaz_log (YLOG_LOG, "Called CSV filter grs_retrieve_csv");
309 res = zebra_grs_retrieve(clientData, ctrl, grs_read_csv);
310 yaz_log (YLOG_LOG, "Ended CSV filter grs_retrieve_csv");
315 static struct recType grs_type_csv =
327 #ifdef IDZEBRA_STATIC_GRS_CSV
328 idzebra_filter_grs_csv
340 * indent-tabs-mode: nil
342 * vim: shiftwidth=4 tabstop=8 expandtab