rec_get.c revision 92986
11573Srgrimes/*- 214272Spst * Copyright (c) 1990, 1993, 1994 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * Redistribution and use in source and binary forms, with or without 61573Srgrimes * modification, are permitted provided that the following conditions 71573Srgrimes * are met: 81573Srgrimes * 1. Redistributions of source code must retain the above copyright 91573Srgrimes * notice, this list of conditions and the following disclaimer. 101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111573Srgrimes * notice, this list of conditions and the following disclaimer in the 121573Srgrimes * documentation and/or other materials provided with the distribution. 131573Srgrimes * 3. All advertising materials mentioning features or use of this software 141573Srgrimes * must display the following acknowledgement: 151573Srgrimes * This product includes software developed by the University of 161573Srgrimes * California, Berkeley and its contributors. 171573Srgrimes * 4. Neither the name of the University nor the names of its contributors 181573Srgrimes * may be used to endorse or promote products derived from this software 191573Srgrimes * without specific prior written permission. 201573Srgrimes * 211573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311573Srgrimes * SUCH DAMAGE. 321573Srgrimes */ 331573Srgrimes 341573Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 3514272Spststatic char sccsid[] = "@(#)rec_get.c 8.9 (Berkeley) 8/18/94"; 361573Srgrimes#endif /* LIBC_SCCS and not lint */ 3792986Sobrien#include <sys/cdefs.h> 3892986Sobrien__FBSDID("$FreeBSD: head/lib/libc/db/recno/rec_get.c 92986 2002-03-22 21:53:29Z obrien $"); 391573Srgrimes 401573Srgrimes#include <sys/types.h> 411573Srgrimes 421573Srgrimes#include <errno.h> 431573Srgrimes#include <stddef.h> 441573Srgrimes#include <stdio.h> 451573Srgrimes#include <stdlib.h> 461573Srgrimes#include <string.h> 471573Srgrimes#include <unistd.h> 481573Srgrimes 491573Srgrimes#include <db.h> 501573Srgrimes#include "recno.h" 511573Srgrimes 521573Srgrimes/* 531573Srgrimes * __REC_GET -- Get a record from the btree. 541573Srgrimes * 551573Srgrimes * Parameters: 561573Srgrimes * dbp: pointer to access method 571573Srgrimes * key: key to find 581573Srgrimes * data: data to return 591573Srgrimes * flag: currently unused 601573Srgrimes * 611573Srgrimes * Returns: 621573Srgrimes * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. 631573Srgrimes */ 641573Srgrimesint 651573Srgrimes__rec_get(dbp, key, data, flags) 661573Srgrimes const DB *dbp; 671573Srgrimes const DBT *key; 681573Srgrimes DBT *data; 691573Srgrimes u_int flags; 701573Srgrimes{ 711573Srgrimes BTREE *t; 721573Srgrimes EPG *e; 731573Srgrimes recno_t nrec; 741573Srgrimes int status; 751573Srgrimes 761573Srgrimes t = dbp->internal; 771573Srgrimes 781573Srgrimes /* Toss any page pinned across calls. */ 791573Srgrimes if (t->bt_pinned != NULL) { 801573Srgrimes mpool_put(t->bt_mp, t->bt_pinned, 0); 811573Srgrimes t->bt_pinned = NULL; 821573Srgrimes } 831573Srgrimes 841573Srgrimes /* Get currently doesn't take any flags, and keys of 0 are illegal. */ 851573Srgrimes if (flags || (nrec = *(recno_t *)key->data) == 0) { 861573Srgrimes errno = EINVAL; 871573Srgrimes return (RET_ERROR); 881573Srgrimes } 891573Srgrimes 901573Srgrimes /* 911573Srgrimes * If we haven't seen this record yet, try to find it in the 921573Srgrimes * original file. 931573Srgrimes */ 941573Srgrimes if (nrec > t->bt_nrecs) { 9514272Spst if (F_ISSET(t, R_EOF | R_INMEM)) 961573Srgrimes return (RET_SPECIAL); 971573Srgrimes if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS) 981573Srgrimes return (status); 991573Srgrimes } 1001573Srgrimes 1011573Srgrimes --nrec; 1021573Srgrimes if ((e = __rec_search(t, nrec, SEARCH)) == NULL) 1031573Srgrimes return (RET_ERROR); 1041573Srgrimes 1051573Srgrimes status = __rec_ret(t, e, 0, NULL, data); 10614272Spst if (F_ISSET(t, B_DB_LOCK)) 1071573Srgrimes mpool_put(t->bt_mp, e->page, 0); 1081573Srgrimes else 1091573Srgrimes t->bt_pinned = e->page; 1101573Srgrimes return (status); 1111573Srgrimes} 1121573Srgrimes 1131573Srgrimes/* 1141573Srgrimes * __REC_FPIPE -- Get fixed length records from a pipe. 1151573Srgrimes * 1161573Srgrimes * Parameters: 1171573Srgrimes * t: tree 1181573Srgrimes * cnt: records to read 1191573Srgrimes * 1201573Srgrimes * Returns: 1211573Srgrimes * RET_ERROR, RET_SUCCESS 1221573Srgrimes */ 1231573Srgrimesint 1241573Srgrimes__rec_fpipe(t, top) 1251573Srgrimes BTREE *t; 1261573Srgrimes recno_t top; 1271573Srgrimes{ 1281573Srgrimes DBT data; 1291573Srgrimes recno_t nrec; 1301573Srgrimes size_t len; 1311573Srgrimes int ch; 13214272Spst u_char *p; 1331573Srgrimes 13414272Spst if (t->bt_rdata.size < t->bt_reclen) { 13514272Spst t->bt_rdata.data = t->bt_rdata.data == NULL ? 13614272Spst malloc(t->bt_reclen) : 13739327Simp reallocf(t->bt_rdata.data, t->bt_reclen); 13814272Spst if (t->bt_rdata.data == NULL) 1391573Srgrimes return (RET_ERROR); 14014272Spst t->bt_rdata.size = t->bt_reclen; 1411573Srgrimes } 14214272Spst data.data = t->bt_rdata.data; 1431573Srgrimes data.size = t->bt_reclen; 1441573Srgrimes 14514272Spst for (nrec = t->bt_nrecs; nrec < top;) { 1461573Srgrimes len = t->bt_reclen; 14714272Spst for (p = t->bt_rdata.data;; *p++ = ch) 14814272Spst if ((ch = getc(t->bt_rfp)) == EOF || !--len) { 14914272Spst if (ch != EOF) 15014272Spst *p = ch; 15114272Spst if (len != 0) 15214272Spst memset(p, t->bt_bval, len); 15314272Spst if (__rec_iput(t, 15414272Spst nrec, &data, 0) != RET_SUCCESS) 1551573Srgrimes return (RET_ERROR); 15614272Spst ++nrec; 1571573Srgrimes break; 1581573Srgrimes } 1591573Srgrimes if (ch == EOF) 1601573Srgrimes break; 1611573Srgrimes } 1621573Srgrimes if (nrec < top) { 16314272Spst F_SET(t, R_EOF); 1641573Srgrimes return (RET_SPECIAL); 1651573Srgrimes } 1661573Srgrimes return (RET_SUCCESS); 1671573Srgrimes} 1681573Srgrimes 1691573Srgrimes/* 1701573Srgrimes * __REC_VPIPE -- Get variable length records from a pipe. 1711573Srgrimes * 1721573Srgrimes * Parameters: 1731573Srgrimes * t: tree 1741573Srgrimes * cnt: records to read 1751573Srgrimes * 1761573Srgrimes * Returns: 1771573Srgrimes * RET_ERROR, RET_SUCCESS 1781573Srgrimes */ 1791573Srgrimesint 1801573Srgrimes__rec_vpipe(t, top) 1811573Srgrimes BTREE *t; 1821573Srgrimes recno_t top; 1831573Srgrimes{ 1841573Srgrimes DBT data; 1851573Srgrimes recno_t nrec; 18668455Sobrien size_t len; 1871573Srgrimes size_t sz; 1881573Srgrimes int bval, ch; 18914272Spst u_char *p; 1901573Srgrimes 1911573Srgrimes bval = t->bt_bval; 1921573Srgrimes for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 19314272Spst for (p = t->bt_rdata.data, 19414272Spst sz = t->bt_rdata.size;; *p++ = ch, --sz) { 1951573Srgrimes if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) { 19614272Spst data.data = t->bt_rdata.data; 19714272Spst data.size = p - (u_char *)t->bt_rdata.data; 1981573Srgrimes if (ch == EOF && data.size == 0) 1991573Srgrimes break; 2001573Srgrimes if (__rec_iput(t, nrec, &data, 0) 2011573Srgrimes != RET_SUCCESS) 2021573Srgrimes return (RET_ERROR); 2031573Srgrimes break; 2041573Srgrimes } 2051573Srgrimes if (sz == 0) { 20614272Spst len = p - (u_char *)t->bt_rdata.data; 20714272Spst t->bt_rdata.size += (sz = 256); 20814272Spst t->bt_rdata.data = t->bt_rdata.data == NULL ? 20914272Spst malloc(t->bt_rdata.size) : 21039327Simp reallocf(t->bt_rdata.data, t->bt_rdata.size); 21114272Spst if (t->bt_rdata.data == NULL) 2121573Srgrimes return (RET_ERROR); 21314272Spst p = (u_char *)t->bt_rdata.data + len; 2141573Srgrimes } 2151573Srgrimes } 2161573Srgrimes if (ch == EOF) 2171573Srgrimes break; 2181573Srgrimes } 2191573Srgrimes if (nrec < top) { 22014272Spst F_SET(t, R_EOF); 2211573Srgrimes return (RET_SPECIAL); 2221573Srgrimes } 2231573Srgrimes return (RET_SUCCESS); 2241573Srgrimes} 2251573Srgrimes 2261573Srgrimes/* 2271573Srgrimes * __REC_FMAP -- Get fixed length records from a file. 2281573Srgrimes * 2291573Srgrimes * Parameters: 2301573Srgrimes * t: tree 2311573Srgrimes * cnt: records to read 2321573Srgrimes * 2331573Srgrimes * Returns: 2341573Srgrimes * RET_ERROR, RET_SUCCESS 2351573Srgrimes */ 2361573Srgrimesint 2371573Srgrimes__rec_fmap(t, top) 2381573Srgrimes BTREE *t; 2391573Srgrimes recno_t top; 2401573Srgrimes{ 2411573Srgrimes DBT data; 2421573Srgrimes recno_t nrec; 24314272Spst u_char *sp, *ep, *p; 2441573Srgrimes size_t len; 2451573Srgrimes 24614272Spst if (t->bt_rdata.size < t->bt_reclen) { 24714272Spst t->bt_rdata.data = t->bt_rdata.data == NULL ? 24814272Spst malloc(t->bt_reclen) : 24939327Simp reallocf(t->bt_rdata.data, t->bt_reclen); 25014272Spst if (t->bt_rdata.data == NULL) 2511573Srgrimes return (RET_ERROR); 25214272Spst t->bt_rdata.size = t->bt_reclen; 2531573Srgrimes } 25414272Spst data.data = t->bt_rdata.data; 2551573Srgrimes data.size = t->bt_reclen; 2561573Srgrimes 25714272Spst sp = (u_char *)t->bt_cmap; 25814272Spst ep = (u_char *)t->bt_emap; 2591573Srgrimes for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 2601573Srgrimes if (sp >= ep) { 26114272Spst F_SET(t, R_EOF); 2621573Srgrimes return (RET_SPECIAL); 2631573Srgrimes } 2641573Srgrimes len = t->bt_reclen; 26514272Spst for (p = t->bt_rdata.data; 26614272Spst sp < ep && len > 0; *p++ = *sp++, --len); 26714272Spst if (len != 0) 26814272Spst memset(p, t->bt_bval, len); 2691573Srgrimes if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 2701573Srgrimes return (RET_ERROR); 2711573Srgrimes } 27214272Spst t->bt_cmap = (caddr_t)sp; 2731573Srgrimes return (RET_SUCCESS); 2741573Srgrimes} 2751573Srgrimes 2761573Srgrimes/* 2771573Srgrimes * __REC_VMAP -- Get variable length records from a file. 2781573Srgrimes * 2791573Srgrimes * Parameters: 2801573Srgrimes * t: tree 2811573Srgrimes * cnt: records to read 2821573Srgrimes * 2831573Srgrimes * Returns: 2841573Srgrimes * RET_ERROR, RET_SUCCESS 2851573Srgrimes */ 2861573Srgrimesint 2871573Srgrimes__rec_vmap(t, top) 2881573Srgrimes BTREE *t; 2891573Srgrimes recno_t top; 2901573Srgrimes{ 2911573Srgrimes DBT data; 29214272Spst u_char *sp, *ep; 2931573Srgrimes recno_t nrec; 2941573Srgrimes int bval; 2951573Srgrimes 29614272Spst sp = (u_char *)t->bt_cmap; 29714272Spst ep = (u_char *)t->bt_emap; 2981573Srgrimes bval = t->bt_bval; 2991573Srgrimes 3001573Srgrimes for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 3011573Srgrimes if (sp >= ep) { 30214272Spst F_SET(t, R_EOF); 3031573Srgrimes return (RET_SPECIAL); 3041573Srgrimes } 3051573Srgrimes for (data.data = sp; sp < ep && *sp != bval; ++sp); 30614272Spst data.size = sp - (u_char *)data.data; 3071573Srgrimes if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 3081573Srgrimes return (RET_ERROR); 3091573Srgrimes ++sp; 3101573Srgrimes } 31114272Spst t->bt_cmap = (caddr_t)sp; 3121573Srgrimes return (RET_SUCCESS); 3131573Srgrimes} 314