GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/db/recno/rec_get.c Lines: 0 110 0.0 %
Date: 2017-11-07 Branches: 0 88 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: rec_get.c,v 1.11 2007/08/08 07:16:50 ray Exp $	*/
2
3
/*-
4
 * Copyright (c) 1990, 1993, 1994
5
 *	The Regents of the University of California.  All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 * 3. Neither the name of the University nor the names of its contributors
16
 *    may be used to endorse or promote products derived from this software
17
 *    without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
 * SUCH DAMAGE.
30
 */
31
32
#include <sys/types.h>
33
34
#include <errno.h>
35
#include <stddef.h>
36
#include <stdio.h>
37
#include <stdlib.h>
38
#include <string.h>
39
#include <unistd.h>
40
41
#include <db.h>
42
#include "recno.h"
43
44
/*
45
 * __REC_GET -- Get a record from the btree.
46
 *
47
 * Parameters:
48
 *	dbp:	pointer to access method
49
 *	key:	key to find
50
 *	data:	data to return
51
 *	flag:	currently unused
52
 *
53
 * Returns:
54
 *	RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
55
 */
56
int
57
__rec_get(const DB *dbp, const DBT *key, DBT *data, u_int flags)
58
{
59
	BTREE *t;
60
	EPG *e;
61
	recno_t nrec;
62
	int status;
63
64
	t = dbp->internal;
65
66
	/* Toss any page pinned across calls. */
67
	if (t->bt_pinned != NULL) {
68
		mpool_put(t->bt_mp, t->bt_pinned, 0);
69
		t->bt_pinned = NULL;
70
	}
71
72
	/* Get currently doesn't take any flags, and keys of 0 are illegal. */
73
	if (flags || (nrec = *(recno_t *)key->data) == 0) {
74
		errno = EINVAL;
75
		return (RET_ERROR);
76
	}
77
78
	/*
79
	 * If we haven't seen this record yet, try to find it in the
80
	 * original file.
81
	 */
82
	if (nrec > t->bt_nrecs) {
83
		if (F_ISSET(t, R_EOF | R_INMEM))
84
			return (RET_SPECIAL);
85
		if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
86
			return (status);
87
	}
88
89
	--nrec;
90
	if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
91
		return (RET_ERROR);
92
93
	status = __rec_ret(t, e, 0, NULL, data);
94
	if (F_ISSET(t, B_DB_LOCK))
95
		mpool_put(t->bt_mp, e->page, 0);
96
	else
97
		t->bt_pinned = e->page;
98
	return (status);
99
}
100
101
/*
102
 * __REC_FPIPE -- Get fixed length records from a pipe.
103
 *
104
 * Parameters:
105
 *	t:	tree
106
 *	cnt:	records to read
107
 *
108
 * Returns:
109
 *	RET_ERROR, RET_SUCCESS
110
 */
111
int
112
__rec_fpipe(BTREE *t, recno_t top)
113
{
114
	DBT data;
115
	recno_t nrec;
116
	size_t len;
117
	int ch;
118
	u_char *p;
119
	void *tp;
120
121
	if (t->bt_rdata.size < t->bt_reclen) {
122
		tp = realloc(t->bt_rdata.data, t->bt_reclen);
123
		if (tp == NULL)
124
			return (RET_ERROR);
125
		t->bt_rdata.data = tp;
126
		t->bt_rdata.size = t->bt_reclen;
127
	}
128
	data.data = t->bt_rdata.data;
129
	data.size = t->bt_reclen;
130
131
	for (nrec = t->bt_nrecs; nrec < top;) {
132
		len = t->bt_reclen;
133
		for (p = t->bt_rdata.data;; *p++ = ch)
134
			if ((ch = getc(t->bt_rfp)) == EOF || !--len) {
135
				if (ch != EOF)
136
					*p = ch;
137
				if (len != 0)
138
					memset(p, t->bt_bval, len);
139
				if (__rec_iput(t,
140
				    nrec, &data, 0) != RET_SUCCESS)
141
					return (RET_ERROR);
142
				++nrec;
143
				break;
144
			}
145
		if (ch == EOF)
146
			break;
147
	}
148
	if (nrec < top) {
149
		F_SET(t, R_EOF);
150
		return (RET_SPECIAL);
151
	}
152
	return (RET_SUCCESS);
153
}
154
155
/*
156
 * __REC_VPIPE -- Get variable length records from a pipe.
157
 *
158
 * Parameters:
159
 *	t:	tree
160
 *	cnt:	records to read
161
 *
162
 * Returns:
163
 *	RET_ERROR, RET_SUCCESS
164
 */
165
int
166
__rec_vpipe(BTREE *t, recno_t top)
167
{
168
	DBT data;
169
	recno_t nrec;
170
	size_t len;
171
	size_t sz;
172
	int bval, ch;
173
	u_char *p;
174
	void *tp;
175
176
	bval = t->bt_bval;
177
	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
178
		for (p = t->bt_rdata.data,
179
		    sz = t->bt_rdata.size;; *p++ = ch, --sz) {
180
			if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
181
				data.data = t->bt_rdata.data;
182
				data.size = p - (u_char *)t->bt_rdata.data;
183
				if (ch == EOF && data.size == 0)
184
					break;
185
				if (__rec_iput(t, nrec, &data, 0)
186
				    != RET_SUCCESS)
187
					return (RET_ERROR);
188
				break;
189
			}
190
			if (sz == 0) {
191
				len = p - (u_char *)t->bt_rdata.data;
192
				t->bt_rdata.size += (sz = 256);
193
				tp = realloc(t->bt_rdata.data, t->bt_rdata.size);
194
				if (tp == NULL)
195
					return (RET_ERROR);
196
				t->bt_rdata.data = tp;
197
				p = (u_char *)t->bt_rdata.data + len;
198
			}
199
		}
200
		if (ch == EOF)
201
			break;
202
	}
203
	if (nrec < top) {
204
		F_SET(t, R_EOF);
205
		return (RET_SPECIAL);
206
	}
207
	return (RET_SUCCESS);
208
}
209
210
/*
211
 * __REC_FMAP -- Get fixed length records from a file.
212
 *
213
 * Parameters:
214
 *	t:	tree
215
 *	cnt:	records to read
216
 *
217
 * Returns:
218
 *	RET_ERROR, RET_SUCCESS
219
 */
220
int
221
__rec_fmap(BTREE *t, recno_t top)
222
{
223
	DBT data;
224
	recno_t nrec;
225
	u_char *sp, *ep, *p;
226
	size_t len;
227
	void *tp;
228
229
	if (t->bt_rdata.size < t->bt_reclen) {
230
		tp = realloc(t->bt_rdata.data, t->bt_reclen);
231
		if (tp == NULL)
232
			return (RET_ERROR);
233
		t->bt_rdata.data = tp;
234
		t->bt_rdata.size = t->bt_reclen;
235
	}
236
	data.data = t->bt_rdata.data;
237
	data.size = t->bt_reclen;
238
239
	sp = (u_char *)t->bt_cmap;
240
	ep = (u_char *)t->bt_emap;
241
	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
242
		if (sp >= ep) {
243
			F_SET(t, R_EOF);
244
			return (RET_SPECIAL);
245
		}
246
		len = t->bt_reclen;
247
		for (p = t->bt_rdata.data;
248
		    sp < ep && len > 0; *p++ = *sp++, --len);
249
		if (len != 0)
250
			memset(p, t->bt_bval, len);
251
		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
252
			return (RET_ERROR);
253
	}
254
	t->bt_cmap = (caddr_t)sp;
255
	return (RET_SUCCESS);
256
}
257
258
/*
259
 * __REC_VMAP -- Get variable length records from a file.
260
 *
261
 * Parameters:
262
 *	t:	tree
263
 *	cnt:	records to read
264
 *
265
 * Returns:
266
 *	RET_ERROR, RET_SUCCESS
267
 */
268
int
269
__rec_vmap(BTREE *t, recno_t top)
270
{
271
	DBT data;
272
	u_char *sp, *ep;
273
	recno_t nrec;
274
	int bval;
275
276
	sp = (u_char *)t->bt_cmap;
277
	ep = (u_char *)t->bt_emap;
278
	bval = t->bt_bval;
279
280
	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
281
		if (sp >= ep) {
282
			F_SET(t, R_EOF);
283
			return (RET_SPECIAL);
284
		}
285
		for (data.data = sp; sp < ep && *sp != bval; ++sp);
286
		data.size = sp - (u_char *)data.data;
287
		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
288
			return (RET_ERROR);
289
		++sp;
290
	}
291
	t->bt_cmap = (caddr_t)sp;
292
	return (RET_SUCCESS);
293
}