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