grbseek.c
来自「麻省理工学院的人工智能工具箱,很珍贵,希望对大家有用!」· C语言 代码 · 共 590 行 · 第 1/2 页
C
590 行
/* File: grbseek.c based on Decoder's trqgetmsg() func; Revised by: 28oct96 Alice T. Nakajima (ATN), SAIC, Monterey 18jun97 ATN check Edition before reading in entire msg; 27aug97 ATN *SEEK_SET to 0 (gcc complains) 20Oct97 ATN print #bytes read when fread fails; 03nov97 ATN -Realloc 22oct98 ATN *error msg;*/#include <stdio.h>#include <math.h>#include "dprints.h" /* for dprints */#include "gribfuncs.h" /* prototypes *//************************************************************************ A. FUNCTION: grbseek* search the input file starting at the given offset for a GRIB * message. If found, return it in GRIB_HDR structure.** INTERFACE:* int grbseek (InFile, offset, Read_Index, gh, errmsg)** ARGUMENTS (I=input, O=output, I&O=input and output):* (I) char *InFile;* name of input file to search for message;* (I&O) long *offset;* number of bytes to skip from the beginning of file;* gets updated upon leaving to absolute #bytes from beginning of* file to beginning of message found;* (I) int Read_Index; * if set, only proceed if 'GRIB' starts exactly at the given * byte offset;* (O) GRIB_HDR *gh;* empty upon entry; to hold the Message found and its info;* (O) char *errmsg;* empty array, only filled if error occurred;** RETURN CODE: * 0> no errors, may or may not have a valid message;* If no Msg was Found: * a) errmsg will hold the Warning msg;* If a valid Msg was Found: * a) long *offset: if succesful, gets updated to absolute * beginning of Mesg;* b) struct GRIB_HDR holds its info:* entire_msg: is assigned to newly MAlloced * unsigned char * array to hold entire message;* msg_length: size of entire_msg array in bytes;* ids_len, pds_len, gds_len, bms_len, bds_len, eds_len:* size of each defined sections in bytes;* ids_ptr: pts to message's Ident Data Sect;* pds_ptr: pts to message's Prod Defn Sect;* gds_ptr: pts to message's Grid Defn Sect;* bms_ptr: pts to message's Bitmap Defn Sect;* bds_ptr: pts to message's Binary Data Sect;* eds_ptr: pts to message's End Data Sect;* c) errmsg remains empty;* 1> fseek/fread error, all ptrs in grib_hdr set to null; errmsg filled;* 2> got end of file, all ptrs in grib_hdr set to null; errmsg filled;* 3> Null entire_msg pointer; errmsg filled;* 4> unable to open input file; errmsg filled;************************************************************************/#if PROTOTYPE_NEEDEDint grbseek ( char *InFile,FILE **fp, long *offset, int Read_Index, GRIB_HDR *gh, char *errmsg)#elseint grbseek (InFile,fp, offset, Read_Index,gh,errmsg) char *InFile; FILE **fp; long *offset; int Read_Index; GRIB_HDR *gh; char *errmsg;#endif{ char *func="grbseek"; char *GG, sm_blk[5004], *fwa_msg=NULL; unsigned long lMessageSize; unsigned long Edition; long pos; /* current byte offs fr. beg. of file */ int bytenum; /* Index w/in sm_blk */ int bytestoread=5004; /* #bytes to read into sm_blk at a time */ int check_limit; /* #bytes in sm_blk to check */ int gotone = 0; /* set if found good msg */ int nread; /* #bytes got back from Read */ int status; unsigned long iskip; /* for getbyte */ int gdsbmsflag, bit_set, sect_len; /* working vars */ char *ptr, *end_ptr; DPRINT3 ("Entering %s\nfile=%s, offs=%ld \n", func, InFile, *offset);/** A.1 INIT variables* !gh structure is cleared out*/ if (gh->entire_msg==NULL) { DPRINT1 ( "%s: expecting non-null Grib Hdr;\n",func); sprintf(errmsg, "%s: expecting non-NULL Grib Hdr;\n",func); status= 3; goto DONE; } gh->msg_length = 0; gh->ids_ptr=gh->pds_ptr= 0; gh->gds_ptr=gh->bms_ptr=gh->bds_ptr=gh->eds_ptr=0; memset ((void *)gh->entire_msg, '\0', gh->abs_size); DPRINT2 ("gh= %ld, gh->entire_msg=%ld\n", gh, gh->entire_msg);/*** A.2 OPEN Input file * IF (fails) RETURN w/ error stat 4 !errmsg filled*//* if ((fp = fopen (InFile, "rb")) == NULL) { DPRINT2 ("%s: Cannot open input file %s\n", func,InFile ); sprintf (errmsg,"%s: Cannot open input file '%s'\n", func,InFile ); status = 4; goto DONE; }*/ if(*fp==NULL){ if ((*fp = fopen (InFile, "rb")) == NULL) { DPRINT2 ("%s: Cannot open input file %s\n", func,InFile ); sprintf (errmsg,"%s: Cannot open input file '%s'\n", func,InFile ); status = 4; goto DONE; } }/*** A.3 FOR (loop while no error) !read a block at a time*/ for (status=0, pos= *offset, gotone= 0; status == 0; pos += check_limit) {/** A.3.1 IF (cannot SET file position to correct place)* THEN* SET Status to 1 !fseek err* CONTINUE (Loop around to A.3)* ENDIF*/ if (fseek(*fp, pos, 0)!=0) { DPRINT2 ("%s: Got fseek error to pos= %ld\n",func, pos); sprintf(errmsg,"%s %s: Got fseek error to pos= %ld\n",func,InFile,pos); status = 1; goto DONE; }/** A.3.2 IF (read less than 40 bytes)* THEN* FILL error buffer* RETURN status 2 !eof or <40 bytes left, errmsg filled* ENDIF*/ nread= fread (sm_blk,sizeof(char), bytestoread,*fp); if (nread <= 40) { if (nread<=4) { DPRINT0 ("No bytes left to check for msg;\n"); /* Errmsg left blank cuz its just EOF */ } else { sprintf(errmsg,"%s %s: skip last %d bytes, too few for a Msg\n", func, InFile, nread); DPRINT1 ("Only read %d bytes, too few to check for msg;\n",nread); } status= 2; goto DONE; } else check_limit= nread - 4; /** ! search block for the next the 'G'* ! load entire Msg if everything is ok;* ! if No 'G' found, then quit right away if no 'G'* ! if GRIB is not at absolute Offset address, quit too;* ! * A.3.3 WHILE (there is another 'G' in this block) DO*/ bytenum= 0; while ((GG= (char *) memchr (sm_blk, 'G', check_limit))) {/*--- Saw 'G' ---*//** A.3.3.1 IF ('RIB' is not after 'G') THEN* IF (Offset from Index file) THEN * ABORT search; !Break out of loop* ELSE* CLEAR out the 'G' in temp block* CONTINUE !Loop around to A.3.3* ENDIF* ENDIF*/ if (strncmp(GG, "GRIB",4)) /* not 'RIB' after the 'G' */ if ( Read_Index) break; /* Offset IS from Indexfile: Quit here */ else { /* offset is NOT fr. IndexFile: keep looping; */ *GG='-'; /* no RIB after G, clear it */ continue; /* let Memchr find next G in block */ }/*--- Saw 'G R I B' ----*//** A.3.3.2 CALCULATE byte position within this block* where this message begins*/ bytenum = GG - sm_blk; /* byte pos w/in this block *//** A.3.3.3 IF (offset is from Indexfile AND* string GRIB found is not at Absolute IndexFile's offset)* THEN abort search; ENDIF*/ DPRINT1 ("Found string 'GRIB' at %ld\n", pos+bytenum); if (Read_Index && *offset != (bytenum + pos)) { sprintf(errmsg, "%s %s: No Grib msg found at offset= %ld; check Index File\n", func, InFile, *offset); break; /* Abort here, Ret w/ no errros & no msg too */ }/*--- Read Mesg Length, Edition ---*//** A.3.3.4 FUNCTION gbyte !extract lMessageSize*/ iskip=32; gbyte (sm_blk+bytenum ,&lMessageSize, &iskip,24); DPRINT0 ("lMessageSize\n");/*--- Make sure it's Edition 1 first ---*//** A.3.3.5 FUNCTION gbyte !extract Grib Edition Number* IF (not edition 1) THEN* CLEAR out the 'G' in temp block* CONTINUE !Loop around to A.3.3* ENDIF*/ gbyte (sm_blk+bytenum, &Edition, &iskip, 8); DPRINT0 ("Edition\n"); if (Edition != 1) { DPRINT1 ("Edition (%d) is not 1, start over\n", Edition); *GG='-'; /* blank out G of current GRIB location found */ continue; /* let Memchr find next G in block */ }/** A.3.3.6 IF (cannot MOVE ptr to start of the message) THEN* RETURN status 1 !errmsg filled* ENDIF*/ if (fseek(*fp, (long)(pos+bytenum), 0)!=0) { DPRINT3 ( "%s: FSEEK %s error to pos+bytenum= %ld\n", func, InFile, pos+bytenum); sprintf(errmsg, "%s %s: FSEEK error to pos+bytenum= %ld\n", func, InFile, pos+bytenum); status= 1; goto DONE; }/** A.3.3.7 INIT all section length to zero*/ gh->ids_len= gh->pds_len= gh->gds_len= 0; gh->bds_len= gh->bms_len= gh->eds_len= 0;/** A.3.3.8 EXPAND Entire_Msg array if it's smaller than msglen* RETURN Malloc Err (stat=2) if fails !errmsg filled*/ if (lMessageSize > gh->abs_size ) { /* if (realloc((void *)gh->entire_msg, lMessageSize) == NULL) {..}* gh->abs_size = lMessageSize;*/ if (Expand_gribhdr (gh, lMessageSize, errmsg)) { upd_child_errmsg (func, errmsg); status = 1; /* to get out of Outer loop */ goto DONE; } DPRINT1 ("Expanded entire_msg to be %ld bytes long\n", gh->abs_size); } /* size changed */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?