NCEPLIBS-bufr 11.7.1
readerme.f
Go to the documentation of this file.
1C> @file
2C> @brief Read a BUFR message from a memory array.
3
4C> This subroutine is similar to subroutine readmg(), except that it
5C> reads a BUFR message from an array already in memory, whereas
6C> readmg() reads a BUFR message from a file on the local system.
7C>
8C> @authors J. Woollen
9C> @authors J. Ator
10C> @date 1995-06-28
11C>
12C> @param[in] MESG -- integer(*): BUFR message
13C> @param[in] LUNIT -- integer: Fortran logical unit number for
14C> BUFR file
15C> @param[out] SUBSET -- character*8: Table A mnemonic for type of BUFR
16C> message that was read
17C> (see [DX BUFR Tables](@ref dfbftab)
18C> for further information about Table A mnemonics)
19C> @param[out] JDATE -- integer: Date-time stored within Section 1 of
20C> BUFR message that was read, in format of either
21C> YYMMDDHH or YYYYMMDDHH, depending on the most
22C> recent call to subroutine datelen()
23C> @param[out] IRET -- integer: return code
24C> - 0 = MESG was successfully read
25C> - 11 = MESG contained a DX BUFR table message
26C> - -1 = MESG contained an unrecognized
27C> Table A message type
28C>
29C> <p>This subroutine looks and behaves a lot like subroutine readmg()
30C> except that here we have one additional input argument MESG which
31C> contains the BUFR message to be read by the BUFRLIB software.
32C> As such, this subroutine can be used in any context in which readmg()
33C> might otherwise be used, and from that point on, the application
34C> program can proceed with a call to one of the
35C> [subset-reading subroutines](@ref hierarchy) (and then,
36C> subsequently, to any of the
37C> [values-reading subroutines](@ref hierarchy)), just
38C> like if readmg() had been called instead.
39C>
40C> <p>When using this subroutine, it's still necessary for the
41C> application program to have previously called subroutine openbf() in
42C> order to associate a DX BUFR tables file with the messages that are
43C> being input via MESG, and it's still also necessary to pass in the
44C> relevant LUNIT value as a call argument, even though in this case
45C> the subroutine will not actually try to read from the associated
46C> Fortran logical unit.
47C>
48C> <p>If MESG contains a DX BUFR table message, the subroutine will
49C> store the contents internally and use them to process any
50C> future BUFR messages associated with LUNIT. In this case, the
51C> subroutine will return with IRET = 11, and any number of
52C> DX BUFR table messages passed in via consecutive calls to this
53C> subroutine will accumulate internally and be treated as a single DX
54C> BUFR table, up until a call is made where MESG no longer contains a
55C> DX BUFR table message.
56C>
57C> <b>Program history log:</b>
58C> | Date | Programmer | Comments |
59C> | -----|------------|----------|
60C> | 1995-06-28 | J. Woollen | Original author |
61C> | 1997-07-29 | J. Woollen | Modified to process GOES soundings from NESDIS |
62C> | 1998-07-08 | J. Woollen | Replaced call to Cray library routine "ABORT" with call to new internal routine bort(); modified to make Y2K compliant; improved machine portability |
63C> | 1999-11-18 | J. Woollen | The number of BUFR files which can be opened at one time increased from 10 to 32; increased the maximum number of possible descriptors in a subset from 1000 to 3000 |
64C> | 2000-09-19 | J. Woollen | Removed logic that had been replicated in this and other read routines and consolidated it into a new routine cktaba(); maximum message length increased from 10,000 to 20,000 bytes |
65C> | 2003-11-04 | S. Bender | Added remarks and routine interdependencies |
66C> | 2003-11-04 | D. Keyser | Unified/portable for WRF; added documentation; outputs more complete diagnostic info when routine terminates abnormally |
67C> | 2004-08-18 | J. Ator | Modified 'BUFR' string test for portability to EBCDIC machines; maximum message length increased from 20,000 to 50,000 bytes |
68C> | 2005-11-29 | J. Ator | Use ichkstr() |
69C> | 2009-03-23 | D. Keyser | Call bort() in case of MBAY overflow |
70C> | 2009-03-23 | J. Ator | Add logic to allow Section 3 decoding; add logic to process dictionary messages |
71C> | 2012-06-07 | J. Ator | Don't respond to DX table messages if Section 3 decoding is being used |
72C> | 2014-12-10 | J. Ator | Use modules instead of COMMON blocks |
73C>
74 SUBROUTINE readerme(MESG,LUNIT,SUBSET,JDATE,IRET)
75
76 USE modv_mxmsgl
77
78 USE moda_sc3bfr
79 USE moda_idrdm
80 USE moda_bitbuf
81
82 COMMON /hrdwrd/ nbytw,nbitw,iord(8)
83 COMMON /quiet/ iprt
84
85 CHARACTER*128 BORT_STR,ERRSTR
86 CHARACTER*8 SUBSET,SEC0
87 CHARACTER*1 CEC0(8)
88
89 dimension mesg(*),iec0(2)
90
91 LOGICAL ENDTBL
92
93 equivalence(sec0,iec0,cec0)
94
95C-----------------------------------------------------------------------
96C-----------------------------------------------------------------------
97
98 iret = 0
99
100C CHECK THE FILE STATUS
101C ---------------------
102
103 CALL status(lunit,lun,il,im)
104 IF(il.EQ.0) GOTO 900
105 IF(il.GT.0) GOTO 901
106 CALL wtstat(lunit,lun,il, 1)
107
108C COPY THE INPUT MESSAGE INTO THE INTERNAL MESSAGE BUFFER
109C -------------------------------------------------------
110
111 iec0(1) = mesg(1)
112 iec0(2) = mesg(2)
113 lnmsg = lmsg(sec0)
114 IF(lnmsg*nbytw.GT.mxmsgl) GOTO 902
115 DO i=1,lnmsg
116 mbay(i,lun) = mesg(i)
117 ENDDO
118
119C Confirm that the first 4 bytes of SEC0 contain 'BUFR' encoded in
120C CCITT IA5 (i.e. ASCII).
121
122 IF(ichkstr('BUFR',cec0,4).NE.0) GOTO 903
123
124C PARSE THE MESSAGE SECTION CONTENTS
125C ----------------------------------
126
127 IF(isc3(lun).NE.0) CALL reads3(lun)
128
129 CALL cktaba(lun,subset,jdate,iret)
130
131 IF(isc3(lun).NE.0) RETURN
132
133C CHECK FOR A DX DICTIONARY MESSAGE
134C ---------------------------------
135
136C A new DX dictionary table can be passed in as a consecutive set of
137C DX dictionary messages. Each message should be passed in one at a
138C time, via input argument MESG during consecutive calls to this
139C subroutine, and will be processed as a single dictionary table up
140C until the next message is passed in which either contains no data
141C subsets or else is a non-DX dictionary message.
142
143 endtbl = .false.
144
145 IF(idxmsg(mbay(1,lun)).EQ.1) THEN
146
147C This is a DX dictionary message that was generated by the
148C BUFRLIB archive library software.
149
150 IF(iupbs3(mbay(1,lun),'NSUB').EQ.0) THEN
151
152C But it doesn't contain any actual dictionary information, so
153C assume we've reached the end of the dictionary table.
154
155 IF(idrdm(lun).GT.0) THEN
156 endtbl = .true.
157 ENDIF
158 ELSE
159 IF(idrdm(lun).EQ.0) THEN
160
161C This is the first DX dictionary message that is part of a
162C new dictionary table.
163
164 CALL dxinit(lun,0)
165 ENDIF
166 idrdm(lun) = idrdm(lun) + 1
167 CALL stbfdx(lun,mbay(1,lun))
168 ENDIF
169 ELSE IF(idrdm(lun).GT.0) THEN
170
171C This is the first non-DX dictionary message received following a
172C string of DX dictionary messages, so assume we've reached the
173C end of the dictionary table.
174
175 endtbl = .true.
176 ENDIF
177
178 IF(endtbl) THEN
179 IF ( iprt .GE. 2 ) THEN
180 CALL errwrt('+++++++++++++++++++++++++++++++++++++++++++++++++')
181 WRITE ( unit=errstr, fmt='(A,I3,A)' )
182 . 'BUFRLIB: READERME - STORED NEW DX TABLE CONSISTING OF (',
183 . idrdm(lun), ') MESSAGES;'
184 CALL errwrt(errstr)
185 errstr = 'WILL APPLY THIS TABLE TO ALL SUBSEQUENT DATA '//
186 . 'MESSAGES UNTIL NEXT DX TABLE IS PASSED IN'
187 CALL errwrt(errstr)
188 CALL errwrt('+++++++++++++++++++++++++++++++++++++++++++++++++')
189 CALL errwrt(' ')
190 ENDIF
191 idrdm(lun) = 0
192 CALL makestab
193 ENDIF
194
195C EXITS
196C -----
197
198 RETURN
199900 CALL bort('BUFRLIB: READERME - INPUT BUFR FILE IS CLOSED, IT '//
200 . 'MUST BE OPEN FOR INPUT')
201901 CALL bort('BUFRLIB: READERME - INPUT BUFR FILE IS OPEN FOR '//
202 . 'OUTPUT, IT MUST BE OPEN FOR INPUT')
203902 WRITE(bort_str,'("BUFRLIB: READERME - INPUT BUFR MESSAGE LENGTH",
204 . 1X,I6," BYTES) IS LARGER THAN LIMIT OF ",I6," BYTES")')
205 . lnmsg*nbytw,mxmsgl
206 CALL bort(bort_str)
207903 CALL bort('BUFRLIB: READERME - FIRST 4 BYTES READ FROM RECORD'//
208 . ' NOT "BUFR", DOES NOT CONTAIN BUFR DATA')
209 END
subroutine bort(STR)
This subroutine calls subroutine errwrt() to log an error message, then calls subroutine bort_exit() ...
Definition: bort.f:23
subroutine cktaba(LUN, SUBSET, JDATE, IRET)
THIS SUBROUTINE PARSES THE TABLE A MNEMONIC AND THE DATE OUT OF SECTION 1 OF A BUFR MESSAGE PREVIOUSL...
Definition: cktaba.f:76
subroutine dxinit(LUN, IOI)
THIS SUBROUTINE INITIALIZES THE INTERNAL ARRAYS (IN MODULE TABABD) HOLDING THE DICTIONARY TABLE.
Definition: dxinit.f:41
subroutine errwrt(STR)
This subroutine allows the user to specify a custom location for the logging of error and diagnostic ...
Definition: errwrt.f:42
function ichkstr(STR, CHR, N)
THIS FUNCTION COMPARES A SPECIFIED NUMBER OF CHARACTERS FROM AN INPUT CHARACTER ARRAY AGAINST THE SAM...
Definition: ichkstr.f:33
function idxmsg(MESG)
This function determines whether a given BUFR message contains DX BUFR tables information that was ge...
Definition: idxmsg.f:24
function iupbs3(MBAY, S3MNEM)
This function returns a specified value from within Section 3 of a BUFR message.
Definition: iupbs3.f:35
function lmsg(SEC0)
GIVEN A CHARACTER STRING CONTAINING SECTION ZERO FROM A BUFR MESSAGE, THIS FUNCTION DETERMINES A COUN...
Definition: lmsg.f:32
subroutine makestab
THIS SUBROUTINE CONSTRUCTS AN INTERNAL JUMP/LINK TABLE WITHIN MODULE TABLES, USING THE INFORMATION WI...
Definition: makestab.f:75
This module contains array and variable declarations used to store BUFR messages internally for multi...
Definition: moda_bitbuf.F:10
integer, dimension(:,:), allocatable mbay
Current BUFR message for each internal I/O stream.
Definition: moda_bitbuf.F:26
This module declares and initializes the MXMSGL variable.
Definition: modv_MXMSGL.f:13
integer mxmsgl
Maximum length (in bytes) of a BUFR message that can be read or written by the BUFRLIB software.
Definition: modv_MXMSGL.f:22
subroutine readerme(MESG, LUNIT, SUBSET, JDATE, IRET)
This subroutine is similar to subroutine readmg(), except that it reads a BUFR message from an array ...
Definition: readerme.f:75
subroutine reads3(LUN)
THIS SUBROUTINE READS THE SECTION 3 DESCRIPTORS FROM THE BUFR MESSAGE IN MBAY(1,LUN).
Definition: reads3.f:31
subroutine status(LUNIT, LUN, IL, IM)
This subroutine checks whether a specified Fortran logical unit number is currently connected to the ...
Definition: status.f:56
subroutine stbfdx(LUN, MESG)
THIS SUBROUTINE COPIES A BUFR TABLE (DICTIONARY) MESSAGE FROM THE INPUT ARRAY MESG INTO THE INTERNAL ...
Definition: stbfdx.f:29
subroutine wtstat(LUNIT, LUN, IL, IM)
This subroutine can be used to connect or disconnect a specified Fortran logical unit number to/from ...
Definition: wtstat.f:53