xref: /csrg-svn/lib/libc/db/recno/rec_get.c (revision 54279)
150995Sbostic /*-
250995Sbostic  * Copyright (c) 1990 The Regents of the University of California.
350995Sbostic  * All rights reserved.
450995Sbostic  *
550995Sbostic  * %sccs.include.redist.c%
650995Sbostic  */
750995Sbostic 
850995Sbostic #if defined(LIBC_SCCS) && !defined(lint)
9*54279Sbostic static char sccsid[] = "@(#)rec_get.c	5.3 (Berkeley) 06/23/92";
1050995Sbostic #endif /* LIBC_SCCS and not lint */
1150995Sbostic 
1250995Sbostic #include <sys/types.h>
1350995Sbostic #include <errno.h>
1450995Sbostic #include <db.h>
1550995Sbostic #include <unistd.h>
1650995Sbostic #include <stddef.h>
1750995Sbostic #include <stdio.h>
1850995Sbostic #include <stdlib.h>
1950995Sbostic #include <string.h>
2051086Sbostic #include "recno.h"
2150995Sbostic 
2250995Sbostic /*
2350995Sbostic  * __REC_GET -- Get a record from the btree.
2450995Sbostic  *
2550995Sbostic  * Parameters:
2650995Sbostic  *	dbp:	pointer to access method
2750995Sbostic  *	key:	key to find
2850995Sbostic  *	data:	data to return
2950995Sbostic  *	flag:	currently unused
3050995Sbostic  *
3150995Sbostic  * Returns:
3250995Sbostic  *	RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
3350995Sbostic  */
3450995Sbostic int
3550995Sbostic __rec_get(dbp, key, data, flags)
3650995Sbostic 	const DB *dbp;
3751086Sbostic 	const DBT *key;
3851086Sbostic 	DBT *data;
3950995Sbostic 	u_int flags;
4050995Sbostic {
4150995Sbostic 	BTREE *t;
4250995Sbostic 	EPG *e;
4350995Sbostic 	recno_t nrec;
44*54279Sbostic 	int status;
4550995Sbostic 
4650995Sbostic 	if (flags || (nrec = *(recno_t *)key->data) == 0) {
4750995Sbostic 		errno = EINVAL;
4850995Sbostic 		return (RET_ERROR);
4950995Sbostic 	}
5050995Sbostic 
5150995Sbostic 	/*
5250995Sbostic 	 * If we haven't seen this record yet, try to find it in the
5350995Sbostic 	 * original file.
5450995Sbostic 	 */
5550995Sbostic 	t = dbp->internal;
56*54279Sbostic 	if (nrec > t->bt_nrecs &&
57*54279Sbostic 	    (status = t->bt_irec(t, nrec)) != RET_SUCCESS)
5850995Sbostic 			return (status);
5950995Sbostic 
6050995Sbostic 	--nrec;
6151086Sbostic 	if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
6250995Sbostic 		return (RET_ERROR);
6350995Sbostic 
6450995Sbostic 	status = __rec_ret(t, e, data);
6550995Sbostic 	mpool_put(t->bt_mp, e->page, 0);
6650995Sbostic 	return (status);
6750995Sbostic }
6850995Sbostic 
6950995Sbostic /*
7050995Sbostic  * __REC_FPIPE -- Get fixed length records from a pipe.
7150995Sbostic  *
7250995Sbostic  * Parameters:
7350995Sbostic  *	t:	tree
7450995Sbostic  *	cnt:	records to read
7550995Sbostic  *
7650995Sbostic  * Returns:
7750995Sbostic  *	RET_ERROR, RET_SUCCESS
7850995Sbostic  */
7950995Sbostic int
8050995Sbostic __rec_fpipe(t, top)
8150995Sbostic 	BTREE *t;
8250995Sbostic 	recno_t top;
8350995Sbostic {
8450995Sbostic 	DBT data;
8550995Sbostic 	recno_t nrec;
8650995Sbostic 	size_t len;
8750995Sbostic 	int ch;
8850995Sbostic 	char *p;
8950995Sbostic 
90*54279Sbostic 	if (t->bt_reof)
9150995Sbostic 		return (RET_SPECIAL);
9250995Sbostic 
9350995Sbostic 	data.data = t->bt_dbuf;
9450995Sbostic 	data.size = t->bt_reclen;
9550995Sbostic 
9650995Sbostic 	if (t->bt_dbufsz < t->bt_reclen) {
9750995Sbostic 		if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
9850995Sbostic 			return (RET_ERROR);
9950995Sbostic 		t->bt_dbufsz = t->bt_reclen;
10050995Sbostic 	}
10150995Sbostic 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
10250995Sbostic 		for (p = t->bt_dbuf;; *p++ = ch)
10350995Sbostic 			if ((ch = getc(t->bt_rfp)) == EOF || !len--) {
10450995Sbostic 				if (__rec_iput(t, nrec, &data, 0)
10550995Sbostic 				    != RET_SUCCESS)
10650995Sbostic 					return (RET_ERROR);
10750995Sbostic 				break;
10850995Sbostic 			}
10950995Sbostic 		if (ch == EOF)
11050995Sbostic 			break;
11150995Sbostic 	}
11250995Sbostic 	if (nrec < top) {
113*54279Sbostic 		t->bt_reof = 1;
11450995Sbostic 		return (RET_SPECIAL);
11550995Sbostic 	}
11650995Sbostic 	return (RET_SUCCESS);
11750995Sbostic }
11850995Sbostic 
11950995Sbostic /*
12050995Sbostic  * __REC_VPIPE -- Get variable length records from a pipe.
12150995Sbostic  *
12250995Sbostic  * Parameters:
12350995Sbostic  *	t:	tree
12450995Sbostic  *	cnt:	records to read
12550995Sbostic  *
12650995Sbostic  * Returns:
12750995Sbostic  *	RET_ERROR, RET_SUCCESS
12850995Sbostic  */
12950995Sbostic int
13050995Sbostic __rec_vpipe(t, top)
13150995Sbostic 	BTREE *t;
13250995Sbostic 	recno_t top;
13350995Sbostic {
13450995Sbostic 	DBT data;
13550995Sbostic 	recno_t nrec;
13650995Sbostic 	index_t len;
13750995Sbostic 	size_t sz;
13850995Sbostic 	int bval, ch;
13950995Sbostic 	char *p;
14050995Sbostic 
141*54279Sbostic 	if (t->bt_reof)
14250995Sbostic 		return (RET_SPECIAL);
14350995Sbostic 
14450995Sbostic 	bval = t->bt_bval;
14550995Sbostic 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
14650995Sbostic 		for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) {
14750995Sbostic 			if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
14850995Sbostic 				data.data = t->bt_dbuf;
14950995Sbostic 				data.size = p - t->bt_dbuf;
15050995Sbostic 				if (__rec_iput(t, nrec, &data, 0)
15150995Sbostic 				    != RET_SUCCESS)
15250995Sbostic 					return (RET_ERROR);
15350995Sbostic 				break;
15450995Sbostic 			}
15550995Sbostic 			if (sz == 0) {
15650995Sbostic 				len = p - t->bt_dbuf;
15750995Sbostic 				sz = t->bt_dbufsz += 256;
15850995Sbostic 				if ((t->bt_dbuf =
15950995Sbostic 				    realloc(t->bt_dbuf, sz)) == NULL)
16050995Sbostic 					return (RET_ERROR);
16150995Sbostic 				p = t->bt_dbuf + len;
16250995Sbostic 			}
16350995Sbostic 		}
16450995Sbostic 		if (ch == EOF)
16550995Sbostic 			break;
16650995Sbostic 	}
16750995Sbostic 	if (nrec < top) {
168*54279Sbostic 		t->bt_reof = 1;
16950995Sbostic 		return (RET_SPECIAL);
17050995Sbostic 	}
17150995Sbostic 	return (RET_SUCCESS);
17250995Sbostic }
17350995Sbostic 
17450995Sbostic /*
17550995Sbostic  * __REC_FMAP -- Get fixed length records from a file.
17650995Sbostic  *
17750995Sbostic  * Parameters:
17850995Sbostic  *	t:	tree
17950995Sbostic  *	cnt:	records to read
18050995Sbostic  *
18150995Sbostic  * Returns:
18250995Sbostic  *	RET_ERROR, RET_SUCCESS
18350995Sbostic  */
18450995Sbostic int
18550995Sbostic __rec_fmap(t, top)
18650995Sbostic 	BTREE *t;
18750995Sbostic 	recno_t top;
18850995Sbostic {
18950995Sbostic 	DBT data;
19050995Sbostic 	recno_t nrec;
19150995Sbostic 	caddr_t sp, ep;
19250995Sbostic 	size_t len;
19350995Sbostic 	char *p;
19450995Sbostic 
195*54279Sbostic 	if (t->bt_reof)
19650995Sbostic 		return (RET_SPECIAL);
19750995Sbostic 
19850995Sbostic 	sp = t->bt_smap;
19950995Sbostic 	ep = t->bt_emap;
20050995Sbostic 	data.data = t->bt_dbuf;
20150995Sbostic 	data.size = t->bt_reclen;
20250995Sbostic 
20350995Sbostic 	if (t->bt_dbufsz < t->bt_reclen) {
20450995Sbostic 		if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
20550995Sbostic 			return (RET_ERROR);
20650995Sbostic 		t->bt_dbufsz = t->bt_reclen;
20750995Sbostic 	}
20850995Sbostic 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
20950995Sbostic 		if (sp >= ep) {
210*54279Sbostic 			t->bt_reof = 1;
21150995Sbostic 			return (RET_SPECIAL);
21250995Sbostic 		}
21350995Sbostic 		len = t->bt_reclen;
21450995Sbostic 		for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++);
21550995Sbostic 		memset(p, t->bt_bval, len);
21650995Sbostic 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
21750995Sbostic 			return (RET_ERROR);
21850995Sbostic 	}
21950995Sbostic 	t->bt_smap = sp;
22050995Sbostic 	return (RET_SUCCESS);
22150995Sbostic }
22250995Sbostic 
22350995Sbostic /*
22450995Sbostic  * __REC_VMAP -- Get variable length records from a file.
22550995Sbostic  *
22650995Sbostic  * Parameters:
22750995Sbostic  *	t:	tree
22850995Sbostic  *	cnt:	records to read
22950995Sbostic  *
23050995Sbostic  * Returns:
23150995Sbostic  *	RET_ERROR, RET_SUCCESS
23250995Sbostic  */
23350995Sbostic int
23450995Sbostic __rec_vmap(t, top)
23550995Sbostic 	BTREE *t;
23650995Sbostic 	recno_t top;
23750995Sbostic {
23850995Sbostic 	DBT data;
23951086Sbostic 	caddr_t sp, ep;
24050995Sbostic 	recno_t nrec;
24150995Sbostic 	int bval;
24250995Sbostic 
243*54279Sbostic 	if (t->bt_reof)
24450995Sbostic 		return (RET_SPECIAL);
24550995Sbostic 
24650995Sbostic 	sp = t->bt_smap;
24750995Sbostic 	ep = t->bt_emap;
24850995Sbostic 	bval = t->bt_bval;
24950995Sbostic 
25050995Sbostic 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
25150995Sbostic 		if (sp >= ep) {
252*54279Sbostic 			t->bt_reof = 1;
25350995Sbostic 			return (RET_SPECIAL);
25450995Sbostic 		}
25550995Sbostic 		for (data.data = sp; sp < ep && *sp != bval; ++sp);
25650995Sbostic 		data.size = sp - (caddr_t)data.data;
25750995Sbostic 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
25850995Sbostic 			return (RET_ERROR);
25950995Sbostic 		++sp;
26050995Sbostic 	}
26150995Sbostic 	t->bt_smap = sp;
26250995Sbostic 	return (RET_SUCCESS);
26350995Sbostic }
264