Changed the way sequence numbers are generated.
[idzebra-moved-to-github.git] / recctrl / rectext.c
1 /*
2  * Copyright (C) 1994-1998, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: rectext.c,v $
7  * Revision 1.7  1998-03-11 11:19:05  adam
8  * Changed the way sequence numbers are generated.
9  *
10  * Revision 1.6  1998/02/10 12:03:06  adam
11  * Implemented Sort.
12  *
13  * Revision 1.5  1997/10/27 14:33:06  adam
14  * Moved towards generic character mapping depending on "structure"
15  * field in abstract syntax file. Fixed a few memory leaks. Fixed
16  * bug with negative integers when doing searches with relational
17  * operators.
18  *
19  * Revision 1.4  1996/11/04 14:09:16  adam
20  * Minor changes.
21  *
22  * Revision 1.3  1996/11/01 09:00:33  adam
23  * This simple "text" format now supports element specs B and M.
24  *
25  * Revision 1.2  1996/10/29 14:02:45  adam
26  * Uses buffered read to speed up things.
27  *
28  * Revision 1.1  1996/10/11 10:57:28  adam
29  * New module recctrl. Used to manage records (extract/retrieval).
30  *
31  * Revision 1.7  1996/01/17 14:57:55  adam
32  * Prototype changed for reader functions in extract/retrieve. File
33  *  is identified by 'void *' instead of 'int.
34  *
35  * Revision 1.6  1995/10/10  13:59:24  adam
36  * Function rset_open changed its wflag parameter to general flags.
37  *
38  * Revision 1.5  1995/10/02  16:24:39  adam
39  * Use attribute actually used in search requests.
40  *
41  * Revision 1.4  1995/10/02  15:42:55  adam
42  * Extract uses file descriptors instead of FILE pointers.
43  *
44  * Revision 1.3  1995/09/28  09:19:45  adam
45  * xfree/xmalloc used everywhere.
46  * Extract/retrieve method seems to work for text records.
47  *
48  * Revision 1.2  1995/09/15  14:45:21  adam
49  * Retrieve control.
50  * Work on truncation.
51  *
52  * Revision 1.1  1995/09/14  07:48:25  adam
53  * Record control management.
54  *
55  */
56 #include <stdio.h>
57 #include <assert.h>
58 #include <ctype.h>
59
60 #include <zebrautl.h>
61 #include "rectext.h"
62
63 static void text_init (void)
64 {
65 }
66
67 struct buf_info {
68     struct recExtractCtrl *p;
69     char *buf;
70     int offset;
71     int max;
72 };
73
74 struct buf_info *buf_open (struct recExtractCtrl *p)
75 {
76     struct buf_info *fi = xmalloc (sizeof(*fi));
77
78     fi->p = p;
79     fi->buf = xmalloc (4096);
80     fi->offset = 1;
81     fi->max = 1;
82     return fi;
83 }
84
85 int buf_read (struct buf_info *fi, char *dst)
86 {
87     if (fi->offset >= fi->max)
88     {
89         if (fi->max <= 0)
90             return 0;
91         fi->max = (*fi->p->readf)(fi->p->fh, fi->buf, 4096);
92         fi->offset = 0;
93         if (fi->max <= 0)
94             return 0;
95     }
96     *dst = fi->buf[(fi->offset)++];
97     return 1;
98 }
99
100 void buf_close (struct buf_info *fi)
101 {
102     xfree (fi->buf);
103     xfree (fi);
104 }
105
106 static int text_extract (struct recExtractCtrl *p)
107 {
108     char w[512];
109     RecWord recWord;
110     int r;
111     struct buf_info *fi = buf_open (p);
112
113     (*p->init)(p, &recWord);
114     recWord.reg_type = 'w';
115     do
116     {
117         int i = 0;
118             
119         r = buf_read (fi, w);
120         while (r > 0 && i < 511 && w[i] != '\n' && w[i] != '\r')
121         {
122             i++;
123             r = buf_read (fi, w + i);
124         }
125         if (i)
126         {
127             recWord.string = w;
128             recWord.length = i;
129             (*p->add)(&recWord);
130         }
131     } while (r > 0);
132     buf_close (fi);
133     return 0;
134 }
135
136 static int text_retrieve (struct recRetrieveCtrl *p)
137 {
138     int r, text_ptr = 0;
139     static char *text_buf = NULL;
140     static int text_size = 0;
141     int start_flag = 1;
142     const char *elementSetName = NULL;
143     int no_lines = 0;
144
145     if (p->comp && p->comp->which == Z_RecordComp_simple &&
146         p->comp->u.simple->which == Z_ElementSetNames_generic)
147         elementSetName = p->comp->u.simple->u.generic;
148
149     while (1)
150     {
151         if (text_ptr + 4096 >= text_size)
152         {
153             char *nb;
154
155             text_size = 2*text_size + 8192;
156             nb = xmalloc (text_size);
157             if (text_buf)
158             {
159                 memcpy (nb, text_buf, text_ptr);
160                 xfree (text_buf);
161             }
162             text_buf = nb;
163         }
164         if (start_flag)
165         {
166             start_flag = 0;
167             if (p->score >= 0)
168             {
169                 sprintf (text_buf, "Rank: %d\n", p->score);
170                 text_ptr = strlen(text_buf);
171             }
172             sprintf (text_buf + text_ptr, "Local Number: %d\n", p->localno);
173             text_ptr = strlen(text_buf);
174         }
175         r = (*p->readf)(p->fh, text_buf + text_ptr, 4096);
176         if (r <= 0)
177             break;
178         text_ptr += r;
179     }
180     text_buf[text_ptr] = '\0';
181     if (elementSetName)
182     {
183         if (!strcmp (elementSetName, "B"))
184             no_lines = 4;
185         if (!strcmp (elementSetName, "M"))
186             no_lines = 20;
187     }
188     if (no_lines)
189     {
190         char *p = text_buf;
191         int i = 0;
192
193         while (++i <= no_lines && (p = strchr (p, '\n')))
194             p++;
195         if (p)
196         {
197             p[1] = '\0';
198             text_ptr = p-text_buf;
199         }
200     }
201     p->output_format = VAL_SUTRS;
202     p->rec_buf = text_buf;
203     p->rec_len = text_ptr; 
204     return 0;
205 }
206
207 static struct recType text_type = {
208     "text",
209     text_init,
210     text_extract,
211     text_retrieve
212 };
213
214 RecType recTypeText = &text_type;