NCEPLIBS-g2c  1.7.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 
66 g2int
67 g2_info(unsigned char *cgrib, g2int *listsec0, g2int *listsec1,
68  g2int *numfields, g2int *numlocal)
69 {
70  g2int mapsec1len = 13;
71  g2int mapsec1[13] = {2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1};
72  g2int i, j, istart, iofst, lengrib, lensec0, lensec1;
73  g2int ipos, isecnum, nbits, lensec;
74 
75  *numlocal = 0;
76  *numfields = 0;
77 
78  /* Check for beginning of GRIB message in the first 100 bytes. */
79  istart = -1;
80  for (j = 0; j < 100; j++)
81  {
82  if (cgrib[j] == 'G' && cgrib[j + 1] == 'R' && cgrib[j + 2] == 'I' &&
83  cgrib[j + 3] == 'B')
84  {
85  istart = j;
86  break;
87  }
88  }
89  if (istart == -1)
90  {
91  printf("g2_info: Beginning characters GRIB not found.");
92  return G2_INFO_NO_GRIB;
93  }
94 
95  /* Unpack Section 0 - Indicator Section. */
96  iofst = 8 * (istart + 6);
97  gbit(cgrib, listsec0, iofst, 8); /* Discipline */
98  iofst = iofst + 8;
99  gbit(cgrib, listsec0 + 1, iofst, 8); /* GRIB edition number */
100  iofst = iofst + 8;
101  iofst = iofst + 32;
102  gbit(cgrib, &lengrib, iofst, 32); /* Length of GRIB message */
103  iofst = iofst + 32;
104  listsec0[2] = lengrib;
105  lensec0 = 16;
106  ipos = istart + lensec0;
107 
108  /* Currently handles only GRIB Edition 2. */
109  if (listsec0[1] != 2)
110  {
111  printf("g2_info: can only decode GRIB edition 2.");
112  return G2_INFO_GRIB_VERSION;
113  }
114 
115  /* Unpack Section 1 - Identification Section */
116  gbit(cgrib, &lensec1, iofst, 32); /* Length of Section 1 */
117  iofst = iofst + 32;
118  gbit(cgrib, &isecnum, iofst, 8); /* Section number (1) */
119  iofst = iofst + 8;
120  if (isecnum != 1)
121  {
122  printf("g2_info: Could not find section 1.");
123  return G2_INFO_NO_SEC1;
124  }
125 
126  /* Unpack each input value in array listsec1 into the
127  appropriate number of octets, which are specified in
128  corresponding entries in array mapsec1. */
129  for (i = 0; i < mapsec1len; i++)
130  {
131  nbits = mapsec1[i] * 8;
132  gbit(cgrib, listsec1 + i, iofst, nbits);
133  iofst = iofst + nbits;
134  }
135  ipos = ipos + lensec1;
136 
137  /* Loop through the remaining sections to see if they are
138  * valid. Also count the number of times Section 2 and Section
139  * 4 appear. */
140  for (;;)
141  {
142  if (cgrib[ipos] == '7' && cgrib[ipos + 1] == '7' && cgrib[ipos + 2] == '7' &&
143  cgrib[ipos + 3] == '7')
144  {
145  ipos = ipos + 4;
146  if (ipos != (istart + lengrib))
147  {
148  printf("g2_info: '7777' found, but not where expected.\n");
149  return G2_INFO_WRONG_END;
150  }
151  break;
152  }
153 
154  iofst = ipos * 8;
155  gbit(cgrib, &lensec, iofst, 32); /* Get Length of Section */
156  iofst = iofst + 32;
157  gbit(cgrib, &isecnum, iofst, 8); /* Get Section number */
158  iofst = iofst + 8;
159  ipos = ipos + lensec; /* Update beginning of section pointer */
160  if (ipos > (istart + lengrib))
161  {
162  printf("g2_info: '7777' not found at end of GRIB message.\n");
163  return G2_INFO_BAD_END;
164  }
165  if (isecnum >= 2 && isecnum <= 7)
166  {
167  /* Increment counter for total number of local sections
168  * or fields found. */
169  if (isecnum == 2)
170  (*numlocal)++;
171  else if (isecnum == 4)
172  (*numfields)++;
173  }
174  else
175  {
176  printf("g2_info: Invalid section number found in GRIB message: %ld\n", isecnum);
177  return G2_INFO_INVAL_SEC;
178  }
179  }
180 
181  return 0;
182 }
G2_INFO_NO_GRIB
#define G2_INFO_NO_GRIB
g2_info() can't find beginning characters "GRIB".
Definition: grib2.h:277
g2_info
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:67
G2_INFO_WRONG_END
#define G2_INFO_WRONG_END
g2_info() found "7777" not where expected.
Definition: grib2.h:280
G2_INFO_NO_SEC1
#define G2_INFO_NO_SEC1
g2_info() can't find section 1.
Definition: grib2.h:279
G2_INFO_GRIB_VERSION
#define G2_INFO_GRIB_VERSION
Wrong GRIB version for g2_info(), must be 2.
Definition: grib2.h:278
grib2_int.h
Header file with internal function prototypes NCEPLIBS-g2c library.
gbit
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
G2_INFO_BAD_END
#define G2_INFO_BAD_END
g2_info() didn't find "7777" at end of message.
Definition: grib2.h:281
g2int
int64_t g2int
Long integer type.
Definition: grib2.h:28
G2_INFO_INVAL_SEC
#define G2_INFO_INVAL_SEC
g2_info() found invalid section number.
Definition: grib2.h:282