NCEPLIBS-bufr 11.7.1
writsa.f
Go to the documentation of this file.
1C> @file
2C> @brief Write a data subset into a BUFR message, and return each
3C> completed message within a memory array.
4
5C> This subroutine is similar to subroutine writsb(), except that in
6C> addition to writing each completed message to a specified Fortran
7C> logical unit, it also returns a copy of each completed message to
8C> the application program within a memory array.
9C>
10C> @authors J. Woollen
11C> @authors J. Ator
12C> @date 1994-01-06
13C>
14C> @param[in] LUNXX -- integer: Absolute value is Fortran logical
15C> unit number for BUFR file
16C> @param[in] LMSGT -- integer: Dimensioned size (in integers) of
17C> MSGT; used by the subroutine to ensure that
18C> it doesn't overflow the MSGT array
19C> @param[out] MSGT -- integer(*): BUFR message
20C> @param[out] MSGL -- integer: Size (in integers) of BUFR message
21C> in MSGT
22C> - 0 = No BUFR message was returned within
23C> MSGT
24C>
25C> <p>This subroutine looks and behaves a lot like subroutine writsb().
26C> Specifically, it is called to indicate to the BUFRLIB software that
27C> all necessary values for a data subset (i.e. report) have been written,
28C> and thus that the subset is ready to be encoded and packed into the
29C> current message for the BUFR file associated with logical unit
30C> ABS(LUNXX). Logical unit ABS(LUNXX) should have already been opened
31C> for output operations via a previous call to subroutine openbf(),
32C> and a BUFR message should already be open for output within internal
33C> arrays via a previous call to one of the BUFRLIB
34C> [message-writing subroutines](@ref hierarchy).
35C> Furthermore, all of the values for the data subset should have
36C> already been written into internal arrays via calls to any of the
37C> BUFRLIB [values-writing subroutines](@ref hierarchy)
38C>
39C> <p>Where this subroutine differs from writsb() is that, in addition
40C> to doing all of the above, it also returns a copy of each completed
41C> BUFR message to the application program within a memory array.
42C> When using this subroutine, it is important to note that the BUFRLIB
43C> software is designed to pack as many data subsets as possible into
44C> each message for output, and therefore not every call to this
45C> subroutine will result in a message being returned in MSGT. In
46C> such cases, MSGL will contain the value 0, indicating that no
47C> message was returned.
48C>
49C> <p>In other words, only when MSGL contains a value
50C> greater than 0 is there an actual BUFR message within MSGT; otherwise,
51C> the message into which the data subset was packed remains internally
52C> within BUFRLIB so that future data subsets can be packed into it as
53C> well, and the message will eventually be returned during some other
54C> future call to this subroutine. For this reason, there is a way to
55C> force the subroutine to return any message contained within the
56C> internal BUFRLIB arrays, such as when there are no more data subsets
57C> to be encoded and we're ready to exit the application program. In
58C> this case, the application program should make one final call to
59C> this subroutine, but with LUNXX set to a negative value;
60C> specifically, to the additive inverse of the Fortran logical unit
61C> number of the BUFR file. This signals to the subroutine that there
62C> are no more data subsets to be packed into the current message for
63C> logical unit ABS(LUNXX), and that the existing message should
64C> instead be immediately flushed to output and returned in MSGT.
65C>
66C> @remarks
67C> - There is a maximum size for any BUFR message that can be written
68C> by the BUFRLIB software. This maximum message size is initially set
69C> to an internal default value within subroutine bfrini(), but it can
70C> be changed to a different value via a separate prior call to
71C> subroutine maxout().
72C> - As is the case for subroutine writsb(), this subroutine will also
73C> check to ensure that the data subset, when encoded and packed, will
74C> fit into the current BUFR message that is open within the internal
75C> arrays associated with logical unit ABS(LUNXX). If adding the data
76C> subset to the current message would cause the maximum message size
77C> to be exceeded, then the subroutine will automatically flush the
78C> current message to logical unit ABS(LUNXX) and to array MSGT, then
79C> open and initialize a new internal message using the same SUBSET and
80C> JDATE values that were specified in the most recent call to one of
81C> the [message-writing subroutines](@ref hierarchy) for ABS(LUNXX),
82C> then encode and pack the data subset into that new message.
83C> - If the user would prefer that output messages only be returned
84C> to the calling program via the MSGT memory array and not also
85C> written to Fortran logical unit ABS(LUNXX), then this can be
86C> accomplished by setting IO = 'NUL' when calling subroutine openbf()
87C> for ABS(LUNXX). In such cases, the logical unit number ABS(LUNXX)
88C> does not even need to be associated with an actual file on the
89C> local system.
90C>
91C> <b>Program history log:</b>
92C> | Date | Programmer | Comments |
93C> | -----|------------|----------|
94C> | 1994-01-06 | J. Woollen | Original author |
95C> | 1998-07-08 | J. Woollen | Replaced call to Cray library routine "ABORT" with call to new internal routine bort(); modified to make Y2K compliant |
96C> | 2000-09-19 | J. Woollen | Maximum message length increased from 10,000 to 20,000 bytes |
97C> | 2003-11-04 | S. Bender | Added remarks and routine interdependencies |
98C> | 2003-11-04 | D. Keyser | Unified/portable for WRF; added documentation; outputs more complete diagnostic info when routine terminates abnormally |
99C> | 2004-08-18 | J. Ator | Add post msgupd() check for and return of message within MSGT in order to prevent loss of message in certain situations; maximum message length increased from 20,000 to 50,000 bytes |
100C> | 2005-03-09 | J. Ator | Added capability for compressed messages |
101C> | 2009-03-23 | J. Ator | Added LMSGT argument and check |
102C> | 2014-12-10 | J. Ator | Use modules instead of COMMON blocks |
103C> | 2019-05-09 | J. Ator | Added dimensions for MSGLEN and MSGTXT |
104C> | 2020-09-22 | J. Ator | Added capability to return two BUFR messages within MSGT during the same call to this routine, in the rare instances where this can occur |
105C>
106 SUBROUTINE writsa(LUNXX,LMSGT,MSGT,MSGL)
107
108 USE moda_bufrmg
109
110 COMMON /msgcmp/ ccmf
111
112 CHARACTER*1 CCMF
113
114 dimension msgt(*)
115
116C----------------------------------------------------------------------
117C----------------------------------------------------------------------
118
119 lunit = abs(lunxx)
120
121C CHECK THE FILE STATUS
122C ---------------------
123
124 CALL status(lunit,lun,il,im)
125 IF(il.EQ.0) GOTO 900
126 IF(il.LT.0) GOTO 901
127 IF(im.EQ.0) GOTO 902
128
129C IF LUNXX < 0, FORCE MEMORY MSG TO BE WRITTEN (W/O ANY CURRENT SUBSET)
130C ---------------------------------------------------------------------
131
132 IF(lunxx.LT.0) CALL closmg(lunit)
133
134C IS THERE A COMPLETED BUFR MESSAGE TO BE RETURNED?
135C -------------------------------------------------
136
137 IF(msglen(lun).GT.0) THEN
138 IF(msglen(lun).GT.lmsgt) GOTO 904
139 msgl = msglen(lun)
140 DO n=1,msgl
141 msgt(n) = msgtxt(n,lun)
142 ENDDO
143 msglen(lun) = 0
144 ELSE
145 msgl = 0
146 ENDIF
147
148 IF(lunxx.LT.0) GOTO 100
149
150C PACK UP THE SUBSET AND PUT IT INTO THE MESSAGE
151C ----------------------------------------------
152
153 CALL wrtree(lun)
154 IF( ccmf.EQ.'Y' ) THEN
155 CALL wrcmps(lunit)
156 ELSE
157 CALL msgupd(lunit,lun)
158 ENDIF
159
160C IF THE JUST-COMPLETED CALL TO WRCMPS OR MSGUPD FOR THIS SUBSET CAUSED
161C A MESSAGE TO BE FLUSHED TO ABS(LUNXX), THEN ATTEMPT TO RETRIEVE AND
162C RETURN THAT MESSAGE NOW. OTHERWISE, WE RUN THE RISK THAT THE NEXT
163C CALL TO OPENMB OR OPENMG MIGHT CAUSE ANOTHER MESSAGE TO BE FLUSHED,
164C AND THUS OVERWRITE THE CURRENT MESSAGE WITHIN ARRAY MSGTXT BEFORE WE
165C HAD THE CHANCE TO RETRIEVE IT DURING THE NEXT CALL TO WRITSA.
166
167C ALSO NOTE THAT, IN RARE INSTANCES (E.G. IF THE BYTE COUNT OF THE MOST
168C RECENT SUBSET IS > 65530), WE COULD END UP WITH TWO BUFR MESSAGES
169C AVAILABLE TO BE RETURNED FROM THIS ONE CALL TO WRITSA. IF SUFFICIENT
170C SPACE IS AVAILABLE IN THE MSGT ARRAY, THEN GO AHEAD AND RETURN BOTH
171C MESSAGES NOW.
172
173 IF( (msglen(lun).GT.0) .AND. (msgl+msglen(lun).LE.lmsgt) ) THEN
174 DO n = 1,msglen(lun)
175 msgt(msgl+n) = msgtxt(n,lun)
176 ENDDO
177 msgl = msgl+msglen(lun)
178 msglen(lun) = 0
179 ENDIF
180
181C EXITS
182C -----
183
184100 RETURN
185900 CALL bort('BUFRLIB: WRITSA - OUTPUT BUFR FILE IS CLOSED, IT '//
186 . 'MUST BE OPEN FOR OUTPUT')
187901 CALL bort('BUFRLIB: WRITSA - OUTPUT BUFR FILE IS OPEN FOR '//
188 . 'INPUT, IT MUST BE OPEN FOR OUTPUT')
189902 CALL bort('BUFRLIB: WRITSA - A MESSAGE MUST BE OPEN IN OUTPUT '//
190 . 'BUFR FILE, NONE ARE')
191904 CALL bort('BUFRLIB: WRITSA - OVERFLOW OF OUTPUT BUFR MESSAGE '//
192 . 'ARRAY; TRY A LARGER DIMENSION FOR THIS ARRAY')
193 END
subroutine bort(STR)
This subroutine calls subroutine errwrt() to log an error message, then calls subroutine bort_exit() ...
Definition: bort.f:23
subroutine closmg(LUNIN)
This subroutine closes the BUFR message that is currently open for writing within internal arrays ass...
Definition: closmg.f:41
subroutine msgupd(LUNIT, LUN)
THIS SUBROUTINE PACKS UP THE CURRENT SUBSET WITHIN MEMORY (ARRAY IBAY IN MODULE BITBUF) AND THEN TRIE...
Definition: msgupd.f:60
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 wrcmps(LUNIX)
THIS SUBROUTINE PACKS UP THE CURRENT SUBSET WITHIN MEMORY (ARRAY IBAY IN MODULE BITBUF),...
Definition: wrcmps.f:81
subroutine writsa(LUNXX, LMSGT, MSGT, MSGL)
This subroutine is similar to subroutine writsb(), except that in addition to writing each completed ...
Definition: writsa.f:107
subroutine wrtree(LUN)
THIS SUBROUTINE CONVERTS USER NUMBERS INTO SCALED INTEGERS AND PACKS THE USER ARRAY INTO THE SUBSET B...
Definition: wrtree.f:51