NCEPLIBS-g2c  1.8.0
g2cinq.c
Go to the documentation of this file.
1 
7 #include "grib2_int.h"
8 #include <stdarg.h>
9 
12 
16 
30 int
31 g2c_inq(int g2cid, int *num_msg)
32 {
33  int ret = G2C_NOERROR;
34 
35  /* Is this an open GRIB2 file? */
36  if (g2cid < 0 || g2cid > G2C_MAX_FILES)
37  return G2C_EBADID;
38 
39  /* If using threading, lock the mutex. */
40  MUTEX_LOCK(m);
41 
42  if (g2c_file[g2cid].g2cid != g2cid)
43  ret = G2C_EBADID;
44 
45  /* If the caller wants to know the number of messages, tell
46  * them. */
47  if (!ret)
48  if (num_msg)
49  *num_msg = g2c_file[g2cid].num_messages;
50 
51  /* If using threading, unlock the mutex. */
52  MUTEX_UNLOCK(m);
53 
54  return ret;
55 }
56 
85 int
86 g2c_inq_msg(int g2cid, int msg_num, unsigned char *discipline, int *num_fields,
87  int *num_local, short *center, short *subcenter, unsigned char *master_version,
88  unsigned char *local_version)
89 {
90  G2C_MESSAGE_INFO_T *msg;
91  /* Is this an open GRIB2 file? */
92  if (g2cid < 0 || g2cid > G2C_MAX_FILES || g2c_file[g2cid].g2cid != g2cid)
93  return G2C_EBADID;
94 
95  /* Find the file and message. */
96  for (msg = g2c_file[g2cid].msg; msg; msg = msg->next)
97  {
98  if (msg->msg_num == msg_num)
99  {
100  if (discipline)
101  *discipline = msg->discipline;
102  if (num_fields)
103  *num_fields = msg->num_fields;
104  if (num_local)
105  *num_local = msg->num_local;
106  if (center)
107  *center = msg->center;
108  if (subcenter)
109  *subcenter = msg->subcenter;
110  if (master_version)
111  *master_version = msg->master_version;
112  if (local_version)
113  *local_version = msg->local_version;
114  return G2C_NOERROR;
115  }
116  }
117  return G2C_ENOMSG;
118 }
119 
148 int
149 g2c_inq_msg_time(int g2cid, int msg_num, unsigned char *sig_ref_time, short *year,
150  unsigned char *month, unsigned char *day, unsigned char *hour,
151  unsigned char *minute, unsigned char *second)
152 {
153  G2C_MESSAGE_INFO_T *msg;
154 
155  /* Is this an open GRIB2 file? */
156  if (g2cid < 0 || g2cid > G2C_MAX_FILES || g2c_file[g2cid].g2cid != g2cid)
157  return G2C_EBADID;
158 
159  /* Find the message. */
160  for (msg = g2c_file[g2cid].msg; msg; msg = msg->next)
161  {
162  if (msg->msg_num == msg_num)
163  {
164  if (sig_ref_time)
165  *sig_ref_time = msg->sig_ref_time;
166  if (year)
167  *year = msg->year;
168  if (month)
169  *month = msg->month;
170  if (day)
171  *day = msg->day;
172  if (hour)
173  *hour = msg->hour;
174  if (minute)
175  *minute = msg->minute;
176  if (second)
177  *second = msg->second;
178  return G2C_NOERROR;
179  }
180  }
181  return G2C_ENOMSG;
182 }
183 
206 int
207 g2c_inq_prod(int g2cid, int msg_num, int prod_num, int *pds_template_len,
208  int *pds_template, int *gds_template_len, int *gds_template,
209  int *drs_template_len, int *drs_template)
210 {
211  G2C_MESSAGE_INFO_T *msg;
212  G2C_SECTION_INFO_T *sec4, *sec3, *sec5;
213  int t;
214  int ret = G2C_NOERROR;
215 
216  /* Is this an open GRIB2 file? */
217  if (g2cid < 0 || g2cid > G2C_MAX_FILES)
218  return G2C_EBADID;
219 
220  /* If using threading, lock the mutex. */
221  MUTEX_LOCK(m);
222 
223  if (g2c_file[g2cid].g2cid != g2cid)
224  ret = G2C_EBADID;
225 
226  /* Find the message. */
227  if (!ret)
228  {
229  for (msg = g2c_file[g2cid].msg; msg; msg = msg->next)
230  if (msg->msg_num == msg_num)
231  break;
232  if (!msg)
233  ret = G2C_ENOMSG;
234  }
235 
236  /* Find the product. After this, sec4 will point to the
237  * appropropriate section 4 G2C_SECTION_INFO_T. */
238  if (!ret)
239  {
240  for (sec4 = msg->sec; sec4; sec4 = sec4->next)
241  if (sec4->sec_num == 4 && ((G2C_SECTION4_INFO_T *)sec4->sec_info)->field_num == prod_num)
242  break;
243  if (!sec4)
244  ret = G2C_ENOPRODUCT;
245  /* sec4_info = (G2C_SECTION4_INFO_T *)sec4->sec_info; */
246  }
247 
248  /* Return the info to the caller. */
249  if (!ret)
250  {
251  if (pds_template_len)
252  *pds_template_len = sec4->template_len;
253  if (pds_template)
254  for (t = 0; t < sec4->template_len; t++)
255  pds_template[t] = sec4->template[t];
256  }
257 
258  /* Find the GDS. */
259  if (!ret)
260  {
261  for (sec3 = sec4->prev; sec3; sec3 = sec3->prev)
262  if (sec3->sec_num == 3)
263  break;
264  if (!sec3)
265  ret = G2C_ENOSECTION;
266  }
267 
268  /* Return the info to the caller. */
269  if (!ret)
270  {
271  if (gds_template_len)
272  *gds_template_len = sec3->template_len;
273  if (gds_template)
274  for (t = 0; t < sec3->template_len; t++)
275  gds_template[t] = sec3->template[t];
276  }
277 
278  /* Find the DRS. */
279  if (!ret)
280  {
281  for (sec5 = sec4->next; sec5; sec5 = sec5->next)
282  if (sec5->sec_num == 5)
283  break;
284  if (!sec5)
285  ret = G2C_ENOSECTION;
286  }
287 
288  /* Return the info to the caller. */
289  if (!ret)
290  {
291  if (drs_template_len)
292  *drs_template_len = sec5->template_len;
293  if (drs_template)
294  for (t = 0; t < sec5->template_len; t++)
295  drs_template[t] = sec5->template[t];
296  }
297 
298  /* If using threading, unlock the mutex. */
299  MUTEX_UNLOCK(m);
300 
301  return ret;
302 }
303 
327 int
328 g2c_inq_dim(int g2cid, int msg_num, int prod_num, int dim_num, size_t *len,
329  char *name, float *val)
330 {
331  G2C_MESSAGE_INFO_T *msg;
332  G2C_SECTION_INFO_T *sec4, *sec3;
333  G2C_DIM_INFO_T *dim;
334  int d;
335  int ret = G2C_NOERROR;
336 
337  /* Is this an open GRIB2 file? */
338  if (g2cid < 0 || g2cid > G2C_MAX_FILES)
339  return G2C_EBADID;
340 
341  /* If using threading, lock the mutex. */
342  MUTEX_LOCK(m);
343 
344  if (g2c_file[g2cid].g2cid != g2cid)
345  return G2C_EBADID;
346 
347  /* Find the message. */
348  for (msg = g2c_file[g2cid].msg; msg; msg = msg->next)
349  if (msg->msg_num == msg_num)
350  break;
351  if (!msg)
352  return G2C_ENOMSG;
353 
354  /* Find the product. After this, sec4 will point to the
355  * appropropriate section 4 G2C_SECTION_INFO_T. */
356  for (sec4 = msg->sec; sec4; sec4 = sec4->next)
357  if (sec4->sec_num == 4 && ((G2C_SECTION4_INFO_T *)sec4->sec_info)->field_num == prod_num)
358  break;
359  if (!sec4)
360  return G2C_ENOPRODUCT;
361  /* sec4_info = (G2C_SECTION4_INFO_T *)sec4->sec_info; */
362 
363  /* Find the GDS. */
364  for (sec3 = sec4->prev; sec3; sec3 = sec3->prev)
365  if (sec3->sec_num == 3)
366  break;
367  if (!sec3)
368  return G2C_ENOSECTION;
369  dim = &((G2C_SECTION3_INFO_T *)sec3->sec_info)->dim[dim_num];
370 
371  /* Give the caller the info they want. */
372  if (len)
373  *len = dim->len;
374  if (name)
375  strncpy(name, dim->name, G2C_MAX_NAME);
376  if (val)
377  for (d = 0; d < dim->len; d++)
378  val[d] = dim->value[d];
379 
380 
381  return ret;
382 }
int g2c_inq_prod(int g2cid, int msg_num, int prod_num, int *pds_template_len, int *pds_template, int *gds_template_len, int *gds_template, int *drs_template_len, int *drs_template)
Inquire about a product.
Definition: g2cinq.c:207
int g2c_inq(int g2cid, int *num_msg)
Learn about a GRIB2 file.
Definition: g2cinq.c:31
G2C_FILE_INFO_T g2c_file[G2C_MAX_FILES+1]
Global file information.
Definition: g2cfile.c:10
int g2c_inq_dim(int g2cid, int msg_num, int prod_num, int dim_num, size_t *len, char *name, float *val)
Learn about the one of the dimensions of a GRIB2 product.
Definition: g2cinq.c:328
int g2c_inq_msg_time(int g2cid, int msg_num, unsigned char *sig_ref_time, short *year, unsigned char *month, unsigned char *day, unsigned char *hour, unsigned char *minute, unsigned char *second)
Learn about the date/time information in a GRIB2 message.
Definition: g2cinq.c:149
int g2c_inq_msg(int g2cid, int msg_num, unsigned char *discipline, int *num_fields, int *num_local, short *center, short *subcenter, unsigned char *master_version, unsigned char *local_version)
Learn about a GRIB2 message.
Definition: g2cinq.c:86
EXTERN_MUTEX(m)
If pthreads are enabled, use externally-defined mutex for thread-safety.
#define G2C_MAX_FILES
Maximum number of open files.
Definition: grib2.h:289
#define G2C_ENOMSG
No GRIB message found.
Definition: grib2.h:502
#define G2C_ENOSECTION
Cannot find section.
Definition: grib2.h:506
#define G2C_MAX_NAME
Maximum length of a name.
Definition: grib2.h:290
#define G2C_ENOPRODUCT
Product not found.
Definition: grib2.h:515
#define G2C_EBADID
Bad ID.
Definition: grib2.h:498
#define G2C_NOERROR
No error.
Definition: grib2.h:491
Header file with internal function prototypes NCEPLIBS-g2c library.
struct g2c_section_info * next
Pointer to next in list.
Definition: grib2_int.h:176
struct g2c_section_info * sec
List of section metadata.
Definition: grib2_int.h:162
size_t len
Length of dimension.
Definition: grib2_int.h:186
short subcenter
Originating subcenter.
Definition: grib2_int.h:150
unsigned char master_version
GRIB master tables version number.
Definition: grib2_int.h:151
#define MUTEX_UNLOCK(m)
Pthreads not enabled, so do nothing.
Definition: grib2_int.h:117
unsigned char hour
Hour.
Definition: grib2_int.h:157
unsigned char minute
Minute.
Definition: grib2_int.h:158
size_t num_messages
Number of messages in the file.
Definition: grib2_int.h:240
int num_local
Number of local sections in the message.
Definition: grib2_int.h:141
unsigned char sig_ref_time
Significance of reference time.
Definition: grib2_int.h:153
unsigned char discipline
Discipline from section 0.
Definition: grib2_int.h:138
char name[G2C_MAX_NAME+1]
Name of dimension.
Definition: grib2_int.h:187
struct g2c_section_info * prev
Pointer to previous in list.
Definition: grib2_int.h:177
int num_fields
Number of fields in the message.
Definition: grib2_int.h:140
unsigned char sec_num
Section number.
Definition: grib2_int.h:173
void * sec_info
Pointer to struct specific for section 3, 4, 5, 6, or 7.
Definition: grib2_int.h:175
float * value
Array of dimension values.
Definition: grib2_int.h:188
short year
Year.
Definition: grib2_int.h:154
unsigned char second
Second.
Definition: grib2_int.h:159
unsigned char day
Day.
Definition: grib2_int.h:156
int template_len
Number of entries in template.
Definition: grib2_int.h:179
unsigned char local_version
Version number of GRIB local tables used to augment Master Tables.
Definition: grib2_int.h:152
unsigned char month
Month.
Definition: grib2_int.h:155
size_t msg_num
Number of message in file (0-based).
Definition: grib2_int.h:135
#define MUTEX_LOCK(m)
Pthreads not enabled, so do nothing.
Definition: grib2_int.h:114
long long int * template
Grid, product, or data template.
Definition: grib2_int.h:178
struct g2c_message_info * next
Pointer to next in list.
Definition: grib2_int.h:164
short center
Originating center.
Definition: grib2_int.h:149
Keep information about dimensions defined in section 3.
Definition: grib2_int.h:184
This is the information about each open file.
Definition: grib2_int.h:236
This is the information about each message.
Definition: grib2_int.h:134
Information about Section 3 GRID DEFINITION SECTION.
Definition: grib2_int.h:194
Information about Section 4 PRODUCT DEFINITION SECTION.
Definition: grib2_int.h:207
Information about a section 3 through 7 in a GRIB2 message.
Definition: grib2_int.h:169