#include #include #include "grib2.h" g2int g2_info(unsigned char *cgrib,g2int *listsec0,g2int *listsec1, g2int *numfields,g2int *numlocal) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: g2_info // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-28 // // ABSTRACT: This subroutine searches through a GRIB2 message and // returns the number of gridded fields found in the message and // the number (and maximum size) of Local Use Sections. // Also various checks are performed // to see if the message is a valid GRIB2 message. // // PROGRAM HISTORY LOG: // 2002-10-28 Gilbert // // USAGE: int g2_info(unsigned char *cgrib,g2int *listsec0,g2int *listsec1, // g2int *numfields,g2int *numlocal) // INPUT ARGUMENT: // cgrib - Character pointer to the GRIB2 message // // OUTPUT ARGUMENTS: // listsec0 - pointer to an array containing information decoded from // GRIB Indicator Section 0. // Must be allocated with >= 3 elements. // listsec0[0]=Discipline-GRIB Master Table Number // (see Code Table 0.0) // listsec0[1]=GRIB Edition Number (currently 2) // listsec0[2]=Length of GRIB message // listsec1 - pointer to an array containing information read from GRIB // Identification Section 1. // Must be allocated with >= 13 elements. // listsec1[0]=Id of orginating centre (Common Code Table C-1) // listsec1[1]=Id of orginating sub-centre (local table) // listsec1[2]=GRIB Master Tables Version Number (Code Table 1.0) // listsec1[3]=GRIB Local Tables Version Number // listsec1[4]=Significance of Reference Time (Code Table 1.1) // listsec1[5]=Reference Time - Year (4 digits) // listsec1[6]=Reference Time - Month // listsec1[7]=Reference Time - Day // listsec1[8]=Reference Time - Hour // listsec1[9]=Reference Time - Minute // listsec1[10]=Reference Time - Second // listsec1[11]=Production status of data (Code Table 1.2) // listsec1[12]=Type of processed data (Code Table 1.3) // numfields- The number of gridded fields found in the GRIB message. // That is, the number of occurences of Sections 4 - 7. // numlocal - The number of Local Use Sections ( Section 2 ) found in // the GRIB message. // // RETURN VALUES: // ierr - Error return code. // 0 = no error // 1 = Beginning characters "GRIB" not found. // 2 = GRIB message is not Edition 2. // 3 = Could not find Section 1, where expected. // 4 = End string "7777" found, but not where expected. // 5 = End string "7777" not found at end of message. // 6 = Invalid section number found. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$ { g2int ierr,mapsec1len=13; g2int mapsec1[13]={2,2,1,1,1,2,1,1,1,1,1,1,1}; g2int i,j,istart,iofst,lengrib,lensec0,lensec1; g2int ipos,isecnum,nbits,lensec; ierr=0; *numlocal=0; *numfields=0; // // Check for beginning of GRIB message in the first 100 bytes // istart=-1; for (j=0;j<100;j++) { if (cgrib[j]=='G' && cgrib[j+1]=='R' &&cgrib[j+2]=='I' && cgrib[j+3]=='B') { istart=j; break; } } if (istart == -1) { printf("g2_info: Beginning characters GRIB not found."); ierr=1; return(ierr); } // // Unpack Section 0 - Indicator Section // iofst=8*(istart+6); gbit(cgrib,listsec0+0,iofst,8); // Discipline iofst=iofst+8; gbit(cgrib,listsec0+1,iofst,8); // GRIB edition number iofst=iofst+8; iofst=iofst+32; gbit(cgrib,&lengrib,iofst,32); // Length of GRIB message iofst=iofst+32; listsec0[2]=lengrib; lensec0=16; ipos=istart+lensec0; // // Currently handles only GRIB Edition 2. // if (listsec0[1] != 2) { printf("g2_info: can only decode GRIB edition 2."); ierr=2; return(ierr); } // // Unpack Section 1 - Identification Section // gbit(cgrib,&lensec1,iofst,32); // Length of Section 1 iofst=iofst+32; gbit(cgrib,&isecnum,iofst,8); // Section number ( 1 ) iofst=iofst+8; if (isecnum != 1) { printf("g2_info: Could not find section 1."); ierr=3; return(ierr); } // // Unpack each input value in array listsec1 into the // the appropriate number of octets, which are specified in // corresponding entries in array mapsec1. // for (i=0;i (istart+lengrib)) { printf("g2_info: '7777' not found at end of GRIB message.\n"); ierr=5; return(ierr); } if ( isecnum>=2 && isecnum<=7 ) { if (isecnum == 2) // Local Section 2 // increment counter for total number of local sections found (*numlocal)++; else if (isecnum == 4) // increment counter for total number of fields found (*numfields)++; } else { printf("g2_info: Invalid section number found in GRIB message: %ld\n" ,isecnum); ierr=6; return(ierr); } } return(0); }