1 : #include <stdio.h>
2 : #include "grib2.h"
3 :
4 : #define MAPSEC1LEN 13
5 :
6 0 : g2int g2_create(unsigned char *cgrib,g2int *listsec0,g2int *listsec1)
7 : //$$$ SUBPROGRAM DOCUMENTATION BLOCK
8 : // . . . .
9 : // SUBPROGRAM: g2_create
10 : // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-31
11 : //
12 : // ABSTRACT: This routine initializes a new GRIB2 message and packs
13 : // GRIB2 sections 0 (Indicator Section) and 1 (Identification Section).
14 : // This routine is used with routines "g2_addlocal", "g2_addgrid",
15 : // "g2_addfield", and "g2_gribend" to create a complete GRIB2 message.
16 : // g2_create must be called first to initialize a new GRIB2 message.
17 : // Also, a call to g2_gribend is required to complete GRIB2 message
18 : // after all fields have been added.
19 : //
20 : // PROGRAM HISTORY LOG:
21 : // 2002-10-31 Gilbert
22 : //
23 : // USAGE: int g2_create(unsigned char *cgrib,g2int *listsec0,g2int *listsec1)
24 : // INPUT ARGUMENTS:
25 : // cgrib - Character array to contain the GRIB2 message
26 : // listsec0 - Contains information needed for GRIB Indicator Section 0.
27 : // Must be dimensioned >= 2.
28 : // listsec0[0]=Discipline-GRIB Master Table Number
29 : // (see Code Table 0.0)
30 : // listsec0[1]=GRIB Edition Number (currently 2)
31 : // listsec1 - Contains information needed for GRIB Identification Section 1.
32 : // Must be dimensioned >= 13.
33 : // listsec1[0]=Id of orginating centre (Common Code Table C-1)
34 : // listsec1[1]=Id of orginating sub-centre (local table)
35 : // listsec1[2]=GRIB Master Tables Version Number (Code Table 1.0)
36 : // listsec1[3]=GRIB Local Tables Version Number (Code Table 1.1)
37 : // listsec1[4]=Significance of Reference Time (Code Table 1.2)
38 : // listsec1[5]=Reference Time - Year (4 digits)
39 : // listsec1[6]=Reference Time - Month
40 : // listsec1[7]=Reference Time - Day
41 : // listsec1[8]=Reference Time - Hour
42 : // listsec1[9]=Reference Time - Minute
43 : // listsec1[10]=Reference Time - Second
44 : // listsec1[11]=Production status of data (Code Table 1.3)
45 : // listsec1[12]=Type of processed data (Code Table 1.4)
46 : //
47 : // OUTPUT ARGUMENTS:
48 : // cgrib - Char array to contain the new GRIB2 message.
49 : // Must be allocated large enough to store the entire
50 : // GRIB2 message.
51 : //
52 : // RETURN VALUES:
53 : // ierr - return code.
54 : // > 0 = Current size of new GRIB2 message
55 : // -1 = Tried to use for version other than GRIB Edition 2
56 : //
57 : // REMARKS: This routine is intended for use with routines "g2_addlocal",
58 : // "g2_addgrid", "g2_addfield", and "g2_gribend" to create a complete
59 : // GRIB2 message.
60 : //
61 : // ATTRIBUTES:
62 : // LANGUAGE: C
63 : // MACHINE:
64 : //
65 : //$$$
66 : {
67 :
68 : g2int ierr;
69 0 : g2int zero=0,one=1;
70 0 : g2int mapsec1len=MAPSEC1LEN;
71 0 : g2int mapsec1[MAPSEC1LEN]={ 2,2,1,1,1,2,1,1,1,1,1,1,1 };
72 : g2int i,lensec0,lensec1,iofst,ibeg,nbits,len;
73 :
74 0 : ierr=0;
75 : //
76 : // Currently handles only GRIB Edition 2.
77 : //
78 0 : if (listsec0[1] != 2) {
79 0 : printf("g2_create: can only code GRIB edition 2.");
80 0 : ierr=-1;
81 0 : return (ierr);
82 : }
83 : //
84 : // Pack Section 0 - Indicator Section
85 : // ( except for total length of GRIB message )
86 : //
87 0 : cgrib[0]=0x47; // 'G' // Beginning of GRIB message
88 0 : cgrib[1]=0x52; // 'R'
89 0 : cgrib[2]=0x49; // 'I'
90 0 : cgrib[3]=0x42; // 'B'
91 0 : sbit(cgrib,&zero,32,16); // reserved for future use
92 0 : sbit(cgrib,listsec0+0,48,8); // Discipline
93 0 : sbit(cgrib,listsec0+1,56,8); // GRIB edition number
94 0 : lensec0=16; // bytes (octets)
95 : //
96 : // Pack Section 1 - Identification Section
97 : //
98 0 : ibeg=lensec0*8; // Calculate offset for beginning of section 1
99 0 : iofst=ibeg+32; // leave space for length of section
100 0 : sbit(cgrib,&one,iofst,8); // Store section number ( 1 )
101 0 : iofst=iofst+8;
102 : //
103 : // Pack up each input value in array listsec1 into the
104 : // the appropriate number of octets, which are specified in
105 : // corresponding entries in array mapsec1.
106 : //
107 0 : for (i=0;i<mapsec1len;i++) {
108 0 : nbits=mapsec1[i]*8;
109 0 : sbit(cgrib,listsec1+i,iofst,nbits);
110 0 : iofst=iofst+nbits;
111 : }
112 : //
113 : // Calculate length of section 1 and store it in octets
114 : // 1-4 of section 1.
115 : //
116 0 : lensec1=(iofst-ibeg)/8;
117 0 : sbit(cgrib,&lensec1,ibeg,32);
118 : //
119 : // Put current byte total of message into Section 0
120 : //
121 0 : sbit(cgrib,&zero,64,32);
122 0 : len=lensec0+lensec1;
123 0 : sbit(cgrib,&len,96,32);
124 :
125 0 : return (len);
126 :
127 : }
|