xref: /csrg-svn/lib/libc/db/recno/rec_get.c (revision 57933)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * 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	5.5 (Berkeley) 02/11/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 	if (flags || (nrec = *(recno_t *)key->data) == 0) {
49 		errno = EINVAL;
50 		return (RET_ERROR);
51 	}
52 
53 	/*
54 	 * If we haven't seen this record yet, try to find it in the
55 	 * original file.
56 	 */
57 	t = dbp->internal;
58 	if (nrec > t->bt_nrecs && (ISSET(t, BTF_RINMEM) ||
59 	    (status = t->bt_irec(t, nrec)) != RET_SUCCESS))
60 			return (status);
61 
62 	--nrec;
63 	if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
64 		return (RET_ERROR);
65 
66 	status = __rec_ret(t, e, 0, NULL, data);
67 	mpool_put(t->bt_mp, e->page, 0);
68 	return (status);
69 }
70 
71 /*
72  * __REC_FPIPE -- Get fixed length records from a pipe.
73  *
74  * Parameters:
75  *	t:	tree
76  *	cnt:	records to read
77  *
78  * Returns:
79  *	RET_ERROR, RET_SUCCESS
80  */
81 int
82 __rec_fpipe(t, top)
83 	BTREE *t;
84 	recno_t top;
85 {
86 	DBT data;
87 	recno_t nrec;
88 	size_t len;
89 	int ch;
90 	char *p;
91 
92 	if (t->bt_reof)
93 		return (RET_SPECIAL);
94 
95 	data.data = t->bt_dbuf;
96 	data.size = t->bt_reclen;
97 
98 	if (t->bt_dbufsz < t->bt_reclen) {
99 		if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
100 			return (RET_ERROR);
101 		t->bt_dbufsz = t->bt_reclen;
102 	}
103 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
104 		len = t->bt_reclen;
105 		for (p = t->bt_dbuf;; *p++ = ch)
106 			if ((ch = getc(t->bt_rfp)) == EOF || !len--) {
107 				if (__rec_iput(t, nrec, &data, 0)
108 				    != RET_SUCCESS)
109 					return (RET_ERROR);
110 				break;
111 			}
112 		if (ch == EOF)
113 			break;
114 	}
115 	if (nrec < top) {
116 		t->bt_reof = 1;
117 		return (RET_SPECIAL);
118 	}
119 	return (RET_SUCCESS);
120 }
121 
122 /*
123  * __REC_VPIPE -- Get variable length records from a pipe.
124  *
125  * Parameters:
126  *	t:	tree
127  *	cnt:	records to read
128  *
129  * Returns:
130  *	RET_ERROR, RET_SUCCESS
131  */
132 int
133 __rec_vpipe(t, top)
134 	BTREE *t;
135 	recno_t top;
136 {
137 	DBT data;
138 	recno_t nrec;
139 	index_t len;
140 	size_t sz;
141 	int bval, ch;
142 	char *p;
143 
144 	if (t->bt_reof)
145 		return (RET_SPECIAL);
146 
147 	bval = t->bt_bval;
148 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
149 		for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) {
150 			if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
151 				data.data = t->bt_dbuf;
152 				data.size = p - t->bt_dbuf;
153 				if (__rec_iput(t, nrec, &data, 0)
154 				    != RET_SUCCESS)
155 					return (RET_ERROR);
156 				break;
157 			}
158 			if (sz == 0) {
159 				len = p - t->bt_dbuf;
160 				sz = t->bt_dbufsz += 256;
161 				if ((t->bt_dbuf =
162 				    realloc(t->bt_dbuf, sz)) == NULL)
163 					return (RET_ERROR);
164 				p = t->bt_dbuf + len;
165 			}
166 		}
167 		if (ch == EOF)
168 			break;
169 	}
170 	if (nrec < top) {
171 		t->bt_reof = 1;
172 		return (RET_SPECIAL);
173 	}
174 	return (RET_SUCCESS);
175 }
176 
177 /*
178  * __REC_FMAP -- Get fixed length records from a file.
179  *
180  * Parameters:
181  *	t:	tree
182  *	cnt:	records to read
183  *
184  * Returns:
185  *	RET_ERROR, RET_SUCCESS
186  */
187 int
188 __rec_fmap(t, top)
189 	BTREE *t;
190 	recno_t top;
191 {
192 	DBT data;
193 	recno_t nrec;
194 	caddr_t sp, ep;
195 	size_t len;
196 	char *p;
197 
198 	if (t->bt_reof)
199 		return (RET_SPECIAL);
200 
201 	sp = t->bt_smap;
202 	ep = t->bt_emap;
203 	data.data = t->bt_dbuf;
204 	data.size = t->bt_reclen;
205 
206 	if (t->bt_dbufsz < t->bt_reclen) {
207 		if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
208 			return (RET_ERROR);
209 		t->bt_dbufsz = t->bt_reclen;
210 	}
211 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
212 		if (sp >= ep) {
213 			t->bt_reof = 1;
214 			return (RET_SPECIAL);
215 		}
216 		len = t->bt_reclen;
217 		for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++);
218 		memset(p, t->bt_bval, len);
219 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
220 			return (RET_ERROR);
221 	}
222 	t->bt_smap = sp;
223 	return (RET_SUCCESS);
224 }
225 
226 /*
227  * __REC_VMAP -- Get variable length records from a file.
228  *
229  * Parameters:
230  *	t:	tree
231  *	cnt:	records to read
232  *
233  * Returns:
234  *	RET_ERROR, RET_SUCCESS
235  */
236 int
237 __rec_vmap(t, top)
238 	BTREE *t;
239 	recno_t top;
240 {
241 	DBT data;
242 	caddr_t sp, ep;
243 	recno_t nrec;
244 	int bval;
245 
246 	if (t->bt_reof)
247 		return (RET_SPECIAL);
248 
249 	sp = t->bt_smap;
250 	ep = t->bt_emap;
251 	bval = t->bt_bval;
252 
253 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
254 		if (sp >= ep) {
255 			t->bt_reof = 1;
256 			return (RET_SPECIAL);
257 		}
258 		for (data.data = sp; sp < ep && *sp != bval; ++sp);
259 		data.size = sp - (caddr_t)data.data;
260 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
261 			return (RET_ERROR);
262 		++sp;
263 	}
264 	t->bt_smap = sp;
265 	return (RET_SUCCESS);
266 }
267