NCEPLIBS-g2c  1.6.4
g2_addlocal.c
Go to the documentation of this file.
1 
6 #include <stdio.h>
7 #include "grib2.h"
8 
36 g2int
37 g2_addlocal(unsigned char *cgrib, unsigned char *csec2, g2int lcsec2)
38 {
39  static unsigned char G = 0x47; /* 'G' */
40  static unsigned char R = 0x52; /* 'R' */
41  static unsigned char I = 0x49; /* 'I' */
42  static unsigned char B = 0x42; /* 'B' */
43  static unsigned char seven = 0x37; /* '7' */
44 
45  static g2int two = 2;
46  g2int j, k, lensec2, iofst, ibeg, lencurr, ilen, len, istart;
47  g2int isecnum;
48  g2int ierr = 0;
49 
50  /* Check to see if beginning of GRIB message exists. */
51  if (cgrib[0] != G || cgrib[1] != R || cgrib[2] != I || cgrib[3] != B)
52  {
53  printf("g2_addlocal: GRIB not found in given message.\n");
54  printf("g2_addlocal: Call to routine g2_create required to initialize GRIB messge.\n");
55  ierr = -1;
56  return(ierr);
57  }
58 
59  /* Get current length of GRIB message. */
60  gbit(cgrib, &lencurr, 96, 32);
61 
62  /* Check to see if GRIB message is already complete. */
63  if (cgrib[lencurr - 4] == seven && cgrib[lencurr - 3] == seven &&
64  cgrib[lencurr - 2] == seven && cgrib[lencurr - 1] == seven)
65  {
66  printf("g2_addlocal: GRIB message already complete. Cannot add new section.\n");
67  ierr = -2;
68  return(ierr);
69  }
70 
71  /* Loop through all current sections of the GRIB message to find
72  * the last section number. */
73  len = 16; /* length of Section 0 */
74  for (;;)
75  {
76  /* Get section number and length of next section. */
77  iofst = len * 8;
78  gbit(cgrib, &ilen, iofst, 32);
79  iofst = iofst + 32;
80  gbit(cgrib, &isecnum, iofst, 8);
81  len = len + ilen;
82  /* Exit loop if last section reached. */
83  if (len == lencurr)
84  break;
85  /* If byte count for each section doesn't match current total
86  * length, then there is a problem. */
87  if (len > lencurr)
88  {
89  printf("g2_addlocal: Section byte counts don't add to total.\n");
90  printf("g2_addlocal: Sum of section byte counts = %ld\n", len);
91  printf("g2_addlocal: Total byte count in Section 0 = %ld\n", lencurr);
92  ierr = -3;
93  return(ierr);
94  }
95  }
96 
97  /* Section 2 can only be added after sections 1 and 7. */
98  if (isecnum != 1 && isecnum != 7)
99  {
100  printf("g2_addlocal: Section 2 can only be added after Section 1 or Section 7.\n");
101  printf("g2_addlocal: Section %ld was the last found in given GRIB message.\n", isecnum);
102  ierr = -4;
103  return(ierr);
104  }
105 
106  /* Add Section 2 - Local Use Section. */
107  ibeg = lencurr * 8; /* Calculate offset for beginning of section 2 */
108  iofst = ibeg + 32; /* leave space for length of section */
109  sbit(cgrib, &two, iofst, 8); /* Store section number (2) */
110  istart = lencurr + 5;
111  //cgrib(istart+1:istart+lcsec2) = csec2(1:lcsec2)
112  k = 0;
113  for (j = istart; j < istart + lcsec2; j++)
114  cgrib[j] = csec2[k++];
115 
116  /* Calculate length of section 2 and store it in octets 1-4 of section 2. */
117  lensec2 = lcsec2 + 5; /* bytes */
118  sbit(cgrib, &lensec2, ibeg, 32);
119 
120  /* Update current byte total of message in Section 0. */
121  lencurr += lensec2;
122  sbit(cgrib, &lencurr, 96, 32);
123 
124  return(lencurr);
125 }
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:37
void gbit(unsigned char *in, g2int *iout, g2int iskip, g2int nbyte)
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 nbyte)
Store bits - put arbitrary size values into a packed bit string, taking the low order bits from each ...
Definition: gbits.c:38
Header file for NCEPLIBS-g2c library.
int64_t g2int
Long integer type.
Definition: grib2.h:20