NCEPLIBS-g2c  1.8.0
g2_addlocal.c
Go to the documentation of this file.
1 
6 #include <stdio.h>
7 #include "grib2_int.h"
8 
39 g2int
40 g2_addlocal(unsigned char *cgrib, unsigned char *csec2, g2int lcsec2)
41 {
42  static g2int two = 2;
43  g2int j, k, lensec2, iofst, ibeg, lencurr, ilen, len, istart;
44  g2int isecnum;
45  int ret;
46 
47  /* Check for GRIB header and terminator. Translate the error codes
48  * to the legacy G2 error codes. */
49  if ((ret = g2c_check_msg(cgrib, &lencurr, 1)))
50  {
51  if (ret == G2C_ENOTGRIB)
52  return G2_ADD_MSG_INIT;
53  if (ret == G2C_EMSGCOMPLETE)
54  return G2_ADD_MSG_COMPLETE;
55  }
56 
57  /* Loop through all current sections of the GRIB message to find
58  * the last section number. */
59  len = 16; /* length of Section 0 */
60  for (;;)
61  {
62  /* Get section number and length of next section. */
63  iofst = len * 8;
64  gbit(cgrib, &ilen, iofst, 32);
65  iofst = iofst + 32;
66  gbit(cgrib, &isecnum, iofst, 8);
67  len = len + ilen;
68 
69  /* Exit loop if last section reached. */
70  if (len == lencurr)
71  break;
72 
73  /* If byte count for each section doesn't match current total
74  * length, then there is a problem. */
75  if (len > lencurr)
76  {
77  printf("g2_addlocal: Section byte counts don't add to total.\n");
78  printf("g2_addlocal: Sum of section byte counts = %ld\n", len);
79  printf("g2_addlocal: Total byte count in Section 0 = %ld\n", lencurr);
80  return G2_BAD_SEC_COUNTS;
81  }
82  }
83 
84  /* Section 2 can only be added after sections 1 and 7. */
85  if (isecnum != 1 && isecnum != 7)
86  {
87  printf("g2_addlocal: Section 2 can only be added after Section 1 or Section 7.\n");
88  printf("g2_addlocal: Section %ld was the last found in given GRIB message.\n", isecnum);
89  return G2_BAD_SEC;
90  }
91 
92  /* Add Section 2 - Local Use Section. */
93  ibeg = lencurr * 8; /* Calculate offset for beginning of section 2 */
94  iofst = ibeg + 32; /* leave space for length of section */
95  sbit(cgrib, &two, iofst, 8); /* Store section number (2) */
96  istart = lencurr + 5;
97  k = 0;
98  for (j = istart; j < istart + lcsec2; j++)
99  cgrib[j] = csec2[k++];
100 
101  /* Calculate length of section 2 and store it in octets 1-4 of
102  * section 2. */
103  lensec2 = lcsec2 + 5; /* bytes */
104  sbit(cgrib, &lensec2, ibeg, 32);
105 
106  /* Update current byte total of message in Section 0. */
107  lencurr += lensec2;
108  sbit(cgrib, &lencurr, 96, 32);
109 
110  return lencurr;
111 }
g2int g2_addlocal(unsigned char *cgrib, unsigned char *csec2, g2int lcsec2)
This routine adds a Local Use Section (Section 2) to a GRIB2 message.
Definition: g2_addlocal.c:40
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