NCEPLIBS-bufr  12.0.0
readerme.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Read a BUFR message from a memory array.
3 C>
4 C> @authors J. Woollen J. Ator @date 1995-06-28
5 
6 C> Read a BUFR message from a memory array.
7 C>
8 C> This subroutine is similar to subroutine readmg(), except that it
9 C> reads a BUFR message from an array passed as input, whereas
10 C> readmg() reads a BUFR message from a file on the local system.
11 C>
12 C> This subroutine can be used in any context in which readmg()
13 C> might otherwise be used, and from that point on, the application
14 C> program can proceed with a call to one of the
15 C> [subset-reading subroutines](@ref hierarchy) (and then,
16 C> subsequently, to any of the
17 C> [values-reading subroutines](@ref hierarchy)).
18 C>
19 C> When using this subroutine, it's necessary for the
20 C> application program to have previously called subroutine openbf() in
21 C> order to associate a DX BUFR tables file with the message that is
22 C> being input via MESG; it's also necessary to pass in the
23 C> relevant LUNIT value as a call argument, even though in this case
24 C> the subroutine will not actually try to read from the associated
25 C> Fortran logical unit.
26 C>
27 C> If MESG contains a DX BUFR table message, the subroutine will
28 C> store the contents internally and use them to process any
29 C> future BUFR messages associated with LUNIT. In this case, the
30 C> subroutine will return with IRET = 11, and any number of
31 C> DX BUFR table messages passed in via consecutive calls to this
32 C> subroutine will accumulate internally and be treated as a single DX
33 C> BUFR table, up until a call is made where MESG no longer contains a
34 C> DX BUFR table message.
35 C>
36 C> @param[in] MESG - integer(*): BUFR message.
37 C> @param[in] LUNIT - integer: Fortran logical unit number for BUFR file.
38 C> @param[out] SUBSET - character*8: Table A mnemonic for type of BUFR
39 C> message that was read (see [DX BUFR Tables](@ref dfbftab)
40 C> for further information about Table A mnemonics).
41 C> @param[out] JDATE - integer: Date-time stored within Section 1 of
42 C> BUFR message that was read, in format of either YYMMDDHH or YYYYMMDDHH,
43 C> depending on the most recent call to datelen().
44 C> @param[out] IRET - integer: return code:
45 C> - 0 MESG was successfully read.
46 C> - 11 MESG contained a DX BUFR table message.
47 C> - -1 MESG contained an unrecognized Table A message type.
48 C>
49 C> @authors J. Woollen J. Ator @date 1995-06-28
50 
51  RECURSIVE SUBROUTINE readerme(MESG,LUNIT,SUBSET,JDATE,IRET)
52 
53  USE modv_mxmsgl
54  USE modv_im8b
55 
56  USE moda_sc3bfr
57  USE moda_idrdm
58  USE moda_bitbuf
59 
60  COMMON /hrdwrd/ nbytw,nbitw,iord(8)
61  COMMON /quiet/ iprt
62 
63  CHARACTER*128 bort_str,errstr
64  CHARACTER*8 subset,sec0
65 
66  dimension mesg(*),iec0(2)
67 
68  LOGICAL endtbl
69 
70  equivalence(sec0,iec0)
71 
72 C-----------------------------------------------------------------------
73 C-----------------------------------------------------------------------
74 
75 C CHECK FOR I8 INTEGERS
76 C ---------------------
77 
78  IF(im8b) THEN
79  im8b=.false.
80 
81  CALL x84(lunit,my_lunit,1)
82  CALL readerme(mesg,my_lunit,subset,jdate,iret)
83  CALL x48(jdate,jdate,1)
84  CALL x48(iret,iret,1)
85 
86  im8b=.true.
87  RETURN
88  ENDIF
89 
90  iret = 0
91 
92 C CHECK THE FILE STATUS
93 C ---------------------
94 
95  CALL status(lunit,lun,il,im)
96  IF(il.EQ.0) GOTO 900
97  IF(il.GT.0) GOTO 901
98  CALL wtstat(lunit,lun,il, 1)
99 
100 C COPY THE INPUT MESSAGE INTO THE INTERNAL MESSAGE BUFFER
101 C -------------------------------------------------------
102 
103  iec0(1) = mesg(1)
104  iec0(2) = mesg(2)
105  lnmsg = lmsg(sec0)
106  IF(lnmsg*nbytw.GT.mxmsgl) GOTO 902
107  DO i=1,lnmsg
108  mbay(i,lun) = mesg(i)
109  ENDDO
110 
111 C Confirm that the first 4 bytes of SEC0 contain 'BUFR'.
112 
113  IF(sec0(1:4).NE.'BUFR') GOTO 903
114 
115 C PARSE THE MESSAGE SECTION CONTENTS
116 C ----------------------------------
117 
118  IF(isc3(lun).NE.0) CALL reads3(lun)
119 
120  CALL cktaba(lun,subset,jdate,iret)
121 
122  IF(isc3(lun).NE.0) RETURN
123 
124 C CHECK FOR A DX DICTIONARY MESSAGE
125 C ---------------------------------
126 
127 C A new DX dictionary table can be passed in as a consecutive set of
128 C DX dictionary messages. Each message should be passed in one at a
129 C time, via input argument MESG during consecutive calls to this
130 C subroutine, and will be processed as a single dictionary table up
131 C until the next message is passed in which either contains no data
132 C subsets or else is a non-DX dictionary message.
133 
134  endtbl = .false.
135 
136  IF(idxmsg(mbay(1,lun)).EQ.1) THEN
137 
138 C This is a DX dictionary message that was generated by the
139 C BUFRLIB archive library software.
140 
141  IF(iupbs3(mbay(1,lun),'NSUB').EQ.0) THEN
142 
143 C But it doesn't contain any actual dictionary information, so
144 C assume we've reached the end of the dictionary table.
145 
146  IF(idrdm(lun).GT.0) THEN
147  endtbl = .true.
148  ENDIF
149  ELSE
150  IF(idrdm(lun).EQ.0) THEN
151 
152 C This is the first DX dictionary message that is part of a
153 C new dictionary table.
154 
155  CALL dxinit(lun,0)
156  ENDIF
157  idrdm(lun) = idrdm(lun) + 1
158  CALL stbfdx(lun,mbay(1,lun))
159  ENDIF
160  ELSE IF(idrdm(lun).GT.0) THEN
161 
162 C This is the first non-DX dictionary message received following a
163 C string of DX dictionary messages, so assume we've reached the
164 C end of the dictionary table.
165 
166  endtbl = .true.
167  ENDIF
168 
169  IF(endtbl) THEN
170  IF ( iprt .GE. 2 ) THEN
171  CALL errwrt('+++++++++++++++++++++++++++++++++++++++++++++++++')
172  WRITE ( unit=errstr, fmt='(A,I3,A)' )
173  . 'BUFRLIB: READERME - STORED NEW DX TABLE CONSISTING OF (',
174  . idrdm(lun), ') MESSAGES;'
175  CALL errwrt(errstr)
176  errstr = 'WILL APPLY THIS TABLE TO ALL SUBSEQUENT DATA '//
177  . 'MESSAGES UNTIL NEXT DX TABLE IS PASSED IN'
178  CALL errwrt(errstr)
179  CALL errwrt('+++++++++++++++++++++++++++++++++++++++++++++++++')
180  CALL errwrt(' ')
181  ENDIF
182  idrdm(lun) = 0
183  CALL makestab
184  ENDIF
185 
186 C EXITS
187 C -----
188 
189  RETURN
190 900 CALL bort('BUFRLIB: READERME - INPUT BUFR FILE IS CLOSED, IT '//
191  . 'MUST BE OPEN FOR INPUT')
192 901 CALL bort('BUFRLIB: READERME - INPUT BUFR FILE IS OPEN FOR '//
193  . 'OUTPUT, IT MUST BE OPEN FOR INPUT')
194 902 WRITE(bort_str,'("BUFRLIB: READERME - INPUT BUFR MESSAGE LENGTH",
195  . 1X,I6," BYTES) IS LARGER THAN LIMIT OF ",I6," BYTES")')
196  . lnmsg*nbytw,mxmsgl
197  CALL bort(bort_str)
198 903 CALL bort('BUFRLIB: READERME - FIRST 4 BYTES READ FROM RECORD'//
199  . ' NOT "BUFR", DOES NOT CONTAIN BUFR DATA')
200  END
subroutine bort(STR)
Log one error message and abort application program.
Definition: bort.f:18
subroutine cktaba(LUN, SUBSET, JDATE, IRET)
This subroutine parses the Table A mnemonic and date out of Section 1 of a BUFR message that was prev...
Definition: cktaba.f:27
subroutine dxinit(LUN, IOI)
This subroutine initializes the internal arrays (in module moda_tababd) holding the DX BUFR table.
Definition: dxinit.f:18
subroutine errwrt(STR)
This subroutine allows the user to specify a custom location for the logging of error and diagnostic ...
Definition: errwrt.f:36
recursive function idxmsg(MESG)
Check whether a BUFR message contains DX BUFR tables information.
Definition: idxmsg.f:23
recursive function iupbs3(MBAY, S3MNEM)
This function returns a specified value from within Section 3 of a BUFR message.
Definition: iupbs3.f:30
recursive function lmsg(SEC0)
Given a character string containing Section 0 from a BUFR message, this function determines the array...
Definition: lmsg.f:24
subroutine makestab
This subroutine constructs the internal jump/link table within module tables, using all of the intern...
Definition: makestab.f:24
This module contains array and variable declarations used to store BUFR messages internally for multi...
integer, dimension(:,:), allocatable mbay
Current BUFR message for each internal I/O stream.
This module contains a declaration for an array used by subroutine readerme() to read in a new DX dic...
integer, dimension(:), allocatable idrdm
DX BUFR tables message count for each I/O internal stream index.
This module contains an array declaration used to store a switch for each internal I/O stream index,...
integer, dimension(:), allocatable isc3
Section 3 switch for each internal I/O stream index:
This module declares and initializes the IM8B variable.
logical, public im8b
Status indicator to keep track of whether all future calls to BUFRLIB subroutines and functions from ...
This module declares and initializes the MXMSGL variable.
integer mxmsgl
Maximum length (in bytes) of a BUFR message that can be read or written by the BUFRLIB software.
recursive subroutine readerme(MESG, LUNIT, SUBSET, JDATE, IRET)
Read a BUFR message from a memory array.
Definition: readerme.f:52
subroutine reads3(LUN)
This subroutine reads the Section 3 descriptors from the BUFR message in mbay(1,lun).
Definition: reads3.f:15
recursive subroutine status(LUNIT, LUN, IL, IM)
Check whether a specified Fortran logical unit number is currently connected to the NCEPLIBS-bufr sof...
Definition: status.f:36
subroutine stbfdx(LUN, MESG)
This subroutine copies a DX BUFR tables message from the input array mesg into the internal memory ar...
Definition: stbfdx.f:15
subroutine wtstat(LUNIT, LUN, IL, IM)
Update file status in library internals.
Definition: wtstat.f:37
subroutine x48(IIN4, IOUT8, NVAL)
Encode one or more 4-byte integer values as 8-byte integer values.
Definition: x48.F:19
subroutine x84(IIN8, IOUT4, NVAL)
Encode one or more 8-byte integer values as 4-byte integer values.
Definition: x84.F:19