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