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