NCEPLIBS-g2c  1.8.0
g2_info.c
Go to the documentation of this file.
1 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include "grib2_int.h"
13 
67 g2int
68 g2_info(unsigned char *cgrib, g2int *listsec0, g2int *listsec1,
69  g2int *numfields, g2int *numlocal)
70 {
71  g2int mapsec1len = 13;
72  g2int mapsec1[13] = {2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1};
73  g2int i, j, istart, iofst, lengrib, lensec0, lensec1;
74  g2int ipos, isecnum, nbits, lensec;
75 
76  *numlocal = 0;
77  *numfields = 0;
78 
79  LOG((2, "g2_info"));
80 
81  /* Check for beginning of GRIB message in the first 100 bytes. */
82  istart = -1;
83  for (j = 0; j < 100; j++)
84  {
85  if (cgrib[j] == 'G' && cgrib[j + 1] == 'R' && cgrib[j + 2] == 'I' &&
86  cgrib[j + 3] == 'B')
87  {
88  istart = j;
89  break;
90  }
91  }
92  if (istart == -1)
93  {
94  printf("g2_info: Beginning characters GRIB not found.");
95  return G2_INFO_NO_GRIB;
96  }
97 
98  LOG((3, "msg found at byte %ld", istart));
99 
100  /* Unpack Section 0 - Indicator Section. */
101  iofst = 8 * (istart + 6);
102  gbit(cgrib, listsec0, iofst, 8); /* Discipline */
103  iofst = iofst + 8;
104  gbit(cgrib, &listsec0[1], iofst, 8); /* GRIB edition number */
105  iofst = iofst + 8;
106  /* iofst = iofst + 32; */
107  /* gbit(cgrib, &lengrib, iofst, 32); /\* Length of GRIB message *\/ */
108  gbit(cgrib, &lengrib, iofst, 64); /* Length of GRIB message */
109  /* iofst = iofst + 32; */
110  iofst = iofst + 64;
111  listsec0[2] = lengrib;
112  lensec0 = 16;
113  ipos = istart + lensec0;
114  LOG((3, "unpacked section 0, lengrib %ld now at byte %ld", lengrib, ipos));
115 
116  /* Currently handles only GRIB Edition 2. */
117  if (listsec0[1] != 2)
118  {
119  printf("g2_info: can only decode GRIB edition 2.");
120  return G2_INFO_GRIB_VERSION;
121  }
122 
123  /* Unpack Section 1 - Identification Section */
124  gbit(cgrib, &lensec1, iofst, 32); /* Length of Section 1 */
125  iofst = iofst + 32;
126  gbit(cgrib, &isecnum, iofst, 8); /* Section number (1) */
127  iofst = iofst + 8;
128  if (isecnum != 1)
129  {
130  printf("g2_info: Could not find section 1.");
131  return G2_INFO_NO_SEC1;
132  }
133 
134  /* Unpack each input value in array listsec1 into the
135  appropriate number of octets, which are specified in
136  corresponding entries in array mapsec1. */
137  for (i = 0; i < mapsec1len; i++)
138  {
139  nbits = mapsec1[i] * 8;
140  gbit(cgrib, &listsec1[i], iofst, nbits);
141  iofst = iofst + nbits;
142  }
143  ipos = ipos + lensec1;
144  LOG((3, "unpacked section 1, now at byte %ld", ipos));
145 
146  /* Loop through the remaining sections to see if they are
147  * valid. Also count the number of times Section 2 and Section
148  * 4 appear. */
149  for (;;)
150  {
151  if (cgrib[ipos] == '7' && cgrib[ipos + 1] == '7' && cgrib[ipos + 2] == '7' &&
152  cgrib[ipos + 3] == '7')
153  {
154  LOG((3, "found 7777 at byte %ld", ipos));
155  ipos = ipos + 4;
156  if (ipos != (istart + lengrib))
157  {
158  printf("g2_info: '7777' found, but not where expected.\n");
159  return G2_INFO_WRONG_END;
160  }
161  break;
162  }
163 
164  iofst = ipos * 8;
165  gbit(cgrib, &lensec, iofst, 32); /* Get Length of Section */
166  iofst = iofst + 32;
167  gbit(cgrib, &isecnum, iofst, 8); /* Get Section number */
168  LOG((3, "found section number %ld of length %ld", isecnum, lensec));
169  iofst = iofst + 8;
170  ipos = ipos + lensec; /* Update beginning of section pointer */
171  if (ipos > (istart + lengrib))
172  {
173  printf("g2_info: '7777' not found at end of GRIB message.\n");
174  return G2_INFO_BAD_END;
175  }
176  if (isecnum >= 2 && isecnum <= 7)
177  {
178  /* Increment counter for total number of local sections
179  * or fields found. */
180  if (isecnum == 2)
181  (*numlocal)++;
182  else if (isecnum == 4)
183  (*numfields)++;
184  }
185  else
186  {
187  printf("g2_info: Invalid section number found in GRIB message: %ld\n", isecnum);
188  return G2_INFO_INVAL_SEC;
189  }
190  }
191 
192  return 0;
193 }
g2int g2_info(unsigned char *cgrib, g2int *listsec0, g2int *listsec1, g2int *numfields, g2int *numlocal)
This subroutine searches through a GRIB2 message and returns the number of gridded fields found in th...
Definition: g2_info.c:68
void gbit(unsigned char *in, g2int *iout, g2int iskip, g2int nbits)
Get bits - unpack bits: Extract arbitrary size values from a packed bit string, right justifying each...
Definition: gbits.c:20
#define G2_INFO_NO_SEC1
g2_info() can't find section 1.
Definition: grib2.h:442
#define G2_INFO_INVAL_SEC
g2_info() found invalid section number.
Definition: grib2.h:445
#define G2_INFO_GRIB_VERSION
Wrong GRIB version for g2_info(), must be 2.
Definition: grib2.h:441
#define G2_INFO_BAD_END
g2_info() didn't find "7777" at end of message.
Definition: grib2.h:444
int64_t g2int
Long integer type.
Definition: grib2.h:33
#define G2_INFO_NO_GRIB
g2_info() can't find beginning characters "GRIB".
Definition: grib2.h:440
#define G2_INFO_WRONG_END
g2_info() found "7777" not where expected.
Definition: grib2.h:443
Header file with internal function prototypes NCEPLIBS-g2c library.
#define LOG(e)
Ignore logging to stdout.
Definition: grib2_int.h:426