/* * __REC_VMAP -- Get variable length records from a file. * * Parameters: * t: tree * cnt: records to read * * Returns: * RET_ERROR, RET_SUCCESS */ int __rec_vmap(BTREE *t, recno_t top) { DBT data; unsigned char *sp, *ep; recno_t nrec; int bval; sp = (unsigned char *)t->bt_cmap; ep = (unsigned char *)t->bt_emap; bval = t->bt_bval; for (nrec = t->bt_nrecs; nrec < top; ++nrec) { if (sp >= ep) { F_SET(t, R_EOF); return (RET_SPECIAL); } for (data.data = sp; sp < ep && *sp != bval; ++sp); data.size = sp - (unsigned char *)data.data; if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) return (RET_ERROR); ++sp; } t->bt_cmap = (caddr_t)sp; return (RET_SUCCESS); }
/* * __REC_FMAP -- Get fixed length records from a file. * * Parameters: * t: tree * cnt: records to read * * Returns: * RET_ERROR, RET_SUCCESS */ int __rec_fmap(BTREE *t, recno_t top) { DBT data; recno_t nrec; unsigned char *sp, *ep, *p; size_t len; if (t->bt_rdata.size < t->bt_reclen) { t->bt_rdata.data = reallocf(t->bt_rdata.data, t->bt_reclen); if (t->bt_rdata.data == NULL) return (RET_ERROR); t->bt_rdata.size = t->bt_reclen; } data.data = t->bt_rdata.data; data.size = t->bt_reclen; sp = (unsigned char *)t->bt_cmap; ep = (unsigned char *)t->bt_emap; for (nrec = t->bt_nrecs; nrec < top; ++nrec) { if (sp >= ep) { F_SET(t, R_EOF); return (RET_SPECIAL); } len = t->bt_reclen; for (p = t->bt_rdata.data; sp < ep && len > 0; *p++ = *sp++, --len); if (len != 0) memset(p, t->bt_bval, len); if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) return (RET_ERROR); } t->bt_cmap = (caddr_t)sp; return (RET_SUCCESS); }
/* * __REC_VPIPE -- Get variable length records from a pipe. * * Parameters: * t: tree * cnt: records to read * * Returns: * RET_ERROR, RET_SUCCESS */ int __rec_vpipe(BTREE *t, recno_t top) { DBT data; recno_t nrec; size_t len; size_t sz; int bval, ch; unsigned char *p; bval = t->bt_bval; for (nrec = t->bt_nrecs; nrec < top; ++nrec) { for (p = t->bt_rdata.data, sz = t->bt_rdata.size;; *p++ = ch, --sz) { if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) { data.data = t->bt_rdata.data; data.size = p - (unsigned char *)t->bt_rdata.data; if (ch == EOF && data.size == 0) break; if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) return (RET_ERROR); break; } if (sz == 0) { len = p - (unsigned char *)t->bt_rdata.data; t->bt_rdata.size += (sz = 256); t->bt_rdata.data = reallocf(t->bt_rdata.data, t->bt_rdata.size); if (t->bt_rdata.data == NULL) return (RET_ERROR); p = (unsigned char *)t->bt_rdata.data + len; } } if (ch == EOF) break; } if (nrec < top) { F_SET(t, R_EOF); return (RET_SPECIAL); } return (RET_SUCCESS); }
/* * __REC_FPIPE -- Get fixed length records from a pipe. * * Parameters: * t: tree * cnt: records to read * * Returns: * RET_ERROR, RET_SUCCESS */ int __rec_fpipe(BTREE *t, recno_t top) { DBT data; recno_t nrec; size_t len; int ch; unsigned char *p; if (t->bt_rdata.size < t->bt_reclen) { t->bt_rdata.data = reallocf(t->bt_rdata.data, t->bt_reclen); if (t->bt_rdata.data == NULL) return (RET_ERROR); t->bt_rdata.size = t->bt_reclen; } data.data = t->bt_rdata.data; data.size = t->bt_reclen; for (nrec = t->bt_nrecs; nrec < top;) { len = t->bt_reclen; for (p = t->bt_rdata.data;; *p++ = ch) if ((ch = getc(t->bt_rfp)) == EOF || !--len) { if (ch != EOF) *p = ch; if (len != 0) memset(p, t->bt_bval, len); if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) return (RET_ERROR); ++nrec; break; } if (ch == EOF) break; } if (nrec < top) { F_SET(t, R_EOF); return (RET_SPECIAL); } return (RET_SUCCESS); }
/* * __REC_PUT -- Add a recno item to the tree. * * Parameters: * dbp: pointer to access method * key: key * data: data * flag: R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE * * Returns: * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is * already in the tree and R_NOOVERWRITE specified. */ int __rec_put(const DB *dbp, DBT *key, const DBT *data, u_int flags) { BTREE *t; DBT fdata, tdata; recno_t nrec; int status; t = dbp->internal; /* Toss any page pinned across calls. */ if (t->bt_pinned != NULL) { mpool_put(t->bt_mp, t->bt_pinned, 0); t->bt_pinned = NULL; } /* * If using fixed-length records, and the record is long, return * EINVAL. If it's short, pad it out. Use the record data return * memory, it's only short-term. */ if (F_ISSET(t, R_FIXLEN) && data->size != t->bt_reclen) { if (data->size > t->bt_reclen) goto einval; if (t->bt_rdata.size < t->bt_reclen) { t->bt_rdata.data = t->bt_rdata.data == NULL ? malloc(t->bt_reclen) : realloc(t->bt_rdata.data, t->bt_reclen); if (t->bt_rdata.data == NULL) return (RET_ERROR); t->bt_rdata.size = t->bt_reclen; } memmove(t->bt_rdata.data, data->data, data->size); memset((char *)t->bt_rdata.data + data->size, t->bt_bval, t->bt_reclen - data->size); fdata.data = t->bt_rdata.data; fdata.size = t->bt_reclen; } else { fdata.data = data->data; fdata.size = data->size; } switch (flags) { case R_CURSOR: if (!F_ISSET(&t->bt_cursor, CURS_INIT)) goto einval; nrec = t->bt_cursor.rcursor; break; case R_SETCURSOR: if ((nrec = *(recno_t *)key->data) == 0) goto einval; break; case R_IAFTER: if ((nrec = *(recno_t *)key->data) == 0) { nrec = 1; flags = R_IBEFORE; } break; case 0: case R_IBEFORE: if ((nrec = *(recno_t *)key->data) == 0) goto einval; break; case R_NOOVERWRITE: if ((nrec = *(recno_t *)key->data) == 0) goto einval; if (nrec <= t->bt_nrecs) return (RET_SPECIAL); break; default: einval: errno = EINVAL; return (RET_ERROR); } /* * Make sure that records up to and including the put record are * already in the database. If skipping records, create empty ones. */ if (nrec > t->bt_nrecs) { if (!F_ISSET(t, R_EOF | R_INMEM) && t->bt_irec(t, nrec) == RET_ERROR) return (RET_ERROR); if (nrec > t->bt_nrecs + 1) { if (F_ISSET(t, R_FIXLEN)) { if ((tdata.data = (void *)malloc(t->bt_reclen)) == NULL) return (RET_ERROR); tdata.size = t->bt_reclen; memset(tdata.data, t->bt_bval, tdata.size); } else { tdata.data = NULL; tdata.size = 0; } while (nrec > t->bt_nrecs + 1) if (__rec_iput(t, t->bt_nrecs, &tdata, 0) != RET_SUCCESS) return (RET_ERROR); if (F_ISSET(t, R_FIXLEN)) free(tdata.data); } } if ((status = __rec_iput(t, nrec - 1, &fdata, flags)) != RET_SUCCESS) return (status); if (flags == R_SETCURSOR) t->bt_cursor.rcursor = nrec; F_SET(t, R_MODIFIED); return (__rec_ret(t, NULL, nrec, key, NULL)); }