1 : #include <stdio.h>
2 : #include "grib2.h"
3 :
4 0 : 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 : static unsigned char G=0x47; // 'G'
53 : static unsigned char R=0x52; // 'R'
54 : static unsigned char I=0x49; // 'I'
55 : static unsigned char B=0x42; // 'B'
56 : static unsigned char seven=0x37; // '7'
57 :
58 0 : ierr=0;
59 : //
60 : // Check to see if beginning of GRIB message exists
61 : //
62 0 : if ( cgrib[0]!=G || cgrib[1]!=R || cgrib[2]!=I || cgrib[3]!=B ) {
63 0 : printf("g2_gribend: GRIB not found in given message.\n");
64 0 : ierr=-1;
65 0 : return (ierr);
66 : }
67 : //
68 : // Get current length of GRIB message
69 : //
70 0 : gbit(cgrib,&lencurr,96,32);
71 : //
72 : // Loop through all current sections of the GRIB message to
73 : // find the last section number.
74 : //
75 0 : len=16; // Length of Section 0
76 : for (;;) {
77 : // Get number and length of next section
78 0 : iofst=len*8;
79 0 : gbit(cgrib,&ilen,iofst,32);
80 0 : iofst=iofst+32;
81 0 : gbit(cgrib,&isecnum,iofst,8);
82 0 : len=len+ilen;
83 : // Exit loop if last section reached
84 0 : if ( len == lencurr ) break;
85 : // If byte count for each section doesn't match current
86 : // total length, then there is a problem.
87 0 : if ( len > lencurr ) {
88 0 : printf("g2_gribend: Section byte counts don''t add to total.\n");
89 0 : printf("g2_gribend: Sum of section byte counts = %d\n",(int)len);
90 0 : printf("g2_gribend: Total byte count in Section 0 = %d\n",(int)lencurr);
91 0 : ierr=-3;
92 0 : return (ierr);
93 : }
94 0 : }
95 : //
96 : // Can only add End Section (Section 8) after Section 7.
97 : //
98 0 : if ( isecnum != 7 ) {
99 0 : printf("g2_gribend: Section 8 can only be added after Section 7.\n");
100 0 : printf("g2_gribend: Section %d was the last found in given GRIB message.\n",isecnum);
101 0 : ierr=-4;
102 0 : return (ierr);
103 : }
104 : //
105 : // Add Section 8 - End Section
106 : //
107 : //cgrib(lencurr+1:lencurr+4)=c7777
108 0 : cgrib[lencurr]=seven;
109 0 : cgrib[lencurr+1]=seven;
110 0 : cgrib[lencurr+2]=seven;
111 0 : cgrib[lencurr+3]=seven;
112 :
113 : //
114 : // Update current byte total of message in Section 0
115 : //
116 0 : lengrib=lencurr+4;
117 0 : sbit(cgrib,&lengrib,96,32);
118 :
119 0 : return (lengrib);
120 :
121 : }
122 :
|