📄 ioroutin.c
字号:
/* low level i/o routines for ah format records * -- witte 6 june 85 */#include <stdio.h>#include <stdlib.h>#include <sys/ioctl.h>#include <rpc/rpc.h>#include <math.h>#include "ahhead.h"/* ah error processing */int ah_errno = 0;int ah_nerr = 10;/* ah error numbers */#define AE_RHED 1 /* error reading header */#define AE_DTYPE 2 /* bad data type */#define AE_WHED 3 /* error writing header */#define AE_RDATA 4 /* error reading data */#define AE_WDATA 5 /* error writing data */#define AE_WRECORD 6 /* error writing record */#define AE_RRECORD 7 /* error reading record */#define AE_TTYOUT 8 /* binary going to tty */#define AE_TTYIN 9 /* binary coming from tty *//* ah errlist */char *ah_errlist[] = { "no error", /* 0 no error */ "read header error", /* 1 AE_RHED */ "bad data type", /* 2 AE_DTYPE */ "write header error", /* 3 AE_WHED */ "read data error", /* 4 AE_RDATA */ "write data error", /* 5 AE_WDATA */ "write record error", /* 6 AE_WRECORD */ "read record error", /* 7 AE_RRECORD */ "tty can't get binary", /* 8 AE_TTYOUT */ "tty can't send binary" /* 9 AE_TTYIN */ };/* gethead * gets the next header from the stream pointed to by * file_pt and returns this header in the structure head. * file_pt is assumed to be positioned at the next header, * and does not search. * returns: * 1 -> no error * -1 -> not enough head to read * -2 -> bad data type */int gethead(head,file_pt) FILE *file_pt; ahhed *head;{ int ierr = 0; if((ierr = fread((char *)head,sizeof(ahhed),1,file_pt)) == 1) { if((head->record.type < TYPEMIN) || (head->record.type > TYPEMAX)) { get_null_head(head); ierr = -2; /* bad data type */ ah_errno= AE_DTYPE; } } else /* not enough head */ { get_null_head(head); ierr = -1; ah_errno= AE_RHED; } return(ierr);}/* puthead * writes the header head onto the stream pointed to by * file_pt. * returns: * 1 -> no error * -1 -> error writing header */int puthead(head,file_pt) FILE *file_pt; ahhed *head;{ int ierr = 0; if((ierr= fwrite((char *)head,sizeof(ahhed),1,file_pt)) != 1) { ah_errno= AE_WHED; ierr= -1; } return(ierr);}/* size * returns the size (in bytes) of the data type given by * head->record.type. * returns: * size of data type -> no error * -1 -> unknown data type */int size(head) ahhed *head;{ int type_size = 0; switch(head->record.type) { case 1: /* real time series */ type_size= sizeof(float); break; case 2: /* complex time series */ type_size= sizeof(complex); break; case 3: /* real x,y pairs */ type_size= sizeof(vector); break; case 4: /* x real, y complex, or real x,y,z */ type_size= sizeof(tensor); break; case 5: /* complex x,y pairs */ type_size= 2*sizeof(complex); break; case 6: /* double */ type_size=sizeof(double); break; default: /* unknown data type */ type_size= -1; ah_errno= AE_DTYPE; break; } return(type_size);}/* tohead * positions the read/write head to the beginning of the * n-th header in the file pointed to by file_pt. * returns: * n -> no error * -1 -> not enough heads * -2 -> bad seek */int tohead(n,file_pt) FILE *file_pt; int n;{ ahhed head; int i,ierr; rewind(file_pt); for(i=1; i<n; ++i) { if(gethead(&head,file_pt) == 1) { if(fseek(file_pt,(long)(head.record.ndata)*(size(&head)),1) == -1) { ierr = -2; /* bad seek */ ah_errno= AE_RHED; return(ierr); } } else { ierr = -1; /* not enough head */ ah_errno= AE_RHED; return(ierr); } } return(i); /* success */}/* getdata * reads from the file pointed to by file_pt into * the array pointed to by array. It assumes that * the read/write head is positioned correctly * (i.e., right after the header), and does not * search. Works for any allowed data type. * returns: * number of elements read -> OK * -1 -> error */int getdata(head,array,file_pt) ahhed *head; char *array; FILE *file_pt;{ int ierr = 0; if((ierr = fread(array,size(head),(int)head->record.ndata,file_pt)) != (int)head->record.ndata) { ah_errno= AE_RDATA; ierr = -1; } return(ierr);}/* putdata * writes array to the file pointed to by * file_pt. Works for any allowed data type. * returns: * number of elements written -> OK * -1 -> error */int putdata(head,array,file_pt) ahhed *head; char *array; FILE *file_pt;{ int ierr = 0; if((ierr = fwrite(array,size(head),(int)head->record.ndata,file_pt)) != (int)head->record.ndata) { ah_errno= AE_WDATA; ierr = -1; } return(ierr);}/* putrecord * writes head and array to the file pointed to by * file_pt. Works for any allowed data type. * returns: * 0 -> OK * -1 -> error writing header * -2 -> error writing data */int putrecord(head,array,file_pt) ahhed *head; char *array; FILE *file_pt;{ int ierr = 0; (puthead(head,file_pt) == 1) ? ((putdata(head,array,file_pt) < 0) ? (ierr = -2) : (ierr = 0)) : (ierr = -1); if(ierr) ah_errno= AE_WRECORD; return(ierr);}/* getrecord * gets header and data from the file pointed to by * file_pt and puts them in head and array. It assumes * that the read/write head is positioned at the beginning * of the header, and does not search. Obviously, calling * routine must have allocated enough space. * returns: * 0 -> OK * -1 -> error reading header * -2 -> error reading data */int getrecord(head,array,file_pt) ahhed *head; char *array; FILE *file_pt;{ int ierr = 0; (gethead(head,file_pt) == 1) ? ((getdata(head,array,file_pt) < 0) ? (ierr = -2) : (ierr = 0)) : (ierr = -1); if(ierr) ah_errno= AE_RRECORD; return(ierr);}/* * getrecord2 * gets header and data from the file pointed to by * file_pt and puts them in head and array. It assumes * that the read/write head is positioned at the beginning * of the header, and does not search (although it does * some error checking). Space for array is allocated, so * be sure to pass a pointer to the data pointer. Got it? * returns: * 0 -> ok * -1 -> error reading record * -2 -> error allocating space for data */int getrecord2(head,array,file_pt) ahhed *head; char **array; FILE *file_pt;{ int ierr = 0; int gethead(); char *mkdatspace(); if(gethead(head, file_pt) != 1) { ierr = -1; return(ierr); } *array= mkdatspace(head); if(*array == NULL) { ierr= -2; return(ierr); } if(getdata(head,*array,file_pt) < 0) ierr= -1; return(ierr);}/* gogethead * gets n-th header from the stream pointed to by * file_pt and returns this header in the structure * head. * returns: * 0 -> OK * -1 -> stream not long enough * -2 -> error reading header */int gogethead(n,head,file_pt) int n; ahhed *head; FILE *file_pt;{ int ierr = 0; (tohead(n,file_pt) == n) ? ((gethead(head,file_pt) < 1) ? (ierr = -2) : (ierr = 0)) : (ierr = -1); return(ierr);}/* gogetrecord * gets n-th record (header and data) from the stream * pointed to by file_pt and places it in head and array. * Calling routine must allocate enough space. * returns: * 0 -> OK * -1 -> stream not long enough * -2 -> error reading record */int gogetrecord(n,head,array,file_pt) int n; ahhed *head; char *array; FILE *file_pt;{ int ierr = 0; (tohead(n,file_pt) == n) ? ((getrecord(head,array,file_pt) < 0) ? (ierr = -2) : (ierr = 0)) : (ierr = -1); return(ierr);}/* logger adds a 10 character comment to the log section of the header * comment should be passed as a character pointer must be terminated * by a ';' and a `/0` * returns: * logger = 0 -> log info added to header structure * logger = -1 -> no ';', added * logger = -2 -> input string greater than LOGENT * input truncated to allowable limit * logger = -3 -> attempt to make log string greater than LOGSIZE * input comment truncated to fit * * written by Tom Boyd 6/10/85 */int logger(char_pt,head_pt)ahhed *head_pt;char *char_pt;{ int org,in,err,diff; char *strncat(); err=0;/* find length of log array and input array */ org=strlen(head_pt->record.log); /*log array*/ in=strlen(char_pt); /*input array*//* check for a terminating ';' in the input array */ if(*(char_pt+in-1) != ';') { /* no semicolon----add it*/ err=(-1); *(char_pt+in)=';'; *(char_pt+in+1)='\0'; in+=1; }/* check the length of the input array */ if(in > LOGENT) { /* entry length too long-----truncate it*/ err=(-2); *(char_pt+LOGENT-1)=';'; *(char_pt+LOGENT)='\0'; in=LOGENT; }/* check combined length of array and new input and add it */ diff=LOGSIZE-(org+in); if(diff == -in) return(-3); /* no room left in log array */ if(diff < 0)diff*=(-1),err=(-3); /*partial room left----use it */ strncat(head_pt->record.log,char_pt,diff); /* cat two strings */ return(err);}/* out_is_tty * determines whether stdout is being sent to screen. * returns: * 0 -> stdout is not tty * 1 -> stdout is tty */int out_is_tty(){ if(isatty(1)) /* sun specific --- stdout */ { ah_errno= AE_TTYOUT; return(1); } return(0);}/* in_is_tty * determines whether stdin is tty * returns: * 0 -> stdin is not tty * 1 -> stdin is tty */int in_is_tty(){ if(isatty(0)) /* sun specific --- stdin */ { ah_errno= AE_TTYIN; return(1); } return(0);}/* mkdatspace * allocates enough space for the data array, and * returns a pointer to the memory location, or * NULL if failure. * returns: * character pointer -> success * NULL -> failure */char *mkdatspace(head) ahhed *head;{ return(calloc((unsigned)head->record.ndata,(unsigned)size(head)));}get_null_head(hed)ahhed *hed;{int i;char *strcpy(); strcpy(hed->station.code,"null"); strcpy(hed->station.chan,"null"); strcpy(hed->station.stype,"null"); hed->station.slat= 0.0; hed->station.slon= 0.0; hed->station.elev= 0.0; hed->station.DS= 0.0; hed->station.A0= 0.0; for(i=0; i< NOCALPTS; ++i) { hed->station.cal[i].pole.r= 0.0; hed->station.cal[i].pole.i= 0.0; hed->station.cal[i].zero.r= 0.0; hed->station.cal[i].zero.i= 0.0; } hed->event.lat= 0.0; hed->event.lon= 0.0; hed->event.dep= 0.0; hed->event.ot.yr= (short)0; hed->event.ot.mo= (short)0; hed->event.ot.day= (short)0; hed->event.ot.hr= (short)0; hed->event.ot.mn= (short)0; hed->event.ot.sec= 0.0; strcpy(hed->event.ecomment,"null"); hed->record.type= (short)0; hed->record.ndata= 0L; hed->record.delta= 0.0; hed->record.maxamp= 0.0; hed->record.abstime.yr= (short)0; hed->record.abstime.mo= (short)0; hed->record.abstime.day= (short)0; hed->record.abstime.hr= (short)0; hed->record.abstime.mn= (short)0; hed->record.abstime.sec= 0.0; hed->record.rmin= 0.0; strcpy(hed->record.rcomment,"null"); strcpy(hed->record.log,"null"); for(i=0; i< NEXTRAS; ++i) hed->extra[i]= 0.0; return;}/* acpy(from,to,nbytes) copies nbytes from the array "from" to the * array "to". */acpy(from,to,nbytes)char *from;char *to;unsigned nbytes;{ while(nbytes--) *from++ = *to++; return;}/*ah_error(s1,s2,status) */ /* print ah format error message and die */ /*char *s1,*s2;int status;{ extern char *progname; if(progname) fprintf(stderr,"%s: ",progname); fprintf(stderr,s1,s2); if(ah_errno > 0 && ah_errno < ah_nerr) fprintf(stderr," (%s)",ah_errlist[ah_errno]); fprintf(stderr,"\n"); exit(status);}*/#define MAXI(a,b) (((a) > (b)) ? (a) : (b))#define MINI(a,b) (((a) < (b)) ? (a) : (b))/* * maxamp * determines the maximum absolute amplitude of the data array, and * places that number in head.record.maxamp. * returns: * 0 -> ok * -1 -> error */int maxamp(head,data) ahhed *head; char *data;{ float *fpt; double *dpt, dmin, dmax; float max,min; long n_data_pts; switch(head->record.type) { case FLOAT: n_data_pts= head->record.ndata; break; case COMPLEX: case VECTOR: n_data_pts= 2 * head->record.ndata; break; case TENSOR: n_data_pts= 3 * head->record.ndata; break; case 5: n_data_pts= 4 * head->record.ndata; break; case DOUBLE: n_data_pts= head->record.ndata; break; default: ah_errno= AE_DTYPE; return(-1); break; } if (head->record.type == DOUBLE) { dpt= (double *)data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -