NCEPLIBS-bufr  12.0.0
ufbrep.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Read/write one or more data values from/to a data subset.
3 C>
4 C> @author J. Woollen @date 1994-01-06
5 
6 C> Read/write one or more data values from/to a data subset.
7 C>
8 C> This subroutine reads or writes one or more data values from or to
9 C> the BUFR data subset that is currently open within the BUFRLIB
10 C> internal arrays. The direction of the data transfer is determined
11 C> by the context of ABS(LUNIN):
12 C> - If ABS(LUNIN) points to a file that was previously opened for
13 C> input using subroutine openbf(), then data values are read from
14 C> the current data subset.
15 C> - If ABS(LUNIN) points to a file that was previously opened for
16 C> output using subroutine openbf(), then data values are written to
17 C> the current data subset.
18 C>
19 C> This subroutine is specifically designed for use with Table B
20 C> mnemonics which are part of a fixed (i.e. non-delayed) replication
21 C> sequence, or for mnemonics which are replicated by being directly
22 C> listed more than once within an overall subset definition.
23 C> See also subroutines ufbint(),
24 C> ufbseq() and ufbstp(), which can also be used to read/write one or
25 C> more data values from/to a data subset but are designed for
26 C> different use cases. A more detailed discussion of
27 C> these different use cases, including examples, is available in
28 C> [DX BUFR Tables](@ref ufbsubs).
29 C>
30 C> It is the user's responsibility to ensure that USR is dimensioned
31 C> sufficiently large enough to accommodate the number of data values
32 C> that are to be read from or written to the data subset. Note also
33 C> that USR is an array of real*8 values; therefore, any data that are
34 C> to be written out as character (i.e. CCITT IA5) values in
35 C> BUFR must be converted from character into real*8 format within the
36 C> application program before calling this subroutine. Conversely,
37 C> when this subroutine is being used to read character values from a
38 C> data subset, the value that is returned will be in real*8 format
39 C> and must be converted back into character format by the application
40 C> program before it can be used as such. Alternatively, there are
41 C> different subroutines such as readlc() and writlc() which can be
42 C> used to read/write character data directly from/to a data subset
43 C> without the need to convert from/to real*8 format as an intermediate
44 C> step.
45 C>
46 C> Numeric (i.e. non-character) data values within USR are always in
47 C> the exact units specified for the corresponding mnemonic within the
48 C> relevant DX or master BUFR table, without any scale or reference
49 C> values applied. Specifically, this means that, when writing
50 C> data values into an output subset, the user only needs to store each
51 C> respective value into USR using the units specified within the table,
52 C> and the BUFRLIB software will take care of any necessary scaling or
53 C> referencing of the value before it is actually encoded into BUFR.
54 C> Conversely, when reading data values from an input subset, the
55 C> values returned in USR are already de-scaled and de-referenced and,
56 C> thus, are already in the exact units that were defined for the
57 C> corresponding mnemonics within the table.
58 C>
59 C> "Missing" values in USR are always denoted by a unique
60 C> placeholder value. This placeholder value is initially set
61 C> to a default value of 10E10_8, but it can be reset to
62 C> any substitute value of the user's choice via a separate
63 C> call to subroutine setbmiss(). In any case, and whenever this
64 C> subroutine is used to read data values from an input subset, any
65 C> returned value in USR can be easily checked for equivalence to the
66 C> current placeholder value via a call to function ibfms(), and a
67 C> positive result means that the value for the corresponding mnemonic
68 C> was encoded as "missing" in BUFR (i.e. all bits set to 1) within the
69 C> original data subset. Conversely, whenever this subroutine
70 C> is used to write data values to an output subset, the current
71 C> placeholder value can be obtained via a separate call to function
72 C> getbmiss(), and the resulting value can then be stored into the
73 C> USR array whereever the user desires a BUFR "missing" value (i.e.
74 C> all bits set to 1) to be encoded for the corresponding mnemonic
75 C> within the output subset.
76 C>
77 C> @remarks
78 C> - If LUNIN < 0, and if ABS(LUNIN) points to a file that is open
79 C> for output (writing BUFR), then the subroutine will treat the file
80 C> pointed to by ABS(LUNIN) as though it was open for input (reading
81 C> BUFR). This is a special capability for use by some applications
82 C> that need to read certain values back out from a BUFR file during
83 C> the same time that it is in the process of being written to.
84 C>
85 C> @param[in] LUNIN - integer: Absolute value is Fortran logical
86 C> unit number for BUFR file.
87 C> @param[in,out] USR - real*8(*,*): Data values
88 C> - If ABS(LUNIN) was opened for input, then
89 C> USR is output from this subroutine and
90 C> contains data values that were read
91 C> from the current data subset.
92 C> - If ABS(LUNIN) was opened for output, then
93 C> USR is input to this subroutine and
94 C> contains data values that are to be
95 C> written to the current data subset.
96 C> @param[in] I1 - integer: First dimension of USR as allocated
97 C> within the calling program.
98 C> @param[in] I2 - integer:
99 C> - If ABS(LUNIN) was opened for input, then I2
100 C> must be set equal to the second dimension
101 C> of USR as allocated within the calling program
102 C> - If ABS(LUNIN) was opened for output, then I2
103 C> must be set equal to the number of replications
104 C> of STR that are to be written to the data subset
105 C> @param[out] IRET - integer: Number of replications of STR that were
106 C> read/written from/to the data subset.
107 C> @param[in] STR - character*(*): String of blank-separated
108 C> Table B mnemonics in one-to-one correspondence with the number of data
109 C> values that will be read/written from/to the data
110 C> subset within the first dimension of USR (see
111 C> [DX BUFR Tables](@ref dfbftab) for further
112 C> information about Table B mnemonics).
113 C>
114 C> @author J. Woollen @date 1994-01-06
115  RECURSIVE SUBROUTINE ufbrep(LUNIN,USR,I1,I2,IRET,STR)
116 
117  USE modv_im8b
118  USE modv_bmiss
119 
120  USE moda_usrint
121  USE moda_msgcwd
122 
123  COMMON /acmode/ iac
124  COMMON /quiet / iprt
125 
126  CHARACTER*(*) str
127  CHARACTER*128 bort_str1,bort_str2,errstr
128  real*8 usr(i1,i2)
129 
130  DATA ifirst1/0/,ifirst2/0/
131 
132  SAVE ifirst1, ifirst2
133 
134 C----------------------------------------------------------------------
135 C----------------------------------------------------------------------
136 
137 C CHECK FOR I8 INTEGERS
138 C ---------------------
139 
140  IF(im8b) THEN
141  im8b=.false.
142 
143  CALL x84(lunin,my_lunin,1)
144  CALL x84(i1,my_i1,1)
145  CALL x84(i2,my_i2,1)
146  CALL ufbrep(my_lunin,usr,my_i1,my_i2,iret,str)
147  CALL x48(iret,iret,1)
148 
149  im8b=.true.
150  RETURN
151  ENDIF
152 
153  iret = 0
154 
155 C CHECK THE FILE STATUS AND I-NODE
156 C --------------------------------
157 
158  lunit = abs(lunin)
159  CALL status(lunit,lun,il,im)
160  IF(il.EQ.0) GOTO 900
161  IF(im.EQ.0) GOTO 901
162  IF(inode(lun).NE.inv(1,lun)) GOTO 902
163 
164  io = min(max(0,il),1)
165  IF(lunin.NE.lunit) io = 0
166 
167  IF(i1.LE.0) THEN
168  IF(iprt.GE.0) THEN
169  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
170  errstr = .LE.'BUFRLIB: UFBREP - 3rd ARG. (INPUT) IS 0, ' //
171  . 'SO RETURN WITH 5th ARG. (IRET) = 0; 6th ARG. (STR) ='
172  CALL errwrt(errstr)
173  CALL errwrt(str)
174  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
175  CALL errwrt(' ')
176  ENDIF
177  GOTO 100
178  ELSEIF(i2.LE.0) THEN
179  IF(iprt.EQ.-1) ifirst1 = 1
180  IF(io.EQ.0 .OR. ifirst1.EQ.0 .OR. iprt.GE.1) THEN
181  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
182  errstr = .LE.'BUFRLIB: UFBREP - 4th ARG. (INPUT) IS 0, ' //
183  . 'SO RETURN WITH 5th ARG. (IRET) = 0; 6th ARG. (STR) ='
184  CALL errwrt(errstr)
185  CALL errwrt(str)
186  IF(iprt.EQ.0 .AND. io.EQ.1) THEN
187  errstr = 'Note: Only the first occurrence of this WARNING ' //
188  . 'message is printed, there may be more. To output all ' //
189  . 'such messages,'
190  CALL errwrt(errstr)
191  errstr = 'modify your application program to add ' //
192  . '"CALL OPENBF(0,''QUIET'',1)" prior to the first call ' //
193  . 'to a BUFRLIB routine.'
194  CALL errwrt(errstr)
195  ENDIF
196  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
197  CALL errwrt(' ')
198  ifirst1 = 1
199  ENDIF
200  GOTO 100
201  ENDIF
202 
203 C INITIALIZE USR ARRAY PRECEEDING AN INPUT OPERATION
204 C --------------------------------------------------
205 
206  IF(io.EQ.0) THEN
207  DO j=1,i2
208  DO i=1,i1
209  usr(i,j) = bmiss
210  ENDDO
211  ENDDO
212  ENDIF
213 
214 C PARSE OR RECALL THE INPUT STRING - READ/WRITE VALUES
215 C ----------------------------------------------------
216 
217  ia2 = iac
218  iac = 1
219  CALL string(str,lun,i1,io)
220 
221 C CALL THE MNEMONIC READER/WRITER
222 C -------------------------------
223 
224  CALL ufbrp(lun,usr,i1,i2,io,iret)
225  iac = ia2
226 
227  IF(io.EQ.1 .AND. iret.LT.i2) GOTO 903
228 
229  IF(iret.EQ.0) THEN
230  IF(io.EQ.0) THEN
231  IF(iprt.GE.1) THEN
232  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
233  errstr = 'BUFRLIB: UFBREP - NO SPECIFIED VALUES READ IN, ' //
234  . 'SO RETURN WITH 5th ARG. (IRET) = 0; 6th ARG. (STR) ='
235  CALL errwrt(errstr)
236  CALL errwrt(str)
237  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
238  CALL errwrt(' ')
239  ENDIF
240  ELSE
241  IF(iprt.EQ.-1) ifirst2 = 1
242  IF(ifirst2.EQ.0 .OR. iprt.GE.1) THEN
243  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
244  errstr = 'BUFRLIB: UFBREP - NO SPECIFIED VALUES WRITTEN OUT, ' //
245  . 'SO RETURN WITH 5th ARG. (IRET) = 0; 6th ARG. (STR) ='
246  CALL errwrt(errstr)
247  CALL errwrt(str)
248  CALL errwrt('MAY NOT BE IN THE BUFR TABLE(?)')
249  IF(iprt.EQ.0) THEN
250  errstr = 'Note: Only the first occurrence of this WARNING ' //
251  . 'message is printed, there may be more. To output all ' //
252  . 'such messages,'
253  CALL errwrt(errstr)
254  errstr = 'modify your application program to add ' //
255  . '"CALL OPENBF(0,''QUIET'',1)" prior to the first call ' //
256  . 'to a BUFRLIB routine.'
257  CALL errwrt(errstr)
258  ENDIF
259  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
260  CALL errwrt(' ')
261  ifirst2 = 1
262  ENDIF
263  ENDIF
264  ENDIF
265 
266 C EXITS
267 C -----
268 
269 100 RETURN
270 900 CALL bort('BUFRLIB: UFBREP - BUFR FILE IS CLOSED, IT MUST BE'//
271  . ' OPEN')
272 901 CALL bort('BUFRLIB: UFBREP - A MESSAGE MUST BE OPEN IN BUFR '//
273  . 'FILE, NONE ARE')
274 902 CALL bort('BUFRLIB: UFBREP - LOCATION OF INTERNAL TABLE FOR '//
275  . 'BUFR FILE DOES NOT AGREE WITH EXPECTED LOCATION IN INTERNAL '//
276  . 'SUBSET ARRAY')
277 903 WRITE(bort_str1,'("BUFRLIB: UFBREP - MNEMONIC STRING READ IN IS'//
278  . ': ",A)') str
279  WRITE(bort_str2,'(18X,"THE NUMBER OF ''LEVELS'' ACTUALLY '//
280  . 'WRITTEN (",I3,") LESS THAN THE NUMBER REQUESTED (",I3,") - '//
281  . 'INCOMPLETE WRITE")') iret,i2
282  CALL bort2(bort_str1,bort_str2)
283  END
subroutine bort2(STR1, STR2)
Log two error messages and abort application program.
Definition: bort2.f:18
subroutine bort(STR)
Log one error message and abort application program.
Definition: bort.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
This module contains declarations for arrays used to store information about the current BUFR message...
integer, dimension(:), allocatable inode
Table A mnemonic for type of BUFR message.
This module contains declarations for arrays used to store data values and associated metadata for th...
integer, dimension(:,:), allocatable, target inv
Inventory pointer which links each data value to its corresponding node in the internal jump/link tab...
This module declares and initializes the BMISS variable.
Definition: modules_vars.F90:9
real *8, public bmiss
Current placeholder value to represent "missing" data when reading from or writing to BUFR files; thi...
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 ...
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 string(STR, LUN, I1, IO)
This subroutine checks to see if a user-specified character string is in the string cache (arrays in ...
Definition: string.f:28
recursive subroutine ufbrep(LUNIN, USR, I1, I2, IRET, STR)
Read/write one or more data values from/to a data subset.
Definition: ufbrep.f:116
subroutine ufbrp(LUN, USR, I1, I2, IO, IRET)
This subroutine writes or reads specified data values to or from the current BUFR data subset within ...
Definition: ufbrp.f:31
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