xref: /csrg-svn/lib/libc/db/recno/rec_get.c (revision 64461)
150995Sbostic /*-
261207Sbostic  * Copyright (c) 1990, 1993
361207Sbostic  *	The Regents of the University of California.  All rights reserved.
450995Sbostic  *
550995Sbostic  * %sccs.include.redist.c%
650995Sbostic  */
750995Sbostic 
850995Sbostic #if defined(LIBC_SCCS) && !defined(lint)
9*64461Sbostic static char sccsid[] = "@(#)rec_get.c	8.2 (Berkeley) 09/07/93";
1050995Sbostic #endif /* LIBC_SCCS and not lint */
1150995Sbostic 
1250995Sbostic #include <sys/types.h>
1356753Sbostic 
1450995Sbostic #include <errno.h>
1550995Sbostic #include <stddef.h>
1650995Sbostic #include <stdio.h>
1750995Sbostic #include <stdlib.h>
1850995Sbostic #include <string.h>
1956753Sbostic #include <unistd.h>
2056753Sbostic 
2157933Sbostic #include <db.h>
2251086Sbostic #include "recno.h"
2350995Sbostic 
2450995Sbostic /*
2550995Sbostic  * __REC_GET -- Get a record from the btree.
2650995Sbostic  *
2750995Sbostic  * Parameters:
2850995Sbostic  *	dbp:	pointer to access method
2950995Sbostic  *	key:	key to find
3050995Sbostic  *	data:	data to return
3150995Sbostic  *	flag:	currently unused
3250995Sbostic  *
3350995Sbostic  * Returns:
3450995Sbostic  *	RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
3550995Sbostic  */
3650995Sbostic int
3750995Sbostic __rec_get(dbp, key, data, flags)
3850995Sbostic 	const DB *dbp;
3951086Sbostic 	const DBT *key;
4051086Sbostic 	DBT *data;
4150995Sbostic 	u_int flags;
4250995Sbostic {
4350995Sbostic 	BTREE *t;
4450995Sbostic 	EPG *e;
4550995Sbostic 	recno_t nrec;
4654279Sbostic 	int status;
4750995Sbostic 
48*64461Sbostic 	t = dbp->internal;
49*64461Sbostic 
50*64461Sbostic 	/* Toss any page pinned across calls. */
51*64461Sbostic 	if (t->bt_pinned != NULL) {
52*64461Sbostic 		mpool_put(t->bt_mp, t->bt_pinned, 0);
53*64461Sbostic 		t->bt_pinned = NULL;
54*64461Sbostic 	}
55*64461Sbostic 
56*64461Sbostic 	/* Get currently doesn't take any flags, and keys of 0 are illegal. */
5750995Sbostic 	if (flags || (nrec = *(recno_t *)key->data) == 0) {
5850995Sbostic 		errno = EINVAL;
5950995Sbostic 		return (RET_ERROR);
6050995Sbostic 	}
6150995Sbostic 
6250995Sbostic 	/*
6350995Sbostic 	 * If we haven't seen this record yet, try to find it in the
6450995Sbostic 	 * original file.
6550995Sbostic 	 */
6658747Sbostic 	if (nrec > t->bt_nrecs) {
6760051Sbostic 		if (ISSET(t, R_EOF | R_INMEM))
6858747Sbostic 			return (RET_SPECIAL);
6958747Sbostic 		if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
7050995Sbostic 			return (status);
7158747Sbostic 	}
7250995Sbostic 
7350995Sbostic 	--nrec;
7451086Sbostic 	if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
7550995Sbostic 		return (RET_ERROR);
7650995Sbostic 
7756753Sbostic 	status = __rec_ret(t, e, 0, NULL, data);
78*64461Sbostic 	if (ISSET(t, B_DB_LOCK))
79*64461Sbostic 		mpool_put(t->bt_mp, e->page, 0);
80*64461Sbostic 	else
81*64461Sbostic 		t->bt_pinned = e->page;
8250995Sbostic 	return (status);
8350995Sbostic }
8450995Sbostic 
8550995Sbostic /*
8650995Sbostic  * __REC_FPIPE -- Get fixed length records from a pipe.
8750995Sbostic  *
8850995Sbostic  * Parameters:
8950995Sbostic  *	t:	tree
9050995Sbostic  *	cnt:	records to read
9150995Sbostic  *
9250995Sbostic  * Returns:
9350995Sbostic  *	RET_ERROR, RET_SUCCESS
9450995Sbostic  */
9550995Sbostic int
9650995Sbostic __rec_fpipe(t, top)
9750995Sbostic 	BTREE *t;
9850995Sbostic 	recno_t top;
9950995Sbostic {
10050995Sbostic 	DBT data;
10150995Sbostic 	recno_t nrec;
10250995Sbostic 	size_t len;
10350995Sbostic 	int ch;
10450995Sbostic 	char *p;
10550995Sbostic 
10650995Sbostic 	data.data = t->bt_dbuf;
10750995Sbostic 	data.size = t->bt_reclen;
10850995Sbostic 
10950995Sbostic 	if (t->bt_dbufsz < t->bt_reclen) {
11050995Sbostic 		if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
11150995Sbostic 			return (RET_ERROR);
11250995Sbostic 		t->bt_dbufsz = t->bt_reclen;
11350995Sbostic 	}
11450995Sbostic 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
11556753Sbostic 		len = t->bt_reclen;
11650995Sbostic 		for (p = t->bt_dbuf;; *p++ = ch)
11750995Sbostic 			if ((ch = getc(t->bt_rfp)) == EOF || !len--) {
11850995Sbostic 				if (__rec_iput(t, nrec, &data, 0)
11950995Sbostic 				    != RET_SUCCESS)
12050995Sbostic 					return (RET_ERROR);
12150995Sbostic 				break;
12250995Sbostic 			}
12350995Sbostic 		if (ch == EOF)
12450995Sbostic 			break;
12550995Sbostic 	}
12650995Sbostic 	if (nrec < top) {
12760051Sbostic 		SET(t, R_EOF);
12850995Sbostic 		return (RET_SPECIAL);
12950995Sbostic 	}
13050995Sbostic 	return (RET_SUCCESS);
13150995Sbostic }
13250995Sbostic 
13350995Sbostic /*
13450995Sbostic  * __REC_VPIPE -- Get variable length records from a pipe.
13550995Sbostic  *
13650995Sbostic  * Parameters:
13750995Sbostic  *	t:	tree
13850995Sbostic  *	cnt:	records to read
13950995Sbostic  *
14050995Sbostic  * Returns:
14150995Sbostic  *	RET_ERROR, RET_SUCCESS
14250995Sbostic  */
14350995Sbostic int
14450995Sbostic __rec_vpipe(t, top)
14550995Sbostic 	BTREE *t;
14650995Sbostic 	recno_t top;
14750995Sbostic {
14850995Sbostic 	DBT data;
14950995Sbostic 	recno_t nrec;
15057988Sbostic 	indx_t len;
15150995Sbostic 	size_t sz;
15250995Sbostic 	int bval, ch;
15350995Sbostic 	char *p;
15450995Sbostic 
15550995Sbostic 	bval = t->bt_bval;
15650995Sbostic 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
15750995Sbostic 		for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) {
15850995Sbostic 			if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
15950995Sbostic 				data.data = t->bt_dbuf;
16050995Sbostic 				data.size = p - t->bt_dbuf;
16159793Sbostic 				if (ch == EOF && data.size == 0)
16259793Sbostic 					break;
16350995Sbostic 				if (__rec_iput(t, nrec, &data, 0)
16450995Sbostic 				    != RET_SUCCESS)
16550995Sbostic 					return (RET_ERROR);
16650995Sbostic 				break;
16750995Sbostic 			}
16850995Sbostic 			if (sz == 0) {
16950995Sbostic 				len = p - t->bt_dbuf;
17058098Sbostic 				t->bt_dbufsz += (sz = 256);
17150995Sbostic 				if ((t->bt_dbuf =
17258098Sbostic 				    realloc(t->bt_dbuf, t->bt_dbufsz)) == NULL)
17350995Sbostic 					return (RET_ERROR);
17450995Sbostic 				p = t->bt_dbuf + len;
17550995Sbostic 			}
17650995Sbostic 		}
17750995Sbostic 		if (ch == EOF)
17850995Sbostic 			break;
17950995Sbostic 	}
18050995Sbostic 	if (nrec < top) {
18160051Sbostic 		SET(t, R_EOF);
18250995Sbostic 		return (RET_SPECIAL);
18350995Sbostic 	}
18450995Sbostic 	return (RET_SUCCESS);
18550995Sbostic }
18650995Sbostic 
18750995Sbostic /*
18850995Sbostic  * __REC_FMAP -- Get fixed length records from a file.
18950995Sbostic  *
19050995Sbostic  * Parameters:
19150995Sbostic  *	t:	tree
19250995Sbostic  *	cnt:	records to read
19350995Sbostic  *
19450995Sbostic  * Returns:
19550995Sbostic  *	RET_ERROR, RET_SUCCESS
19650995Sbostic  */
19750995Sbostic int
19850995Sbostic __rec_fmap(t, top)
19950995Sbostic 	BTREE *t;
20050995Sbostic 	recno_t top;
20150995Sbostic {
20250995Sbostic 	DBT data;
20350995Sbostic 	recno_t nrec;
20450995Sbostic 	caddr_t sp, ep;
20550995Sbostic 	size_t len;
20650995Sbostic 	char *p;
20750995Sbostic 
20858747Sbostic 	sp = t->bt_cmap;
20950995Sbostic 	ep = t->bt_emap;
21050995Sbostic 	data.data = t->bt_dbuf;
21150995Sbostic 	data.size = t->bt_reclen;
21250995Sbostic 
21350995Sbostic 	if (t->bt_dbufsz < t->bt_reclen) {
21450995Sbostic 		if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
21550995Sbostic 			return (RET_ERROR);
21650995Sbostic 		t->bt_dbufsz = t->bt_reclen;
21750995Sbostic 	}
21850995Sbostic 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
21950995Sbostic 		if (sp >= ep) {
22060051Sbostic 			SET(t, R_EOF);
22150995Sbostic 			return (RET_SPECIAL);
22250995Sbostic 		}
22350995Sbostic 		len = t->bt_reclen;
22450995Sbostic 		for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++);
22550995Sbostic 		memset(p, t->bt_bval, len);
22650995Sbostic 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
22750995Sbostic 			return (RET_ERROR);
22850995Sbostic 	}
22958747Sbostic 	t->bt_cmap = sp;
23050995Sbostic 	return (RET_SUCCESS);
23150995Sbostic }
23250995Sbostic 
23350995Sbostic /*
23450995Sbostic  * __REC_VMAP -- Get variable length records from a file.
23550995Sbostic  *
23650995Sbostic  * Parameters:
23750995Sbostic  *	t:	tree
23850995Sbostic  *	cnt:	records to read
23950995Sbostic  *
24050995Sbostic  * Returns:
24150995Sbostic  *	RET_ERROR, RET_SUCCESS
24250995Sbostic  */
24350995Sbostic int
24450995Sbostic __rec_vmap(t, top)
24550995Sbostic 	BTREE *t;
24650995Sbostic 	recno_t top;
24750995Sbostic {
24850995Sbostic 	DBT data;
24951086Sbostic 	caddr_t sp, ep;
25050995Sbostic 	recno_t nrec;
25150995Sbostic 	int bval;
25250995Sbostic 
25358747Sbostic 	sp = t->bt_cmap;
25450995Sbostic 	ep = t->bt_emap;
25550995Sbostic 	bval = t->bt_bval;
25650995Sbostic 
25750995Sbostic 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
25850995Sbostic 		if (sp >= ep) {
25960051Sbostic 			SET(t, R_EOF);
26050995Sbostic 			return (RET_SPECIAL);
26150995Sbostic 		}
26250995Sbostic 		for (data.data = sp; sp < ep && *sp != bval; ++sp);
26350995Sbostic 		data.size = sp - (caddr_t)data.data;
26450995Sbostic 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
26550995Sbostic 			return (RET_ERROR);
26650995Sbostic 		++sp;
26750995Sbostic 	}
26858747Sbostic 	t->bt_cmap = sp;
26950995Sbostic 	return (RET_SUCCESS);
27050995Sbostic }
271