<HTML> <BODY BGCOLOR=#ccccdd LINK=#0000aa VLINK=#0000ff ALINK=#ff0000 ><BASE TARGET="bottom_target"><PRE>
/*$$$ SUBPROGRAM DOCUMENTATION BLOCK
C
C SUBPROGRAM: CRBMG
C PRGMMR: ATOR ORG: NP12 DATE: 2005-11-29
C
C ABSTRACT: THIS ROUTINE READS THE NEXT BUFR MESSAGE FROM THE SYSTEM
C FILE MOST RECENTLY OPENED FOR READING/INPUT VIA BUFR ARCHIVE LIBRARY
C ROUTINE COBFL. ANY BUFR EDITION 0 OR EDITION 1 MESSAGES THAT ARE
C READ ARE AUTOMATICALLY CONVERTED TO BUFR EDITION 2.
C
C PROGRAM HISTORY LOG:
C 2005-11-29 J. ATOR -- ORIGINAL AUTHOR
C
C USAGE: CALL CRBMG( BMG, MXMB, NMB, IRET )
C INPUT ARGUMENT LIST:
C MXMB - INTEGER: DIMENSIONED SIZE (IN BYTES) OF BMG; USED
C BY THE ROUTINE TO ENSURE THAT IT DOES NOT OVERFLOW
C THE BMG ARRAY
C
C OUTPUT ARGUMENT LIST:
C BMG - CHARACTER*1: ARRAY CONTAINING BUFR MESSAGE
C NMB - INTEGER: SIZE (IN BYTES) OF BUFR MESSAGE IN BMG
C IRET - INTEGER: RETURN CODE:
C 0 = normal return
C 1 = overflow of BMG array
C 2 = "7777" indicator not found in expected location
C -1 = end-of-file encountered while reading
C -2 = I/O error encountered while reading
C
C REMARKS:
C THIS ROUTINE CALLS: BORT GETS1LOC ICHKSTR IPKM
C IUPBS01 IUPM RBYTES
C THIS ROUTINE IS CALLED BY: None
C Normally called only by application
C programs.
C
C ATTRIBUTES:
C LANGUAGE: C
C MACHINE: PORTABLE TO ALL PLATFORMS
C
C$$$*/
#include "bufrlib.h"
void crbmg( char *bmg, f77int *mxmb, f77int *nmb, f77int *iret )
{
f77int i1 = 1, i2 = 2, i3 = 3, i4 = 4, i24 = 24;
f77int wkint[2];
f77int iben, isbyt, iwid;
char errstr[129];
unsigned short i, nsecs;
unsigned int lsec;
/*
** Make sure that a file is open for reading.
*/
if ( pbf[0] == NULL ) {
sprintf( errstr, "BUFRLIB: CRBMG - NO FILE IS OPEN FOR READING" );
bort( errstr, ( f77int ) strlen( errstr ) );
}
/*
** Initialize the first 4 characters of the output array to blanks.
*/
if ( *mxmb < 4 ) {
*iret = 1;
return;
}
strncpy( bmg, " ", 4);
/*
** Look for the start of the next BUFR message.
*/
while ( ichkstr( "BUFR", bmg, &i4, 4, 4 ) != 0 ) {
memmove( bmg, &bmg[1], 3 );
if ( ( *iret = rbytes( bmg, mxmb, 3, 1 ) ) != 0 ) return;
}
/*
** Read the next 4 bytes and determine the BUFR edition number that was used
** to encode the message.
*/
if ( ( *iret = rbytes( bmg, mxmb, 4, 4 ) ) != 0 ) return;
memcpy( wkint, bmg, 8 );
iben = iupbs01
( wkint, "BEN", 3 );
if ( iben >= 2 ) {
/*
** Get the length of the BUFR message.
*/
*nmb = iupbs01
( wkint, "LENM", 4 );
/*
** Read the remainder of the BUFR message.
*/
if ( ( *iret = rbytes( bmg, mxmb, 8, *nmb-8 ) ) != 0 ) return;
}
else {
/*
** Read the remainder of the BUFR message and then convert it to BUFR
** edition 2. The message length isn't encoded in Section 0, so we need
** to compute it by unpacking and summing the lengths of the individual
** sections.
*/
lsec = 4; /* length of Section 0 */
/*
** Get the length of Section 1 and add it to the total.
*/
gets1loc( "LEN1", &iben, &isbyt, &iwid, &wkint[0], 4 );
*nmb = lsec + iupm( &bmg[lsec+isbyt-1], &iwid, 3 );
/*
** Read up through the end of Section 1.
*/
if ( ( *iret = rbytes( bmg, mxmb, 8, *nmb-8 ) ) != 0 ) return;
/*
** Is there a Section 2?
*/
gets1loc( "ISC2", &iben, &isbyt, &iwid, &wkint[0], 4 );
nsecs = iupm
( &bmg[lsec+isbyt-1], &iwid, 1 ) + 2;
/*
** Read up through the end of Section 4.
*/
for ( i = 1; i <= nsecs; i++ ) {
if ( ( *iret = rbytes( bmg, mxmb, *nmb, 3 ) ) != 0 ) return;
lsec = iupm
( &bmg[*nmb], &i24, 3 );
if ( ( *iret = rbytes( bmg, mxmb, *nmb+3, lsec-3 ) ) != 0 ) return;
*nmb += lsec;
}
/*
** Read Section 5.
*/
if ( ( *iret = rbytes( bmg, mxmb, *nmb, 4 ) ) != 0 ) return;
*nmb += 4;
/*
** Expand Section 0 from 4 bytes to 8 bytes, then encode the message length
** and new edition number (i.e. 2) into the new (expanded) Section 0.
*/
if ( *nmb + 4 > *mxmb ) {
*iret = 1;
return;
}
memmove( &bmg[8], &bmg[4], *nmb-4 );
*nmb += 4;
ipkm( &bmg[4], &i3, nmb, 3 );
ipkm( &bmg[7], &i1, &i2, 1 );
}
/*
** Check that the "7777" is in the expected location.
*/
*iret = ( ( ichkstr( "7777", &bmg[*nmb-4], &i4, 4, 4 ) == 0 ) ? 0 : 2 );
return;
}