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