xref: /csrg-svn/lib/libc/db/recno/rec_get.c (revision 58747)
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.8 (Berkeley) 03/19/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, BTF_EOF | BTF_RINMEM))
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, BTF_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 (__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 				t->bt_dbufsz += (sz = 256);
158 				if ((t->bt_dbuf =
159 				    realloc(t->bt_dbuf, t->bt_dbufsz)) == 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 		SET(t, BTF_EOF);
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 	sp = t->bt_cmap;
196 	ep = t->bt_emap;
197 	data.data = t->bt_dbuf;
198 	data.size = t->bt_reclen;
199 
200 	if (t->bt_dbufsz < t->bt_reclen) {
201 		if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
202 			return (RET_ERROR);
203 		t->bt_dbufsz = t->bt_reclen;
204 	}
205 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
206 		if (sp >= ep) {
207 			SET(t, BTF_EOF);
208 			return (RET_SPECIAL);
209 		}
210 		len = t->bt_reclen;
211 		for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++);
212 		memset(p, t->bt_bval, len);
213 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
214 			return (RET_ERROR);
215 	}
216 	t->bt_cmap = sp;
217 	return (RET_SUCCESS);
218 }
219 
220 /*
221  * __REC_VMAP -- Get variable length records from a file.
222  *
223  * Parameters:
224  *	t:	tree
225  *	cnt:	records to read
226  *
227  * Returns:
228  *	RET_ERROR, RET_SUCCESS
229  */
230 int
231 __rec_vmap(t, top)
232 	BTREE *t;
233 	recno_t top;
234 {
235 	DBT data;
236 	caddr_t sp, ep;
237 	recno_t nrec;
238 	int bval;
239 
240 	sp = t->bt_cmap;
241 	ep = t->bt_emap;
242 	bval = t->bt_bval;
243 
244 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
245 		if (sp >= ep) {
246 			SET(t, BTF_EOF);
247 			return (RET_SPECIAL);
248 		}
249 		for (data.data = sp; sp < ep && *sp != bval; ++sp);
250 		data.size = sp - (caddr_t)data.data;
251 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
252 			return (RET_ERROR);
253 		++sp;
254 	}
255 	t->bt_cmap = sp;
256 	return (RET_SUCCESS);
257 }
258