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