diff options
author | Stig Bakken <ssb@php.net> | 1999-04-19 13:56:50 +0000 |
---|---|---|
committer | Stig Bakken <ssb@php.net> | 1999-04-19 13:56:50 +0000 |
commit | 6094128afeacfa87d35d1246610a3010654b052f (patch) | |
tree | 369d029066cf2a735b6a638b94d4bdc529b6c373 /ext/dbase/dbf_ndx.c | |
parent | b515f34dd1d5956aeb758cc3f636c183c8adcc73 (diff) | |
download | php-git-6094128afeacfa87d35d1246610a3010654b052f.tar.gz |
moved dbase into ext/ along with the bundled library
dbase programs are no longer included
Diffstat (limited to 'ext/dbase/dbf_ndx.c')
-rw-r--r-- | ext/dbase/dbf_ndx.c | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/ext/dbase/dbf_ndx.c b/ext/dbase/dbf_ndx.c new file mode 100644 index 0000000000..9263b02b0c --- /dev/null +++ b/ext/dbase/dbf_ndx.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 1991, 1992, 1993 Brad Eacker, + * (Music, Intuition, Software, and Computers) + * All Rights Reserved + */ + +#include <stdio.h> +#include <fcntl.h> + +#include "dbf.h" +#include "dbf_ndx.h" + +/* + * get the ndx header for this file + */ +ndx_header_t *ndx_get_header(int fd) +{ + dndx_header_t *dp; + ndx_header_t *np; + + if ((dp = (dndx_header_t *)malloc(NDX_PAGE_SZ)) == NULL) + return NULL; + if ((np = (ndx_header_t *)malloc(sizeof(ndx_header_t))) == NULL) { + free(dp); + return NULL; + } + if ((lseek(fd, 0, 0) < 0) || (read(fd, dp, NDX_PAGE_SZ) < 0)) { + free(dp); free(np); + return NULL; + } + np->ndx_hpage = dp; + np->ndx_fd = fd; + np->ndx_start_pg = get_long(dp->dndx_st_pg); + np->ndx_total_pgs = get_long(dp->dndx_tot_pg); + np->ndx_key_len = get_short(dp->dndx_key_len); + np->ndx_keys_ppg = get_short(dp->dndx_keys_ppg); + np->ndx_key_type = get_short(dp->dndx_key_type); + np->ndx_key_size = get_long(dp->dndx_size_key); + np->ndx_key_name = dp->dndx_key_name; + np->ndx_unique = dp->dndx_unique; + + np->ndx_fp = NULL; + + return np; +} + +static ndx_page_t *ndx_get_page(ndx_header_t *hp, int pageno) +{ + ndx_page_t *fp; + dndx_page_t *dp; + ndx_record_t *rp; + +#if DEBUG + printf("getting page %d", pageno); +#endif + if ((fp = (ndx_page_t *)malloc(sizeof(ndx_page_t))) == NULL) + return NULL; + if ((dp = (dndx_page_t *)malloc(NDX_PAGE_SZ)) == NULL) { + free(fp); + return NULL; + } + if ((rp = (ndx_record_t *)malloc(sizeof(ndx_record_t) * hp->ndx_keys_ppg)) == NULL) { + free(dp); free(fp); + return NULL; + } + fp->ndxp_page_data = dp; + if ((lseek(hp->ndx_fd, pageno * NDX_PAGE_SZ, 0) < 0) || + (read(hp->ndx_fd, dp, NDX_PAGE_SZ) < 0)) { + free(fp); free(dp); + return NULL; + } + fp->ndxp_parent = NULL; + fp->ndxp_page_no = pageno; + fp->ndxp_num_keys = get_long(dp->dndxp_num_keys); + memset(rp, 0, sizeof(ndx_record_t) * hp->ndx_keys_ppg); + fp->ndxp_records = rp; + fp->ndxp_header_p = hp; +#if DEBUG + printf(", n_keys %ld\n", fp->ndxp_num_keys); +#endif + return fp; +} + +/* + * get the first entry for this ndx + */ +static ndx_page_t *ndx_get_first_pg(ndx_header_t *hp) +{ + ndx_page_t *fp; + + if (hp->ndx_fp) + return hp->ndx_fp; + if ((fp = ndx_get_page(hp, hp->ndx_start_pg))) { + hp->ndx_fp = fp; + } + return fp; +} + +static ndx_record_t *ndx_get_record(ndx_page_t *fp, int rec_no) +{ + ndx_record_t *rp; + ndx_header_t *hp = fp->ndxp_header_p; + struct dndx_record *drp; + +#if DEBUG + printf("page %ld, rec %d: ", fp->ndxp_page_no, rec_no); +#endif + if (rec_no >= fp->ndxp_num_keys) + return NULL; + rp = &(fp->ndxp_records[rec_no]); + if (!rp->ndxr_page) { + rp->ndxr_page = fp; + drp = (dndx_record_t *)((char *)&fp->ndxp_page_data->dndx_rp + + rec_no * hp->ndx_key_size); + rp->ndxr_left = get_long(drp->dndx_left_pg); + rp->ndxr_rec = get_long(drp->dndx_dbf_rec); + rp->ndxr_key_data = &drp->dndx_key_data; + rp->ndxr_p_nrec = rec_no; + } +#if DEBUG + printf("left %ld, dbf_rec %ld, data '%s'\n", rp->ndxr_left, + rp->ndxr_rec, rp->ndxr_key_data); +#endif + return rp; +} + +static ndx_record_t *ndx_scan_down(ndx_header_t *hp, ndx_page_t *fp, int recno) +{ + ndx_page_t *np; + ndx_record_t *rp; + + while ((rp = ndx_get_record(fp, recno)) && (rp->ndxr_rec == 0)) { + np = ndx_get_page(hp, rp->ndxr_left); + np->ndxp_parent = fp; + np->ndxp_par_rno = recno; + fp = np; + recno = 0; + } + return rp; +} + +static ndx_record_t *ndx_scan_up(ndx_header_t *hp, ndx_page_t *fp, int recno) +{ + ndx_record_t *rp; + + if (fp == NULL) + rp = NULL; + else if (recno < fp->ndxp_num_keys) { + rp = ndx_scan_down(hp, fp, recno); + } else { + rp = ndx_scan_up(hp, fp->ndxp_parent, fp->ndxp_par_rno + 1); + } + return rp; +} + +ndx_record_t *ndx_get_first_rec(ndx_header_t *hp) +{ + ndx_page_t *fp; + ndx_record_t *rp = NULL; + + if ((fp = ndx_get_first_pg(hp))) { + fp->ndxp_last_key = 0; + rp = ndx_scan_down(hp, fp, 0); + } + hp->ndx_cur_rec = rp; + return rp; +} + +ndx_record_t *ndx_get_next_rec(ndx_header_t *hp, ndx_record_t *rp) +{ + ndx_page_t *fp; + int rec_no; + + fp = rp->ndxr_page; + rec_no = rp->ndxr_p_nrec + 1; + if (rec_no < fp->ndxp_num_keys) { + rp = ndx_scan_down(hp, fp, rec_no); + } else { + rp = ndx_scan_up(hp, fp->ndxp_parent, fp->ndxp_par_rno + 1); + } + return rp; +} + |