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.8 (Berkeley) 03/19/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) { 59 if (ISSET(t, BTF_EOF | BTF_RINMEM)) 60 return (RET_SPECIAL); 61 if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS) 62 return (status); 63 } 64 65 --nrec; 66 if ((e = __rec_search(t, nrec, SEARCH)) == NULL) 67 return (RET_ERROR); 68 69 status = __rec_ret(t, e, 0, NULL, data); 70 mpool_put(t->bt_mp, e->page, 0); 71 return (status); 72 } 73 74 /* 75 * __REC_FPIPE -- Get fixed length records from a pipe. 76 * 77 * Parameters: 78 * t: tree 79 * cnt: records to read 80 * 81 * Returns: 82 * RET_ERROR, RET_SUCCESS 83 */ 84 int 85 __rec_fpipe(t, top) 86 BTREE *t; 87 recno_t top; 88 { 89 DBT data; 90 recno_t nrec; 91 size_t len; 92 int ch; 93 char *p; 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 SET(t, BTF_EOF); 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 indx_t len; 140 size_t sz; 141 int bval, ch; 142 char *p; 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 t->bt_dbufsz += (sz = 256); 158 if ((t->bt_dbuf = 159 realloc(t->bt_dbuf, t->bt_dbufsz)) == 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 SET(t, BTF_EOF); 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 sp = t->bt_cmap; 196 ep = t->bt_emap; 197 data.data = t->bt_dbuf; 198 data.size = t->bt_reclen; 199 200 if (t->bt_dbufsz < t->bt_reclen) { 201 if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 202 return (RET_ERROR); 203 t->bt_dbufsz = t->bt_reclen; 204 } 205 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 206 if (sp >= ep) { 207 SET(t, BTF_EOF); 208 return (RET_SPECIAL); 209 } 210 len = t->bt_reclen; 211 for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++); 212 memset(p, t->bt_bval, len); 213 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 214 return (RET_ERROR); 215 } 216 t->bt_cmap = sp; 217 return (RET_SUCCESS); 218 } 219 220 /* 221 * __REC_VMAP -- Get variable length records from a file. 222 * 223 * Parameters: 224 * t: tree 225 * cnt: records to read 226 * 227 * Returns: 228 * RET_ERROR, RET_SUCCESS 229 */ 230 int 231 __rec_vmap(t, top) 232 BTREE *t; 233 recno_t top; 234 { 235 DBT data; 236 caddr_t sp, ep; 237 recno_t nrec; 238 int bval; 239 240 sp = t->bt_cmap; 241 ep = t->bt_emap; 242 bval = t->bt_bval; 243 244 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 245 if (sp >= ep) { 246 SET(t, BTF_EOF); 247 return (RET_SPECIAL); 248 } 249 for (data.data = sp; sp < ep && *sp != bval; ++sp); 250 data.size = sp - (caddr_t)data.data; 251 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 252 return (RET_ERROR); 253 ++sp; 254 } 255 t->bt_cmap = sp; 256 return (RET_SUCCESS); 257 } 258