1 /*$$$ SUBPROGRAM DOCUMENTATION BLOCK
4 C PRGMMR: ATOR ORG: NP12 DATE: 2005-11-29
6 C ABSTRACT: THIS ROUTINE READS THE NEXT BUFR MESSAGE FROM THE SYSTEM
7 C FILE MOST RECENTLY OPENED FOR READING/INPUT VIA BUFR ARCHIVE LIBRARY
8 C ROUTINE COBFL. ANY BUFR EDITION 0 OR EDITION 1 MESSAGES THAT ARE
9 C READ ARE AUTOMATICALLY CONVERTED TO BUFR EDITION 2.
11 C PROGRAM HISTORY LOG:
12 C 2005-11-29 J. ATOR -- ORIGINAL AUTHOR
14 C USAGE: CALL CRBMG( BMG, MXMB, NMB, IRET )
15 C INPUT ARGUMENT LIST:
16 C MXMB - INTEGER: DIMENSIONED SIZE (IN BYTES) OF BMG; USED
17 C BY THE ROUTINE TO ENSURE THAT IT DOES NOT OVERFLOW
20 C OUTPUT ARGUMENT LIST:
21 C BMG - CHARACTER*1: ARRAY CONTAINING BUFR MESSAGE
22 C NMB - INTEGER: SIZE (IN BYTES) OF BUFR MESSAGE IN BMG
23 C IRET - INTEGER: RETURN CODE:
25 C 1 = overflow of BMG array
26 C 2 = "7777" indicator not found in expected location
27 C -1 = end-of-file encountered while reading
28 C -2 = I/O error encountered while reading
31 C THIS ROUTINE CALLS: BORT GETS1LOC ICHKSTR IPKM
33 C THIS ROUTINE IS CALLED BY: None
34 C Normally called only by application
39 C MACHINE: PORTABLE TO ALL PLATFORMS
45 void crbmg( char *bmg
, f77int
*mxmb
, f77int
*nmb
, f77int
*iret
)
47 f77int i1
= 1, i2
= 2, i3
= 3, i4
= 4, i24
= 24;
49 f77int iben
, isbyt
, iwid
;
53 unsigned short i
, nsecs
;
56 ** Make sure that a file is open for reading.
58 if ( pbf
[0] == NULL
) {
59 sprintf( errstr
, "BUFRLIB: CRBMG - NO FILE IS OPEN FOR READING" );
60 bort( errstr
, ( f77int
) strlen( errstr
) );
63 ** Initialize the first 4 characters of the output array to blanks.
69 strncpy( bmg
, " ", 4);
71 ** Look for the start of the next BUFR message.
73 while ( ichkstr( "BUFR", bmg
, &i4
, 4, 4 ) != 0 ) {
74 memmove( bmg
, &bmg
[1], 3 );
75 if ( ( *iret
= rbytes( bmg
, mxmb
, 3, 1 ) ) != 0 ) return;
78 ** Read the next 4 bytes and determine the BUFR edition number that was used
79 ** to encode the message.
81 if ( ( *iret
= rbytes( bmg
, mxmb
, 4, 4 ) ) != 0 ) return;
82 memcpy( wkint
, bmg
, 8 );
83 iben
= iupbs01( wkint
, "BEN", 3 );
87 ** Get the length of the BUFR message.
89 *nmb
= iupbs01( wkint
, "LENM", 4 );
91 ** Read the remainder of the BUFR message.
93 if ( ( *iret
= rbytes( bmg
, mxmb
, 8, *nmb
-8 ) ) != 0 ) return;
97 ** Read the remainder of the BUFR message and then convert it to BUFR
98 ** edition 2. The message length isn't encoded in Section 0, so we need
99 ** to compute it by unpacking and summing the lengths of the individual
102 lsec
= 4; /* length of Section 0 */
104 ** Get the length of Section 1 and add it to the total.
106 gets1loc( "LEN1", &iben
, &isbyt
, &iwid
, &wkint
[0], 4 );
107 *nmb
= lsec
+ iupm( &bmg
[lsec
+isbyt
-1], &iwid
, 3 );
109 ** Read up through the end of Section 1.
111 if ( ( *iret
= rbytes( bmg
, mxmb
, 8, *nmb
-8 ) ) != 0 ) return;
113 ** Is there a Section 2?
115 gets1loc( "ISC2", &iben
, &isbyt
, &iwid
, &wkint
[0], 4 );
116 nsecs
= iupm( &bmg
[lsec
+isbyt
-1], &iwid
, 1 ) + 2;
118 ** Read up through the end of Section 4.
120 for ( i
= 1; i
<= nsecs
; i
++ ) {
121 if ( ( *iret
= rbytes( bmg
, mxmb
, *nmb
, 3 ) ) != 0 ) return;
122 lsec
= iupm( &bmg
[*nmb
], &i24
, 3 );
123 if ( ( *iret
= rbytes( bmg
, mxmb
, *nmb
+3, lsec
-3 ) ) != 0 ) return;
129 if ( ( *iret
= rbytes( bmg
, mxmb
, *nmb
, 4 ) ) != 0 ) return;
132 ** Expand Section 0 from 4 bytes to 8 bytes, then encode the message length
133 ** and new edition number (i.e. 2) into the new (expanded) Section 0.
135 if ( *nmb
+ 4 > *mxmb
) {
139 memmove( &bmg
[8], &bmg
[4], *nmb
-4 );
141 ipkm( &bmg
[4], &i3
, nmb
, 3 );
142 ipkm( &bmg
[7], &i1
, &i2
, 1 );
145 ** Check that the "7777" is in the expected location.
147 *iret
= ( ( ichkstr( "7777", &bmg
[*nmb
-4], &i4
, 4, 4 ) == 0 ) ? 0 : 2 );