NCEPLIBS-g2c  1.8.0
g2_gribend.c
Go to the documentation of this file.
1 
6 #include <stdio.h>
7 #include "grib2_int.h"
8 
37 g2int g2_gribend(unsigned char *cgrib)
38 {
39  g2int iofst, lencurr, len, ilen, isecnum;
40  g2int lengrib;
41  unsigned char seven = 0x37; /* '7' */
42  int ret;
43 
44  /* Check for GRIB header and terminator. Translate the error codes
45  * to the legacy G2 error codes. */
46  if ((ret = g2c_check_msg(cgrib, &lencurr, 1)))
47  {
48  if (ret == G2C_ENOTGRIB)
49  return G2_ADD_MSG_INIT;
50  if (ret == G2C_EMSGCOMPLETE)
51  return G2_ADD_MSG_COMPLETE;
52  }
53 
54  /* Loop through all current sections of the GRIB message to find
55  * the last section number. */
56  len = 16; /* Length of Section 0. */
57  for (;;)
58  {
59  /* Get number and length of next section. */
60  iofst = len * 8;
61  gbit(cgrib, &ilen, iofst, 32);
62  iofst = iofst + 32;
63  gbit(cgrib, &isecnum, iofst, 8);
64  len = len + ilen;
65 
66  /* Exit loop if last section reached. */
67  if (len == lencurr)
68  break;
69 
70  /* If byte count for each section doesn't match current
71  * total length, then there is a problem. */
72  if (len > lencurr)
73  {
74  printf("g2_gribend: Section byte counts don''t add to total.\n");
75  printf("g2_gribend: Sum of section byte counts = %d\n", (int)len);
76  printf("g2_gribend: Total byte count in Section 0 = %d\n", (int)lencurr);
77  return G2_BAD_SEC_COUNTS;
78  }
79  }
80 
81  /* Can only add End Section (Section 8) after Section 7. */
82  if (isecnum != 7 )
83  {
84  printf("g2_gribend: Section 8 can only be added after Section 7.\n");
85  printf("g2_gribend: Section %ld was the last found in given GRIB message.\n", isecnum);
86  return G2_BAD_SEC;
87  }
88 
89  /* Add Section 8 - End Section */
90  cgrib[lencurr] = seven;
91  cgrib[lencurr + 1] = seven;
92  cgrib[lencurr + 2] = seven;
93  cgrib[lencurr + 3] = seven;
94 
95  /* Update current byte total of message in Section 0. */
96  lengrib = lencurr + 4;
97  sbit(cgrib, &lengrib, 96, 32);
98 
99  /* Return the length of the message. */
100  return lengrib;
101 }
g2int g2_gribend(unsigned char *cgrib)
This routine finalizes a GRIB2 message after all grids and fields have been added.
Definition: g2_gribend.c:37
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
void sbit(unsigned char *out, g2int *in, g2int iskip, g2int nbits)
Store bits - put arbitrary size values into a packed bit string, taking the low order bits from each ...
Definition: gbits.c:38
#define G2_BAD_SEC_COUNTS
Sum of Section byte counts doesn't add to total byte count.
Definition: grib2.h:475
#define G2_BAD_SEC
Previous Section was unexpected.
Definition: grib2.h:463
#define G2_ADD_MSG_COMPLETE
GRIB message already complete.
Definition: grib2.h:474
#define G2_ADD_MSG_INIT
GRIB message was not initialized - call g2_create() first.
Definition: grib2.h:473
#define G2C_ENOTGRIB
GRIB header not found.
Definition: grib2.h:493
#define G2C_EMSGCOMPLETE
GRIB message already complete.
Definition: grib2.h:494
int64_t g2int
Long integer type.
Definition: grib2.h:33
Header file with internal function prototypes NCEPLIBS-g2c library.
int g2c_check_msg(unsigned char *cgrib, g2int *lencurr, int verbose)
Check for 'GRIB' at the beginning of a GRIB message, and check to see if the message is already termi...
Definition: util.c:26