PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/wrfv2_fire/external/io_grib1/MEL_grib1/grib_enc.c

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