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_head.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_head.c')
-rw-r--r-- | ext/dbase/dbf_head.c | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/ext/dbase/dbf_head.c b/ext/dbase/dbf_head.c new file mode 100644 index 0000000000..1f104e3d81 --- /dev/null +++ b/ext/dbase/dbf_head.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 1991, 1992, 1993 Brad Eacker, + * (Music, Intuition, Software, and Computers) + * All Rights Reserved + */ + +#include <stdio.h> +#include <fcntl.h> + +#include "dbf.h" + +void free_dbf_head(dbhead_t *dbh); +int get_dbf_field(dbhead_t *dbh, dbfield_t *dbf); + +/* + * get the header info from the file + * basic header info & field descriptions + */ +dbhead_t *get_dbf_head(int fd) +{ + dbhead_t *dbh; + struct dbf_dhead dbhead; + dbfield_t *dbf, *cur_f; + int ret, nfields, offset; + + if ((dbh = (dbhead_t *)malloc(sizeof(dbhead_t))) == NULL) + return NULL; + if (lseek(fd, 0, 0) < 0) + return NULL; + if ((ret = read(fd, &dbhead, sizeof(dbhead))) < 0) + return NULL; + + /* build in core info */ + dbh->db_fd = fd; + dbh->db_dbt = dbhead.dbh_dbt; + dbh->db_records = get_long(dbhead.dbh_records); + dbh->db_hlen = get_short(dbhead.dbh_hlen); + dbh->db_rlen = get_short(dbhead.dbh_rlen); + + db_set_date(dbh->db_date, dbhead.dbh_date[DBH_DATE_YEAR] + 1900, + dbhead.dbh_date[DBH_DATE_MONTH], + dbhead.dbh_date[DBH_DATE_DAY]); + + dbh->db_nfields = nfields = (dbh->db_hlen - sizeof(struct dbf_dhead)) / + sizeof(struct dbf_dfield); + + /* get all the field info */ + dbf = (dbfield_t *)malloc(sizeof(dbfield_t) * nfields); + + offset = 1; + for (cur_f = dbf; cur_f < &dbf[nfields] ; cur_f++) { + if (get_dbf_field(dbh, cur_f) < 0) { + free_dbf_head(dbh); + return NULL; + } + cur_f->db_foffset = offset; + offset += cur_f->db_flen; + } + dbh->db_fields = dbf; + + return dbh; +} + +/* + * free up the header info built above + */ +void free_dbf_head(dbhead_t *dbh) +{ + dbfield_t *dbf, *cur_f; + int nfields; + + dbf = dbh->db_fields; + nfields = dbh->db_nfields; + for (cur_f = dbf; cur_f < &dbf[nfields]; cur_f++) { + if (cur_f->db_format) { + free(cur_f->db_format); + } + } + + free(dbf); + free(dbh); +} + +/* + * put out the header info + */ +int put_dbf_head(dbhead_t *dbh) +{ + int fd = dbh->db_fd; + struct dbf_dhead dbhead; + int ret; + + memset (&dbhead, 0, sizeof(dbhead)); + + /* build on disk info */ + dbhead.dbh_dbt = dbh->db_dbt; + put_long(dbhead.dbh_records, dbh->db_records); + put_short(dbhead.dbh_hlen, dbh->db_hlen); + put_short(dbhead.dbh_rlen, dbh->db_rlen); + + /* put the date spec'd into the on disk header */ + dbhead.dbh_date[DBH_DATE_YEAR] =(char)(db_date_year(dbh->db_date) - + 1900); + dbhead.dbh_date[DBH_DATE_MONTH]=(char)(db_date_month(dbh->db_date)); + dbhead.dbh_date[DBH_DATE_DAY] =(char)(db_date_day(dbh->db_date)); + + if (lseek(fd, 0, 0) < 0) + return -1; + if ((ret = write(fd, &dbhead, sizeof(dbhead))) < 0) + return -1; + return ret; +} + +/* + * get a field off the disk from the current file offset + */ +int get_dbf_field(dbhead_t *dbh, dbfield_t *dbf) +{ + struct dbf_dfield dbfield; + int ret; + + if ((ret = read(dbh->db_fd, &dbfield, sizeof(dbfield))) < 0) { + return ret; + } + + /* build the field name */ + copy_crimp(dbf->db_fname, dbfield.dbf_name, DBF_NAMELEN); + + dbf->db_type = dbfield.dbf_type; + switch (dbf->db_type) { + case 'N': + dbf->db_flen = dbfield.dbf_flen[0]; + dbf->db_fdc = dbfield.dbf_flen[1]; + break; + default: + dbf->db_flen = get_short(dbfield.dbf_flen); + } + + if ((dbf->db_format = get_dbf_f_fmt(dbf)) == NULL) { + return 1; + } + + return 0; +} + +/* + * put a field out on the disk at the current file offset + */ +int put_dbf_field(dbhead_t *dbh, dbfield_t *dbf) +{ + struct dbf_dfield dbfield; + char *scp, *dcp; + int ret; + + memset (&dbfield, 0, sizeof(dbfield)); + + /* build the on disk field info */ + scp = dbf->db_fname; dcp = dbfield.dbf_name; + + strncpy(dbfield.dbf_name, dbf->db_fname, DBF_NAMELEN); + + dbfield.dbf_type = dbf->db_type; + switch (dbf->db_type) { + case 'N': + dbfield.dbf_flen[0] = dbf->db_flen; + dbfield.dbf_flen[1] = dbf->db_fdc; + break; + default: + put_short(dbfield.dbf_flen, dbf->db_flen); + } + + /* now write it out to disk */ + if ((ret = write(dbh->db_fd, &dbfield, sizeof(dbfield))) < 0) { + return ret; + } + return 1; +} + +/* + * put out all the info at the top of the file... + */ +static char end_stuff[2] = {0x0d, 0}; + +void put_dbf_info(dbhead_t *dbh) +{ + dbfield_t *dbf; + char *cp; + int fcnt; + + if ((cp = db_cur_date(NULL))) { + strncpy(dbh->db_date, cp, 8); + free(cp); + } + put_dbf_head(dbh); + dbf = dbh->db_fields; + for (fcnt = dbh->db_nfields; fcnt > 0; fcnt--, dbf++) + put_dbf_field(dbh, dbf); + write(dbh->db_fd, end_stuff, 1); +} + +char *get_dbf_f_fmt(dbfield_t *dbf) +{ + char format[100]; + + /* build the field format for printf */ + switch (dbf->db_type) { + case 'C': + sprintf(format, "%%-%ds", dbf->db_flen); + break; + case 'N': + case 'L': + case 'D': + sprintf(format, "%%%ds", dbf->db_flen); + break; + case 'M': + strcpy(format, "%s"); + break; + } + return (char *)strdup(format); +} + +dbhead_t *dbf_open(char *dp, int o_flags) +{ + int fd; + char *cp; + dbhead_t *dbh; + + cp = dp; + if ((fd = open(cp, o_flags|O_BINARY)) < 0) { + cp = (char *)malloc(256); + strcpy(cp, dp); strcat(cp, ".dbf"); + if ((fd = open(cp, o_flags)) < 0) { + perror("open"); + return NULL; + } + } + + if ((dbh = get_dbf_head(fd)) == 0) { + fprintf(stderr, "Unable to get header\n"); + return NULL; + } + dbh->db_name = cp; + dbh->db_cur_rec = 0; + + return dbh; +} + +void dbf_head_info(dbhead_t *dbh) +{ + int nfields; + dbfield_t *dbf, *cur_f; + + nfields = dbh->db_nfields; + printf("# fields: %d, record len: %d, total records %ld\n", + nfields, dbh->db_rlen, dbh->db_records); + dbf = dbh->db_fields; + for (cur_f = dbf; cur_f < &dbf[nfields] ; cur_f++) { + printf("# %s, %c, %d, %d\n", cur_f->db_fname, + cur_f->db_type, cur_f->db_flen, cur_f->db_fdc); + } +} |