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