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 + -
显示快捷键?