xref: /original-bsd/lib/libc/db/recno/rec_get.c (revision f737e041)
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.4 (Berkeley) 03/01/94";
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 	if (t->bt_dbufsz < t->bt_reclen) {
107 		if ((t->bt_dbuf =
108 		    (char *)realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
109 			return (RET_ERROR);
110 		t->bt_dbufsz = t->bt_reclen;
111 	}
112 	data.data = t->bt_dbuf;
113 	data.size = t->bt_reclen;
114 
115 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
116 		len = t->bt_reclen;
117 		for (p = t->bt_dbuf;; *p++ = ch)
118 			if ((ch = getc(t->bt_rfp)) == EOF || !len--) {
119 				if (__rec_iput(t, nrec, &data, 0)
120 				    != RET_SUCCESS)
121 					return (RET_ERROR);
122 				break;
123 			}
124 		if (ch == EOF)
125 			break;
126 	}
127 	if (nrec < top) {
128 		SET(t, R_EOF);
129 		return (RET_SPECIAL);
130 	}
131 	return (RET_SUCCESS);
132 }
133 
134 /*
135  * __REC_VPIPE -- Get variable length records from a pipe.
136  *
137  * Parameters:
138  *	t:	tree
139  *	cnt:	records to read
140  *
141  * Returns:
142  *	RET_ERROR, RET_SUCCESS
143  */
144 int
145 __rec_vpipe(t, top)
146 	BTREE *t;
147 	recno_t top;
148 {
149 	DBT data;
150 	recno_t nrec;
151 	indx_t len;
152 	size_t sz;
153 	int bval, ch;
154 	char *p;
155 
156 	bval = t->bt_bval;
157 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
158 		for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) {
159 			if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
160 				data.data = t->bt_dbuf;
161 				data.size = p - t->bt_dbuf;
162 				if (ch == EOF && data.size == 0)
163 					break;
164 				if (__rec_iput(t, nrec, &data, 0)
165 				    != RET_SUCCESS)
166 					return (RET_ERROR);
167 				break;
168 			}
169 			if (sz == 0) {
170 				len = p - t->bt_dbuf;
171 				t->bt_dbufsz += (sz = 256);
172 				if ((t->bt_dbuf = (char *)realloc(t->bt_dbuf,
173 				    t->bt_dbufsz)) == NULL)
174 					return (RET_ERROR);
175 				p = t->bt_dbuf + len;
176 			}
177 		}
178 		if (ch == EOF)
179 			break;
180 	}
181 	if (nrec < top) {
182 		SET(t, R_EOF);
183 		return (RET_SPECIAL);
184 	}
185 	return (RET_SUCCESS);
186 }
187 
188 /*
189  * __REC_FMAP -- Get fixed length records from a file.
190  *
191  * Parameters:
192  *	t:	tree
193  *	cnt:	records to read
194  *
195  * Returns:
196  *	RET_ERROR, RET_SUCCESS
197  */
198 int
199 __rec_fmap(t, top)
200 	BTREE *t;
201 	recno_t top;
202 {
203 	DBT data;
204 	recno_t nrec;
205 	caddr_t sp, ep;
206 	size_t len;
207 	char *p;
208 
209 	if (t->bt_dbufsz < t->bt_reclen) {
210 		if ((t->bt_dbuf =
211 		    (char *)realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
212 			return (RET_ERROR);
213 		t->bt_dbufsz = t->bt_reclen;
214 	}
215 	data.data = t->bt_dbuf;
216 	data.size = t->bt_reclen;
217 
218 	sp = t->bt_cmap;
219 	ep = t->bt_emap;
220 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
221 		if (sp >= ep) {
222 			SET(t, R_EOF);
223 			return (RET_SPECIAL);
224 		}
225 		len = t->bt_reclen;
226 		for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++);
227 		memset(p, t->bt_bval, len);
228 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
229 			return (RET_ERROR);
230 	}
231 	t->bt_cmap = sp;
232 	return (RET_SUCCESS);
233 }
234 
235 /*
236  * __REC_VMAP -- Get variable 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  */
245 int
246 __rec_vmap(t, top)
247 	BTREE *t;
248 	recno_t top;
249 {
250 	DBT data;
251 	caddr_t sp, ep;
252 	recno_t nrec;
253 	int bval;
254 
255 	sp = t->bt_cmap;
256 	ep = t->bt_emap;
257 	bval = t->bt_bval;
258 
259 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
260 		if (sp >= ep) {
261 			SET(t, R_EOF);
262 			return (RET_SPECIAL);
263 		}
264 		for (data.data = sp; sp < ep && *sp != bval; ++sp);
265 		data.size = sp - (caddr_t)data.data;
266 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
267 			return (RET_ERROR);
268 		++sp;
269 	}
270 	t->bt_cmap = sp;
271 	return (RET_SUCCESS);
272 }
273