Added dummy sort in test server.
[yaz-moved-to-github.git] / ztest / ztest.c
1 /*
2  * Copyright (c) 1995-1998, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * NT Service interface by
7  *    Chas Woodfield, Fretwell Downing Datasystems.
8  *
9  * $Log: ztest.c,v $
10  * Revision 1.6  1998-01-29 13:16:02  adam
11  * Added dummy sort in test server.
12  *
13  * Revision 1.5  1997/11/07 13:31:58  adam
14  * Added NT Service name part of statserv_options_block. Moved NT
15  * service utility to server library.
16  *
17  * Revision 1.4  1997/09/17 12:10:43  adam
18  * YAZ version 1.4.
19  *
20  * Revision 1.3  1997/09/09 10:10:20  adam
21  * Another MSV5.0 port. Changed projects to include proper
22  * library/include paths.
23  * Server starts server in test-mode when no options are given.
24  *
25  * Revision 1.2  1997/09/04 13:50:31  adam
26  * Bug fix in ztest.
27  *
28  */
29
30 /*
31  * Demonstration of simple server
32  */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <ctype.h>
37 #include <assert.h>
38
39 #include <backend.h>
40 #include <xmalloc.h>
41 #include <proto.h>
42
43 Z_GenericRecord *read_grs1(FILE *f, ODR o);
44
45 int bend_sort (void *handle, bend_sortrequest *req, bend_sortresult *res)
46 {
47     res->errcode = 1;
48     res->errstring = "Sort not implemented";
49     res->sort_status = Z_SortStatus_failure;
50     return 0;
51 }
52
53 bend_initresult *bend_init(bend_initrequest *q)
54 {
55     bend_initresult *r = odr_malloc (q->stream, sizeof(*r));
56     static char *dummy = "Hej fister";
57
58     r->errcode = 0;
59     r->errstring = 0;
60     r->handle = dummy;
61     q->bend_sort = bend_sort;    /* register sort handler */
62     return r;
63 }
64
65 bend_searchresult *bend_search(void *handle, bend_searchrequest *q, int *fd)
66 {
67     bend_searchresult *r = odr_malloc (q->stream, sizeof(*r));
68
69     r->errcode = 0;
70     r->errstring = 0;
71     r->hits = rand() % 22;
72
73     return r;
74 }
75
76 static int atoin (const char *buf, int n)
77 {
78     int val = 0;
79     while (--n >= 0)
80     {
81         if (isdigit(*buf))
82             val = val*10 + (*buf - '0');
83         buf++;
84     }
85     return val;
86 }
87
88 char *marc_read(FILE *inf)
89 {
90     char length_str[5];
91     size_t size;
92     char *buf;
93
94     if (fread (length_str, 1, 5, inf) != 5)
95         return NULL;
96     size = atoin (length_str, 5);
97     if (size <= 6)
98         return NULL;
99     if (!(buf = xmalloc (size+1)))
100         return NULL;
101     if (fread (buf+5, 1, size-5, inf) != (size-5))
102     {
103         xfree (buf);
104         return NULL;
105     }
106     memcpy (buf, length_str, 5);
107     buf[size] = '\0';
108     return buf;
109 }
110
111 static char *dummy_database_record (int num)
112 {
113     FILE *inf = fopen ("dummy-records", "r");
114     char *buf = 0;
115
116     if (!inf)
117         return NULL;
118     while (--num >= 0)
119     {
120         if (buf)
121            xfree(buf);
122         if (num == 98)
123         {
124             assert(buf = xmalloc(2101));
125             memset(buf, 'A', 2100);
126             buf[2100] = '\0';
127             break;
128         }
129         else
130             buf = marc_read (inf);
131         if (!num || !buf)
132             break;
133     }
134     fclose(inf);
135     if (num < 0)
136         return 0;
137     return buf;
138 }
139
140 static Z_GenericRecord *dummy_grs_record (int num, ODR o)
141 {
142     FILE *f = fopen("dummy-grs", "r");
143     char line[512];
144     Z_GenericRecord *r = 0;
145     int n;
146
147     if (!f)
148         return 0;
149     while (fgets(line, 512, f))
150         if (*line == '#' && sscanf(line, "#%d", &n) == 1 && n == num)
151         {
152             r = read_grs1(f, o);
153             break;
154         }
155     fclose(f);
156     return r;
157 }
158
159 bend_fetchresult *bend_fetch(void *handle, bend_fetchrequest *q, int *num)
160 {
161     bend_fetchresult *r = odr_malloc (q->stream, sizeof(*r));
162     static char *bbb = 0;
163
164     r->errstring = 0;
165     r->last_in_set = 0;
166     r->basename = "DUMMY";
167     if (bbb)
168     {
169         xfree(bbb);
170         bbb = 0;
171     }
172     r->format = q->format;  
173     if (q->format == VAL_SUTRS)
174     {
175         char buf[100];
176
177         sprintf(buf, "This is dummy SUTRS record number %d\n", q->number);
178         assert(r->record = bbb = xmalloc(strlen(buf)+1));
179         strcpy(bbb, buf);
180         r->len = strlen(buf);
181     }
182     else if (q->format == VAL_GRS1)
183     {
184         r->len = -1;
185         r->record = (char*) dummy_grs_record(q->number, q->stream);
186         if (!r->record)
187         {
188             r->errcode = 13;
189             return r;
190         }
191     }
192     else if (!(r->record = bbb = dummy_database_record(q->number)))
193     {
194         r->errcode = 13;
195         r->format = VAL_USMARC;
196         return r;
197     }
198     else
199         r->len = strlen(r->record);
200     r->errcode = 0;
201     return r;
202 }
203
204 bend_deleteresult *bend_delete(void *handle, bend_deleterequest *q, int *num)
205 {
206     return 0;
207 }
208
209 #if 0
210 bend_scanresult *bend_scan(void *handle, bend_scanrequest *q, int *num)
211 {
212     static struct scan_entry list[200];
213     static char buf[200][200];
214     static bend_scanresult r;
215     int i;
216
217     r.term_position = q->term_position;
218     r.num_entries = q->num_entries;
219     r.entries = list;
220     for (i = 0; i < r.num_entries; i++)
221     {
222         list[i].term = buf[i];
223         sprintf(list[i].term, "term-%d", i+1);
224         list[i].occurrences = rand() % 100000;
225     }
226     r.errcode = 0;
227     r.errstring = 0;
228     return &r;
229 }
230 #else
231 /*
232  * silly dummy-scan what reads words from a file.
233  */
234 bend_scanresult *bend_scan(void *handle, bend_scanrequest *q, int *num)
235 {
236     bend_scanresult *r = odr_malloc (q->stream, sizeof(*r));
237     static FILE *f = 0;
238     static struct scan_entry list[200];
239     static char entries[200][80];
240     int hits[200];
241     char term[80], *p;
242     int i, pos;
243
244     r->errstring = 0;
245     r->entries = list;
246     r->status = BEND_SCAN_SUCCESS;
247     if (!f && !(f = fopen("dummy-words", "r")))
248     {
249         perror("dummy-words");
250         exit(1);
251     }
252     if (q->term->term->which != Z_Term_general)
253     {
254         r->errcode = 229; /* unsupported term type */
255         return r;
256     }
257     if (q->term->term->u.general->len >= 80)
258     {
259         r->errcode = 11; /* term too long */
260         return r;
261     }
262     if (q->num_entries > 200)
263     {
264         r->errcode = 31;
265         return r;
266     }
267     memcpy(term, q->term->term->u.general->buf, q->term->term->u.general->len);
268     term[q->term->term->u.general->len] = '\0';
269     for (p = term; *p; p++)
270         if (islower(*p))
271             *p = toupper(*p);
272
273     fseek(f, 0, 0);
274     r->num_entries = 0;
275     for (i = 0, pos = 0; fscanf(f, " %79[^:]:%d", entries[pos], &hits[pos]) == 2;
276         i++, pos < 199 ? pos++ : (pos = 0))
277     {
278         if (!r->num_entries && strcmp(entries[pos], term) >= 0) /* s-point fnd */
279         {
280             if ((r->term_position = q->term_position) > i + 1)
281             {
282                 r->term_position = i + 1;
283                 r->status = BEND_SCAN_PARTIAL;
284             }
285             for (; r->num_entries < r->term_position; r->num_entries++)
286             {
287                 int po;
288
289                 po = pos - r->term_position + r->num_entries + 1; /* find pos */
290                 if (po < 0)
291                     po += 200;
292                 list[r->num_entries].term = entries[po];
293                 list[r->num_entries].occurrences = hits[po];
294             }
295         }
296         else if (r->num_entries)
297         {
298             list[r->num_entries].term = entries[pos];
299             list[r->num_entries].occurrences = hits[pos];
300             r->num_entries++;
301         }
302         if (r->num_entries >= q->num_entries)
303             break;
304     }
305     if (feof(f))
306         r->status = BEND_SCAN_PARTIAL;
307     return r;
308 }
309
310 #endif
311
312 void bend_close(void *handle)
313 {
314     return;
315 }
316
317 int main(int argc, char **argv)
318 {
319     return statserv_main(argc, argv);
320 }