1 | /* |
---|
2 | REVISIONS: |
---|
3 | 10/15/96 A. Nakajima, SAIC: removed 'write_grib' call; make combined lib; |
---|
4 | 11/03/97 /ATN -Realloc |
---|
5 | */ |
---|
6 | #include <stdio.h> |
---|
7 | #include <string.h> |
---|
8 | #include <stdlib.h> |
---|
9 | #ifdef XT3_Catamount |
---|
10 | #include <features.h> |
---|
11 | #undef htonl |
---|
12 | #define htonl(x) swap_byte4(x) |
---|
13 | #else |
---|
14 | #include <netinet/in.h> |
---|
15 | #endif |
---|
16 | #include "dprints.h" /* for dprints */ |
---|
17 | #include "grib_lookup.h" /* parm/model/lvl defn */ |
---|
18 | #include "gribfuncs.h" /* prototypes */ |
---|
19 | |
---|
20 | /* |
---|
21 | * |
---|
22 | **************************************************************************** |
---|
23 | * A. FUNCTION: grib_enc |
---|
24 | * to encode a GRIB Edition 1 message using the three |
---|
25 | * input internal structures (DATA_INPUT, USER_INPUT, GEOM_IN), |
---|
26 | * and the Floating point data array; |
---|
27 | * It's ok for Float array to be null if Grib Hdr shows that |
---|
28 | * it contains a predefined BDS; that case, just exits w/ no errs; |
---|
29 | * |
---|
30 | * INTERFACE: |
---|
31 | * int grib_enc (Data_Input, User_Input, Geom_In, pfData_Array, gh, errmsg) |
---|
32 | * |
---|
33 | * ARGUMENTS (I=input, O=output, I&O=input and output): |
---|
34 | * (I) DATA_INPUT Data_Input; |
---|
35 | * Structure containing input field information. |
---|
36 | * (I) USER_INPUT User_Input; |
---|
37 | * Structure containing encoder configuration data. |
---|
38 | * (I) GEOM_IN Geom_In; |
---|
39 | * Structure containing grid geometry description. |
---|
40 | * (I&O) float *pfData_Array; |
---|
41 | * array of float data to be packed and stored in the Binary Data |
---|
42 | * Section. Float array may be Null if the Grib Header already |
---|
43 | * contains a Binary Data Section in its attribute 'entire_msg'. |
---|
44 | * That case is referred to as the 'Shuffle Mode' which results |
---|
45 | * in the encoder to only create the sections which are not already |
---|
46 | * in entire_msg; |
---|
47 | * Note: non-null data array will be returned with the data being |
---|
48 | * scaled up by the Decimal Scale Factor. |
---|
49 | * (I&O) GRIB_HDR *gh; |
---|
50 | * Pre-malloced structure used to hold the encoded GRIB message |
---|
51 | * and its info. It contains a large array to hold the encoded |
---|
52 | * message, pointers to each of the Section along with their length, |
---|
53 | * and a flag 'shuffled' which determines how the message is encoded. |
---|
54 | * If 'shuffled' is zero upon entry, all 6 sections will be created |
---|
55 | * and array (float *pfData_Array) must contain the float data. |
---|
56 | * If 'shuffled' is set upon entry, there is already one or more |
---|
57 | * sections in Entire_msg; Each of these pre-included sections |
---|
58 | * sections will have a Non-Null pointer & a non-Zero length. |
---|
59 | * The encoder will then only create the missing sections and |
---|
60 | * append them at the end of the existing sections in array |
---|
61 | * 'entire_msg', hence these sections may not be in the proper |
---|
62 | * order expected by GRIB. |
---|
63 | * (O) char *errmsg |
---|
64 | * Empty array, returned filled if error occurred; |
---|
65 | * |
---|
66 | * RETURN VALUE: |
---|
67 | * 0> no errors; |
---|
68 | * GRIB_HDR is returned with the encoded message in 'entire_msg', |
---|
69 | * w/ total message length in msg_length, |
---|
70 | * w/ pointers to each defined Grib Header Sections in |
---|
71 | * ids_ptr, pds_ptr, gds_ptr, bms_ptr, gds_ptr, eds_ptr, |
---|
72 | * and each section length in ids_len, pds_len, gds_len, bms_len, |
---|
73 | * bds_len, eds_len; Note that the sections may not be in order if |
---|
74 | * the 'shuffled' bit is set; |
---|
75 | * 1> failed, msg in errmsg; |
---|
76 | ****************************************************************************/ |
---|
77 | #if PROTOTYPE_NEEDED |
---|
78 | int grib_enc (DATA_INPUT Data_Input, USER_INPUT User_Input, GEOM_IN Geom_In, |
---|
79 | float *pfData_Array, GRIB_HDR *gh, char *errmsg) |
---|
80 | #else |
---|
81 | int grib_enc (Data_Input, User_Input, Geom_In, pfData_Array, gh, errmsg) |
---|
82 | DATA_INPUT Data_Input; |
---|
83 | USER_INPUT User_Input; |
---|
84 | GEOM_IN Geom_In; |
---|
85 | float *pfData_Array; |
---|
86 | GRIB_HDR *gh; |
---|
87 | char *errmsg; |
---|
88 | #endif |
---|
89 | { |
---|
90 | PDS_INPUT *pPDS_Input= 0; /* internal Pds struc */ |
---|
91 | GDS_HEAD_INPUT *pGDS_Head_Input = 0; /* Internal Gds struc */ |
---|
92 | void *pvGDS_Proj_Input = 0; /* depends on Projection*/ |
---|
93 | BDS_HEAD_INPUT *pBDS_Head_Input = 0; /* Internal Bds struc */ |
---|
94 | char *func= "grib_enc"; |
---|
95 | char *Sevens= "7777"; |
---|
96 | int gdsbms_flag= 0; /* whether to include them */ |
---|
97 | unsigned char *px; /* working ptr w/in EntireMsg */ |
---|
98 | long lTemp; /* working var */ |
---|
99 | int n,Stat= 1; /* default to error */ |
---|
100 | |
---|
101 | DPRINT1 ("Entering %s...\n", func); |
---|
102 | /* |
---|
103 | * |
---|
104 | * A.1 IF (ptr is null or if the Entire_msg buffer is null) THEN |
---|
105 | * RETURN 1 !errmsg filled |
---|
106 | * ENDIF |
---|
107 | */ |
---|
108 | if (!gh || !gh->entire_msg) |
---|
109 | { |
---|
110 | sprintf (errmsg, "%s: expecting non-null GRIB_HDR struct\n", func); |
---|
111 | goto BYE; |
---|
112 | } |
---|
113 | |
---|
114 | /* |
---|
115 | * |
---|
116 | * A.2 CREATE storage for the Internal structures; |
---|
117 | * ! PDS_INPUT |
---|
118 | * ! GDS_HEAD_INPUT |
---|
119 | * ! GDS_Proj_Input set to MAX_INP_PROJ_SIZE defined in grib.h |
---|
120 | * ! BDS_HEAD_INPUT |
---|
121 | * RETURN with Malloc Err in errmsg if fails; |
---|
122 | * INITIALIZE Internal structures |
---|
123 | */ |
---|
124 | if (! (pPDS_Input= (PDS_INPUT *)malloc(sizeof(PDS_INPUT))) || |
---|
125 | ! (pGDS_Head_Input =(GDS_HEAD_INPUT*)malloc(sizeof(GDS_HEAD_INPUT))) || |
---|
126 | ! (pvGDS_Proj_Input= (void *) malloc (MAX_INP_PROJ_SIZE)) || |
---|
127 | ! (pBDS_Head_Input =(BDS_HEAD_INPUT*)malloc(sizeof(BDS_HEAD_INPUT)))) |
---|
128 | { |
---|
129 | sprintf(errmsg,"%s: failed to make storage for Internal Structs\n", |
---|
130 | func); |
---|
131 | goto BYE; |
---|
132 | } |
---|
133 | memset ((void *) pPDS_Input, '\0', sizeof(PDS_INPUT)); |
---|
134 | memset ((void *) pGDS_Head_Input, '\0', sizeof (GDS_HEAD_INPUT)); |
---|
135 | memset ((void *) pvGDS_Proj_Input,'\0', MAX_INP_PROJ_SIZE); |
---|
136 | memset ((void *) pBDS_Head_Input, '\0', sizeof (BDS_HEAD_INPUT)); |
---|
137 | |
---|
138 | /* |
---|
139 | * |
---|
140 | * A.3 IF (creating all sections) |
---|
141 | * ! ** (shuffled == 0) ** |
---|
142 | * ! user passed Float data in, and the GribHdr's |
---|
143 | * ! Entire_Msg array has no valid data in it; |
---|
144 | * ! Must 'put' all Sections 0 thru 5 into Grib Hdr in that order; |
---|
145 | * A.3.a THEN |
---|
146 | */ |
---|
147 | if (! gh->shuffled) |
---|
148 | { |
---|
149 | /* Create All Sections mode: user must send float data */ |
---|
150 | DPRINT0 ("(SHUFFLE=0) Create ALL sections mode\n"); |
---|
151 | |
---|
152 | /* |
---|
153 | * A.3.a.1 RETURN if Float array is Null; !errmsg filled |
---|
154 | */ |
---|
155 | if ( !pfData_Array) |
---|
156 | { |
---|
157 | sprintf(errmsg, |
---|
158 | "%s: <Create-All mode> No DataArray avail to encode\n",func); |
---|
159 | goto BYE; |
---|
160 | } |
---|
161 | |
---|
162 | /* |
---|
163 | * A.3.a.2 CLEAR out the length and section ptrs |
---|
164 | * ASSIGN beginning of Entire Msg to 'px', as location to |
---|
165 | * append things to; |
---|
166 | */ |
---|
167 | gh->msg_length= gh->eds_len= gh->pds_len= gh->gds_len= 0; |
---|
168 | gh->bms_len= gh->bds_len= gh->eds_len= 0; |
---|
169 | gh->eds_ptr= gh->pds_ptr= gh->gds_ptr= NULL; |
---|
170 | gh->bms_ptr= gh->bds_ptr= gh->eds_ptr= NULL; |
---|
171 | px = gh->entire_msg; /* append from here on */ |
---|
172 | /* |
---|
173 | * |
---|
174 | * A.3.a.3 BUILD IDS SECTION |
---|
175 | * SET up pointer to IDS |
---|
176 | * SET up IDS length (8 for Edition 1) |
---|
177 | * WRITE the Ident Data Section to Grib Hdr |
---|
178 | * UPDATE 'px' to end of IDS !where to write next section |
---|
179 | */ |
---|
180 | gh->ids_len = 8; |
---|
181 | gh->msg_length += 8L; |
---|
182 | gh->ids_ptr = px; |
---|
183 | memcpy ((void *) gh->ids_ptr, (void *)"GRIB....", 8); |
---|
184 | px = gh->entire_msg + gh->msg_length; |
---|
185 | DPRINT3 ("%s: 'putting' IDS (%ld), msg_len=%ld\n", |
---|
186 | func, gh->ids_len,gh->msg_length); |
---|
187 | |
---|
188 | /* |
---|
189 | * |
---|
190 | * A.3.a.4 FUNCTION gribputpds !Build PDS Section into GRIB_HDR |
---|
191 | * IF failed |
---|
192 | * THEN return with error !errmsg filled |
---|
193 | * ELSE bump 'px' to end of this section |
---|
194 | */ |
---|
195 | if (n= gribputpds (Data_Input, User_Input, pPDS_Input, &gh, errmsg)) |
---|
196 | { |
---|
197 | upd_child_errmsg (func, errmsg); |
---|
198 | goto BYE; |
---|
199 | } |
---|
200 | else px = gh->entire_msg + gh->msg_length; |
---|
201 | |
---|
202 | DPRINT3("%s: Encoding PDS (%ld), msg_len=%ld\n", |
---|
203 | func, gh->pds_len,gh->msg_length); |
---|
204 | |
---|
205 | /* |
---|
206 | * |
---|
207 | * A.3.a.5 FUNCTION gribputgds !Build GDS Section into GRIB_HDR |
---|
208 | * IF failed |
---|
209 | * THEN return with error !errmsg filled |
---|
210 | * ELSE bump 'px' to end of this section |
---|
211 | */ |
---|
212 | if ((int) (User_Input.usGds_bms_id) >= 128) |
---|
213 | { |
---|
214 | if ( n = gribputgds (Geom_In, |
---|
215 | pGDS_Head_Input, &pvGDS_Proj_Input, &gh, errmsg) ) |
---|
216 | { |
---|
217 | upd_child_errmsg (func, errmsg); |
---|
218 | goto BYE; |
---|
219 | } |
---|
220 | else px = gh->entire_msg + gh->msg_length; |
---|
221 | |
---|
222 | DPRINT3 ("%s: Encoding GDS (%ld), msg_len=%ld\n", |
---|
223 | func, gh->gds_len,gh->msg_length); |
---|
224 | } |
---|
225 | else DPRINT1 ("%s: SKIPPING GDS!\n", func); |
---|
226 | |
---|
227 | /* |
---|
228 | * |
---|
229 | * A.3.a.6 Force no BMS by default |
---|
230 | */ |
---|
231 | gh->bms_ptr=0; gh->bms_len= 0; |
---|
232 | DPRINT1 ("%s: Skipping BMS by default\n", func); |
---|
233 | |
---|
234 | /* |
---|
235 | * |
---|
236 | * A.3.a.7 FUNCTION gribputbds Build BDS Section into GRIB_HDR |
---|
237 | * IF failed |
---|
238 | * THEN return with error !errmsg filled |
---|
239 | * ELSE bump 'px' to end of this section |
---|
240 | */ |
---|
241 | if (n= gribputbds (User_Input, Geom_In.nx*Geom_In.ny, |
---|
242 | pPDS_Input->sDec_sc_fctr, |
---|
243 | pfData_Array, |
---|
244 | pBDS_Head_Input, &gh, errmsg)) |
---|
245 | { |
---|
246 | upd_child_errmsg (func, errmsg); |
---|
247 | goto BYE; |
---|
248 | } |
---|
249 | else px = gh->entire_msg + gh->msg_length; |
---|
250 | |
---|
251 | DPRINT3 ("%s: Encoding BDS (%ld), msg_len=%ld\n", |
---|
252 | func, gh->bds_len,gh->msg_length); |
---|
253 | |
---|
254 | /* |
---|
255 | * |
---|
256 | * A.3.a.8 IF (Entire Msg buffer isn't big enough to hold EDS) |
---|
257 | * THEN |
---|
258 | * FUNCTION Expand_gribhdr !make it 4 bytes larger |
---|
259 | * RETURN with Error if fails !errmsg filled |
---|
260 | * ENDIF |
---|
261 | * SET up pointer to EDS |
---|
262 | * WRITE Grib EDS section to the end of Data !"7777" |
---|
263 | * UPDATE Grib Hdr's Eds_Ptr, Eds_Len |
---|
264 | */ |
---|
265 | if (gh->msg_length > gh->abs_size |
---|
266 | && Expand_gribhdr (gh, gh->msg_length, errmsg) != 0) |
---|
267 | { |
---|
268 | upd_child_errmsg (func, errmsg); |
---|
269 | goto BYE; |
---|
270 | } |
---|
271 | |
---|
272 | gh->eds_ptr= px; |
---|
273 | gh->eds_len= 4; |
---|
274 | gh->msg_length += gh->eds_len; |
---|
275 | memcpy ((void *)gh->eds_ptr, (void*)Sevens, 4); |
---|
276 | DPRINT3 ("%s: 'putting' EDS (%ld), msg_len=%ld\n", |
---|
277 | func, gh->eds_len,gh->msg_length); |
---|
278 | |
---|
279 | } /* END SHUFFLED == 0 SECTION */ |
---|
280 | |
---|
281 | /* |
---|
282 | * A.3.b ELSE |
---|
283 | * ! ** (shuffled == 1) ** |
---|
284 | * ! means that user has already put 1/more GRIB sections |
---|
285 | * ! in GRIB_HDR struct's Entire_Msg; The already included |
---|
286 | * ! Sections may not be in proper GRIB-format order, and have |
---|
287 | * ! non-null Pointers and non-zero length; Msg_Length also |
---|
288 | * ! reflects total length of all included sections; |
---|
289 | * ! -if the Float data is Null, the Bds must already be included |
---|
290 | * ! in the Grib Hdr; Func will return error if the Bds pointer |
---|
291 | * ! is Null or the Bds Len is zero; |
---|
292 | * ! -if the incoming Float data has data and the Grib hdr shows |
---|
293 | * ! that BMS is already defined then the func will Ignore the |
---|
294 | * ! float data; |
---|
295 | * ! otherwise, the float data will be used to create a new |
---|
296 | * ! Binary Data Section; |
---|
297 | * ! Only need to 'put' the Sections that have not already been |
---|
298 | * ! included in the Grib Header; |
---|
299 | */ |
---|
300 | else { /* Shuffle Mode: Create Missing Sections mode */ |
---|
301 | |
---|
302 | /* |
---|
303 | * A.3.b.1 IF (there is discrepency in section pointers and length) |
---|
304 | * RETURN 1 !errmsg filled |
---|
305 | * ENDIF |
---|
306 | */ |
---|
307 | if ( (gh->ids_ptr && !gh->ids_len) || (gh->ids_len && !gh->ids_ptr) |
---|
308 | || (gh->pds_ptr && !gh->pds_len) || (gh->pds_len && !gh->pds_ptr) |
---|
309 | || (gh->gds_ptr && !gh->gds_len) || (gh->gds_len && !gh->gds_ptr) |
---|
310 | || (gh->bms_ptr && !gh->bms_len) || (gh->bms_len && !gh->bms_ptr) |
---|
311 | || (gh->bds_ptr && !gh->bds_len) || (gh->bds_len && !gh->bds_ptr) |
---|
312 | || (gh->eds_ptr && !gh->eds_len) || (gh->eds_len && !gh->eds_ptr) |
---|
313 | || (gh->entire_msg && !gh->msg_length) |
---|
314 | || (gh->msg_length && !gh->entire_msg) ) |
---|
315 | { |
---|
316 | sprintf (errmsg, |
---|
317 | "%s: GribHdr Length/Ptr to sections are not consistent\n", func); |
---|
318 | goto BYE; |
---|
319 | } |
---|
320 | |
---|
321 | /* |
---|
322 | * A.3.b.2 IF (no float array was passed in AND |
---|
323 | * Grib Hdr shows BDS is undefined) THEN |
---|
324 | * RETURN 1 !errmsg filed |
---|
325 | * ENDIF |
---|
326 | */ |
---|
327 | if ( !pfData_Array && !gh->bds_ptr) { |
---|
328 | sprintf(errmsg, |
---|
329 | "%s: <Create Missing Sect mode> No DataArray avail to encode Bds\n", |
---|
330 | func); |
---|
331 | goto BYE; |
---|
332 | } |
---|
333 | |
---|
334 | /* |
---|
335 | * A.3.b.3 IF (user did send in float array AND |
---|
336 | * Grib Hdr shows BDS is already defined) THEN |
---|
337 | * PRINT warning !won't encode float array |
---|
338 | * ENDIF |
---|
339 | */ |
---|
340 | if ( pfData_Array && gh->bds_ptr && gh->bds_len>0) { |
---|
341 | DPRINT2 ("%s: GribHdr already has a BDS (Len=%ld), " \ |
---|
342 | " not going to encode the Float Data\n" , func, gh->bds_len); |
---|
343 | } |
---|
344 | |
---|
345 | DPRINT7 ("(SHUFFLE=1) gribhdr contains msg with totlen=%ld\n" \ |
---|
346 | " IDS(%d), PDS(%d), GDS(%d), BMS(%d), BDS(%d), EDS(%d)\n", |
---|
347 | gh->msg_length, gh->ids_len, gh->pds_len, gh->gds_len, |
---|
348 | gh->bms_len, gh->bds_len, gh->eds_len); |
---|
349 | |
---|
350 | /* |
---|
351 | * A.3.b.4 ASSIGN to local ptr 'px' the address of Msg_length bytes |
---|
352 | * away from Entire Msg, as location to append things to; |
---|
353 | */ |
---|
354 | px = gh->entire_msg + gh->msg_length; /* append from here */ |
---|
355 | |
---|
356 | /* |
---|
357 | * |
---|
358 | * A.3.b.5 IF (GribHdr has no IDS yet) |
---|
359 | * THEN |
---|
360 | * SET up pointer to IDS |
---|
361 | * SET up IDS length (8 for Edition 1) |
---|
362 | * WRITE the Ident Data Section to Grib Hdr |
---|
363 | * !use dummy message length for now |
---|
364 | * UPDATE 'px' to end of IDS !where to write next section |
---|
365 | * ENDIF |
---|
366 | */ |
---|
367 | if ( gh->ids_ptr==NULL ) |
---|
368 | { |
---|
369 | gh->ids_len = 8; |
---|
370 | gh->msg_length += 8L; |
---|
371 | gh->ids_ptr = px; |
---|
372 | memcpy ((void *) gh->ids_ptr, (void *)"GRIB....", 8); |
---|
373 | px = gh->entire_msg + gh->msg_length; |
---|
374 | DPRINT3 ("%s: 'putting' IDS (%ld), msg_len=%ld\n", |
---|
375 | func, gh->ids_len,gh->msg_length); |
---|
376 | } |
---|
377 | else DPRINT1 ("%s: skip writing IDS\n", func); |
---|
378 | |
---|
379 | /* |
---|
380 | * |
---|
381 | * A.3.b.6 IF (GribHdr has no PDS yet) |
---|
382 | * THEN |
---|
383 | * FUNCTION gribputpds !Build PDS Section into GRIB_HDR |
---|
384 | * IF failed |
---|
385 | * THEN return with error !errmsg filled |
---|
386 | * ELSE bump 'px' to end of this section |
---|
387 | * ENDIF |
---|
388 | */ |
---|
389 | if ( gh->pds_ptr==NULL) |
---|
390 | { |
---|
391 | if (n= gribputpds (Data_Input, User_Input, pPDS_Input, &gh, errmsg)) |
---|
392 | { |
---|
393 | DPRINT2 ("%s: got err=%d in Grib Put Pds()\n",func,n); |
---|
394 | upd_child_errmsg (func, errmsg); |
---|
395 | goto BYE; |
---|
396 | } |
---|
397 | else px = gh->entire_msg + gh->msg_length; |
---|
398 | |
---|
399 | DPRINT3("%s: 'putting' PDS (%ld), msg_len=%ld\n", |
---|
400 | func, gh->pds_len,gh->msg_length); |
---|
401 | } |
---|
402 | else DPRINT1("%s: skip writing PDS\n", func); |
---|
403 | |
---|
404 | /* |
---|
405 | * |
---|
406 | * A.3.b.7 IF (GribHdr has no GDS yet) |
---|
407 | * THEN |
---|
408 | * FUNCTION gribputgds !Build GDS Section into GRIB_HDR |
---|
409 | * IF failed |
---|
410 | * THEN return with error !errmsg filled |
---|
411 | * ELSE bump 'px' to end of this section |
---|
412 | * ENDIF |
---|
413 | */ |
---|
414 | |
---|
415 | if ((gh->gds_ptr==NULL) && (User_Input.usGds_bms_id >= 128)) |
---|
416 | { |
---|
417 | if ( n = gribputgds (Geom_In, |
---|
418 | pGDS_Head_Input, &pvGDS_Proj_Input, &gh, errmsg) ) |
---|
419 | { |
---|
420 | DPRINT2 ("%s: got err=%d in Grib Put Gds()\n",func,n); |
---|
421 | upd_child_errmsg (func, errmsg); |
---|
422 | goto BYE; |
---|
423 | } |
---|
424 | else px = gh->entire_msg + gh->msg_length; |
---|
425 | |
---|
426 | DPRINT3 ("%s: 'putting' GDS (%ld), msg_len=%ld\n", |
---|
427 | func, gh->gds_len,gh->msg_length); |
---|
428 | } |
---|
429 | else DPRINT1 ("%s: skip writing GDS\n", func); |
---|
430 | |
---|
431 | /* |
---|
432 | * |
---|
433 | * A.3.b.8 CHECK consistency on Gds/Bms flag |
---|
434 | * IF (GDS is included) |
---|
435 | * THEN SET the GdsPresent bit |
---|
436 | * ELSE CLEAR the GdsPresent bit |
---|
437 | * ENDIF |
---|
438 | */ |
---|
439 | gdsbms_flag = (int)gh->pds_ptr[7] & 0x000000FF; |
---|
440 | DPRINT1 ("orig gds/bms flag, pds[7] = 0x%x\n", gdsbms_flag); |
---|
441 | |
---|
442 | if (gh->gds_ptr == NULL) { |
---|
443 | gdsbms_flag &= ~(0x00000080); |
---|
444 | DPRINT2 ("%s: GDS missing, so CLEAR 0x80; newFLG=0x%x, \n", |
---|
445 | func, gdsbms_flag); |
---|
446 | } |
---|
447 | else { |
---|
448 | gdsbms_flag |= (0x00000080); |
---|
449 | DPRINT2 ("%s: GDS Present, so SET 0x80; newFLG=0x%x, \n", |
---|
450 | func, gdsbms_flag); |
---|
451 | /* |
---|
452 | DONOT set grid id to 255, since it is possible for user to |
---|
453 | define a new grid with id w/in range, and still include GDS; |
---|
454 | */ |
---|
455 | } |
---|
456 | |
---|
457 | /* |
---|
458 | * |
---|
459 | * A.3.b.9 IF (BMS is there) THEN |
---|
460 | * SET the BmsPresent bit |
---|
461 | * ELSE |
---|
462 | * CLEAR the BmsPresent bit |
---|
463 | * ENDIF |
---|
464 | */ |
---|
465 | if (gh->bms_ptr == NULL) { |
---|
466 | gdsbms_flag &= ~(0x00000040); |
---|
467 | DPRINT2 ("%s: no BMS, so CLEAR 0x40; new FLG=0x%x",func,gdsbms_flag); |
---|
468 | } |
---|
469 | else { gdsbms_flag |= (0x00000040); |
---|
470 | DPRINT2("%s: BMS Present, so SET 0x40; new FLG=0x%x",func,gdsbms_flag); |
---|
471 | } |
---|
472 | |
---|
473 | gh->pds_ptr[7] = (unsigned char)gdsbms_flag; |
---|
474 | DPRINT1 ("; PDS_ptr[7]= %x\n",gh->pds_ptr[7]); |
---|
475 | |
---|
476 | /* |
---|
477 | * |
---|
478 | * A.3.b.10 IF (GribHdr has no BDS yet) THEN |
---|
479 | * FUNCTION gribputBds !Build BDS Section into GRIB_HDR |
---|
480 | * !**NOT doing anything to Data even if BMS is included *** |
---|
481 | * IF failed |
---|
482 | * THEN return with error !errmsg filled |
---|
483 | * ELSE bump 'px' to end of this section |
---|
484 | * ENDIF |
---|
485 | */ |
---|
486 | if ( gh->bds_ptr==NULL ) |
---|
487 | { |
---|
488 | if (n= gribputbds (User_Input, Geom_In.nx*Geom_In.ny, |
---|
489 | pPDS_Input->sDec_sc_fctr, |
---|
490 | pfData_Array, |
---|
491 | pBDS_Head_Input, &gh, errmsg)) |
---|
492 | { |
---|
493 | DPRINT2 ("%s: got err=%d in Grib Put BDS()\n",func,n); |
---|
494 | upd_child_errmsg (func, errmsg); |
---|
495 | goto BYE; |
---|
496 | } |
---|
497 | else px = gh->entire_msg + gh->msg_length; |
---|
498 | |
---|
499 | DPRINT3 ("%s: 'putting' BDS (%ld), msg_len=%ld\n", |
---|
500 | func, gh->bds_len,gh->msg_length); |
---|
501 | } |
---|
502 | else DPRINT1("%s: skip writing BDS\n", func); |
---|
503 | |
---|
504 | /* |
---|
505 | * |
---|
506 | * A.3.b.11 IF (GribHdr has no EDS yet) |
---|
507 | * THEN |
---|
508 | * IF (Entire Msg buffer isn't big enough to hold EDS) |
---|
509 | * FUNCTION Expand_gribhdr !make it 4 bytes larger |
---|
510 | * RETURN with Error if fails !errmsg filled |
---|
511 | * ENDIF |
---|
512 | * SET up pointer to EDS |
---|
513 | * WRITE Grib EDS section to the end of Data !"7777" |
---|
514 | * UPDATE Grib Hdr's Eds_Ptr, Eds_Len |
---|
515 | */ |
---|
516 | if ( gh->eds_ptr==NULL ) |
---|
517 | { |
---|
518 | if (gh->msg_length+5L > gh->abs_size ) { |
---|
519 | DPRINT1 ("Need to expand gribhdr (%ld) to hold EDS\n", |
---|
520 | gh->abs_size); |
---|
521 | /*if (NULL == (realloc (gh->entire_msg, gh->msg_length))) */ |
---|
522 | |
---|
523 | if (Expand_gribhdr (gh, gh->msg_length+5L, errmsg) ) { |
---|
524 | upd_child_errmsg (func, errmsg); |
---|
525 | goto BYE; |
---|
526 | } |
---|
527 | DPRINT1("gribhdr now has abs_size of %ld\n", |
---|
528 | gh->abs_size); |
---|
529 | |
---|
530 | } /* size changed */ |
---|
531 | |
---|
532 | gh->eds_ptr= px; |
---|
533 | gh->eds_len= 4; |
---|
534 | gh->msg_length += gh->eds_len; |
---|
535 | memcpy ((void *)gh->eds_ptr, (void*)Sevens, 4); |
---|
536 | DPRINT3 ("%s: 'putting' EDS (%ld), msg_len=%ld\n", |
---|
537 | func, gh->eds_len,gh->msg_length); |
---|
538 | } |
---|
539 | else DPRINT1 ("%s: skip writing EDS\n", func); |
---|
540 | |
---|
541 | /* |
---|
542 | * A.3 ENDIF |
---|
543 | */ |
---|
544 | } /* END SHUFFLED == 1 SECTION */ |
---|
545 | |
---|
546 | /* |
---|
547 | * |
---|
548 | * A.4 UPDATE Total Msg Length in Grib Hdr's Ident Data Sect |
---|
549 | */ |
---|
550 | set_bytes(gh->msg_length, 3, gh->ids_ptr+4); |
---|
551 | |
---|
552 | /* 1 is for the Edition 1 */ |
---|
553 | set_bytes(1,1,gh->ids_ptr+7); |
---|
554 | |
---|
555 | /* |
---|
556 | * |
---|
557 | * A.5 SET status to 0 ! no errors |
---|
558 | */ |
---|
559 | Stat = 0; |
---|
560 | |
---|
561 | |
---|
562 | BYE: |
---|
563 | /* |
---|
564 | * |
---|
565 | * A.6 PRINT message if error occurred |
---|
566 | */ |
---|
567 | if (errmsg[0]!='\0') DPRINT1("%s\n", errmsg); |
---|
568 | /* |
---|
569 | * |
---|
570 | * A.7 FREE up space of local Input structures |
---|
571 | * |
---|
572 | * A.8 RETURN stat |
---|
573 | */ |
---|
574 | /* |
---|
575 | * Changed by Todd Hutchinson, TASC |
---|
576 | * With this original code, not all memory was being freed |
---|
577 | */ |
---|
578 | /* Original |
---|
579 | if (! pPDS_Input) free(pPDS_Input); |
---|
580 | if (! pGDS_Head_Input) free(pGDS_Head_Input); |
---|
581 | if (! pvGDS_Proj_Input) free(pvGDS_Proj_Input); |
---|
582 | if (! pBDS_Head_Input) free(pBDS_Head_Input); |
---|
583 | */ |
---|
584 | /* New: */ |
---|
585 | free(pPDS_Input); |
---|
586 | free(pGDS_Head_Input); |
---|
587 | free(pvGDS_Proj_Input); |
---|
588 | free(pBDS_Head_Input); |
---|
589 | |
---|
590 | DPRINT3 ("Leaving %s (Msglen=%ld), stat=%d\n", func, gh->msg_length,Stat); |
---|
591 | return Stat; |
---|
592 | |
---|
593 | /* |
---|
594 | * |
---|
595 | * END OF FUNCTION |
---|
596 | * |
---|
597 | * |
---|
598 | */ |
---|
599 | } |
---|