!*************************************************************************************************** !* ut_get_bufrmg * !* * !* Given a string of characters and a starting pointer within that string, this routine finds the * !* next BUFR message in the string. * !* * !* ut_get_bufrmg( bull, lenb, ibptr, fbyt, msglen, mtyp, msbti, mxdesc, cdesc, ndesc, iret ) * !* * !* Input parameters: * !* bultn character*(*) String. * !* lenb integer Length of bultn. * !* mxdesc integer Dimensioned size of cdesc. * !* * !* Input and output parameter: * !* ibptr integer On input, pointer within bultn at which to start searching for next * !* BUFR message. On output, pointer within bultn to last byte of found * !* BUFR message. * !* * !* Output parameters: * !* ifbyt integer Pointer within bultn to first byte of found BUFR message. * !* msglen integer Length of BUFR message. * !* mtyp integer Type of BUFR message. * !* msbti integer Standard subtype of BUFR message. * !* cdesc character*6(*) Data descriptors in BUFR message. * !* ndesc integer Number of data descriptors in cdsec. * !* iret integer Return code: * !* 0 = normal return * !* -1 = no BUFR message was found * !** * !* Log: * !* J. Ator/NCEP 06/23 * !*************************************************************************************************** subroutine ut_get_bufrmg( bultn, lenb, ibptr, ifbyt, msglen, mtyp, msbti, mxdesc, cdesc, ndesc, iret ) implicit none character*(*), intent(in) :: bultn character*6, intent(out) :: cdesc(*) integer, intent(in) :: lenb, mxdesc integer, intent(inout) :: ibptr integer, intent(out) :: ifbyt, msglen, mtyp, msbti, ndesc, iret integer :: ipt, n2cpy, ls0, ls1, ls2, ls3, ls4, ls5 integer*4 :: iupbs01 integer, parameter :: mx2cpy = 2000 character :: cbull*(mx2cpy) integer ibull(mx2cpy/4) equivalence ( cbull(1:4), ibull(1) ) iret = -1 do while ( iret == -1 ) ! Look for the start of the next BUFR message. if ( ibptr > lenb ) return ipt = index( bultn (ibptr:lenb), 'BUFR' ) if ( ipt == 0 ) return ifbyt = ibptr + ipt - 1 ! Get the length of the BUFR message. if ( (ifbyt+7) > lenb ) return cbull(1:8) = bultn( ifbyt : ifbyt+7 ) msglen = iupbs01( ibull, 'LENM' ) ! Set the pointer to the last byte of the message. ibptr = ifbyt + msglen - 1 if ( ibptr > lenb ) then call errwrt( 'ERROR: BUFR message length exceeds specified string length' ) return endif ! Don't immediately return if any remaining checks fail. Instead, cycle back to the top of ! the loop and search for another BUFR message further along in the string. ! Check that the end-of-message indicator is in the expected place. if ( bultn( ibptr-3 : ibptr ) /= '7777' ) then call errwrt( 'ERROR: unable to locate 7777 indicator in BUFR message' ) cycle endif ! Copy the minimum number of bytes necessary from the message into a local array, in order to ! check the section lengths and read the data descriptors. n2cpy = min( ((mxdesc*2)+200), mx2cpy, msglen ) cbull(1:n2cpy) = bultn( ifbyt : ifbyt+n2cpy-1 ) ! Check the section lengths. call getlens( ibull, 5, ls0, ls1, ls2, ls3, ls4, ls5 ) if ( ( ls0 + ls1 + ls2 + ls3 + ls4 + ls5 ) /= msglen ) then call errwrt( 'ERROR: BUFR message failed section lengths check' ) cycle endif ! Unpack the data descriptors. if ( ls3 > ((mxdesc*2)+7) ) then call errwrt( 'ERROR: number of data descriptors in BUFR message exceeds specified maximum' ) cycle endif call upds3( ibull, mxdesc, cdesc, ndesc ) ! Get the message type and standard (international) subtype. mtyp = iupbs01( ibull, 'MTYP' ) msbti = iupbs01( ibull, 'MSBTI' ) iret = 0 enddo end subroutine ut_get_bufrmg