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