1*50995Sbostic /*- 2*50995Sbostic * Copyright (c) 1990 The Regents of the University of California. 3*50995Sbostic * All rights reserved. 4*50995Sbostic * 5*50995Sbostic * %sccs.include.redist.c% 6*50995Sbostic */ 7*50995Sbostic 8*50995Sbostic #if defined(LIBC_SCCS) && !defined(lint) 9*50995Sbostic static char sccsid[] = "@(#)rec_get.c 5.1 (Berkeley) 09/04/91"; 10*50995Sbostic #endif /* LIBC_SCCS and not lint */ 11*50995Sbostic 12*50995Sbostic #include <sys/types.h> 13*50995Sbostic #include <errno.h> 14*50995Sbostic #include <db.h> 15*50995Sbostic #include <unistd.h> 16*50995Sbostic #include <stddef.h> 17*50995Sbostic #include <stdio.h> 18*50995Sbostic #include <stdlib.h> 19*50995Sbostic #include <string.h> 20*50995Sbostic #include "../btree/btree.h" 21*50995Sbostic 22*50995Sbostic /* 23*50995Sbostic * __REC_GET -- Get a record from the btree. 24*50995Sbostic * 25*50995Sbostic * Parameters: 26*50995Sbostic * dbp: pointer to access method 27*50995Sbostic * key: key to find 28*50995Sbostic * data: data to return 29*50995Sbostic * flag: currently unused 30*50995Sbostic * 31*50995Sbostic * Returns: 32*50995Sbostic * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. 33*50995Sbostic */ 34*50995Sbostic int 35*50995Sbostic __rec_get(dbp, key, data, flags) 36*50995Sbostic const DB *dbp; 37*50995Sbostic DBT *key, *data; 38*50995Sbostic u_int flags; 39*50995Sbostic { 40*50995Sbostic BTREE *t; 41*50995Sbostic EPG *e; 42*50995Sbostic recno_t nrec; 43*50995Sbostic int exact, status; 44*50995Sbostic 45*50995Sbostic if (flags || (nrec = *(recno_t *)key->data) == 0) { 46*50995Sbostic errno = EINVAL; 47*50995Sbostic return (RET_ERROR); 48*50995Sbostic } 49*50995Sbostic 50*50995Sbostic /* 51*50995Sbostic * If we haven't seen this record yet, try to find it in the 52*50995Sbostic * original file. 53*50995Sbostic */ 54*50995Sbostic t = dbp->internal; 55*50995Sbostic if (nrec > t->bt_nrecs && 56*50995Sbostic (status = t->bt_irec(t, nrec)) != RET_SUCCESS) 57*50995Sbostic return (status); 58*50995Sbostic 59*50995Sbostic --nrec; 60*50995Sbostic if ((e = __rec_search(t, nrec, &exact)) == NULL) 61*50995Sbostic return (RET_ERROR); 62*50995Sbostic 63*50995Sbostic if (!exact) { 64*50995Sbostic mpool_put(t->bt_mp, e->page, 0); 65*50995Sbostic return (RET_SPECIAL); 66*50995Sbostic } 67*50995Sbostic 68*50995Sbostic status = __rec_ret(t, e, data); 69*50995Sbostic mpool_put(t->bt_mp, e->page, 0); 70*50995Sbostic return (status); 71*50995Sbostic } 72*50995Sbostic 73*50995Sbostic /* 74*50995Sbostic * __REC_FPIPE -- Get fixed length records from a pipe. 75*50995Sbostic * 76*50995Sbostic * Parameters: 77*50995Sbostic * t: tree 78*50995Sbostic * cnt: records to read 79*50995Sbostic * 80*50995Sbostic * Returns: 81*50995Sbostic * RET_ERROR, RET_SUCCESS 82*50995Sbostic */ 83*50995Sbostic int 84*50995Sbostic __rec_fpipe(t, top) 85*50995Sbostic BTREE *t; 86*50995Sbostic recno_t top; 87*50995Sbostic { 88*50995Sbostic static int eof; 89*50995Sbostic DBT data; 90*50995Sbostic recno_t nrec; 91*50995Sbostic size_t len; 92*50995Sbostic int ch; 93*50995Sbostic char *p; 94*50995Sbostic 95*50995Sbostic if (eof) 96*50995Sbostic return (RET_SPECIAL); 97*50995Sbostic 98*50995Sbostic data.data = t->bt_dbuf; 99*50995Sbostic data.size = t->bt_reclen; 100*50995Sbostic 101*50995Sbostic if (t->bt_dbufsz < t->bt_reclen) { 102*50995Sbostic if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 103*50995Sbostic return (RET_ERROR); 104*50995Sbostic t->bt_dbufsz = t->bt_reclen; 105*50995Sbostic } 106*50995Sbostic for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 107*50995Sbostic for (p = t->bt_dbuf;; *p++ = ch) 108*50995Sbostic if ((ch = getc(t->bt_rfp)) == EOF || !len--) { 109*50995Sbostic if (__rec_iput(t, nrec, &data, 0) 110*50995Sbostic != RET_SUCCESS) 111*50995Sbostic return (RET_ERROR); 112*50995Sbostic break; 113*50995Sbostic } 114*50995Sbostic if (ch == EOF) 115*50995Sbostic break; 116*50995Sbostic } 117*50995Sbostic if (nrec < top) { 118*50995Sbostic eof = 1; 119*50995Sbostic return (RET_SPECIAL); 120*50995Sbostic } 121*50995Sbostic return (RET_SUCCESS); 122*50995Sbostic } 123*50995Sbostic 124*50995Sbostic /* 125*50995Sbostic * __REC_VPIPE -- Get variable length records from a pipe. 126*50995Sbostic * 127*50995Sbostic * Parameters: 128*50995Sbostic * t: tree 129*50995Sbostic * cnt: records to read 130*50995Sbostic * 131*50995Sbostic * Returns: 132*50995Sbostic * RET_ERROR, RET_SUCCESS 133*50995Sbostic */ 134*50995Sbostic int 135*50995Sbostic __rec_vpipe(t, top) 136*50995Sbostic BTREE *t; 137*50995Sbostic recno_t top; 138*50995Sbostic { 139*50995Sbostic static int eof; 140*50995Sbostic DBT data; 141*50995Sbostic recno_t nrec; 142*50995Sbostic index_t len; 143*50995Sbostic size_t sz; 144*50995Sbostic int bval, ch; 145*50995Sbostic char *p; 146*50995Sbostic 147*50995Sbostic if (eof) 148*50995Sbostic return (RET_SPECIAL); 149*50995Sbostic 150*50995Sbostic bval = t->bt_bval; 151*50995Sbostic for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 152*50995Sbostic for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) { 153*50995Sbostic if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) { 154*50995Sbostic data.data = t->bt_dbuf; 155*50995Sbostic data.size = p - t->bt_dbuf; 156*50995Sbostic if (__rec_iput(t, nrec, &data, 0) 157*50995Sbostic != RET_SUCCESS) 158*50995Sbostic return (RET_ERROR); 159*50995Sbostic break; 160*50995Sbostic } 161*50995Sbostic if (sz == 0) { 162*50995Sbostic len = p - t->bt_dbuf; 163*50995Sbostic sz = t->bt_dbufsz += 256; 164*50995Sbostic if ((t->bt_dbuf = 165*50995Sbostic realloc(t->bt_dbuf, sz)) == NULL) 166*50995Sbostic return (RET_ERROR); 167*50995Sbostic p = t->bt_dbuf + len; 168*50995Sbostic } 169*50995Sbostic } 170*50995Sbostic if (ch == EOF) 171*50995Sbostic break; 172*50995Sbostic } 173*50995Sbostic if (nrec < top) { 174*50995Sbostic eof = 1; 175*50995Sbostic return (RET_SPECIAL); 176*50995Sbostic } 177*50995Sbostic return (RET_SUCCESS); 178*50995Sbostic } 179*50995Sbostic 180*50995Sbostic /* 181*50995Sbostic * __REC_FMAP -- Get fixed length records from a file. 182*50995Sbostic * 183*50995Sbostic * Parameters: 184*50995Sbostic * t: tree 185*50995Sbostic * cnt: records to read 186*50995Sbostic * 187*50995Sbostic * Returns: 188*50995Sbostic * RET_ERROR, RET_SUCCESS 189*50995Sbostic */ 190*50995Sbostic int 191*50995Sbostic __rec_fmap(t, top) 192*50995Sbostic BTREE *t; 193*50995Sbostic recno_t top; 194*50995Sbostic { 195*50995Sbostic static int eof; 196*50995Sbostic DBT data; 197*50995Sbostic recno_t nrec; 198*50995Sbostic caddr_t sp, ep; 199*50995Sbostic size_t len; 200*50995Sbostic char *p; 201*50995Sbostic 202*50995Sbostic if (eof) 203*50995Sbostic return (RET_SPECIAL); 204*50995Sbostic 205*50995Sbostic sp = t->bt_smap; 206*50995Sbostic ep = t->bt_emap; 207*50995Sbostic data.data = t->bt_dbuf; 208*50995Sbostic data.size = t->bt_reclen; 209*50995Sbostic 210*50995Sbostic if (t->bt_dbufsz < t->bt_reclen) { 211*50995Sbostic if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 212*50995Sbostic return (RET_ERROR); 213*50995Sbostic t->bt_dbufsz = t->bt_reclen; 214*50995Sbostic } 215*50995Sbostic for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 216*50995Sbostic if (sp >= ep) { 217*50995Sbostic eof = 1; 218*50995Sbostic return (RET_SPECIAL); 219*50995Sbostic } 220*50995Sbostic len = t->bt_reclen; 221*50995Sbostic for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++); 222*50995Sbostic memset(p, t->bt_bval, len); 223*50995Sbostic if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 224*50995Sbostic return (RET_ERROR); 225*50995Sbostic } 226*50995Sbostic t->bt_smap = sp; 227*50995Sbostic return (RET_SUCCESS); 228*50995Sbostic } 229*50995Sbostic 230*50995Sbostic /* 231*50995Sbostic * __REC_VMAP -- Get variable length records from a file. 232*50995Sbostic * 233*50995Sbostic * Parameters: 234*50995Sbostic * t: tree 235*50995Sbostic * cnt: records to read 236*50995Sbostic * 237*50995Sbostic * Returns: 238*50995Sbostic * RET_ERROR, RET_SUCCESS 239*50995Sbostic */ 240*50995Sbostic int 241*50995Sbostic __rec_vmap(t, top) 242*50995Sbostic BTREE *t; 243*50995Sbostic recno_t top; 244*50995Sbostic { 245*50995Sbostic static int eof; 246*50995Sbostic DBT data; 247*50995Sbostic recno_t nrec; 248*50995Sbostic caddr_t sp, ep; 249*50995Sbostic int bval; 250*50995Sbostic 251*50995Sbostic if (eof) 252*50995Sbostic return (RET_SPECIAL); 253*50995Sbostic 254*50995Sbostic sp = t->bt_smap; 255*50995Sbostic ep = t->bt_emap; 256*50995Sbostic bval = t->bt_bval; 257*50995Sbostic 258*50995Sbostic for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 259*50995Sbostic if (sp >= ep) { 260*50995Sbostic eof = 1; 261*50995Sbostic return (RET_SPECIAL); 262*50995Sbostic } 263*50995Sbostic for (data.data = sp; sp < ep && *sp != bval; ++sp); 264*50995Sbostic data.size = sp - (caddr_t)data.data; 265*50995Sbostic if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 266*50995Sbostic return (RET_ERROR); 267*50995Sbostic ++sp; 268*50995Sbostic } 269*50995Sbostic t->bt_smap = sp; 270*50995Sbostic return (RET_SUCCESS); 271*50995Sbostic } 272