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