1 : #include <stdio.h>
2 : #include "grib2.h"
3 :
4 0 : g2int g2_addlocal(unsigned char *cgrib,unsigned char *csec2,g2int lcsec2)
5 : //$$$ SUBPROGRAM DOCUMENTATION BLOCK
6 : // . . . .
7 : // SUBPROGRAM: g2_addlocal
8 : // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-11-01
9 : //
10 : // ABSTRACT: This routine adds a Local Use Section (Section 2) to
11 : // a GRIB2 message. It is used with routines "g2_create",
12 : // "g2_addgrid", "g2_addfield",
13 : // and "g2_gribend" to create a complete GRIB2 message.
14 : // g2_create must be called first to initialize a new GRIB2 message.
15 : //
16 : // PROGRAM HISTORY LOG:
17 : // 2002-11-01 Gilbert
18 : //
19 : // USAGE: int g2_addlocal(unsigned char *cgrib,unsigned char *csec2,
20 : // g2int lcsec2)
21 : // INPUT ARGUMENTS:
22 : // cgrib - Char array that contains the GRIB2 message to which section
23 : // 2 should be added.
24 : // csec2 - Character array containing information to be added in
25 : // Section 2.
26 : // lcsec2 - Number of bytes of character array csec2 to be added to
27 : // Section 2.
28 : //
29 : // OUTPUT ARGUMENT:
30 : // cgrib - Char array to contain the updated GRIB2 message.
31 : // Must be allocated large enough to store the entire
32 : // GRIB2 message.
33 : //
34 : // RETURN VALUES:
35 : // ierr - Return code.
36 : // > 0 = Current size of updated GRIB2 message
37 : // -1 = GRIB message was not initialized. Need to call
38 : // routine gribcreate first.
39 : // -2 = GRIB message already complete. Cannot add new section.
40 : // -3 = Sum of Section byte counts doesn't add to total byte count
41 : // -4 = Previous Section was not 1 or 7.
42 : //
43 : // REMARKS: Note that the Local Use Section ( Section 2 ) can only follow
44 : // Section 1 or Section 7 in a GRIB2 message.
45 : //
46 : // ATTRIBUTES:
47 : // LANGUAGE: C
48 : // MACHINE:
49 : //
50 : //$$$
51 : {
52 :
53 : g2int ierr;
54 : static unsigned char G=0x47; // 'G'
55 : static unsigned char R=0x52; // 'R'
56 : static unsigned char I=0x49; // 'I'
57 : static unsigned char B=0x42; // 'B'
58 : static unsigned char seven=0x37; // '7'
59 :
60 : static g2int two=2;
61 : g2int j,k,lensec2,iofst,ibeg,lencurr,ilen,len,istart;
62 : g2int isecnum;
63 :
64 0 : ierr=0;
65 : //
66 : // Check to see if beginning of GRIB message exists
67 : //
68 0 : if ( cgrib[0]!=G || cgrib[1]!=R || cgrib[2]!=I || cgrib[3]!=B ) {
69 0 : printf("g2_addlocal: GRIB not found in given message.\n");
70 0 : printf("g2_addlocal: Call to routine g2_create required to initialize GRIB messge.\n");
71 0 : ierr=-1;
72 0 : return(ierr);
73 : }
74 : //
75 : // Get current length of GRIB message
76 : //
77 0 : gbit(cgrib,&lencurr,96,32);
78 : //
79 : // Check to see if GRIB message is already complete
80 : //
81 0 : if ( cgrib[lencurr-4]==seven && cgrib[lencurr-3]==seven &&
82 0 : cgrib[lencurr-2]==seven && cgrib[lencurr-1]==seven ) {
83 0 : printf("g2_addlocal: GRIB message already complete. Cannot add new section.\n");
84 0 : ierr=-2;
85 0 : return(ierr);
86 : }
87 : //
88 : // Loop through all current sections of the GRIB message to
89 : // find the last section number.
90 : //
91 0 : len=16; // length of Section 0
92 : for (;;) {
93 : // Get section number and length of next section
94 0 : iofst=len*8;
95 0 : gbit(cgrib,&ilen,iofst,32);
96 0 : iofst=iofst+32;
97 0 : gbit(cgrib,&isecnum,iofst,8);
98 0 : len=len+ilen;
99 : // Exit loop if last section reached
100 0 : if ( len == lencurr ) break;
101 : // If byte count for each section doesn't match current
102 : // total length, then there is a problem.
103 0 : if ( len > lencurr ) {
104 0 : printf("g2_addlocal: Section byte counts don't add to total.\n");
105 0 : printf("g2_addlocal: Sum of section byte counts = %d\n",len);
106 0 : printf("g2_addlocal: Total byte count in Section 0 = %d\n",lencurr);
107 0 : ierr=-3;
108 0 : return(ierr);
109 : }
110 0 : }
111 : //
112 : // Section 2 can only be added after sections 1 and 7.
113 : //
114 0 : if ( (isecnum!=1) && (isecnum!=7) ) {
115 0 : printf("g2_addlocal: Section 2 can only be added after Section 1 or Section 7.\n");
116 0 : printf("g2_addlocal: Section %d was the last found in given GRIB message.\n",isecnum);
117 0 : ierr=-4;
118 0 : return(ierr);
119 : }
120 : //
121 : // Add Section 2 - Local Use Section
122 : //
123 0 : ibeg=lencurr*8; // Calculate offset for beginning of section 2
124 0 : iofst=ibeg+32; // leave space for length of section
125 0 : sbit(cgrib,&two,iofst,8); // Store section number ( 2 )
126 0 : istart=lencurr+5;
127 : //cgrib(istart+1:istart+lcsec2)=csec2(1:lcsec2)
128 0 : k=0;
129 0 : for (j=istart;j<istart+lcsec2;j++) {
130 0 : cgrib[j]=csec2[k++];
131 : }
132 : //
133 : // Calculate length of section 2 and store it in octets
134 : // 1-4 of section 2.
135 : //
136 0 : lensec2=lcsec2+5; // bytes
137 0 : sbit(cgrib,&lensec2,ibeg,32);
138 :
139 : //
140 : // Update current byte total of message in Section 0
141 : //
142 0 : lencurr+=lensec2;
143 0 : sbit(cgrib,&lencurr,96,32);
144 :
145 0 : return(lencurr);
146 :
147 : }
|