Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/db/recno/rec_get.c
39507 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
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
120
if (t->bt_rdata.size < t->bt_reclen) {
121
t->bt_rdata.data = reallocf(t->bt_rdata.data, t->bt_reclen);
122
if (t->bt_rdata.data == NULL)
123
return (RET_ERROR);
124
t->bt_rdata.size = t->bt_reclen;
125
}
126
data.data = t->bt_rdata.data;
127
data.size = t->bt_reclen;
128
129
for (nrec = t->bt_nrecs; nrec < top;) {
130
len = t->bt_reclen;
131
for (p = t->bt_rdata.data;; *p++ = ch)
132
if ((ch = getc(t->bt_rfp)) == EOF || !--len) {
133
if (ch != EOF)
134
*p = ch;
135
if (len != 0)
136
memset(p, t->bt_bval, len);
137
if (__rec_iput(t,
138
nrec, &data, 0) != RET_SUCCESS)
139
return (RET_ERROR);
140
++nrec;
141
break;
142
}
143
if (ch == EOF)
144
break;
145
}
146
if (nrec < top) {
147
F_SET(t, R_EOF);
148
return (RET_SPECIAL);
149
}
150
return (RET_SUCCESS);
151
}
152
153
/*
154
* __REC_VPIPE -- Get variable length records from a pipe.
155
*
156
* Parameters:
157
* t: tree
158
* cnt: records to read
159
*
160
* Returns:
161
* RET_ERROR, RET_SUCCESS
162
*/
163
int
164
__rec_vpipe(BTREE *t, recno_t top)
165
{
166
DBT data;
167
recno_t nrec;
168
size_t len;
169
size_t sz;
170
int bval, ch;
171
u_char *p;
172
173
bval = t->bt_bval;
174
for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
175
for (p = t->bt_rdata.data,
176
sz = t->bt_rdata.size;; *p++ = ch, --sz) {
177
if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
178
data.data = t->bt_rdata.data;
179
data.size = p - (u_char *)t->bt_rdata.data;
180
if (ch == EOF && data.size == 0)
181
break;
182
if (__rec_iput(t, nrec, &data, 0)
183
!= RET_SUCCESS)
184
return (RET_ERROR);
185
break;
186
}
187
if (sz == 0) {
188
len = p - (u_char *)t->bt_rdata.data;
189
t->bt_rdata.size += (sz = 256);
190
t->bt_rdata.data = reallocf(t->bt_rdata.data, t->bt_rdata.size);
191
if (t->bt_rdata.data == NULL)
192
return (RET_ERROR);
193
p = (u_char *)t->bt_rdata.data + len;
194
}
195
}
196
if (ch == EOF)
197
break;
198
}
199
if (nrec < top) {
200
F_SET(t, R_EOF);
201
return (RET_SPECIAL);
202
}
203
return (RET_SUCCESS);
204
}
205
206
/*
207
* __REC_FMAP -- Get fixed length records from a file.
208
*
209
* Parameters:
210
* t: tree
211
* cnt: records to read
212
*
213
* Returns:
214
* RET_ERROR, RET_SUCCESS
215
*/
216
int
217
__rec_fmap(BTREE *t, recno_t top)
218
{
219
DBT data;
220
recno_t nrec;
221
u_char *sp, *ep, *p;
222
size_t len;
223
224
if (t->bt_rdata.size < t->bt_reclen) {
225
t->bt_rdata.data = reallocf(t->bt_rdata.data, t->bt_reclen);
226
if (t->bt_rdata.data == NULL)
227
return (RET_ERROR);
228
t->bt_rdata.size = t->bt_reclen;
229
}
230
data.data = t->bt_rdata.data;
231
data.size = t->bt_reclen;
232
233
sp = (u_char *)t->bt_cmap;
234
ep = (u_char *)t->bt_emap;
235
for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
236
if (sp >= ep) {
237
F_SET(t, R_EOF);
238
return (RET_SPECIAL);
239
}
240
len = t->bt_reclen;
241
for (p = t->bt_rdata.data;
242
sp < ep && len > 0; *p++ = *sp++, --len);
243
if (len != 0)
244
memset(p, t->bt_bval, len);
245
if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
246
return (RET_ERROR);
247
}
248
t->bt_cmap = (caddr_t)sp;
249
return (RET_SUCCESS);
250
}
251
252
/*
253
* __REC_VMAP -- Get variable length records from a file.
254
*
255
* Parameters:
256
* t: tree
257
* cnt: records to read
258
*
259
* Returns:
260
* RET_ERROR, RET_SUCCESS
261
*/
262
int
263
__rec_vmap(BTREE *t, recno_t top)
264
{
265
DBT data;
266
u_char *sp, *ep;
267
recno_t nrec;
268
int bval;
269
270
sp = (u_char *)t->bt_cmap;
271
ep = (u_char *)t->bt_emap;
272
bval = t->bt_bval;
273
274
for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
275
if (sp >= ep) {
276
F_SET(t, R_EOF);
277
return (RET_SPECIAL);
278
}
279
for (data.data = sp; sp < ep && *sp != bval; ++sp);
280
data.size = sp - (u_char *)data.data;
281
if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
282
return (RET_ERROR);
283
++sp;
284
}
285
t->bt_cmap = (caddr_t)sp;
286
return (RET_SUCCESS);
287
}
288
289