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.3 (Berkeley) 06/23/92"; 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 "recno.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 const DBT *key; 38 DBT *data; 39 u_int flags; 40 { 41 BTREE *t; 42 EPG *e; 43 recno_t nrec; 44 int status; 45 46 if (flags || (nrec = *(recno_t *)key->data) == 0) { 47 errno = EINVAL; 48 return (RET_ERROR); 49 } 50 51 /* 52 * If we haven't seen this record yet, try to find it in the 53 * original file. 54 */ 55 t = dbp->internal; 56 if (nrec > t->bt_nrecs && 57 (status = t->bt_irec(t, nrec)) != RET_SUCCESS) 58 return (status); 59 60 --nrec; 61 if ((e = __rec_search(t, nrec, SEARCH)) == NULL) 62 return (RET_ERROR); 63 64 status = __rec_ret(t, e, data); 65 mpool_put(t->bt_mp, e->page, 0); 66 return (status); 67 } 68 69 /* 70 * __REC_FPIPE -- Get fixed length records from a pipe. 71 * 72 * Parameters: 73 * t: tree 74 * cnt: records to read 75 * 76 * Returns: 77 * RET_ERROR, RET_SUCCESS 78 */ 79 int 80 __rec_fpipe(t, top) 81 BTREE *t; 82 recno_t top; 83 { 84 DBT data; 85 recno_t nrec; 86 size_t len; 87 int ch; 88 char *p; 89 90 if (t->bt_reof) 91 return (RET_SPECIAL); 92 93 data.data = t->bt_dbuf; 94 data.size = t->bt_reclen; 95 96 if (t->bt_dbufsz < t->bt_reclen) { 97 if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 98 return (RET_ERROR); 99 t->bt_dbufsz = t->bt_reclen; 100 } 101 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 102 for (p = t->bt_dbuf;; *p++ = ch) 103 if ((ch = getc(t->bt_rfp)) == EOF || !len--) { 104 if (__rec_iput(t, nrec, &data, 0) 105 != RET_SUCCESS) 106 return (RET_ERROR); 107 break; 108 } 109 if (ch == EOF) 110 break; 111 } 112 if (nrec < top) { 113 t->bt_reof = 1; 114 return (RET_SPECIAL); 115 } 116 return (RET_SUCCESS); 117 } 118 119 /* 120 * __REC_VPIPE -- Get variable length records from a pipe. 121 * 122 * Parameters: 123 * t: tree 124 * cnt: records to read 125 * 126 * Returns: 127 * RET_ERROR, RET_SUCCESS 128 */ 129 int 130 __rec_vpipe(t, top) 131 BTREE *t; 132 recno_t top; 133 { 134 DBT data; 135 recno_t nrec; 136 index_t len; 137 size_t sz; 138 int bval, ch; 139 char *p; 140 141 if (t->bt_reof) 142 return (RET_SPECIAL); 143 144 bval = t->bt_bval; 145 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 146 for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) { 147 if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) { 148 data.data = t->bt_dbuf; 149 data.size = p - t->bt_dbuf; 150 if (__rec_iput(t, nrec, &data, 0) 151 != RET_SUCCESS) 152 return (RET_ERROR); 153 break; 154 } 155 if (sz == 0) { 156 len = p - t->bt_dbuf; 157 sz = t->bt_dbufsz += 256; 158 if ((t->bt_dbuf = 159 realloc(t->bt_dbuf, sz)) == NULL) 160 return (RET_ERROR); 161 p = t->bt_dbuf + len; 162 } 163 } 164 if (ch == EOF) 165 break; 166 } 167 if (nrec < top) { 168 t->bt_reof = 1; 169 return (RET_SPECIAL); 170 } 171 return (RET_SUCCESS); 172 } 173 174 /* 175 * __REC_FMAP -- Get fixed length records from a file. 176 * 177 * Parameters: 178 * t: tree 179 * cnt: records to read 180 * 181 * Returns: 182 * RET_ERROR, RET_SUCCESS 183 */ 184 int 185 __rec_fmap(t, top) 186 BTREE *t; 187 recno_t top; 188 { 189 DBT data; 190 recno_t nrec; 191 caddr_t sp, ep; 192 size_t len; 193 char *p; 194 195 if (t->bt_reof) 196 return (RET_SPECIAL); 197 198 sp = t->bt_smap; 199 ep = t->bt_emap; 200 data.data = t->bt_dbuf; 201 data.size = t->bt_reclen; 202 203 if (t->bt_dbufsz < t->bt_reclen) { 204 if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 205 return (RET_ERROR); 206 t->bt_dbufsz = t->bt_reclen; 207 } 208 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 209 if (sp >= ep) { 210 t->bt_reof = 1; 211 return (RET_SPECIAL); 212 } 213 len = t->bt_reclen; 214 for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++); 215 memset(p, t->bt_bval, len); 216 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 217 return (RET_ERROR); 218 } 219 t->bt_smap = sp; 220 return (RET_SUCCESS); 221 } 222 223 /* 224 * __REC_VMAP -- Get variable length records from a file. 225 * 226 * Parameters: 227 * t: tree 228 * cnt: records to read 229 * 230 * Returns: 231 * RET_ERROR, RET_SUCCESS 232 */ 233 int 234 __rec_vmap(t, top) 235 BTREE *t; 236 recno_t top; 237 { 238 DBT data; 239 caddr_t sp, ep; 240 recno_t nrec; 241 int bval; 242 243 if (t->bt_reof) 244 return (RET_SPECIAL); 245 246 sp = t->bt_smap; 247 ep = t->bt_emap; 248 bval = t->bt_bval; 249 250 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 251 if (sp >= ep) { 252 t->bt_reof = 1; 253 return (RET_SPECIAL); 254 } 255 for (data.data = sp; sp < ep && *sp != bval; ++sp); 256 data.size = sp - (caddr_t)data.data; 257 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 258 return (RET_ERROR); 259 ++sp; 260 } 261 t->bt_smap = sp; 262 return (RET_SUCCESS); 263 } 264