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