📄 files.vtme
字号:
struct header *ih; . . . ifile = fopen(in_file,"r"); /* open the file */ ih = read_header(ifile); /* read the header */ if (ih->common.type != FT_SPEC) bomb();/* must be an ANA file */ p = allo_ana_rec(ih); /* allocate the record */ if (!get_ana_rec(p,ih,ifile) eof(); /* read record */ nfreq = p->n_frqs; /* get number of frequencies*/.fi.vE.lpThe pointer p could be used in subsequent callsto .i get_ana_recprovided that the program deals with only one record at a time. If more than one record is needed at the same time within the program, additional pointers must be declared and additional space must beallocated by calls to .i allo_ana_rec..lpIn the case of the built in file types, the type of the data(\fIe.g.\fR float, integer, etc.) is fixed and defined by the fileformat itself. The header access routine \fIwrite_header\fRautomatically sets the type fields in the common part of the header totheir correct values (which depend on various other fields in theheader). The type codes might be set by code like this (this is donewithin.i write_header\- most ESPS programmers will never have to do anything like this):.vS.nf struct header *h; { . . . /* the tag doesn't count here */ h->common.ndouble = 0; h->common.nfloat = 3 * val1 + 2; h->common.nlong = 0; h->common.\fRshort = 1; h->common.nchar = 0; } .fi.vE.lpThe actual code in the library has additional logic to insure that it isbeing used properly. .lpThere is one case where the type code fields are not set properly by .i write_header\- old style SD files. Since SD files can have data records ofdifferent types (unlike other current file types, in which the typesin records are pre-defined), the user has specify what type of SDrecord is wanted. This is done by means of the function.i set_sd_type,which must be called before writing any data to the file and before calling .i write_header. SD files are exceptional in one other respect, namelythat the "get" and "put" routines come in several flavors. Recognizingthat programmers will sometimes want to read or write SD records to orfrom short, float, and double arrays, different routines are provided tosupport these cases. For example, the routine.i put_sd_recfwill write SD records from a program array of type float. Note that the type of SD record (i.e., the type that will be stored in the SD file) does not matter here. Provided that there has been a previouscall to .i set_sd_type,the right conversion will be performed on output. The new FEA_SD filetype, which is intended to replace SD files, also allows separatespecification of the data type stored in the file and the data type inmemory (see \fIinit_feasd_hd\fP and \fIallo_feasd_recs\fP). .lpAs mentioned above, FEA files provide a mechanism to define their ownrecord structure. That is, users can determine the number, types,sizes, and names of the items stored in FEA records. FEA files includespecial support for labelling the records with pointers to other sourcefiles. The (3\-\s-1ESPS\s+1) functions that deal with FEA files are: \fIallo_fea_rec, add_fea_fld, fea_decode, fea_encode, get_fea_ptr,get_fea_rec, print_fea_rec, \fRand \fIput_fea_rec\fR. For a detailed introduction to FEA files, see [5]. .sh 2 "Using \fIeopen\fP".lpMany ESPS programs go through a sequence of getting a command-linefile name, checking to see if it is a "\-" (for standard input oroutput), opening the file, and checking to see that is an ESPS file type of the proper type (and proper subtype for FEA files). Here's an example with a FEA_ANA file:.vS.nf /* * open the input file */ if (optind < argc) { in_fea = argv[optind++]; if (strcmp (in_fea, "-") == 0) in_fea = "<stdin>"; else TRYOPEN (argv[0], in_fea, "r", infea_strm); } else { Fprintf(stderr, "no input file specified.\n"); SYNTAX; } /* * check for FEA_ANA ESPS file */ if ((fea_ih = read_header(infea_strm)) == NULL) ERROR_EXIT("couldn't read input FEA file header"); if(fea_ih->common.type != FT_FEA) ERROR_EXIT("Input file is not a FEA file"); if(fea_ih->hd.fea->fea_type != FEA_ANA) ERROR_EXIT("Input file is not FEA_ANA type"); /* * allocate a record; input a record, and process */ anafea_rec = allo_anafea_rec(fea_ih); (void) get_anafea_rec(anafea_rec, fea_ih, infea_strm); if (*(short *)get_genhd("spec_rep", fea_ih) != RC) ERROR_EXIT("FEA_ANA file does not have reflection coefficients"); rc0 = anafea_rec->spec_param[0]; /*get first reflection coefficient*/.fi.vE.lpOften, code like the above can be simplified by using .i eopen,as follows:.vS.nf if (optind < argc) in_fea = eopen(ProgName, argv[optind++], "r", FT_FEA, FEA_ANA, &fea_ih, &infea_strm); else { Fprintf(stderr, "no input file specified.\n"); SYNTAX; } /* note that standard input is allowed, so we don't need to check in_fea * * allocate a record; input a record, and process */ anafea_rec = allo_anafea_rec(fea_ih); (void) get_anafea_rec(anafea_rec, fea_ih, infea_strm); if (*(short *)get_genhd("spec_rep", fea_ih) != RC) ERROR_EXIT("FEA_ANA file does not have reflection coefficients"); rc0 = anafea_rec->spec_param[0]; /*get first reflection coefficient*/.fi.vE.sh 2 "Reading Data Files with Generic Programs".lpBefore FEA files were introduced, a different mechanism was availableto allow so-called "generic" (also called "dumb") programs to operateon \s-1ESPS\s+1 data files without knowing the details of the fileformat. We shall describe that mechanism here, but users should avoidusing it as it will be phased out in later releases. .lpAn example of such a "dumb" generic program is.i stats(1\-\s-1ESPS\s+1). This program computes certain statistics on recordsin a data file, without knowledge of the particular data structure.Clearly, in order to support this class of programs sufficientinformation must be available in the file header. To provide thatinformation, the common part of the header contains the number ofdoubles, floats, longs, shorts, and characters that comprise a recordwithin the file. Moreover, the data in each record is stored in theorder listed \- i.e., the given number of doubles followed by the givennumber of floats, etc. These items are set automatically by .i write_headerwhen the ESPS file is created (except in the case of SD files, wherea call to .i set_sd_typeis also needed), and they can be used by generic programs to properlyread a record. To simplify this further, the library function .i get_gen_recdisprovided to read an arbitrary \s-1ESPS\s+1 record into an vector ofdoubles. A short example of reading records from adata file in a non-type specific manner is: .vS.nf FILE *ifile; struct header *ih; double tag; double dbuf[100]; . . . ifile = fopen(in_file,"r"); ih = read_header(ifile); if (get_gen_recd(dubf, &tag, ih, ifile) == EOF) done(); a = dbuf[2]; /* access an element */ .fi.vEProgrammers and users sometimes need to know the correspondence betweenthis generic view of an ESPS record and the type-specific view providedby the C structures such as this one for PIT files (see .i PIT(5\-\s-1ESPS\s+1)):.vS.nf struct pitch { long tag; /*position in the reference file*/ float pulse_dist; /*pulse to pulse distance*/ float raw_pulse_dist; /*raw pulse distance*/ }.fi.vE.lpFor example, a user of a generic statistics program might want to getstatistics on the pulse_dist component of pitch records, and to do somust be able to state which element of the record this is from theviewpoint of generic programs. This information is provided in the section "RECORD ELEMENT FILE STRUCTURE" within each Section 5 ESPSmanual page. Thus, for example, by reading .i SCBK(5-\s-1ESPS\s+1) you can determine that the final_dist component of SCBK records is the element number 1 from the generic viewpoint. In the case of FEA files, the correspondence between the FEA-specificview and the generic view is more complicated since a single such table will not suffice, and for this reason an ESPS program isprovided to translate between the two views; see \fIelemfea\fR(1\-\s-1ESPS\s+1). .sh 1 "The Preamble - Reading ESPS Files with non-ESPS Programs".lpEach ESPS header contains a fixed size structure which we call thepreamble. The preamble contains information necessary for theoperation of the \fIread_header\fR function and will not be described indetail here. However, the preamble does contain information thatallows a non-ESPS program to skip over an ESPS header to access the datadirectly. Note that this can also be achieved by the user levelprogram \fIbhd\fR. The assumption here, is that the user needs toincorporate into an existing non-ESPS program to ability to read an ESPSfile..lpFrom the view point of a non-ESPS program, the preamble is the first 8long words (32 bytes) of the file. The preamble is always written inthe Entropic EDR format (see reference [8]), so on a machine with adifferent default byte order the user program will have to byte swap thedata. EDR format has the same byte order as Sun workstations, so ifyour machine's order if different, you will have to convert it..lpThis is the preamble:.vS.nfstruct preamble { long machine_code; /* machine which wrote file, see header.h */ long check_code; /* version check code */ long data_offset; /* data offset (in bytes, from 0) in file */ long record_size; /* record size in bytes */ long check; /* ESPS magic number, same as main header */ long edr; /* YES if EDR_ESPS, NO if native */ long align_pad_size; /* alignment pad need for some SD files */ long foreign_hd; /* pointer to foreign header, -1 if */ /* there is none */};.fi.vE.lpThe third long word contains the offset from the beginning of the fileto the first data record (in bytes). So to skip over the ESPS header,simply seek to this location in the file. The next long word, containsthe record size in bytes. For a better detailing of the record formatuse the program \fIfea_element\fR(1\-ESPS) or \fIgen_element\fR(1\-ESPS)..lpAll a non-ESPS need do to read an ESPS file, is to declare thisstructure, read in the first part of the file into it and then seek intothe file to the point indicated by \fIdata_offset\fR. If the machineon which you are reading this file has a different byte order from EDR,the you will have to byte swap these fields after reading them. Thefield \fIedr\fR in the preamble tells you whether you have to worryabout the data format of the data records, with respect to byte orderand floating point format. If \fIedr\fR is 1, then the data is in EDRformat. This is the most common data format in the workstation market.If your machine's data formats are different than that of a Sun, thenyou will have to convert the data. If the \fIedr\fR flag is 0, thenthe file is in the native format of the machine which wrote it. Youwill have to determine that machine type (look at \fImachine_code\fR)and convert from that format to that of the destination machine. Inmost cases there is nothing to do, but some cases can be difficult. Itis possible that you can ensure that the ESPS file is written in theeasiest format for you to deal with by your non-ESPS program. Seereference [8] for details on this..lpIf \fIforeign_hd\fR in the preamble is not -1, then the file contains aforeign header and this is a pointer to it. Please note that this isnot the normal way for ESPS programs to access the foreign header. Thatwould be via the generic item \fIforeign_hd_ptr\fR and\fIforeign_hd_length\fR. The foreign header pointer in the preambleis provided just for the case of non-ESPS program access..sp 2.ce 1(end)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -