xref: /original-bsd/lib/libc/db/recno/rec_seq.c (revision c3e32dec)
1 /*-
2  * Copyright (c) 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)rec_seq.c	8.1 (Berkeley) 06/04/93";
10 #endif /* not lint */
11 
12 #include <sys/types.h>
13 
14 #include <errno.h>
15 #include <limits.h>
16 #include <stdio.h>
17 #include <string.h>
18 
19 #include <db.h>
20 #include "recno.h"
21 
22 /*
23  * __REC_SEQ -- Recno sequential scan interface.
24  *
25  * Parameters:
26  *	dbp:	pointer to access method
27  *	key:	key for positioning and return value
28  *	data:	data return value
29  *	flags:	R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
30  *
31  * Returns:
32  *	RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
33  */
34 int
35 __rec_seq(dbp, key, data, flags)
36 	const DB *dbp;
37 	DBT *key, *data;
38 	u_int flags;
39 {
40 	BTREE *t;
41 	EPG *e;
42 	recno_t nrec;
43 	int status;
44 
45 	t = dbp->internal;
46 	switch(flags) {
47 	case R_CURSOR:
48 		if ((nrec = *(recno_t *)key->data) == 0)
49 			goto einval;
50 		break;
51 	case R_NEXT:
52 		if (ISSET(t, B_SEQINIT)) {
53 			nrec = t->bt_rcursor + 1;
54 			break;
55 		}
56 		/* FALLTHROUGH */
57 	case R_FIRST:
58 		nrec = 1;
59 		break;
60 	case R_PREV:
61 		if (ISSET(t, B_SEQINIT)) {
62 			if ((nrec = t->bt_rcursor - 1) == 0)
63 				return (RET_SPECIAL);
64 			break;
65 		}
66 		/* FALLTHROUGH */
67 	case R_LAST:
68 		if (!ISSET(t, R_EOF | R_INMEM) &&
69 		    t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
70 			return (RET_ERROR);
71 		nrec = t->bt_nrecs;
72 		break;
73 	default:
74 einval:		errno = EINVAL;
75 		return (RET_ERROR);
76 	}
77 
78 	if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) {
79 		if (!ISSET(t, R_EOF | R_INMEM) &&
80 		    (status = t->bt_irec(t, nrec)) != RET_SUCCESS)
81 			return (status);
82 		if (t->bt_nrecs == 0 || nrec > t->bt_nrecs)
83 			return (RET_SPECIAL);
84 	}
85 
86 	if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL)
87 		return (RET_ERROR);
88 
89 	SET(t, B_SEQINIT);
90 	t->bt_rcursor = nrec;
91 
92 	status = __rec_ret(t, e, nrec, key, data);
93 
94 	mpool_put(t->bt_mp, e->page, 0);
95 	return (status);
96 }
97