xref: /original-bsd/lib/libc/db/recno/rec_get.c (revision 95ecee29)
1 /*-
2  * Copyright (c) 1990, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)rec_get.c	8.2 (Berkeley) 09/07/93";
10 #endif /* LIBC_SCCS and not lint */
11 
12 #include <sys/types.h>
13 
14 #include <errno.h>
15 #include <stddef.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20 
21 #include <db.h>
22 #include "recno.h"
23 
24 /*
25  * __REC_GET -- Get a record from the btree.
26  *
27  * Parameters:
28  *	dbp:	pointer to access method
29  *	key:	key to find
30  *	data:	data to return
31  *	flag:	currently unused
32  *
33  * Returns:
34  *	RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
35  */
36 int
37 __rec_get(dbp, key, data, flags)
38 	const DB *dbp;
39 	const DBT *key;
40 	DBT *data;
41 	u_int flags;
42 {
43 	BTREE *t;
44 	EPG *e;
45 	recno_t nrec;
46 	int status;
47 
48 	t = dbp->internal;
49 
50 	/* Toss any page pinned across calls. */
51 	if (t->bt_pinned != NULL) {
52 		mpool_put(t->bt_mp, t->bt_pinned, 0);
53 		t->bt_pinned = NULL;
54 	}
55 
56 	/* Get currently doesn't take any flags, and keys of 0 are illegal. */
57 	if (flags || (nrec = *(recno_t *)key->data) == 0) {
58 		errno = EINVAL;
59 		return (RET_ERROR);
60 	}
61 
62 	/*
63 	 * If we haven't seen this record yet, try to find it in the
64 	 * original file.
65 	 */
66 	if (nrec > t->bt_nrecs) {
67 		if (ISSET(t, R_EOF | R_INMEM))
68 			return (RET_SPECIAL);
69 		if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
70 			return (status);
71 	}
72 
73 	--nrec;
74 	if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
75 		return (RET_ERROR);
76 
77 	status = __rec_ret(t, e, 0, NULL, data);
78 	if (ISSET(t, B_DB_LOCK))
79 		mpool_put(t->bt_mp, e->page, 0);
80 	else
81 		t->bt_pinned = e->page;
82 	return (status);
83 }
84 
85 /*
86  * __REC_FPIPE -- Get fixed length records from a pipe.
87  *
88  * Parameters:
89  *	t:	tree
90  *	cnt:	records to read
91  *
92  * Returns:
93  *	RET_ERROR, RET_SUCCESS
94  */
95 int
96 __rec_fpipe(t, top)
97 	BTREE *t;
98 	recno_t top;
99 {
100 	DBT data;
101 	recno_t nrec;
102 	size_t len;
103 	int ch;
104 	char *p;
105 
106 	data.data = t->bt_dbuf;
107 	data.size = t->bt_reclen;
108 
109 	if (t->bt_dbufsz < t->bt_reclen) {
110 		if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
111 			return (RET_ERROR);
112 		t->bt_dbufsz = t->bt_reclen;
113 	}
114 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
115 		len = t->bt_reclen;
116 		for (p = t->bt_dbuf;; *p++ = ch)
117 			if ((ch = getc(t->bt_rfp)) == EOF || !len--) {
118 				if (__rec_iput(t, nrec, &data, 0)
119 				    != RET_SUCCESS)
120 					return (RET_ERROR);
121 				break;
122 			}
123 		if (ch == EOF)
124 			break;
125 	}
126 	if (nrec < top) {
127 		SET(t, R_EOF);
128 		return (RET_SPECIAL);
129 	}
130 	return (RET_SUCCESS);
131 }
132 
133 /*
134  * __REC_VPIPE -- Get variable length records from a pipe.
135  *
136  * Parameters:
137  *	t:	tree
138  *	cnt:	records to read
139  *
140  * Returns:
141  *	RET_ERROR, RET_SUCCESS
142  */
143 int
144 __rec_vpipe(t, top)
145 	BTREE *t;
146 	recno_t top;
147 {
148 	DBT data;
149 	recno_t nrec;
150 	indx_t len;
151 	size_t sz;
152 	int bval, ch;
153 	char *p;
154 
155 	bval = t->bt_bval;
156 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
157 		for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) {
158 			if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
159 				data.data = t->bt_dbuf;
160 				data.size = p - t->bt_dbuf;
161 				if (ch == EOF && data.size == 0)
162 					break;
163 				if (__rec_iput(t, nrec, &data, 0)
164 				    != RET_SUCCESS)
165 					return (RET_ERROR);
166 				break;
167 			}
168 			if (sz == 0) {
169 				len = p - t->bt_dbuf;
170 				t->bt_dbufsz += (sz = 256);
171 				if ((t->bt_dbuf =
172 				    realloc(t->bt_dbuf, t->bt_dbufsz)) == NULL)
173 					return (RET_ERROR);
174 				p = t->bt_dbuf + len;
175 			}
176 		}
177 		if (ch == EOF)
178 			break;
179 	}
180 	if (nrec < top) {
181 		SET(t, R_EOF);
182 		return (RET_SPECIAL);
183 	}
184 	return (RET_SUCCESS);
185 }
186 
187 /*
188  * __REC_FMAP -- Get fixed length records from a file.
189  *
190  * Parameters:
191  *	t:	tree
192  *	cnt:	records to read
193  *
194  * Returns:
195  *	RET_ERROR, RET_SUCCESS
196  */
197 int
198 __rec_fmap(t, top)
199 	BTREE *t;
200 	recno_t top;
201 {
202 	DBT data;
203 	recno_t nrec;
204 	caddr_t sp, ep;
205 	size_t len;
206 	char *p;
207 
208 	sp = t->bt_cmap;
209 	ep = t->bt_emap;
210 	data.data = t->bt_dbuf;
211 	data.size = t->bt_reclen;
212 
213 	if (t->bt_dbufsz < t->bt_reclen) {
214 		if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
215 			return (RET_ERROR);
216 		t->bt_dbufsz = t->bt_reclen;
217 	}
218 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
219 		if (sp >= ep) {
220 			SET(t, R_EOF);
221 			return (RET_SPECIAL);
222 		}
223 		len = t->bt_reclen;
224 		for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++);
225 		memset(p, t->bt_bval, len);
226 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
227 			return (RET_ERROR);
228 	}
229 	t->bt_cmap = sp;
230 	return (RET_SUCCESS);
231 }
232 
233 /*
234  * __REC_VMAP -- Get variable length records from a file.
235  *
236  * Parameters:
237  *	t:	tree
238  *	cnt:	records to read
239  *
240  * Returns:
241  *	RET_ERROR, RET_SUCCESS
242  */
243 int
244 __rec_vmap(t, top)
245 	BTREE *t;
246 	recno_t top;
247 {
248 	DBT data;
249 	caddr_t sp, ep;
250 	recno_t nrec;
251 	int bval;
252 
253 	sp = t->bt_cmap;
254 	ep = t->bt_emap;
255 	bval = t->bt_bval;
256 
257 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
258 		if (sp >= ep) {
259 			SET(t, R_EOF);
260 			return (RET_SPECIAL);
261 		}
262 		for (data.data = sp; sp < ep && *sp != bval; ++sp);
263 		data.size = sp - (caddr_t)data.data;
264 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
265 			return (RET_ERROR);
266 		++sp;
267 	}
268 	t->bt_cmap = sp;
269 	return (RET_SUCCESS);
270 }
271