New result set model and modular ranking system. Moved towards
[idzebra-moved-to-github.git] / index / retrieve.c
1 /*
2  * Copyright (C) 1995-1998, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: retrieve.c,v $
7  * Revision 1.1  1998-03-05 08:45:13  adam
8  * New result set model and modular ranking system. Moved towards
9  * descent server API. System information stored as "SGML" records.
10  *
11  */
12
13 #include <stdio.h>
14 #include <assert.h>
15
16 #include <fcntl.h>
17 #ifdef WINDOWS
18 #include <io.h>
19 #include <process.h>
20 #else
21 #include <unistd.h>
22 #endif
23
24 #include <recctrl.h>
25 #include "zserver.h"
26
27 struct fetch_control {
28     int record_offset;
29     int record_int_pos;
30     char *record_int_buf;
31     int record_int_len;
32     int fd;
33 };
34
35 static int record_ext_read (void *fh, char *buf, size_t count)
36 {
37     struct fetch_control *fc = fh;
38     return read (fc->fd, buf, count);
39 }
40
41 static off_t record_ext_seek (void *fh, off_t offset)
42 {
43     struct fetch_control *fc = fh;
44     return lseek (fc->fd, offset + fc->record_offset, SEEK_SET);
45 }
46
47 static off_t record_ext_tell (void *fh)
48 {
49     struct fetch_control *fc = fh;
50     return lseek (fc->fd, 0, SEEK_CUR) - fc->record_offset;
51 }
52
53 static off_t record_int_seek (void *fh, off_t offset)
54 {
55     struct fetch_control *fc = fh;
56     return (off_t) (fc->record_int_pos = offset);
57 }
58
59 static off_t record_int_tell (void *fh)
60 {
61     struct fetch_control *fc = fh;
62     return (off_t) fc->record_int_pos;
63 }
64
65 static int record_int_read (void *fh, char *buf, size_t count)
66 {
67     struct fetch_control *fc = fh;
68     int l = fc->record_int_len - fc->record_int_pos;
69     if (l <= 0)
70         return 0;
71     l = (l < count) ? l : count;
72     memcpy (buf, fc->record_int_buf + fc->record_int_pos, l);
73     fc->record_int_pos += l;
74     return l;
75 }
76
77 int zebra_record_fetch (ZebraHandle zh, int sysno, int score, ODR stream,
78                         oid_value input_format, Z_RecordComposition *comp,
79                         oid_value *output_format, char **rec_bufp,
80                         int *rec_lenp, char **basenamep)
81 {
82     Record rec;
83     char *fname, *file_type, *basename;
84     RecType rt;
85     struct recRetrieveCtrl retrieveCtrl;
86     char subType[128];
87     struct fetch_control fc;
88     RecordAttr *recordAttr;
89
90     rec = rec_get (zh->records, sysno);
91     if (!rec)
92     {
93         logf (LOG_DEBUG, "rec_get fail on sysno=%d", sysno);
94         return 14;
95     }
96     recordAttr = rec_init_attr (zh->zei, rec);
97
98     file_type = rec->info[recInfo_fileType];
99     fname = rec->info[recInfo_filename];
100     basename = rec->info[recInfo_databaseName];
101     *basenamep = odr_malloc (stream, strlen(basename)+1);
102     strcpy (*basenamep, basename);
103
104     if (!(rt = recType_byName (file_type, subType)))
105     {
106         logf (LOG_WARN, "Retrieve: Cannot handle type %s",  file_type);
107         return 14;
108     }
109     logf (LOG_DEBUG, "retrieve localno=%d score=%d", sysno, score);
110     retrieveCtrl.fh = &fc;
111     fc.fd = -1;
112     if (rec->size[recInfo_storeData] > 0)
113     {
114         retrieveCtrl.readf = record_int_read;
115         retrieveCtrl.seekf = record_int_seek;
116         retrieveCtrl.tellf = record_int_tell;
117         fc.record_int_len = rec->size[recInfo_storeData];
118         fc.record_int_buf = rec->info[recInfo_storeData];
119         fc.record_int_pos = 0;
120         logf (LOG_DEBUG, "Internal retrieve. %d bytes", fc.record_int_len);
121     }
122     else 
123     {
124         if ((fc.fd = open (fname, O_BINARY|O_RDONLY)) == -1)
125         {
126             logf (LOG_WARN|LOG_ERRNO, "Retrieve fail; missing file: %s",
127                   fname);
128             rec_rm (&rec);
129             return 14;
130         }
131         fc.record_offset = recordAttr->recordOffset;
132
133         retrieveCtrl.readf = record_ext_read;
134         retrieveCtrl.seekf = record_ext_seek;
135         retrieveCtrl.tellf = record_ext_tell;
136
137         record_ext_seek (retrieveCtrl.fh, 0);
138     }
139     retrieveCtrl.subType = subType;
140     retrieveCtrl.localno = sysno;
141     retrieveCtrl.score = score;
142     retrieveCtrl.recordSize = recordAttr->recordSize;
143     retrieveCtrl.odr = stream;
144     retrieveCtrl.input_format = retrieveCtrl.output_format = input_format;
145     retrieveCtrl.comp = comp;
146     retrieveCtrl.diagnostic = 0;
147     retrieveCtrl.dh = zh->dh;
148     (*rt->retrieve)(&retrieveCtrl);
149     *output_format = retrieveCtrl.output_format;
150     *rec_bufp = retrieveCtrl.rec_buf;
151     *rec_lenp = retrieveCtrl.rec_len;
152     if (fc.fd != -1)
153         close (fc.fd);
154     rec_rm (&rec);
155
156     return retrieveCtrl.diagnostic;
157 }