]> granicus.if.org Git - php/commitdiff
handle dbase files with padded field headers. (patch from
authorjim winstead <jimw@php.net>
Mon, 8 Oct 2001 21:52:26 +0000 (21:52 +0000)
committerjim winstead <jimw@php.net>
Mon, 8 Oct 2001 21:52:26 +0000 (21:52 +0000)
Landon Bradshaw <landon@bradshaw.org>)

ext/dbase/dbf_head.c

index 2cf2348c8f2e8baeeb58b5595ce6de8fa0cde07a..e73d134907d11f9df74a8ab922550462fade4ba0 100644 (file)
@@ -21,8 +21,8 @@ dbhead_t *get_dbf_head(int fd)
 {
        dbhead_t *dbh;
        struct dbf_dhead  dbhead;
-       dbfield_t *dbf, *cur_f;
-       int ret, nfields, offset;
+       dbfield_t *dbf, *cur_f, *tdbf;
+       int ret, nfields, offset, gf_retval;
 
        if ((dbh = (dbhead_t *)malloc(sizeof(dbhead_t))) == NULL)
                return NULL;
@@ -42,21 +42,33 @@ dbhead_t *get_dbf_head(int fd)
                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);
-
+       /* malloc enough memory for the maximum number of fields:
+          32 * 254 = 8128 bytes */
+       tdbf = (dbfield_t *)malloc(sizeof(dbfield_t)*254);
+       
        offset = 1;
-       for (cur_f = dbf; cur_f < &dbf[nfields] ; cur_f++) {
-               if (get_dbf_field(dbh, cur_f) < 0) {
+       nfields = 0;
+       gf_retval = 0;
+       for (cur_f = tdbf; gf_retval < 2 && nfields < 254; cur_f++) {
+               gf_retval = get_dbf_field(dbh, cur_f);
+
+               if (gf_retval < 0) {
                        free_dbf_head(dbh);
                        return NULL;
                }
-               cur_f->db_foffset = offset;
-               offset += cur_f->db_flen;
+               if (gf_retval != 2 ) {
+                       cur_f->db_foffset = offset;
+                       offset += cur_f->db_flen;
+                       nfields++;
+               }
        }
+       dbh->db_nfields = nfields;
+       
+       /* malloc the right amount of space for records, copy and destroy old */
+       dbf = (dbfield_t *)malloc(sizeof(dbfield_t)*nfields);
+       memcpy(dbf, tdbf, sizeof(dbfield_t)*nfields);
+       free(tdbf);
+
        dbh->db_fields = dbf;
 
        return dbh;
@@ -124,6 +136,12 @@ int get_dbf_field(dbhead_t *dbh, dbfield_t *dbf)
                return ret;
        }
 
+       /* Check for the '0Dh' field terminator , if found return '2'
+          which will tell the loop we are at the end of fields */
+       if (dbfield.dbf_name[0]==0x0d) {
+               return 2;
+       }
+
        /* build the field name */
        copy_crimp(dbf->db_fname, dbfield.dbf_name, DBF_NAMELEN);
 
@@ -135,6 +153,7 @@ int get_dbf_field(dbhead_t *dbh, dbfield_t *dbf)
                break;
            default:
                dbf->db_flen = get_short(dbfield.dbf_flen);
+               break;
        }
 
        if ((dbf->db_format = get_dbf_f_fmt(dbf)) == NULL) {