Line data Source code
1 : #include <stdio.h>
2 : #include <stdlib.h>
3 : #include "grib2.h"
4 :
5 469 : g2int g2_info(unsigned char *cgrib,g2int *listsec0,g2int *listsec1,
6 : g2int *numfields,g2int *numlocal)
7 : //$$$ SUBPROGRAM DOCUMENTATION BLOCK
8 : // . . . .
9 : // SUBPROGRAM: g2_info
10 : // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-28
11 : //
12 : // ABSTRACT: This subroutine searches through a GRIB2 message and
13 : // returns the number of gridded fields found in the message and
14 : // the number (and maximum size) of Local Use Sections.
15 : // Also various checks are performed
16 : // to see if the message is a valid GRIB2 message.
17 : //
18 : // PROGRAM HISTORY LOG:
19 : // 2002-10-28 Gilbert
20 : //
21 : // USAGE: int g2_info(unsigned char *cgrib,g2int *listsec0,g2int *listsec1,
22 : // g2int *numfields,g2int *numlocal)
23 : // INPUT ARGUMENT:
24 : // cgrib - Character pointer to the GRIB2 message
25 : //
26 : // OUTPUT ARGUMENTS:
27 : // listsec0 - pointer to an array containing information decoded from
28 : // GRIB Indicator Section 0.
29 : // Must be allocated with >= 3 elements.
30 : // listsec0[0]=Discipline-GRIB Master Table Number
31 : // (see Code Table 0.0)
32 : // listsec0[1]=GRIB Edition Number (currently 2)
33 : // listsec0[2]=Length of GRIB message
34 : // listsec1 - pointer to an array containing information read from GRIB
35 : // Identification Section 1.
36 : // Must be allocated with >= 13 elements.
37 : // listsec1[0]=Id of originating centre (Common Code Table C-1)
38 : // listsec1[1]=Id of originating sub-centre (local table)
39 : // listsec1[2]=GRIB Master Tables Version Number (Code Table 1.0)
40 : // listsec1[3]=GRIB Local Tables Version Number
41 : // listsec1[4]=Significance of Reference Time (Code Table 1.1)
42 : // listsec1[5]=Reference Time - Year (4 digits)
43 : // listsec1[6]=Reference Time - Month
44 : // listsec1[7]=Reference Time - Day
45 : // listsec1[8]=Reference Time - Hour
46 : // listsec1[9]=Reference Time - Minute
47 : // listsec1[10]=Reference Time - Second
48 : // listsec1[11]=Production status of data (Code Table 1.2)
49 : // listsec1[12]=Type of processed data (Code Table 1.3)
50 : // numfields- The number of gridded fields found in the GRIB message.
51 : // That is, the number of occurrences of Sections 4 - 7.
52 : // numlocal - The number of Local Use Sections ( Section 2 ) found in
53 : // the GRIB message.
54 : //
55 : // RETURN VALUES:
56 : // ierr - Error return code.
57 : // 0 = no error
58 : // 1 = Beginning characters "GRIB" not found.
59 : // 2 = GRIB message is not Edition 2.
60 : // 3 = Could not find Section 1, where expected.
61 : // 4 = End string "7777" found, but not where expected.
62 : // 5 = End string "7777" not found at end of message.
63 : // 6 = Invalid section number found.
64 : //
65 : // REMARKS: None
66 : //
67 : // ATTRIBUTES:
68 : // LANGUAGE: C
69 : // MACHINE:
70 : //
71 : //$$$
72 : {
73 :
74 469 : g2int ierr,mapsec1len=13;
75 469 : g2int mapsec1[13]={2,2,1,1,1,2,1,1,1,1,1,1,1};
76 : g2int i,j,istart,iofst,lengrib,lensec0,lensec1;
77 : g2int ipos,isecnum,nbits,lensec;
78 :
79 469 : ierr=0;
80 469 : *numlocal=0;
81 469 : *numfields=0;
82 : //
83 : // Check for beginning of GRIB message in the first 100 bytes
84 : //
85 469 : istart=-1;
86 469 : for (j=0;j<100;j++) {
87 469 : if (cgrib[j]=='G' && cgrib[j+1]=='R' &&cgrib[j+2]=='I' &&
88 469 : cgrib[j+3]=='B') {
89 469 : istart=j;
90 469 : break;
91 : }
92 : }
93 469 : if (istart == -1) {
94 0 : printf("g2_info: Beginning characters GRIB not found.");
95 0 : ierr=1;
96 0 : return(ierr);
97 : }
98 : //
99 : // Unpack Section 0 - Indicator Section
100 : //
101 469 : iofst=8*(istart+6);
102 469 : gbit(cgrib,listsec0+0,iofst,8); // Discipline
103 469 : iofst=iofst+8;
104 469 : gbit(cgrib,listsec0+1,iofst,8); // GRIB edition number
105 469 : iofst=iofst+8;
106 469 : iofst=iofst+32;
107 469 : gbit(cgrib,&lengrib,iofst,32); // Length of GRIB message
108 469 : iofst=iofst+32;
109 469 : listsec0[2]=lengrib;
110 469 : lensec0=16;
111 469 : ipos=istart+lensec0;
112 : //
113 : // Currently handles only GRIB Edition 2.
114 : //
115 469 : if (listsec0[1] != 2) {
116 0 : printf("g2_info: can only decode GRIB edition 2.");
117 0 : ierr=2;
118 0 : return(ierr);
119 : }
120 : //
121 : // Unpack Section 1 - Identification Section
122 : //
123 469 : gbit(cgrib,&lensec1,iofst,32); // Length of Section 1
124 469 : iofst=iofst+32;
125 469 : gbit(cgrib,&isecnum,iofst,8); // Section number ( 1 )
126 469 : iofst=iofst+8;
127 469 : if (isecnum != 1) {
128 0 : printf("g2_info: Could not find section 1.");
129 0 : ierr=3;
130 0 : return(ierr);
131 : }
132 : //
133 : // Unpack each input value in array listsec1 into the
134 : // the appropriate number of octets, which are specified in
135 : // corresponding entries in array mapsec1.
136 : //
137 6566 : for (i=0;i<mapsec1len;i++) {
138 6097 : nbits=mapsec1[i]*8;
139 6097 : gbit(cgrib,listsec1+i,iofst,nbits);
140 6097 : iofst=iofst+nbits;
141 : }
142 469 : ipos=ipos+lensec1;
143 : //
144 : // Loop through the remaining sections to see if they are valid.
145 : // Also count the number of times Section 2
146 : // and Section 4 appear.
147 : //
148 : for (;;) {
149 3283 : if (cgrib[ipos]=='7' && cgrib[ipos+1]=='7' && cgrib[ipos+2]=='7' &&
150 469 : cgrib[ipos+3]=='7') {
151 469 : ipos=ipos+4;
152 469 : if (ipos != (istart+lengrib)) {
153 0 : printf("g2_info: '7777' found, but not where expected.\n");
154 0 : ierr=4;
155 0 : return(ierr);
156 : }
157 469 : break;
158 : }
159 :
160 2814 : iofst=ipos*8;
161 2814 : gbit(cgrib,&lensec,iofst,32); // Get Length of Section
162 2814 : iofst=iofst+32;
163 2814 : gbit(cgrib,&isecnum,iofst,8); // Get Section number
164 : /*iofst=iofst+8;*/
165 2814 : ipos=ipos+lensec; // Update beginning of section pointer
166 2814 : if (ipos > (istart+lengrib)) {
167 0 : printf("g2_info: '7777' not found at end of GRIB message.\n");
168 0 : ierr=5;
169 0 : return(ierr);
170 : }
171 2814 : if ( isecnum>=2 && isecnum<=7 ) {
172 2814 : if (isecnum == 2) // Local Section 2
173 : // increment counter for total number of local sections found
174 433 : (*numlocal)++;
175 :
176 2381 : else if (isecnum == 4)
177 : // increment counter for total number of fields found
178 478 : (*numfields)++;
179 : }
180 : else {
181 0 : printf("g2_info: Invalid section number found in GRIB message: %d\n" ,isecnum);
182 0 : ierr=6;
183 0 : return(ierr);
184 : }
185 :
186 : }
187 :
188 469 : return(ierr);
189 :
190 : }
|