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