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