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