rec_get.c revision 1.1 1 /*-
2 * Copyright (c) 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #if defined(LIBC_SCCS) && !defined(lint)
35 static char sccsid[] = "@(#)rec_get.c 8.1 (Berkeley) 6/4/93";
36 #endif /* LIBC_SCCS and not lint */
37
38 #include <sys/types.h>
39
40 #include <errno.h>
41 #include <stddef.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46
47 #include <db.h>
48 #include "recno.h"
49
50 /*
51 * __REC_GET -- Get a record from the btree.
52 *
53 * Parameters:
54 * dbp: pointer to access method
55 * key: key to find
56 * data: data to return
57 * flag: currently unused
58 *
59 * Returns:
60 * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
61 */
62 int
63 __rec_get(dbp, key, data, flags)
64 const DB *dbp;
65 const DBT *key;
66 DBT *data;
67 u_int flags;
68 {
69 BTREE *t;
70 EPG *e;
71 recno_t nrec;
72 int status;
73
74 if (flags || (nrec = *(recno_t *)key->data) == 0) {
75 errno = EINVAL;
76 return (RET_ERROR);
77 }
78
79 /*
80 * If we haven't seen this record yet, try to find it in the
81 * original file.
82 */
83 t = dbp->internal;
84 if (nrec > t->bt_nrecs) {
85 if (ISSET(t, R_EOF | R_INMEM))
86 return (RET_SPECIAL);
87 if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
88 return (status);
89 }
90
91 --nrec;
92 if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
93 return (RET_ERROR);
94
95 status = __rec_ret(t, e, 0, NULL, data);
96 mpool_put(t->bt_mp, e->page, 0);
97 return (status);
98 }
99
100 /*
101 * __REC_FPIPE -- Get fixed length records from a pipe.
102 *
103 * Parameters:
104 * t: tree
105 * cnt: records to read
106 *
107 * Returns:
108 * RET_ERROR, RET_SUCCESS
109 */
110 int
111 __rec_fpipe(t, top)
112 BTREE *t;
113 recno_t top;
114 {
115 DBT data;
116 recno_t nrec;
117 size_t len;
118 int ch;
119 char *p;
120
121 data.data = t->bt_dbuf;
122 data.size = t->bt_reclen;
123
124 if (t->bt_dbufsz < t->bt_reclen) {
125 if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
126 return (RET_ERROR);
127 t->bt_dbufsz = t->bt_reclen;
128 }
129 for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
130 len = t->bt_reclen;
131 for (p = t->bt_dbuf;; *p++ = ch)
132 if ((ch = getc(t->bt_rfp)) == EOF || !len--) {
133 if (__rec_iput(t, nrec, &data, 0)
134 != RET_SUCCESS)
135 return (RET_ERROR);
136 break;
137 }
138 if (ch == EOF)
139 break;
140 }
141 if (nrec < top) {
142 SET(t, R_EOF);
143 return (RET_SPECIAL);
144 }
145 return (RET_SUCCESS);
146 }
147
148 /*
149 * __REC_VPIPE -- Get variable length records from a pipe.
150 *
151 * Parameters:
152 * t: tree
153 * cnt: records to read
154 *
155 * Returns:
156 * RET_ERROR, RET_SUCCESS
157 */
158 int
159 __rec_vpipe(t, top)
160 BTREE *t;
161 recno_t top;
162 {
163 DBT data;
164 recno_t nrec;
165 indx_t len;
166 size_t sz;
167 int bval, ch;
168 char *p;
169
170 bval = t->bt_bval;
171 for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
172 for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) {
173 if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
174 data.data = t->bt_dbuf;
175 data.size = p - t->bt_dbuf;
176 if (ch == EOF && data.size == 0)
177 break;
178 if (__rec_iput(t, nrec, &data, 0)
179 != RET_SUCCESS)
180 return (RET_ERROR);
181 break;
182 }
183 if (sz == 0) {
184 len = p - t->bt_dbuf;
185 t->bt_dbufsz += (sz = 256);
186 if ((t->bt_dbuf =
187 realloc(t->bt_dbuf, t->bt_dbufsz)) == NULL)
188 return (RET_ERROR);
189 p = t->bt_dbuf + len;
190 }
191 }
192 if (ch == EOF)
193 break;
194 }
195 if (nrec < top) {
196 SET(t, R_EOF);
197 return (RET_SPECIAL);
198 }
199 return (RET_SUCCESS);
200 }
201
202 /*
203 * __REC_FMAP -- Get fixed length records from a file.
204 *
205 * Parameters:
206 * t: tree
207 * cnt: records to read
208 *
209 * Returns:
210 * RET_ERROR, RET_SUCCESS
211 */
212 int
213 __rec_fmap(t, top)
214 BTREE *t;
215 recno_t top;
216 {
217 DBT data;
218 recno_t nrec;
219 caddr_t sp, ep;
220 size_t len;
221 char *p;
222
223 sp = t->bt_cmap;
224 ep = t->bt_emap;
225 data.data = t->bt_dbuf;
226 data.size = t->bt_reclen;
227
228 if (t->bt_dbufsz < t->bt_reclen) {
229 if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
230 return (RET_ERROR);
231 t->bt_dbufsz = t->bt_reclen;
232 }
233 for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
234 if (sp >= ep) {
235 SET(t, R_EOF);
236 return (RET_SPECIAL);
237 }
238 len = t->bt_reclen;
239 for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++);
240 memset(p, t->bt_bval, len);
241 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
242 return (RET_ERROR);
243 }
244 t->bt_cmap = sp;
245 return (RET_SUCCESS);
246 }
247
248 /*
249 * __REC_VMAP -- Get variable length records from a file.
250 *
251 * Parameters:
252 * t: tree
253 * cnt: records to read
254 *
255 * Returns:
256 * RET_ERROR, RET_SUCCESS
257 */
258 int
259 __rec_vmap(t, top)
260 BTREE *t;
261 recno_t top;
262 {
263 DBT data;
264 caddr_t sp, ep;
265 recno_t nrec;
266 int bval;
267
268 sp = t->bt_cmap;
269 ep = t->bt_emap;
270 bval = t->bt_bval;
271
272 for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
273 if (sp >= ep) {
274 SET(t, R_EOF);
275 return (RET_SPECIAL);
276 }
277 for (data.data = sp; sp < ep && *sp != bval; ++sp);
278 data.size = sp - (caddr_t)data.data;
279 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
280 return (RET_ERROR);
281 ++sp;
282 }
283 t->bt_cmap = sp;
284 return (RET_SUCCESS);
285 }
286