Implemented Sort.
[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.6  1998-02-10 12:03:06  adam
8  * Implemented Sort.
9  *
10  * Revision 1.5  1997/10/27 14:33:06  adam
11  * Moved towards generic character mapping depending on "structure"
12  * field in abstract syntax file. Fixed a few memory leaks. Fixed
13  * bug with negative integers when doing searches with relational
14  * operators.
15  *
16  * Revision 1.4  1996/11/04 14:09:16  adam
17  * Minor changes.
18  *
19  * Revision 1.3  1996/11/01 09:00:33  adam
20  * This simple "text" format now supports element specs B and M.
21  *
22  * Revision 1.2  1996/10/29 14:02:45  adam
23  * Uses buffered read to speed up things.
24  *
25  * Revision 1.1  1996/10/11 10:57:28  adam
26  * New module recctrl. Used to manage records (extract/retrieval).
27  *
28  * Revision 1.7  1996/01/17 14:57:55  adam
29  * Prototype changed for reader functions in extract/retrieve. File
30  *  is identified by 'void *' instead of 'int.
31  *
32  * Revision 1.6  1995/10/10  13:59:24  adam
33  * Function rset_open changed its wflag parameter to general flags.
34  *
35  * Revision 1.5  1995/10/02  16:24:39  adam
36  * Use attribute actually used in search requests.
37  *
38  * Revision 1.4  1995/10/02  15:42:55  adam
39  * Extract uses file descriptors instead of FILE pointers.
40  *
41  * Revision 1.3  1995/09/28  09:19:45  adam
42  * xfree/xmalloc used everywhere.
43  * Extract/retrieve method seems to work for text records.
44  *
45  * Revision 1.2  1995/09/15  14:45:21  adam
46  * Retrieve control.
47  * Work on truncation.
48  *
49  * Revision 1.1  1995/09/14  07:48:25  adam
50  * Record control management.
51  *
52  */
53 #include <stdio.h>
54 #include <assert.h>
55 #include <ctype.h>
56
57 #include <zebrautl.h>
58 #include "rectext.h"
59
60 static void text_init (void)
61 {
62 }
63
64 struct buf_info {
65     struct recExtractCtrl *p;
66     char *buf;
67     int offset;
68     int max;
69 };
70
71 struct buf_info *buf_open (struct recExtractCtrl *p)
72 {
73     struct buf_info *fi = xmalloc (sizeof(*fi));
74
75     fi->p = p;
76     fi->buf = xmalloc (4096);
77     fi->offset = 1;
78     fi->max = 1;
79     return fi;
80 }
81
82 int buf_read (struct buf_info *fi, char *dst)
83 {
84     if (fi->offset >= fi->max)
85     {
86         if (fi->max <= 0)
87             return 0;
88         fi->max = (*fi->p->readf)(fi->p->fh, fi->buf, 4096);
89         fi->offset = 0;
90         if (fi->max <= 0)
91             return 0;
92     }
93     *dst = fi->buf[(fi->offset)++];
94     return 1;
95 }
96
97 void buf_close (struct buf_info *fi)
98 {
99     xfree (fi->buf);
100     xfree (fi);
101 }
102
103 static int text_extract (struct recExtractCtrl *p)
104 {
105     char w[512];
106     RecWord recWord;
107     int r, seqno = 1;
108     struct buf_info *fi = buf_open (p);
109
110     (*p->init)(p, &recWord);
111     recWord.reg_type = 'w';
112     do
113     {
114         int i = 0;
115             
116         r = buf_read (fi, w);
117         while (r > 0 && i < 511 && w[i] != '\n' && w[i] != '\r')
118         {
119             i++;
120             r = buf_read (fi, w + i);
121         }
122         if (i)
123         {
124             recWord.seqno = seqno++;
125             recWord.string = w;
126             recWord.length = i;
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;