[2759] | 1 | /* File: grib_seek.c based on Decoder's trqgetmsg() func; |
---|
| 2 | Revised by: |
---|
| 3 | 28oct96 Alice T. Nakajima (ATN), SAIC, Monterey |
---|
| 4 | 18jun97 ATN check Edition before reading in entire msg; |
---|
| 5 | 27aug97 ATN *SEEK_SET to 0 (gcc complains) |
---|
| 6 | 20Oct97 ATN print #bytes read when fread fails; |
---|
| 7 | 03nov97 ATN -Realloc |
---|
| 8 | 22oct98 ATN *error msg; |
---|
| 9 | */ |
---|
| 10 | #include <stdio.h> |
---|
| 11 | #include <stdlib.h> |
---|
| 12 | #include <string.h> |
---|
| 13 | #include <math.h> |
---|
| 14 | #include "dprints.h" /* for dprints */ |
---|
| 15 | #include "gribfuncs.h" /* prototypes */ |
---|
| 16 | |
---|
| 17 | /* |
---|
| 18 | ********************************************************************** |
---|
| 19 | * A. FUNCTION: grib_seek |
---|
| 20 | * search the input file starting at the given offset for a GRIB |
---|
| 21 | * message. If found, return it in GRIB_HDR structure. |
---|
| 22 | * |
---|
| 23 | * INTERFACE: |
---|
| 24 | * int grib_seek (InFile, offset, Read_Index, gh, errmsg) |
---|
| 25 | * |
---|
| 26 | * ARGUMENTS (I=input, O=output, I&O=input and output): |
---|
| 27 | * (I) char *InFile; |
---|
| 28 | * name of input file to search for message; |
---|
| 29 | * (I&O) long *offset; |
---|
| 30 | * number of bytes to skip from the beginning of file; |
---|
| 31 | * gets updated upon leaving to absolute #bytes from beginning of |
---|
| 32 | * file to beginning of message found; |
---|
| 33 | * (I) int Read_Index; |
---|
| 34 | * if set, only proceed if 'GRIB' starts exactly at the given |
---|
| 35 | * byte offset; |
---|
| 36 | * (O) GRIB_HDR *gh; |
---|
| 37 | * empty upon entry; to hold the Message found and its info; |
---|
| 38 | * (O) char *errmsg; |
---|
| 39 | * empty array, only filled if error occurred; |
---|
| 40 | * |
---|
| 41 | * RETURN CODE: |
---|
| 42 | * 0> no errors, may or may not have a valid message; |
---|
| 43 | * If no Msg was Found: |
---|
| 44 | * a) errmsg will hold the Warning msg; |
---|
| 45 | * If a valid Msg was Found: |
---|
| 46 | * a) long *offset: if succesful, gets updated to absolute |
---|
| 47 | * beginning of Mesg; |
---|
| 48 | * b) struct GRIB_HDR holds its info: |
---|
| 49 | * entire_msg: is assigned to newly MAlloced |
---|
| 50 | * unsigned char * array to hold entire message; |
---|
| 51 | * msg_length: size of entire_msg array in bytes; |
---|
| 52 | * ids_len, pds_len, gds_len, bms_len, bds_len, eds_len: |
---|
| 53 | * size of each defined sections in bytes; |
---|
| 54 | * ids_ptr: pts to message's Ident Data Sect; |
---|
| 55 | * pds_ptr: pts to message's Prod Defn Sect; |
---|
| 56 | * gds_ptr: pts to message's Grid Defn Sect; |
---|
| 57 | * bms_ptr: pts to message's Bitmap Defn Sect; |
---|
| 58 | * bds_ptr: pts to message's Binary Data Sect; |
---|
| 59 | * eds_ptr: pts to message's End Data Sect; |
---|
| 60 | * c) errmsg remains empty; |
---|
| 61 | * 1> fseek/fread error, all ptrs in grib_hdr set to null; errmsg filled; |
---|
| 62 | * 2> got end of file, all ptrs in grib_hdr set to null; errmsg filled; |
---|
| 63 | * 3> Null entire_msg pointer; errmsg filled; |
---|
| 64 | * 4> unable to open input file; errmsg filled; |
---|
| 65 | * |
---|
| 66 | ********************************************************************** |
---|
| 67 | */ |
---|
| 68 | |
---|
| 69 | #if PROTOTYPE_NEEDED |
---|
| 70 | int grib_seek ( char *InFile, long *offset, int Read_Index, |
---|
| 71 | GRIB_HDR *gh, char *errmsg) |
---|
| 72 | #else |
---|
| 73 | int grib_seek (InFile, offset, Read_Index,gh,errmsg) |
---|
| 74 | char *InFile; |
---|
| 75 | long *offset; |
---|
| 76 | int Read_Index; |
---|
| 77 | GRIB_HDR *gh; |
---|
| 78 | char *errmsg; |
---|
| 79 | #endif |
---|
| 80 | { |
---|
| 81 | char *func="grib_seek"; |
---|
| 82 | FILE *fp=NULL; |
---|
| 83 | int status=0; |
---|
| 84 | |
---|
| 85 | DPRINT3 ("Entering %s\nfile=%s, offs=%ld \n", func, InFile, *offset); |
---|
| 86 | |
---|
| 87 | /* |
---|
| 88 | * |
---|
| 89 | * A.2 OPEN Input file |
---|
| 90 | * IF (fails) RETURN w/ error stat 4 !errmsg filled |
---|
| 91 | */ |
---|
| 92 | if ((fp = fopen (InFile, "rb")) == NULL) { |
---|
| 93 | DPRINT2 ("%s: Cannot open input file %s\n", func,InFile ); |
---|
| 94 | sprintf (errmsg,"%s: Cannot open input file '%s'\n", func,InFile ); |
---|
| 95 | status = 4; |
---|
| 96 | goto DONE; |
---|
| 97 | } |
---|
| 98 | |
---|
| 99 | status = grib_fseek(fp,offset,Read_Index,gh,errmsg); |
---|
| 100 | |
---|
| 101 | DONE: |
---|
| 102 | /* |
---|
| 103 | * |
---|
| 104 | * A.4 CLOSE input file; !get here when found no messages |
---|
| 105 | * |
---|
| 106 | */ |
---|
| 107 | if (fp) fclose(fp); |
---|
| 108 | |
---|
| 109 | /* |
---|
| 110 | * A.6 RETURN with status |
---|
| 111 | */ |
---|
| 112 | return (status); |
---|
| 113 | |
---|
| 114 | } |
---|
| 115 | |
---|
| 116 | |
---|
| 117 | |
---|
| 118 | #if PROTOTYPE_NEEDED |
---|
| 119 | int grib_fseek ( FILE *fp, long *offset, int Read_Index, |
---|
| 120 | GRIB_HDR *gh, char *errmsg) |
---|
| 121 | #else |
---|
| 122 | int grib_fseek (fp, offset, Read_Index,gh,errmsg) |
---|
| 123 | FILE *fp; |
---|
| 124 | long *offset; |
---|
| 125 | int Read_Index; |
---|
| 126 | GRIB_HDR *gh; |
---|
| 127 | char *errmsg; |
---|
| 128 | #endif |
---|
| 129 | { |
---|
| 130 | char *func="grib_fseek"; |
---|
| 131 | char *GG, sm_blk[5004], *fwa_msg=NULL; |
---|
| 132 | unsigned long lMessageSize; |
---|
| 133 | unsigned long Edition; |
---|
| 134 | long pos; /* current byte offs fr. beg. of file */ |
---|
| 135 | int bytenum; /* Index w/in sm_blk */ |
---|
| 136 | int bytestoread=5004; /* #bytes to read into sm_blk at a time */ |
---|
| 137 | int check_limit; /* #bytes in sm_blk to check */ |
---|
| 138 | int gotone = 0; /* set if found good msg */ |
---|
| 139 | int nread; /* #bytes got back from Read */ |
---|
| 140 | int status; |
---|
| 141 | unsigned long iskip; /* for getbyte */ |
---|
| 142 | int gdsbmsflag, bit_set, sect_len; /* working vars */ |
---|
| 143 | char *ptr, *end_ptr; |
---|
| 144 | |
---|
| 145 | DPRINT2 ("Entering %s\n, offs=%ld \n", func, *offset); |
---|
| 146 | /* |
---|
| 147 | * A.1 INIT variables |
---|
| 148 | * !gh structure is cleared out |
---|
| 149 | */ |
---|
| 150 | if (gh->entire_msg==NULL) { |
---|
| 151 | DPRINT1 ( "%s: expecting non-null Grib Hdr;\n",func); |
---|
| 152 | sprintf(errmsg, "%s: expecting non-NULL Grib Hdr;\n",func); |
---|
| 153 | status= 3; |
---|
| 154 | goto DONE; |
---|
| 155 | } |
---|
| 156 | |
---|
| 157 | gh->msg_length = 0; |
---|
| 158 | gh->ids_ptr=gh->pds_ptr= 0; |
---|
| 159 | gh->gds_ptr=gh->bms_ptr=gh->bds_ptr=gh->eds_ptr=0; |
---|
| 160 | memset ((void *)gh->entire_msg, '\0', gh->abs_size); |
---|
| 161 | DPRINT2 ("gh= %ld, gh->entire_msg=%ld\n", gh, gh->entire_msg); |
---|
| 162 | |
---|
| 163 | /* |
---|
| 164 | * |
---|
| 165 | * A.3 FOR (loop while no error) !read a block at a time |
---|
| 166 | */ |
---|
| 167 | |
---|
| 168 | for (status=0, pos= *offset, gotone= 0; status == 0; pos += check_limit) |
---|
| 169 | { |
---|
| 170 | /* |
---|
| 171 | * A.3.1 IF (cannot SET file position to correct place) |
---|
| 172 | * THEN |
---|
| 173 | * SET Status to 1 !fseek err |
---|
| 174 | * CONTINUE (Loop around to A.3) |
---|
| 175 | * ENDIF |
---|
| 176 | */ |
---|
| 177 | if (fseek(fp, pos, 0)!=0) { |
---|
| 178 | DPRINT2 ("%s: Got fseek error to pos= %ld\n",func, pos); |
---|
| 179 | sprintf(errmsg,"%s: Got fseek error to pos= %ld\n",func,pos); |
---|
| 180 | perror(""); |
---|
| 181 | status = 1; |
---|
| 182 | goto DONE; |
---|
| 183 | } |
---|
| 184 | |
---|
| 185 | /* |
---|
| 186 | * A.3.2 IF (read less than 40 bytes) |
---|
| 187 | * THEN |
---|
| 188 | * FILL error buffer |
---|
| 189 | * RETURN status 2 !eof or <40 bytes left, errmsg filled |
---|
| 190 | * ENDIF |
---|
| 191 | */ |
---|
| 192 | nread= fread (sm_blk,sizeof(char), bytestoread,fp); |
---|
| 193 | if (nread <= 40) |
---|
| 194 | { |
---|
| 195 | if (nread<=4) { |
---|
| 196 | DPRINT0 ("No bytes left to check for msg;\n"); |
---|
| 197 | /* Errmsg left blank cuz its just EOF */ |
---|
| 198 | } |
---|
| 199 | else { |
---|
| 200 | sprintf(errmsg,"%s: skip last %d bytes, too few for a Msg\n", |
---|
| 201 | func, nread); |
---|
| 202 | DPRINT1 ("Only read %d bytes, too few to check for msg;\n",nread); |
---|
| 203 | } |
---|
| 204 | status= 2; |
---|
| 205 | goto DONE; |
---|
| 206 | } |
---|
| 207 | else check_limit= nread - 4; |
---|
| 208 | |
---|
| 209 | /* |
---|
| 210 | * ! search block for the next the 'G' |
---|
| 211 | * ! load entire Msg if everything is ok; |
---|
| 212 | * ! if No 'G' found, then quit right away if no 'G' |
---|
| 213 | * ! if GRIB is not at absolute Offset address, quit too; |
---|
| 214 | * ! |
---|
| 215 | * A.3.3 WHILE (there is another 'G' in this block) DO |
---|
| 216 | */ |
---|
| 217 | bytenum= 0; |
---|
| 218 | while ((GG= (char *) memchr (sm_blk, 'G', check_limit))) |
---|
| 219 | { |
---|
| 220 | /*--- Saw 'G' ---*/ |
---|
| 221 | /* |
---|
| 222 | * A.3.3.1 IF ('RIB' is not after 'G') THEN |
---|
| 223 | * IF (Offset from Index file) THEN |
---|
| 224 | * ABORT search; !Break out of loop |
---|
| 225 | * ELSE |
---|
| 226 | * CLEAR out the 'G' in temp block |
---|
| 227 | * CONTINUE !Loop around to A.3.3 |
---|
| 228 | * ENDIF |
---|
| 229 | * ENDIF |
---|
| 230 | */ |
---|
| 231 | if (strncmp(GG, "GRIB",4)) /* not 'RIB' after the 'G' */ |
---|
| 232 | if ( Read_Index) |
---|
| 233 | break; /* Offset IS from Indexfile: Quit here */ |
---|
| 234 | else |
---|
| 235 | { /* offset is NOT fr. IndexFile: keep looping; */ |
---|
| 236 | *GG='-'; /* no RIB after G, clear it */ |
---|
| 237 | continue; /* let Memchr find next G in block */ |
---|
| 238 | } |
---|
| 239 | |
---|
| 240 | /*--- Saw 'G R I B' ----*/ |
---|
| 241 | /* |
---|
| 242 | * A.3.3.2 CALCULATE byte position within this block |
---|
| 243 | * where this message begins |
---|
| 244 | */ |
---|
| 245 | bytenum = GG - sm_blk; /* byte pos w/in this block */ |
---|
| 246 | |
---|
| 247 | /* |
---|
| 248 | * A.3.3.3 IF (offset is from Indexfile AND |
---|
| 249 | * string GRIB found is not at Absolute IndexFile's offset) |
---|
| 250 | * THEN abort search; ENDIF |
---|
| 251 | */ |
---|
| 252 | DPRINT1 ("Found string 'GRIB' at %ld\n", pos+bytenum); |
---|
| 253 | if (Read_Index && *offset != (bytenum + pos)) { |
---|
| 254 | sprintf(errmsg, |
---|
| 255 | "%s: No Grib msg found at offset= %ld; check Index File\n", |
---|
| 256 | func, *offset); |
---|
| 257 | break; /* Abort here, Ret w/ no errros & no msg too */ |
---|
| 258 | } |
---|
| 259 | |
---|
| 260 | /*--- Read Mesg Length, Edition ---*/ |
---|
| 261 | /* |
---|
| 262 | * A.3.3.4 FUNCTION gbyte !extract lMessageSize |
---|
| 263 | */ |
---|
| 264 | iskip=32; |
---|
| 265 | gbyte (sm_blk+bytenum ,&lMessageSize, &iskip,24); |
---|
| 266 | DPRINT0 ("lMessageSize\n"); |
---|
| 267 | |
---|
| 268 | /*--- Make sure it's Edition 1 first ---*/ |
---|
| 269 | /* |
---|
| 270 | * A.3.3.5 FUNCTION gbyte !extract Grib Edition Number |
---|
| 271 | * IF (not edition 1) THEN |
---|
| 272 | * CLEAR out the 'G' in temp block |
---|
| 273 | * CONTINUE !Loop around to A.3.3 |
---|
| 274 | * ENDIF |
---|
| 275 | */ |
---|
| 276 | gbyte (sm_blk+bytenum, &Edition, &iskip, 8); |
---|
| 277 | DPRINT0 ("Edition\n"); |
---|
| 278 | if (Edition != 1) { |
---|
| 279 | DPRINT1 ("Edition (%d) is not 1, start over\n", |
---|
| 280 | Edition); |
---|
| 281 | *GG='-'; /* blank out G of current GRIB location found */ |
---|
| 282 | continue; /* let Memchr find next G in block */ |
---|
| 283 | } |
---|
| 284 | |
---|
| 285 | |
---|
| 286 | /* |
---|
| 287 | * A.3.3.6 IF (cannot MOVE ptr to start of the message) THEN |
---|
| 288 | * RETURN status 1 !errmsg filled |
---|
| 289 | * ENDIF |
---|
| 290 | */ |
---|
| 291 | if (fseek(fp, (long)(pos+bytenum), 0)!=0) { |
---|
| 292 | DPRINT2 ( |
---|
| 293 | "%s: FSEEK error to pos+bytenum= %ld\n", |
---|
| 294 | func, pos+bytenum); |
---|
| 295 | sprintf(errmsg, |
---|
| 296 | "%s: FSEEK error to pos+bytenum= %ld\n", |
---|
| 297 | func, pos+bytenum); |
---|
| 298 | status= 1; |
---|
| 299 | goto DONE; |
---|
| 300 | } |
---|
| 301 | |
---|
| 302 | /* |
---|
| 303 | * A.3.3.7 INIT all section length to zero |
---|
| 304 | */ |
---|
| 305 | gh->ids_len= gh->pds_len= gh->gds_len= 0; |
---|
| 306 | gh->bds_len= gh->bms_len= gh->eds_len= 0; |
---|
| 307 | |
---|
| 308 | /* |
---|
| 309 | * A.3.3.8 EXPAND Entire_Msg array if it's smaller than msglen |
---|
| 310 | * RETURN Malloc Err (stat=2) if fails !errmsg filled |
---|
| 311 | */ |
---|
| 312 | if (lMessageSize > gh->abs_size ) { |
---|
| 313 | |
---|
| 314 | /* if (realloc((void *)gh->entire_msg, lMessageSize) == NULL) {..} |
---|
| 315 | * gh->abs_size = lMessageSize; |
---|
| 316 | */ |
---|
| 317 | if (Expand_gribhdr (gh, lMessageSize, errmsg)) { |
---|
| 318 | upd_child_errmsg (func, errmsg); |
---|
| 319 | status = 1; /* to get out of Outer loop */ |
---|
| 320 | goto DONE; |
---|
| 321 | } |
---|
| 322 | |
---|
| 323 | DPRINT1 ("Expanded entire_msg to be %ld bytes long\n", |
---|
| 324 | gh->abs_size); |
---|
| 325 | } /* size changed */ |
---|
| 326 | |
---|
| 327 | /*--- READ ENTIRE MSG into GRIB HEADER's Entire_Msg ---*/ |
---|
| 328 | /* |
---|
| 329 | * |
---|
| 330 | * A.3.3.9 READ the entire message into Grib Hdr's Entire_Msg; |
---|
| 331 | * IF (failed) THEN |
---|
| 332 | * RETURN Fread error stat=1 !errmsg filled |
---|
| 333 | * ENDIF |
---|
| 334 | */ |
---|
| 335 | fwa_msg = (char *)gh->entire_msg; |
---|
| 336 | if ((nread=fread (fwa_msg, 1, lMessageSize, fp)) != lMessageSize) |
---|
| 337 | { |
---|
| 338 | DPRINT2 ( "%s: failed to Fread EntireMsg (sz=%ld)\n", |
---|
| 339 | func, lMessageSize); |
---|
| 340 | sprintf(errmsg, |
---|
| 341 | "%s has truncated msg @offs=%ld (got %ld out of %ld bytes)\n", |
---|
| 342 | func, *offset, nread, lMessageSize); |
---|
| 343 | status= 1; /* to get out of Outer loop */ |
---|
| 344 | goto DONE; /* get out of WHILE */ |
---|
| 345 | } |
---|
| 346 | |
---|
| 347 | /*--- if see '7777', asssign GH's pointers & len ---*/ |
---|
| 348 | /* |
---|
| 349 | * A.3.3.10 IF ('7777' is where expected) THEN |
---|
| 350 | */ |
---|
| 351 | if (!strncmp((fwa_msg + lMessageSize - 4),"7777",4)) |
---|
| 352 | /* && fwa_msg[7]==1) */ |
---|
| 353 | { |
---|
| 354 | end_ptr = fwa_msg + lMessageSize; |
---|
| 355 | |
---|
| 356 | DPRINT0 ("Found string '7777' where expected\n"); |
---|
| 357 | gh->msg_length= lMessageSize; |
---|
| 358 | /* |
---|
| 359 | * A.3.3.10.a.1 STORE loc & len of section 0 into Grib Hdr; |
---|
| 360 | */ |
---|
| 361 | gh->ids_ptr= (unsigned char *)fwa_msg; /* mark sect 0 */ |
---|
| 362 | gh->ids_len= 8L; |
---|
| 363 | |
---|
| 364 | /* |
---|
| 365 | * A.3.3.10.a.2 STORE loc & len of PDS into Grib Hdr; |
---|
| 366 | * FUNCTION gbyte !get 3-byte length |
---|
| 367 | */ |
---|
| 368 | ptr= fwa_msg + gh->ids_len; |
---|
| 369 | gh->pds_ptr= (unsigned char *)ptr; /* mark PDS */ |
---|
| 370 | iskip= 0; gbyte(ptr ,(unsigned long *)&gh->pds_len,&iskip,24); |
---|
| 371 | DPRINT0 (" pds length\n"); |
---|
| 372 | iskip= 8*7; gbyte(ptr ,(unsigned long*)&gdsbmsflag, &iskip, 8); |
---|
| 373 | DPRINT1 (" (%x hex) Gds/Bms flag\n", gdsbmsflag); |
---|
| 374 | /* |
---|
| 375 | * A.3.3.10.a.3 IF (location of next Section is out of bound) THEN |
---|
| 376 | * PRINT message; |
---|
| 377 | * GOTO drop this msg; |
---|
| 378 | * ENDIF |
---|
| 379 | */ |
---|
| 380 | ptr += gh->pds_len; |
---|
| 381 | if (ptr > end_ptr) { |
---|
| 382 | sprintf(errmsg, |
---|
| 383 | "%s: corrupt PDSlen= %ld, Totlen=%ld, drop msg @%ld;\n" |
---|
| 384 | , func, gh->pds_len, gh->msg_length, *offset); |
---|
| 385 | gh->pds_len= 0; /* reset */ |
---|
| 386 | goto DROPMSG_N_LOOP; |
---|
| 387 | } |
---|
| 388 | |
---|
| 389 | /* |
---|
| 390 | * IF (Debug) FUNCTION hdr_print !print PDS |
---|
| 391 | */ |
---|
| 392 | DPRINT1 ("gh->pds_len= %ld\n", gh->pds_len); |
---|
| 393 | HDR_PRINT("Grib_Seek's PDS",gh->pds_ptr, gh->pds_len); |
---|
| 394 | |
---|
| 395 | /* |
---|
| 396 | * A.3.3.10.a.4 IF (GDS is present) THEN |
---|
| 397 | * STORE location & len of GDS into Grib Hdr's Gds_Ptr |
---|
| 398 | * FUNCTION gbyte !get 3-byte length |
---|
| 399 | * IF (location of next Section is out of bound) THEN |
---|
| 400 | * PRINT message; |
---|
| 401 | * DROP this msg & try to find another; |
---|
| 402 | * ENDIF |
---|
| 403 | * IF (Debug) FUNCTION hdr_print !print GDS |
---|
| 404 | * ENDIF |
---|
| 405 | */ |
---|
| 406 | bit_set= gdsbmsflag >> 7 & 1; /* mark GDS if present */ |
---|
| 407 | if (bit_set) { |
---|
| 408 | gh->gds_ptr= (unsigned char *)ptr; |
---|
| 409 | iskip= 0; gbyte(ptr,(unsigned long*)&gh->gds_len,&iskip,24); |
---|
| 410 | DPRINT0 (" Gds length\n"); |
---|
| 411 | ptr += gh->gds_len; /* bump PTR to sect*/ |
---|
| 412 | if (ptr > end_ptr) { |
---|
| 413 | sprintf(errmsg, |
---|
| 414 | "%s: corrupt GDSlen= %ld, Totlen=%ld, drop msg @%ld\n" |
---|
| 415 | , func, gh->gds_len, gh->msg_length, *offset); |
---|
| 416 | gh->gds_len= 0; /* reset */ |
---|
| 417 | goto DROPMSG_N_LOOP; |
---|
| 418 | } |
---|
| 419 | DPRINT1 ("gh->gds_len= %ld\n", gh->gds_len); |
---|
| 420 | HDR_PRINT("Grib_Seek's GDS",gh->gds_ptr,gh->gds_len); |
---|
| 421 | } |
---|
| 422 | |
---|
| 423 | /* |
---|
| 424 | * A.3.3.10.a.5 IF (BMS is present) THEN |
---|
| 425 | * STORE location & len of BMS into Grib Hdr's Bms_Ptr |
---|
| 426 | * FUNCTION gbyte !get 3-byte length |
---|
| 427 | * IF (location of next Section is out of bound) THEN |
---|
| 428 | * PRINT message; |
---|
| 429 | * DROP this msg & try to find another; |
---|
| 430 | * ENDIF |
---|
| 431 | * IF (Debug) FUNCTION hdr_print !byte dump |
---|
| 432 | * ENDIF |
---|
| 433 | */ |
---|
| 434 | bit_set= gdsbmsflag >> 6 & 1; /* mark BMS if present */ |
---|
| 435 | if (bit_set) { |
---|
| 436 | gh->bms_ptr= (unsigned char *)ptr; |
---|
| 437 | iskip= 0; gbyte(ptr,(unsigned long*)&gh->bms_len,&iskip,24); |
---|
| 438 | DPRINT0 (" Bms length\n"); |
---|
| 439 | |
---|
| 440 | ptr += gh->bms_len; /* bump PTR to sect */ |
---|
| 441 | if (ptr > end_ptr) { |
---|
| 442 | sprintf(errmsg, |
---|
| 443 | "%s: corrupt BMSlen= %ld, Totlen=%ld, drop msg @%ld\n" |
---|
| 444 | , func, gh->bms_len, gh->msg_length, *offset); |
---|
| 445 | gh->bms_len= 0; /* reset */ |
---|
| 446 | goto DROPMSG_N_LOOP; |
---|
| 447 | } |
---|
| 448 | DPRINT1 ("gh->bms_len= %ld\n", gh->bms_len); |
---|
| 449 | HDR_PRINT ("Grib_Seek's BMS", gh->bms_ptr, |
---|
| 450 | (gh->bms_len>100? 100: gh->bms_len)); |
---|
| 451 | } |
---|
| 452 | /* |
---|
| 453 | * A.3.3.10.a.6 STORE location and length of BDS into Grib Hdr's Bds_Ptr |
---|
| 454 | * FUNCTION gbyte !get 3-byte length |
---|
| 455 | * IF (location of next Section is out of bound) THEN |
---|
| 456 | * PRINT message; |
---|
| 457 | * DROP this msg & try to find another; |
---|
| 458 | * ENDIF |
---|
| 459 | * IF (Debug) FUNCTION hdr_print !byte dump |
---|
| 460 | */ |
---|
| 461 | |
---|
| 462 | gh->bds_ptr= (unsigned char *)ptr; /* mark BDS */ |
---|
| 463 | iskip= 0; gbyte(ptr,(unsigned long*)&gh->bds_len,&iskip,24); |
---|
| 464 | DPRINT0 (" Bds length\n"); |
---|
| 465 | |
---|
| 466 | ptr += gh->bds_len; |
---|
| 467 | if (ptr > end_ptr) { |
---|
| 468 | sprintf(errmsg, |
---|
| 469 | "%s: corrupt BDSlen= %ld, Totlen=%ld, drop msg @%ld\n" |
---|
| 470 | , func, gh->gds_len, gh->msg_length, *offset); |
---|
| 471 | gh->gds_len= 0; /* reset */ |
---|
| 472 | goto DROPMSG_N_LOOP; |
---|
| 473 | } |
---|
| 474 | DPRINT1 ("gh->bds_len= %ld\n", gh->bds_len); |
---|
| 475 | HDR_PRINT ("Grib_Seek's BDS", gh->bds_ptr, |
---|
| 476 | (gh->bds_len>100? 100: gh->bds_len)); |
---|
| 477 | |
---|
| 478 | /* |
---|
| 479 | * A.3.3.10.a.7 STORE location & len of EDS into Grib Hdr's Eds_Ptr |
---|
| 480 | */ |
---|
| 481 | gh->eds_ptr= (unsigned char *)ptr; /* mark EDS */ |
---|
| 482 | gh->eds_len= 4; |
---|
| 483 | |
---|
| 484 | /* |
---|
| 485 | * A.3.3.10.a.8 SET 'gotone' flag |
---|
| 486 | * ! Return with Msg in Grib hdr, and good stat |
---|
| 487 | */ |
---|
| 488 | gotone=1; /* to get out of FOR loop */ |
---|
| 489 | status=0; /* Return with Msg , good stat */ |
---|
| 490 | goto DONE; |
---|
| 491 | /* |
---|
| 492 | * A.3.3.10 ENDIF |
---|
| 493 | */ |
---|
| 494 | } /* saw 77s */ |
---|
| 495 | else |
---|
| 496 | if (Read_Index) { |
---|
| 497 | sprintf(errmsg, |
---|
| 498 | "%s: no 7777 found for msg at %ld, check indexfile\n", |
---|
| 499 | func, *offset); |
---|
| 500 | } |
---|
| 501 | |
---|
| 502 | /* |
---|
| 503 | * |
---|
| 504 | * !==================================================== |
---|
| 505 | * ! Drop Msg Area: Only get here if : |
---|
| 506 | * ! - first G found not at Indexfile's offset; |
---|
| 507 | * ! - no RIB after G; |
---|
| 508 | * ! - GRIB string found not at Indexfile's offset; |
---|
| 509 | * ! - no 7777 at expected offset; |
---|
| 510 | * ! - got Corrupted Length; |
---|
| 511 | * !==================================================== |
---|
| 512 | */ |
---|
| 513 | DROPMSG_N_LOOP: |
---|
| 514 | /* ERRMSG must already be loaded and the corrupted len reset to 0 |
---|
| 515 | so that Display GH won't go out of bound... |
---|
| 516 | */ |
---|
| 517 | DPRINT1 ("\nDropping, cause=> %s\n", errmsg); |
---|
| 518 | |
---|
| 519 | /* |
---|
| 520 | * A.3.3.11 IF (Debug mode) THEN |
---|
| 521 | * FUNCTION display_gribhdr !show what got loaded sofar |
---|
| 522 | * ENDIF |
---|
| 523 | */ |
---|
| 524 | if (gh->msg_length > 0) |
---|
| 525 | DISPLAY_GRIBHDR(gh); /* before dropping msg*/ |
---|
| 526 | |
---|
| 527 | /* |
---|
| 528 | * ! no message found yet, OR Msg Section lens are corrupted |
---|
| 529 | * A.3.3.12 CLEAR out header struct !data in array is not valid |
---|
| 530 | */ |
---|
| 531 | gh->msg_length =0; |
---|
| 532 | gh->ids_ptr=gh->pds_ptr= gh->eds_ptr=0; |
---|
| 533 | gh->gds_ptr=gh->bms_ptr=gh->bds_ptr= 0; |
---|
| 534 | memset ((void *)gh->entire_msg, '\0', gh->abs_size); |
---|
| 535 | |
---|
| 536 | /* |
---|
| 537 | * A.3.3.13 IF (Offset was read from Indexfile) !quit searching |
---|
| 538 | * A.3.3.13.a THEN |
---|
| 539 | * PUT Error msg in buffer |
---|
| 540 | * RETURN with No Error status |
---|
| 541 | * A.3.3.13.b ELSE |
---|
| 542 | * CLEAR out 'G' in tmp block !go find next 'G' |
---|
| 543 | * ENDIF |
---|
| 544 | */ |
---|
| 545 | if (Read_Index) { |
---|
| 546 | status = 0; /* Ret w/ no errors */ |
---|
| 547 | goto DONE; /* send CAUSE back in Errmsg */ |
---|
| 548 | } |
---|
| 549 | else { |
---|
| 550 | *GG='-'; /* let Memchr find next 'G' in curr. block */ |
---|
| 551 | DPRINT1 ("'GRIB' at location %ld is not a valid message\n", |
---|
| 552 | bytenum+pos); |
---|
| 553 | errmsg[0]='\0'; /* clear out buff */ |
---|
| 554 | } |
---|
| 555 | /* |
---|
| 556 | * A.3.3 ENDWHILE |
---|
| 557 | */ |
---|
| 558 | } /* WHILE seeing 'G'*/ |
---|
| 559 | |
---|
| 560 | |
---|
| 561 | if (Read_Index) { /* Catch 3 cases: |
---|
| 562 | - if no 'G' at all ; |
---|
| 563 | - if no RIB after G ; |
---|
| 564 | - if found GRIB but not at expected place |
---|
| 565 | */ |
---|
| 566 | sprintf(errmsg, |
---|
| 567 | "%s: No Grib Msg found at IndexFile's offset = %ld; "\ |
---|
| 568 | " Check Index File\n" , func, *offset); |
---|
| 569 | status = 0; /* Return w/no errors */ |
---|
| 570 | goto DONE; /* but w/ Warn Msg in buff*/ |
---|
| 571 | } |
---|
| 572 | |
---|
| 573 | /* |
---|
| 574 | A.3.4 DEBUG print !no Sect0 found in this block |
---|
| 575 | */ |
---|
| 576 | DPRINT2 ("No Section 0 found between address %ld and %ld\n", |
---|
| 577 | pos, pos+check_limit); |
---|
| 578 | /* |
---|
| 579 | * |
---|
| 580 | * A.3 ENDFOR !Outer Loop, stay until Status changes |
---|
| 581 | */ |
---|
| 582 | } /* check entire file */ |
---|
| 583 | |
---|
| 584 | |
---|
| 585 | |
---|
| 586 | DONE: |
---|
| 587 | |
---|
| 588 | /* |
---|
| 589 | * |
---|
| 590 | * A.5 IF (found a msg) THEN |
---|
| 591 | * BUMP caller's Offset to absolute Begining of Msg found; |
---|
| 592 | * DEBUG Print |
---|
| 593 | * ENDIF |
---|
| 594 | */ |
---|
| 595 | if (gotone) |
---|
| 596 | { |
---|
| 597 | *offset = (long)(pos+bytenum); /* bump offset to abs. beg. of Msg */ |
---|
| 598 | DPRINT3 ("Exiting %s w/stat=%d, offs=%d, msg in GRIB_HDR\n", |
---|
| 599 | func, status, *offset); |
---|
| 600 | } |
---|
| 601 | else DPRINT2 ("Exiting %s w/stat=%d, no messages\n", func, status); |
---|
| 602 | |
---|
| 603 | /* |
---|
| 604 | * A.6 RETURN with status |
---|
| 605 | */ |
---|
| 606 | return (status); |
---|
| 607 | /* |
---|
| 608 | * |
---|
| 609 | * END OF FUNCTION |
---|
| 610 | * |
---|
| 611 | */ |
---|
| 612 | } |
---|