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