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