NCEPLIBS-bufr 11.7.1
ufbmem.f
Go to the documentation of this file.
1C> @file
2C> @brief Connect a new system file to the BUFRLIB software, and read
3C> the entire file contents into internal arrays.
4
5C> This subroutine connects a new system file to the BUFRLIB software
6C> for input operations, then reads the entire file contents into
7C> internal arrays so that any of the individual BUFR messages can
8C> later be accessed from memory, instead of having to read them one
9C> at a time sequentially from the system file.
10C>
11C> <p>Any embedded DX BUFR tables contained within the file are also
12C> read and processed into separate internal arrays for later use.
13C>
14C> @author J. Woollen
15C> @date 1994-01-06
16C>
17C> @param[in] LUNIT -- integer: Fortran logical unit number for BUFR
18C> file
19C> @param[in] INEW -- integer: Processing option
20C> - 0 = Initialize the internal arrays, then
21C> read all BUFR messages from LUNIT into
22C> internal arrays
23C> - Otherwise, read all BUFR messages from LUNIT
24C> and append them to the existing messages
25C> within the internal arrays
26C> @param[out] IRET -- integer: Number of BUFR messages that were
27C> read from LUNIT and stored into internal arrays
28C> @param[out] IUNIT -- integer: File status
29C> - 0 = LUNIT was empty, so no messages were read
30C> - Otherwise, the Fortran logical unit number to
31C> use for later access to any of the messages
32C> from the internal arrays
33C>
34C> <p>Logical unit number LUNIT must already be associated with an
35C> actual filename on the local system, typically via a Fortran "OPEN"
36C> statement.
37C>
38C> <p>When INEW = 0, the output value IUNIT will be set equal to the
39C> input value LUNIT. Otherwise, the output value IUNIT will be set to
40C> the value of LUNIT that was input when this subroutine was previously
41C> called with INEW = 0, and the system file connected to LUNIT will be
42C> closed via an internal call to subroutine closbf() before exiting
43C> this subroutine. In either case, IUNIT can now be used to access
44C> all BUFR messages that were read and stored by all previous calls
45C> to this subroutine.
46C>
47C> <b>Program history log:</b>
48C> | Date | Programmer | Comments |
49C> | -----|------------|----------|
50C> | 1994-01-06 | J. Woollen | Original author |
51C> | 1998-07-08 | J. Woollen | Replaced call to Cray library routine ABORT with call to new internal routine bort() |
52C> | 1999-11-18 | J. Woollen | Increased MAXMEM from 4 Mb to 8 Mb |
53C> | 2000-09-19 | J. Woollen | Maximum message length increased from 10,000 to 20,000 bytes |
54C> | 2001-08-15 | D. Keyser | Increased MAXMEM from 8 Mb to 16 Mb |
55C> | 2003-11-04 | S. Bender | Added remarks and routine interdependencies |
56C> | 2003-11-04 | D. Keyser | Unified/portable for WRF; added documentation; outputs more complete diagnostic info when routine terminates abnormally; increased MAXMSG from 50000 to 200000 |
57C> | 2004-08-09 | J. Ator | Maximum message length increased from 20,000 to 50,000 bytes |
58C> | 2004-11-15 | D. Keyser | Don't abort when there are either MAXMSG or MAXMEM is exceeded; instead, just store up to MAXMSG messages or MAXMEM bytes and print a diagnostic |
59C> | 2005-11-29 | J. Ator | Use rdmsgw() and nmwrd() |
60C> | 2009-03-23 | J. Ator | Modified to handle embedded DX tables |
61C> | 2012-09-15 | J. Woollen | Modified for C/I/O/BUFR interface; call status() to get LUN; replace Fortran REWIND and BACKSPACE with C routines cewind() and backbufr() |
62C> | 2014-12-10 | J. Ator | Use modules instead of COMMON blocks |
63C> | 2015-09-24 | D. Stokes | Fix missing declaration of COMMON /QUIET/ |
64C>
65 SUBROUTINE ufbmem(LUNIT,INEW,IRET,IUNIT)
66
67 USE modv_maxmem
68 USE modv_maxmsg
69
70 USE moda_mgwa
71 USE moda_msgmem
72
73 COMMON /quiet / iprt
74
75 CHARACTER*128 BORT_STR,ERRSTR
76
77C-----------------------------------------------------------------------
78C-----------------------------------------------------------------------
79
80C TRY TO OPEN BUFR FILE AND SET TO INITIALIZE OR CONCATENATE
81C ----------------------------------------------------------
82
83 CALL openbf(lunit,'IN',lunit)
84
85 IF(inew.EQ.0) THEN
86 msgp(0) = 0
87 munit = 0
88 mlast = 0
89 ndxts = 0
90 ldxts = 0
91 ndxm = 0
92 ldxm = 0
93 ENDIF
94
95 nmsg = msgp(0)
96 iret = 0
97 iflg = 0
98 itim = 0
99
100C Copy any BUFR dictionary table messages from the beginning of
101C LUNIT into MODULE MSGMEM for possible later use. Note that
102C such a table (if one exists) is already now in scope due to the
103C prior call to subroutine OPENBF, which in turn would have
104C automatically called subroutines READDX, RDBFDX and MAKESTAB
105C for this table.
106
107 itemp = ndxts
108 CALL status(lunit,lun,il,im)
109 CALL cewind(lun)
110 CALL cpdxmm(lunit)
111
112C If a table was indeed present at the beginning of the file,
113C then set the flag to indicate that this table is now in scope.
114
115 IF ((itemp+1).EQ.ndxts) ldxts = ndxts
116
117C TRANSFER MESSAGES FROM FILE TO MEMORY - SET MESSAGE POINTERS
118C ------------------------------------------------------------
119
1201 CALL rdmsgw(lunit,mgwa,ier)
121 IF(ier.EQ.-1) GOTO 100
122 IF(ier.EQ.-2) GOTO 900
123
124 IF(idxmsg(mgwa).EQ.1) THEN
125
126C New "embedded" BUFR dictionary table messages have been found in
127C this file. Copy them into MODULE MSGMEM for later use.
128
129 CALL backbufr(lun) !BACKSPACE LUNIT
130 CALL cpdxmm(lunit)
131 GOTO 1
132 ENDIF
133
134 nmsg = nmsg+1
135 IF(nmsg .GT.maxmsg) iflg = 1
136 lmem = nmwrd(mgwa)
137 IF(lmem+mlast.GT.maxmem) iflg = 2
138
139 IF(iflg.EQ.0) THEN
140 iret = iret+1
141 DO i=1,lmem
142 msgs(mlast+i) = mgwa(i)
143 ENDDO
144 msgp(0) = nmsg
145 msgp(nmsg) = mlast+1
146 ELSE
147 IF(itim.EQ.0) THEN
148 mlast0 = mlast
149 itim=1
150 ENDIF
151 ENDIF
152 mlast = mlast+lmem
153 GOTO 1
154
155C EXITS
156C -----
157
158100 IF(iflg.EQ.1) THEN
159
160C EMERGENCY ROOM TREATMENT FOR MAXMSG ARRAY OVERFLOW
161C --------------------------------------------------
162
163 IF(iprt.GE.0) THEN
164 CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
165 WRITE ( unit=errstr, fmt='(A,A,I8,A)' )
166 . 'BUFRLIB: UFBMEM - THE NO. OF MESSAGES REQUIRED TO STORE ',
167 . 'ALL MESSAGES INTERNALLY EXCEEDS MAXIMUM (', maxmsg,
168 . ') - INCOMPLETE READ'
169 CALL errwrt(errstr)
170 WRITE ( unit=errstr, fmt='(A,I8,A,I8,A)' )
171 . '>>>UFBMEM STORED ', msgp(0), ' MESSAGES OUT OF ', nmsg, '<<<'
172 CALL errwrt(errstr)
173 WRITE ( unit=errstr, fmt='(A,I8,A,I8,A)' )
174 . '>>>UFBMEM STORED ', mlast0, ' BYTES OUT OF ', mlast, '<<<'
175 CALL errwrt(errstr)
176 CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
177 CALL errwrt(' ')
178 ENDIF
179 mlast=mlast0
180 ENDIF
181
182 IF(iflg.EQ.2) THEN
183
184C EMERGENCY ROOM TREATMENT FOR MAXMEM ARRAY OVERFLOW
185C --------------------------------------------------
186
187 IF(iprt.GE.0) THEN
188 CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
189 WRITE ( unit=errstr, fmt='(A,A,I8,A)' )
190 . 'BUFRLIB: UFBMEM - THE NO. OF BYTES REQUIRED TO STORE ',
191 . 'ALL MESSAGES INTERNALLY EXCEEDS MAXIMUM (', maxmem,
192 . ') - INCOMPLETE READ'
193 CALL errwrt(errstr)
194 WRITE ( unit=errstr, fmt='(A,I8,A,I8,A)' )
195 . '>>>UFBMEM STORED ', mlast0, ' BYTES OUT OF ', mlast, '<<<'
196 CALL errwrt(errstr)
197 WRITE ( unit=errstr, fmt='(A,I8,A,I8,A)' )
198 . '>>>UFBMEM STORED ', msgp(0), ' MESSAGES OUT OF ', nmsg, '<<<'
199 CALL errwrt(errstr)
200 CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
201 CALL errwrt(' ')
202 ENDIF
203 mlast=mlast0
204 ENDIF
205
206 IF(iret.EQ.0) THEN
207 CALL closbf(lunit)
208 ELSE
209 IF(munit.NE.0) CALL closbf(lunit)
210 IF(munit.EQ.0) munit = lunit
211 ENDIF
212 iunit = munit
213
214C EXITS
215C -----
216
217 RETURN
218900 WRITE(bort_str,'("BUFRLIB: UFBMEM - ERROR READING MESSAGE '//
219 . 'NUMBER",I5," INTO MEMORY FROM UNIT",I3)') nmsg+1,lunit
220 CALL bort(bort_str)
221 END
subroutine bort(STR)
This subroutine calls subroutine errwrt() to log an error message, then calls subroutine bort_exit() ...
Definition: bort.f:23
subroutine closbf(LUNIT)
This subroutine closes the connection between logical unit LUNIT and the BUFRLIB software.
Definition: closbf.f:35
subroutine cpdxmm(LUNIT)
This subroutine reads an entire DX BUFR table from a specified file into internal arrays.
Definition: cpdxmm.f:21
void cewind(f77int *nfile)
This subroutine rewinds a BUFR file back to its beginning.
Definition: cread.c:100
void backbufr(f77int *nfile)
This subroutine backspaces a BUFR file by one BUFR message.
Definition: cread.c:84
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 idxmsg(MESG)
This function determines whether a given BUFR message contains DX BUFR tables information that was ge...
Definition: idxmsg.f:24
This module contains array and variable declarations used to store the contents of one or more BUFR f...
Definition: moda_msgmem.F:14
integer, dimension(:), allocatable msgs
BUFR messages read from one or more BUFR files.
Definition: moda_msgmem.F:80
integer ldxm
Number of array elements filled within mdx (up to a maximum of MXDXW).
Definition: moda_msgmem.F:73
integer mlast
Number of array elements filled within msgs (up to a maximum of MAXMEM).
Definition: moda_msgmem.F:72
integer ndxm
Number of DX BUFR table messages stored within mdx (up to a maximum of MXDXM).
Definition: moda_msgmem.F:74
integer munit
Fortran logical unit number for use in accessing contents of BUFR files within internal memory.
Definition: moda_msgmem.F:71
integer ldxts
Number of DX BUFR table that is currently in scope, depending on which BUFR message within msgs is cu...
Definition: moda_msgmem.F:75
integer, dimension(:), allocatable msgp
Pointers to the beginning of each message within msgs (up to a maximum of MAXMSG, and where array ele...
Definition: moda_msgmem.F:79
integer ndxts
Number of DX BUFR tables represented by the messages within mdx (up to a maximum of MXDXTS).
Definition: moda_msgmem.F:76
This module declares and initializes the MAXMEM variable.
Definition: modv_MAXMEM.f:13
integer maxmem
Maximum number of bytes that can be used to store BUFR messages within internal memory.
Definition: modv_MAXMEM.f:19
This module declares and initializes the MAXMSG variable.
Definition: modv_MAXMSG.f:13
integer maxmsg
Maximum number of BUFR messages that can be stored within internal memory.
Definition: modv_MAXMSG.f:19
function nmwrd(MBAY)
GIVEN AN INTEGER ARRAY CONTAINING SECTION ZERO FROM A BUFR MESSAGE, THIS FUNCTION DETERMINES A COUNT ...
Definition: nmwrd.f:28
subroutine openbf(LUNIT, IO, LUNDX)
This subroutine connects a new file to the BUFRLIB software for input or output operations.
Definition: openbf.f:139
subroutine rdmsgw(LUNIT, MESG, IRET)
THIS SUBROUTINE READS THE NEXT BUFR MESSAGE FROM LOGICAL UNIT LUNIT AS AN ARRAY OF INTEGER WORDS.
Definition: rdmsgw.f:38
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 ufbmem(LUNIT, INEW, IRET, IUNIT)
This subroutine connects a new system file to the BUFRLIB software for input operations,...
Definition: ufbmem.f:66