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