2 * Copyright (C) 1995-1999, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.5 1999-02-17 11:29:56 adam
8 * Fixed in record_fetch. Minor updates to API.
10 * Revision 1.4 1999/02/02 14:51:07 adam
11 * Updated WIN32 code specific sections. Changed header.
13 * Revision 1.3 1998/10/28 10:54:40 adam
16 * Revision 1.2 1998/10/16 08:14:33 adam
17 * Updated record control system.
19 * Revision 1.1 1998/03/05 08:45:13 adam
20 * New result set model and modular ranking system. Moved towards
21 * descent server API. System information stored as "SGML" records.
47 struct fetch_control {
55 static int record_ext_read (void *fh, char *buf, size_t count)
57 struct fetch_control *fc = fh;
58 return read (fc->fd, buf, count);
61 static off_t record_ext_seek (void *fh, off_t offset)
63 struct fetch_control *fc = fh;
64 return lseek (fc->fd, offset + fc->record_offset, SEEK_SET);
67 static off_t record_ext_tell (void *fh)
69 struct fetch_control *fc = fh;
70 return lseek (fc->fd, 0, SEEK_CUR) - fc->record_offset;
73 static off_t record_int_seek (void *fh, off_t offset)
75 struct fetch_control *fc = fh;
76 return (off_t) (fc->record_int_pos = offset);
79 static off_t record_int_tell (void *fh)
81 struct fetch_control *fc = fh;
82 return (off_t) fc->record_int_pos;
85 static int record_int_read (void *fh, char *buf, size_t count)
87 struct fetch_control *fc = fh;
88 int l = fc->record_int_len - fc->record_int_pos;
91 l = (l < (int) count) ? l : count;
92 memcpy (buf, fc->record_int_buf + fc->record_int_pos, l);
93 fc->record_int_pos += l;
97 int zebra_record_fetch (ZebraHandle zh, int sysno, int score, ODR stream,
98 oid_value input_format, Z_RecordComposition *comp,
99 oid_value *output_format, char **rec_bufp,
100 int *rec_lenp, char **basenamep)
103 char *fname, *file_type, *basename;
105 struct recRetrieveCtrl retrieveCtrl;
107 struct fetch_control fc;
108 RecordAttr *recordAttr;
110 rec = rec_get (zh->records, sysno);
113 logf (LOG_DEBUG, "rec_get fail on sysno=%d", sysno);
116 recordAttr = rec_init_attr (zh->zei, rec);
118 file_type = rec->info[recInfo_fileType];
119 fname = rec->info[recInfo_filename];
120 basename = rec->info[recInfo_databaseName];
121 *basenamep = odr_malloc (stream, strlen(basename)+1);
122 strcpy (*basenamep, basename);
124 if (!(rt = recType_byName (zh->recTypes, file_type, subType)))
126 logf (LOG_WARN, "Retrieve: Cannot handle type %s", file_type);
129 logf (LOG_DEBUG, "retrieve localno=%d score=%d", sysno, score);
130 retrieveCtrl.fh = &fc;
132 if (rec->size[recInfo_storeData] > 0)
134 retrieveCtrl.readf = record_int_read;
135 retrieveCtrl.seekf = record_int_seek;
136 retrieveCtrl.tellf = record_int_tell;
137 fc.record_int_len = rec->size[recInfo_storeData];
138 fc.record_int_buf = rec->info[recInfo_storeData];
139 fc.record_int_pos = 0;
140 logf (LOG_DEBUG, "Internal retrieve. %d bytes", fc.record_int_len);
143 else if (*fname == '%')
147 char *cp, xname[128];
150 logf (LOG_DEBUG, "SDR");
151 strcpy (xname, fname+1);
152 if ((cp = strrchr (xname, '.')))
157 h = zebraSdr_open (xname);
160 logf (LOG_WARN, "sdr open %s", xname);
163 if (zebraSdr_segment (h, &segment) < 0)
165 logf (LOG_WARN, "zebraSdr_segment fail segment=%d",
170 r = zebraSdr_read (h, &buf);
173 logf (LOG_WARN, "zebraSdr_read fail segment=%d",
180 fc.record_int_len = recordAttr->recordSize;
181 fc.record_int_buf = buf + recordAttr->recordOffset;
182 fc.record_int_pos = 0;
184 logf (LOG_LOG, "segment = %d len=%d off=%d",
186 recordAttr->recordSize,
187 recordAttr->recordOffset);
188 if (fc.record_int_len > 180)
190 logf (LOG_LOG, "%0.70s", fc.record_int_buf);
191 logf (LOG_LOG, "%0.70s", fc.record_int_buf +
192 (fc.record_int_len - 70));
195 logf (LOG_LOG, "%0.*s",
196 fc.record_int_len, fc.record_int_buf);
198 /* the following two lines makes rec_rm delete buf */
199 rec->size[recInfo_storeData] = r;
200 rec->info[recInfo_storeData] = buf;
202 retrieveCtrl.readf = record_int_read;
203 retrieveCtrl.seekf = record_int_seek;
204 retrieveCtrl.tellf = record_int_tell;
209 if ((fc.fd = open (fname, O_BINARY|O_RDONLY)) == -1)
211 logf (LOG_WARN|LOG_ERRNO, "Retrieve fail; missing file: %s",
216 fc.record_offset = recordAttr->recordOffset;
218 retrieveCtrl.readf = record_ext_read;
219 retrieveCtrl.seekf = record_ext_seek;
220 retrieveCtrl.tellf = record_ext_tell;
222 record_ext_seek (retrieveCtrl.fh, 0);
224 retrieveCtrl.subType = subType;
225 retrieveCtrl.localno = sysno;
226 retrieveCtrl.score = score;
227 retrieveCtrl.recordSize = recordAttr->recordSize;
228 retrieveCtrl.odr = stream;
229 retrieveCtrl.input_format = retrieveCtrl.output_format = input_format;
230 retrieveCtrl.comp = comp;
231 retrieveCtrl.diagnostic = 0;
232 retrieveCtrl.dh = zh->dh;
233 (*rt->retrieve)(&retrieveCtrl);
234 *output_format = retrieveCtrl.output_format;
235 *rec_lenp = retrieveCtrl.rec_len;
236 *rec_bufp = odr_malloc (stream, *rec_lenp);
237 memcpy (*rec_bufp, retrieveCtrl.rec_buf, *rec_lenp);
242 return retrieveCtrl.diagnostic;