staden-lg/src/frog/abi.c

161 lines
3.0 KiB
C

#include <stdio.h>
#include "mach-io.h"
typedef struct {
char id[12];
int_2 s1;
int_2 s2;
int_2 s3;
int_2 s4;
int_2 recs;
int_4 l1;
int_4 offset;
int_4 l2;
} Header;
typedef struct {
char id[4];
int_4 index;
int_2 type;
int_2 size;
int_4 N;
int_4 length;
int_4 ptr1;
int_4 ptr2;
} Rec;
/*
** Meaningful ids: (Explanations c/o jes)
**
** GMBF Gel type
** DATA.1-4 Raw data block
** DATA.5-8 Central (rather featureless) data block
** DATA.9-12 Processed data block
** FWO_ Base order (see seqIOABI.c)
** PBAS.1-2 Base sequence
** PLOC.1-2 Base positions
** S/N% Signal strengths (array of 4 shorts floats)
** SMPL Sample name
** SPAC Base spacing (float)
**
** It appears that if the value for an id occupies less than or equal four
** bytes, it is shoe-horned into the ptr1 field. Otherwise, ptr1 holds
** the byte offset in the file where the data can be found.
**
**
**
**
*/
int read_header(FILE *fp, Header *h)
{
#define FREAD(R) \
if ( fread(&(h->R),sizeof(h->R),1,fp) == 0) \
return 1;
fseek(fp,0,0);
FREAD(id);
FREAD(s1);
FREAD(s2);
FREAD(s3);
FREAD(s4);
FREAD(recs);
FREAD(l1);
FREAD(offset);
FREAD(l2);
return 0;
}
int abi_dump(char *fn)
{
FILE *fp;
Rec *recs;
Header header;
int i;
int reads;
if ( (fp=fopen(fn,"rb")) == NULL ) return 1;
if (read_header(fp,&header)) { fclose(fp); return 2;}
recs = (Rec *) malloc(header.recs * sizeof(Header));
fseek(fp,header.offset,0);
reads = fread(recs,sizeof(Rec),header.recs,fp);
if (reads!=header.recs) {
fclose(fp);
free(recs);
return 3;
}
printf("file:%s\n",fn);
printf(" ID indx type size recs length pointer1 pointer2 Text...\n");
printf(" ---- ---- ---- ---- ------ ------ -------- -------- -------\n");
for (i=0; i<header.recs;i++) {
printf(" %4.4s %4d %04x %4d %6d %6d %08x %08x",
recs[i].id,
recs[i].index,
recs[i].type,
recs[i].size,
recs[i].N,
recs[i].length,
recs[i].ptr1,
recs[i].ptr2
);
switch(recs[i].type) {
case 0x12: /* string */
{
char *s;
char buf[32];
int len;
len = (recs[i].length > sizeof(buf)) ? sizeof(buf) : recs[i].length;
if(recs[i].length<=4) {
/*
** stored in ptr1
*/
s = (char *) &recs[i].ptr1;
} else {
/*
** stored in file at offset ptr1
** NOTE - byte at offset is string length
*/
fseek(fp,recs[i].ptr1,0);
if (len = fread(buf,1,len,fp)) len--;
s = buf+1;
}
printf(" %-32.*s\n",len,s,(len>32)?"...\n":"\n");
break;
}
case 0x0c: /* character array? */
case 0x0d: /* bit array? */
case 0x04: /* integer array */
case 0x02: /* sequence ?*/
case 0x0a: /* date */
case 0x0b: /* time */
case 0x07: /* float */
default:
printf("\n");
break;
}
}
printf("\n");
free(recs);
fclose(fp);
return 0;
}
main(int argc, char **argv)
{
while (--argc) {
int err;
argv++;
if (err=abi_dump(*argv)) printf("Couldn't read %s (%d)\n",*argv,err);
}
}