1 #include <stdio.h>
2 #include "grib2.h"
3
g2_gribend(unsigned char * cgrib)4 g2int g2_gribend(unsigned char *cgrib)
5 //$$$ SUBPROGRAM DOCUMENTATION BLOCK
6 // . . . .
7 // SUBPROGRAM: g2_gribend
8 // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-31
9 //
10 // ABSTRACT: This routine finalizes a GRIB2 message after all grids
11 // and fields have been added. It adds the End Section ( "7777" )
12 // to the end of the GRIB message and calculates the length and stores
13 // it in the appropriate place in Section 0.
14 // This routine is used with routines "g2_create", "g2_addlocal",
15 // "g2_addgrid", and "g2_addfield" to create a complete GRIB2 message.
16 // g2_create must be called first to initialize a new GRIB2 message.
17 //
18 // PROGRAM HISTORY LOG:
19 // 2002-10-31 Gilbert
20 //
21 // USAGE: int g2_gribend(unsigned char *cgrib)
22 // INPUT ARGUMENT:
23 // cgrib - Char array containing all the data sections added
24 // be previous calls to g2_create, g2_addlocal, g2_addgrid,
25 // and g2_addfield.
26 //
27 // OUTPUT ARGUMENTS:
28 // cgrib - Char array containing the finalized GRIB2 message
29 //
30 // RETURN VALUES:
31 // ierr - Return code.
32 // > 0 = Length of the final GRIB2 message in bytes.
33 // -1 = GRIB message was not initialized. Need to call
34 // routine g2_create first.
35 // -2 = GRIB message already complete.
36 // -3 = Sum of Section byte counts doesn't add to total byte count
37 // -4 = Previous Section was not 7.
38 //
39 // REMARKS: This routine is intended for use with routines "g2_create",
40 // "g2_addlocal", "g2_addgrid", and "g2_addfield" to create a complete
41 // GRIB2 message.
42 //
43 // ATTRIBUTES:
44 // LANGUAGE: C
45 // MACHINE:
46 //
47 //$$$
48 {
49
50 g2int iofst,lencurr,len,ilen,isecnum;
51 g2int ierr,lengrib;
52 const unsigned char G=0x47; // 'G'
53 const unsigned char R=0x52; // 'R'
54 const unsigned char I=0x49; // 'I'
55 const unsigned char B=0x42; // 'B'
56 const unsigned char seven=0x37; // '7'
57
58 //
59 // Check to see if beginning of GRIB message exists
60 //
61 if ( cgrib[0]!=G || cgrib[1]!=R || cgrib[2]!=I || cgrib[3]!=B ) {
62 printf("g2_gribend: GRIB not found in given message.\n");
63 ierr=-1;
64 return (ierr);
65 }
66 //
67 // Get current length of GRIB message
68 //
69 gbit(cgrib,&lencurr,96,32);
70 //
71 // Loop through all current sections of the GRIB message to
72 // find the last section number.
73 //
74 len=16; // Length of Section 0
75 for (;;) {
76 // Get 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 ) break;
84 // If byte count for each section doesn't match current
85 // total length, then there is a problem.
86 if ( len > lencurr ) {
87 printf("g2_gribend: Section byte counts don''t add to total.\n");
88 printf("g2_gribend: Sum of section byte counts = %d\n",(int)len);
89 printf("g2_gribend: Total byte count in Section 0 = %d\n",(int)lencurr);
90 ierr=-3;
91 return (ierr);
92 }
93 }
94 //
95 // Can only add End Section (Section 8) after Section 7.
96 //
97 if ( isecnum != 7 ) {
98 printf("g2_gribend: Section 8 can only be added after Section 7.\n");
99 printf("g2_gribend: Section %d was the last found in given GRIB message.\n",isecnum);
100 ierr=-4;
101 return (ierr);
102 }
103 //
104 // Add Section 8 - End Section
105 //
106 //cgrib(lencurr+1:lencurr+4)=c7777
107 cgrib[lencurr]=seven;
108 cgrib[lencurr+1]=seven;
109 cgrib[lencurr+2]=seven;
110 cgrib[lencurr+3]=seven;
111
112 //
113 // Update current byte total of message in Section 0
114 //
115 lengrib=lencurr+4;
116 sbit(cgrib,&lengrib,96,32);
117
118 return (lengrib);
119
120 }
121
122