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