Annotation of src/lib/libc/db/recno/rec_get.c, Revision 1.18
1.18 ! christos 1: /* $NetBSD: rec_get.c,v 1.17 2013/12/14 18:04:56 christos Exp $ */
1.7 cgd 2:
1.1 cgd 3: /*-
1.6 cgd 4: * Copyright (c) 1990, 1993, 1994
1.1 cgd 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.
1.12 agc 15: * 3. Neither the name of the University nor the names of its contributors
1.1 cgd 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:
1.16 joerg 32: #if HAVE_NBTOOL_CONFIG_H
33: #include "nbtool_config.h"
34: #endif
35:
1.9 christos 36: #include <sys/cdefs.h>
1.18 ! christos 37: __RCSID("$NetBSD: rec_get.c,v 1.17 2013/12/14 18:04:56 christos Exp $");
1.1 cgd 38:
1.10 jtc 39: #include "namespace.h"
1.1 cgd 40: #include <sys/types.h>
41:
1.13 christos 42: #include <assert.h>
1.1 cgd 43: #include <errno.h>
44: #include <stddef.h>
45: #include <stdio.h>
46: #include <stdlib.h>
47: #include <string.h>
48: #include <unistd.h>
49:
50: #include <db.h>
51: #include "recno.h"
52:
53: /*
54: * __REC_GET -- Get a record from the btree.
55: *
56: * Parameters:
57: * dbp: pointer to access method
58: * key: key to find
59: * data: data to return
60: * flag: currently unused
61: *
62: * Returns:
63: * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
64: */
65: int
1.13 christos 66: __rec_get(const DB *dbp, const DBT *key, DBT *data, u_int flags)
1.1 cgd 67: {
68: BTREE *t;
69: EPG *e;
70: recno_t nrec;
71: int status;
72:
1.4 cgd 73: t = dbp->internal;
74:
75: /* Toss any page pinned across calls. */
76: if (t->bt_pinned != NULL) {
77: mpool_put(t->bt_mp, t->bt_pinned, 0);
78: t->bt_pinned = NULL;
79: }
80:
81: /* Get currently doesn't take any flags, and keys of 0 are illegal. */
1.1 cgd 82: if (flags || (nrec = *(recno_t *)key->data) == 0) {
83: errno = EINVAL;
84: return (RET_ERROR);
85: }
86:
87: /*
88: * If we haven't seen this record yet, try to find it in the
89: * original file.
90: */
91: if (nrec > t->bt_nrecs) {
1.8 cgd 92: if (F_ISSET(t, R_EOF | R_INMEM))
1.1 cgd 93: return (RET_SPECIAL);
94: if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
95: return (status);
96: }
97:
98: --nrec;
99: if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
100: return (RET_ERROR);
101:
102: status = __rec_ret(t, e, 0, NULL, data);
1.8 cgd 103: if (F_ISSET(t, B_DB_LOCK))
1.4 cgd 104: mpool_put(t->bt_mp, e->page, 0);
105: else
106: t->bt_pinned = e->page;
1.1 cgd 107: return (status);
108: }
109:
110: /*
111: * __REC_FPIPE -- Get fixed length records from a pipe.
112: *
113: * Parameters:
114: * t: tree
115: * cnt: records to read
116: *
117: * Returns:
118: * RET_ERROR, RET_SUCCESS
119: */
120: int
1.13 christos 121: __rec_fpipe(BTREE *t, recno_t top)
1.1 cgd 122: {
123: DBT data;
124: recno_t nrec;
125: size_t len;
126: int ch;
1.14 joerg 127: uint8_t *p;
1.1 cgd 128:
1.8 cgd 129: if (t->bt_rdata.size < t->bt_reclen) {
1.17 christos 130: void *np = realloc(t->bt_rdata.data, t->bt_reclen);
131: if (np == NULL)
1.1 cgd 132: return (RET_ERROR);
1.17 christos 133: t->bt_rdata.data = np;
1.8 cgd 134: t->bt_rdata.size = t->bt_reclen;
1.1 cgd 135: }
1.8 cgd 136: data.data = t->bt_rdata.data;
1.5 cgd 137: data.size = t->bt_reclen;
1.6 cgd 138:
1.8 cgd 139: for (nrec = t->bt_nrecs; nrec < top;) {
1.1 cgd 140: len = t->bt_reclen;
1.8 cgd 141: for (p = t->bt_rdata.data;; *p++ = ch)
142: if ((ch = getc(t->bt_rfp)) == EOF || !--len) {
143: if (ch != EOF)
144: *p = ch;
145: if (len != 0)
146: memset(p, t->bt_bval, len);
147: if (__rec_iput(t,
148: nrec, &data, 0) != RET_SUCCESS)
1.1 cgd 149: return (RET_ERROR);
1.8 cgd 150: ++nrec;
1.1 cgd 151: break;
152: }
153: if (ch == EOF)
154: break;
155: }
156: if (nrec < top) {
1.8 cgd 157: F_SET(t, R_EOF);
1.1 cgd 158: return (RET_SPECIAL);
159: }
160: return (RET_SUCCESS);
161: }
162:
163: /*
164: * __REC_VPIPE -- Get variable length records from a pipe.
165: *
166: * Parameters:
167: * t: tree
168: * cnt: records to read
169: *
170: * Returns:
171: * RET_ERROR, RET_SUCCESS
172: */
173: int
1.13 christos 174: __rec_vpipe(BTREE *t, recno_t top)
1.1 cgd 175: {
176: DBT data;
177: recno_t nrec;
178: size_t sz;
179: int bval, ch;
1.14 joerg 180: uint8_t *p;
1.1 cgd 181:
182: bval = t->bt_bval;
183: for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
1.8 cgd 184: for (p = t->bt_rdata.data,
185: sz = t->bt_rdata.size;; *p++ = ch, --sz) {
1.1 cgd 186: if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
1.8 cgd 187: data.data = t->bt_rdata.data;
1.14 joerg 188: data.size = p - (uint8_t *)t->bt_rdata.data;
1.1 cgd 189: if (ch == EOF && data.size == 0)
190: break;
191: if (__rec_iput(t, nrec, &data, 0)
192: != RET_SUCCESS)
193: return (RET_ERROR);
194: break;
195: }
196: if (sz == 0) {
1.18 ! christos 197: ptrdiff_t len = p - (uint8_t *)t->bt_rdata.data;
! 198: size_t tot = t->bt_rdata.size + (sz = 256);
! 199: void *np = realloc(t->bt_rdata.data, tot);
1.17 christos 200: if (np == NULL)
1.1 cgd 201: return (RET_ERROR);
1.18 ! christos 202: t->bt_rdata.size = tot;
1.17 christos 203: t->bt_rdata.data = np;
1.14 joerg 204: p = (uint8_t *)t->bt_rdata.data + len;
1.1 cgd 205: }
206: }
207: if (ch == EOF)
208: break;
209: }
210: if (nrec < top) {
1.8 cgd 211: F_SET(t, R_EOF);
1.1 cgd 212: return (RET_SPECIAL);
213: }
214: return (RET_SUCCESS);
215: }
216:
217: /*
218: * __REC_FMAP -- Get fixed length records from a file.
219: *
220: * Parameters:
221: * t: tree
222: * cnt: records to read
223: *
224: * Returns:
225: * RET_ERROR, RET_SUCCESS
226: */
227: int
1.13 christos 228: __rec_fmap(BTREE *t, recno_t top)
1.1 cgd 229: {
230: DBT data;
231: recno_t nrec;
1.14 joerg 232: uint8_t *sp, *ep, *p;
1.1 cgd 233: size_t len;
234:
1.8 cgd 235: if (t->bt_rdata.size < t->bt_reclen) {
1.17 christos 236: void *np = realloc(t->bt_rdata.data, t->bt_reclen);
237: if (np == NULL)
1.1 cgd 238: return (RET_ERROR);
1.17 christos 239: t->bt_rdata.data = np;
1.8 cgd 240: t->bt_rdata.size = t->bt_reclen;
1.1 cgd 241: }
1.8 cgd 242: data.data = t->bt_rdata.data;
1.6 cgd 243: data.size = t->bt_reclen;
244:
1.14 joerg 245: sp = (uint8_t *)t->bt_cmap;
246: ep = (uint8_t *)t->bt_emap;
1.1 cgd 247: for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
248: if (sp >= ep) {
1.8 cgd 249: F_SET(t, R_EOF);
1.1 cgd 250: return (RET_SPECIAL);
251: }
252: len = t->bt_reclen;
1.8 cgd 253: for (p = t->bt_rdata.data;
254: sp < ep && len > 0; *p++ = *sp++, --len);
255: if (len != 0)
256: memset(p, t->bt_bval, len);
1.1 cgd 257: if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
258: return (RET_ERROR);
259: }
1.8 cgd 260: t->bt_cmap = (caddr_t)sp;
1.1 cgd 261: return (RET_SUCCESS);
262: }
263:
264: /*
265: * __REC_VMAP -- Get variable length records from a file.
266: *
267: * Parameters:
268: * t: tree
269: * cnt: records to read
270: *
271: * Returns:
272: * RET_ERROR, RET_SUCCESS
273: */
274: int
1.13 christos 275: __rec_vmap(BTREE *t, recno_t top)
1.1 cgd 276: {
277: DBT data;
1.14 joerg 278: uint8_t *sp, *ep;
1.1 cgd 279: recno_t nrec;
280: int bval;
281:
1.14 joerg 282: sp = (uint8_t *)t->bt_cmap;
283: ep = (uint8_t *)t->bt_emap;
1.1 cgd 284: bval = t->bt_bval;
285:
286: for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
287: if (sp >= ep) {
1.8 cgd 288: F_SET(t, R_EOF);
1.1 cgd 289: return (RET_SPECIAL);
290: }
291: for (data.data = sp; sp < ep && *sp != bval; ++sp);
1.14 joerg 292: data.size = sp - (uint8_t *)data.data;
1.1 cgd 293: if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
294: return (RET_ERROR);
295: ++sp;
296: }
1.8 cgd 297: t->bt_cmap = (caddr_t)sp;
1.1 cgd 298: return (RET_SUCCESS);
299: }
CVSweb <webmaster@jp.NetBSD.org>