Skip to content

Commit

Permalink
allow Stat 12 to sneak through
Browse files Browse the repository at this point in the history
  • Loading branch information
raganwald committed Jul 6, 2012
1 parent 1175b22 commit e8c2f34
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 25 deletions.
48 changes: 24 additions & 24 deletions ext/Read.c
Expand Up @@ -21,25 +21,25 @@ double read_double_t() { uint64_t t=0; fread(&t, sizeof(t), 1, fp); if (swap_end
struct stata_file * read_stata_file(char * filename)
{
if (verbose) printf("read file '%s'\n", filename);

long i,j;

struct stata_file * f = (struct stata_file *)malloc(sizeof(struct stata_file));
memset(f, 0, sizeof(struct stata_file));
f->filename = (char*)malloc(strlen(filename)+1);
strcpy(f->filename, filename);

fp = fopen(f->filename, "rb");
if (fp == NULL) { set_error(f, "error reading file"); return f; }

/*fseek(fp, 0 , SEEK_END);
long lSize = ftell(fp);
rewind(fp);
printf("file is %ld bytes long\n", lSize);*/


/* 5.1 Header */
f->ds_format = fgetc(fp); if (f->ds_format != 0x72) { set_error(f, "invalid file ds_format"); return f; }
f->ds_format = fgetc(fp); if (f->ds_format < 0x72) { set_error(f, "invalid file ds_format"); return f; }
f->byteorder = fgetc(fp); if (f->byteorder != 0x01 && f->byteorder != 0x02) { set_error(f, "invalid file byteorder"); return f; }
if (f->byteorder != get_host_endian()) swap_endian_needed = 1;
f->filetype = fgetc(fp); if (f->filetype != 0x01) { set_error(f, "invalid file filetype"); return f; }
Expand All @@ -48,8 +48,8 @@ struct stata_file * read_stata_file(char * filename)
f->nobs = read_uint32_t(); if (f->nobs <= 0) { set_error(f, "invalid nobs (< 1)"); return f; }
fread(&f->data_label, sizeof(f->data_label), 1, fp);
fread(&f->time_stamp, sizeof(f->time_stamp), 1, fp);


/* 5.2 Descriptors */
f->typlist = (uint8_t *)malloc(f->nvar);
fread(f->typlist, 1, f->nvar, fp);
Expand All @@ -58,12 +58,12 @@ struct stata_file * read_stata_file(char * filename)
for (i = 0 ; i <= f->nvar ; i++) f->srtlist[i] = read_uint16_t();
f->fmtlist = read_strings(f->nvar, 49);
f->lbllist = read_strings(f->nvar, 33);


/* 5.3 Variable Labels */
f->variable_labels = read_strings(f->nvar, 81);


/* 5.4 Expansion Fields */
uint8_t data_type;
uint32_t len;
Expand All @@ -73,8 +73,8 @@ struct stata_file * read_stata_file(char * filename)
if (len > 0) for (i = 0 ; i < len ; i++) fgetc(fp);
} while(data_type != 0 || len != 0 || feof(fp));
/*printf ("read %d bytes of expansion fields\n", count);*/


/* 5.5 Data */
/*printf(" read 5.5 Data (%dx%d)\n", f->nobs, f->nvar);*/
f->obs = (struct stata_obs *)malloc(sizeof(struct stata_obs)*f->nobs);
Expand All @@ -85,38 +85,38 @@ struct stata_file * read_stata_file(char * filename)
{
struct stata_var * var = &f->obs[j].var[i];
memset(var, 0, sizeof(struct stata_var));
if (f->typlist[i] != 0 &&

if (f->typlist[i] != 0 &&
f->typlist[i] < 245) { var->v_type = V_STR; var->v_str = read_string(f->typlist[i]); if (feof(fp)) { set_error(f, "end of file reached too soon"); return f; }; }
else if (f->typlist[i] == 251) { var->v_type = V_BYTE; if (fread(&var->v_byte, sizeof(var->v_byte), 1, fp) != 1) { set_error(f, "fread from file failed"); }; if (feof(fp)) { set_error(f, "end of file reached too soon"); return f; }; }
else if (f->typlist[i] == 252) { var->v_type = V_INT; var->v_int = read_int16_t(); if (feof(fp)) { set_error(f, "end of file reached too soon"); return f; }; }
else if (f->typlist[i] == 253) { var->v_type = V_LONG; var->v_long = read_int32_t(); if (feof(fp)) { set_error(f, "end of file reached too soon"); return f; }; }
else if (f->typlist[i] == 254) { var->v_type = V_FLOAT; var->v_float = read_float_t(); if (feof(fp)) { set_error(f, "end of file reached too soon"); return f; }; }
else if (f->typlist[i] == 255) { var->v_type = V_DOUBLE; var->v_double = read_double_t(); if (feof(fp)) { set_error(f, "end of file reached too soon"); return f; }; }
else fprintf(stderr, "error.\n");

if (ferror(fp)) perror("error occurred");
if (feof(fp)) { fprintf(stderr, "eof error at var %ld (error:%d)\n", i, ferror(fp)); break; }
}
if (feof(fp)) { fprintf(stderr, "eof error at obs %ld (error:%d)\n", j, ferror(fp)); exit(1); }
}


/* 5.6 Value labels */
if (!feof(fp))
{
while (!feof(fp))
{
int32_t len = read_int32_t();
if (feof(fp) || len == 0) break;

f->num_vlt++;
f->vlt = (struct stata_vlt *)realloc(f->vlt, sizeof(struct stata_vlt)*f->num_vlt);
struct stata_vlt * vlt = &f->vlt[f->num_vlt-1];

if (fread(vlt->name, 33, 1, fp) != 1) { set_error(f, "fread from file failed"); return f; };
fgetc(fp); fgetc(fp); fgetc(fp); /* padding */

vlt->n = read_int32_t();
vlt->txtlen = read_int32_t(); if (vlt->txtlen >= 32000) { set_error(f, "value label table txtlen is > 32000"); return f; };
vlt->off = (int32_t*)malloc(sizeof(int32_t)*vlt->n);
Expand All @@ -129,7 +129,7 @@ struct stata_file * read_stata_file(char * filename)
}
/*printf(" read 5.6 Value labels (%d)\n", f->num_vlt);*/


fclose(fp);
return f;
}
2 changes: 1 addition & 1 deletion stata.gemspec
Expand Up @@ -2,7 +2,7 @@

Gem::Specification.new do |s|
s.name = 'stata'
s.version = '0.1.1'
s.version = '0.1.2'
s.authors = ['Kevin Branigan']
s.summary = 'Read and write support for the Stata binary format'
s.homepage = 'http://github.com/unspace/stata'
Expand Down

0 comments on commit e8c2f34

Please sign in to comment.