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 | } |
---|