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.10 (Berkeley) 05/16/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, R_EOF | R_INMEM)) 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, R_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 (ch == EOF && data.size == 0) 151 break; 152 if (__rec_iput(t, nrec, &data, 0) 153 != RET_SUCCESS) 154 return (RET_ERROR); 155 break; 156 } 157 if (sz == 0) { 158 len = p - t->bt_dbuf; 159 t->bt_dbufsz += (sz = 256); 160 if ((t->bt_dbuf = 161 realloc(t->bt_dbuf, t->bt_dbufsz)) == NULL) 162 return (RET_ERROR); 163 p = t->bt_dbuf + len; 164 } 165 } 166 if (ch == EOF) 167 break; 168 } 169 if (nrec < top) { 170 SET(t, R_EOF); 171 return (RET_SPECIAL); 172 } 173 return (RET_SUCCESS); 174 } 175 176 /* 177 * __REC_FMAP -- Get fixed length records from a file. 178 * 179 * Parameters: 180 * t: tree 181 * cnt: records to read 182 * 183 * Returns: 184 * RET_ERROR, RET_SUCCESS 185 */ 186 int 187 __rec_fmap(t, top) 188 BTREE *t; 189 recno_t top; 190 { 191 DBT data; 192 recno_t nrec; 193 caddr_t sp, ep; 194 size_t len; 195 char *p; 196 197 sp = t->bt_cmap; 198 ep = t->bt_emap; 199 data.data = t->bt_dbuf; 200 data.size = t->bt_reclen; 201 202 if (t->bt_dbufsz < t->bt_reclen) { 203 if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 204 return (RET_ERROR); 205 t->bt_dbufsz = t->bt_reclen; 206 } 207 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 208 if (sp >= ep) { 209 SET(t, R_EOF); 210 return (RET_SPECIAL); 211 } 212 len = t->bt_reclen; 213 for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++); 214 memset(p, t->bt_bval, len); 215 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 216 return (RET_ERROR); 217 } 218 t->bt_cmap = sp; 219 return (RET_SUCCESS); 220 } 221 222 /* 223 * __REC_VMAP -- Get variable length records from a file. 224 * 225 * Parameters: 226 * t: tree 227 * cnt: records to read 228 * 229 * Returns: 230 * RET_ERROR, RET_SUCCESS 231 */ 232 int 233 __rec_vmap(t, top) 234 BTREE *t; 235 recno_t top; 236 { 237 DBT data; 238 caddr_t sp, ep; 239 recno_t nrec; 240 int bval; 241 242 sp = t->bt_cmap; 243 ep = t->bt_emap; 244 bval = t->bt_bval; 245 246 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 247 if (sp >= ep) { 248 SET(t, R_EOF); 249 return (RET_SPECIAL); 250 } 251 for (data.data = sp; sp < ep && *sp != bval; ++sp); 252 data.size = sp - (caddr_t)data.data; 253 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 254 return (RET_ERROR); 255 ++sp; 256 } 257 t->bt_cmap = sp; 258 return (RET_SUCCESS); 259 } 260