xref: /original-bsd/lib/libc/db/recno/rec_get.c (revision c3e32dec)
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.1 (Berkeley) 06/04/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) {
59 		if (ISSET(t, R_EOF | R_INMEM))
60 			return (RET_SPECIAL);
61 		if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
62 			return (status);
63 	}
64 
65 	--nrec;
66 	if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
67 		return (RET_ERROR);
68 
69 	status = __rec_ret(t, e, 0, NULL, 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 	DBT data;
90 	recno_t nrec;
91 	size_t len;
92 	int ch;
93 	char *p;
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 		SET(t, R_EOF);
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 	indx_t len;
140 	size_t sz;
141 	int bval, ch;
142 	char *p;
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 (ch == EOF && data.size == 0)
151 					break;
152 				if (__rec_iput(t, nrec, &data, 0)
153 				    != RET_SUCCESS)
154 					return (RET_ERROR);
155 				break;
156 			}
157 			if (sz == 0) {
158 				len = p - t->bt_dbuf;
159 				t->bt_dbufsz += (sz = 256);
160 				if ((t->bt_dbuf =
161 				    realloc(t->bt_dbuf, t->bt_dbufsz)) == NULL)
162 					return (RET_ERROR);
163 				p = t->bt_dbuf + len;
164 			}
165 		}
166 		if (ch == EOF)
167 			break;
168 	}
169 	if (nrec < top) {
170 		SET(t, R_EOF);
171 		return (RET_SPECIAL);
172 	}
173 	return (RET_SUCCESS);
174 }
175 
176 /*
177  * __REC_FMAP -- Get fixed length records from a file.
178  *
179  * Parameters:
180  *	t:	tree
181  *	cnt:	records to read
182  *
183  * Returns:
184  *	RET_ERROR, RET_SUCCESS
185  */
186 int
187 __rec_fmap(t, top)
188 	BTREE *t;
189 	recno_t top;
190 {
191 	DBT data;
192 	recno_t nrec;
193 	caddr_t sp, ep;
194 	size_t len;
195 	char *p;
196 
197 	sp = t->bt_cmap;
198 	ep = t->bt_emap;
199 	data.data = t->bt_dbuf;
200 	data.size = t->bt_reclen;
201 
202 	if (t->bt_dbufsz < t->bt_reclen) {
203 		if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
204 			return (RET_ERROR);
205 		t->bt_dbufsz = t->bt_reclen;
206 	}
207 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
208 		if (sp >= ep) {
209 			SET(t, R_EOF);
210 			return (RET_SPECIAL);
211 		}
212 		len = t->bt_reclen;
213 		for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++);
214 		memset(p, t->bt_bval, len);
215 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
216 			return (RET_ERROR);
217 	}
218 	t->bt_cmap = sp;
219 	return (RET_SUCCESS);
220 }
221 
222 /*
223  * __REC_VMAP -- Get variable length records from a file.
224  *
225  * Parameters:
226  *	t:	tree
227  *	cnt:	records to read
228  *
229  * Returns:
230  *	RET_ERROR, RET_SUCCESS
231  */
232 int
233 __rec_vmap(t, top)
234 	BTREE *t;
235 	recno_t top;
236 {
237 	DBT data;
238 	caddr_t sp, ep;
239 	recno_t nrec;
240 	int bval;
241 
242 	sp = t->bt_cmap;
243 	ep = t->bt_emap;
244 	bval = t->bt_bval;
245 
246 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
247 		if (sp >= ep) {
248 			SET(t, R_EOF);
249 			return (RET_SPECIAL);
250 		}
251 		for (data.data = sp; sp < ep && *sp != bval; ++sp);
252 		data.size = sp - (caddr_t)data.data;
253 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
254 			return (RET_ERROR);
255 		++sp;
256 	}
257 	t->bt_cmap = sp;
258 	return (RET_SUCCESS);
259 }
260