2 * Copyright (C) 1995-1999, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.12 2000-03-15 15:00:30 adam
8 * First work on threaded version.
10 * Revision 1.11 1999/10/29 10:00:00 adam
11 * Fixed minor bug where database name wasn't set in zebra_record_fetch.
13 * Revision 1.10 1999/05/26 07:49:13 adam
16 * Revision 1.9 1999/05/20 12:57:18 adam
17 * Implemented TCL filter. Updated recctrl system.
19 * Revision 1.8 1999/03/09 16:27:49 adam
20 * More work on SDRKit integration.
22 * Revision 1.7 1999/03/02 16:15:43 quinn
23 * Added "tagsysno" and "tagrank" directives to zebra.cfg.
25 * Revision 1.6 1999/02/18 15:01:25 adam
28 * Revision 1.5 1999/02/17 11:29:56 adam
29 * Fixed in record_fetch. Minor updates to API.
31 * Revision 1.4 1999/02/02 14:51:07 adam
32 * Updated WIN32 code specific sections. Changed header.
34 * Revision 1.3 1998/10/28 10:54:40 adam
37 * Revision 1.2 1998/10/16 08:14:33 adam
38 * Updated record control system.
40 * Revision 1.1 1998/03/05 08:45:13 adam
41 * New result set model and modular ranking system. Moved towards
42 * descent server API. System information stored as "SGML" records.
68 struct fetch_control {
76 static int record_ext_read (void *fh, char *buf, size_t count)
78 struct fetch_control *fc = (struct fetch_control *) fh;
79 return read (fc->fd, buf, count);
82 static off_t record_ext_seek (void *fh, off_t offset)
84 struct fetch_control *fc = (struct fetch_control *) fh;
85 return lseek (fc->fd, offset + fc->record_offset, SEEK_SET);
88 static off_t record_ext_tell (void *fh)
90 struct fetch_control *fc = (struct fetch_control *) fh;
91 return lseek (fc->fd, 0, SEEK_CUR) - fc->record_offset;
94 static off_t record_int_seek (void *fh, off_t offset)
96 struct fetch_control *fc = (struct fetch_control *) fh;
97 return (off_t) (fc->record_int_pos = offset);
100 static off_t record_int_tell (void *fh)
102 struct fetch_control *fc = (struct fetch_control *) fh;
103 return (off_t) fc->record_int_pos;
106 static int record_int_read (void *fh, char *buf, size_t count)
108 struct fetch_control *fc = (struct fetch_control *) fh;
109 int l = fc->record_int_len - fc->record_int_pos;
112 l = (l < (int) count) ? l : count;
113 memcpy (buf, fc->record_int_buf + fc->record_int_pos, l);
114 fc->record_int_pos += l;
118 int zebra_record_fetch (ZebraHandle zh, int sysno, int score, ODR stream,
119 oid_value input_format, Z_RecordComposition *comp,
120 oid_value *output_format, char **rec_bufp,
121 int *rec_lenp, char **basenamep)
124 char *fname, *file_type, *basename;
126 struct recRetrieveCtrl retrieveCtrl;
128 struct fetch_control fc;
129 RecordAttr *recordAttr;
132 rec = rec_get (zh->service->records, sysno);
135 logf (LOG_DEBUG, "rec_get fail on sysno=%d", sysno);
139 recordAttr = rec_init_attr (zh->service->zei, rec);
141 file_type = rec->info[recInfo_fileType];
142 fname = rec->info[recInfo_filename];
143 basename = rec->info[recInfo_databaseName];
144 *basenamep = (char *) odr_malloc (stream, strlen(basename)+1);
145 strcpy (*basenamep, basename);
147 if (!(rt = recType_byName (zh->service->recTypes,
148 file_type, subType, &clientData)))
150 logf (LOG_WARN, "Retrieve: Cannot handle type %s", file_type);
153 logf (LOG_DEBUG, "retrieve localno=%d score=%d", sysno, score);
154 retrieveCtrl.fh = &fc;
156 if (rec->size[recInfo_storeData] > 0)
158 retrieveCtrl.readf = record_int_read;
159 retrieveCtrl.seekf = record_int_seek;
160 retrieveCtrl.tellf = record_int_tell;
161 fc.record_int_len = rec->size[recInfo_storeData];
162 fc.record_int_buf = rec->info[recInfo_storeData];
163 fc.record_int_pos = 0;
164 logf (LOG_DEBUG, "Internal retrieve. %d bytes", fc.record_int_len);
167 else if (*fname == '%')
171 char *cp, xname[128];
174 logf (LOG_DEBUG, "SDR");
175 strcpy (xname, fname+1);
176 if ((cp = strrchr (xname, '.')))
181 h = zebraSdr_open (xname);
184 logf (LOG_WARN, "sdr open %s", xname);
187 if (zebraSdr_segment (h, &segment) < 0)
189 logf (LOG_WARN, "zebraSdr_segment fail segment=%d",
194 r = zebraSdr_read (h, &buf);
197 logf (LOG_WARN, "zebraSdr_read fail segment=%d",
204 fc.record_int_len = recordAttr->recordSize;
205 fc.record_int_buf = buf + recordAttr->recordOffset;
206 fc.record_int_pos = 0;
208 logf (LOG_LOG, "segment = %d len=%d off=%d",
210 recordAttr->recordSize,
211 recordAttr->recordOffset);
212 if (fc.record_int_len > 180)
214 logf (LOG_LOG, "%.70s", fc.record_int_buf);
215 logf (LOG_LOG, "%.70s", fc.record_int_buf +
216 (fc.record_int_len - 70));
219 logf (LOG_LOG, "%.*s",
220 fc.record_int_len, fc.record_int_buf);
222 /* the following two lines makes rec_rm delete buf */
223 rec->size[recInfo_storeData] = r;
224 rec->info[recInfo_storeData] = buf;
226 retrieveCtrl.readf = record_int_read;
227 retrieveCtrl.seekf = record_int_seek;
228 retrieveCtrl.tellf = record_int_tell;
233 if ((fc.fd = open (fname, O_BINARY|O_RDONLY)) == -1)
235 logf (LOG_WARN|LOG_ERRNO, "Retrieve fail; missing file: %s",
240 fc.record_offset = recordAttr->recordOffset;
242 retrieveCtrl.readf = record_ext_read;
243 retrieveCtrl.seekf = record_ext_seek;
244 retrieveCtrl.tellf = record_ext_tell;
246 record_ext_seek (retrieveCtrl.fh, 0);
248 retrieveCtrl.subType = subType;
249 retrieveCtrl.localno = sysno;
250 retrieveCtrl.score = score;
251 retrieveCtrl.recordSize = recordAttr->recordSize;
252 retrieveCtrl.odr = stream;
253 retrieveCtrl.input_format = retrieveCtrl.output_format = input_format;
254 retrieveCtrl.comp = comp;
255 retrieveCtrl.diagnostic = 0;
256 retrieveCtrl.dh = zh->service->dh;
257 retrieveCtrl.res = zh->service->res;
258 (*rt->retrieve)(clientData, &retrieveCtrl);
259 *output_format = retrieveCtrl.output_format;
260 *rec_bufp = (char *) retrieveCtrl.rec_buf;
261 *rec_lenp = retrieveCtrl.rec_len;
266 return retrieveCtrl.diagnostic;