NCEPLIBS-bufr  11.5.0
 All Data Structures Files Functions Variables Pages
writlc.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Write a long character string (greater than 8 bytes) to
3 C> a data subset.
4 
5 C> This subroutine writes a long character string (greater than 8 bytes)
6 C> to a data subset.
7 C>
8 C> <p>The data subset should have already been written into a BUFR
9 C> message via a previous call to one of the
10 C> [subset-writing subroutines](@ref hierarchy), before calling this
11 C> subroutine to write any long character strings into the same subset.
12 C>
13 C> @authors J. Woollen
14 C> @authors J. Ator
15 C> @date 2003-11-04
16 C>
17 C> @param[in] LUNIT - integer: Fortran logical unit number for BUFR file
18 C> @param[in] CHR - character*(*): Value corresponding to STR
19 C> @param[in] STR - character*(*): Table B mnemonic of long character
20 C> string to be written, possibly supplemented
21 C> with an ordinal occurrence notation
22 C>
23 C> <p>If there is more than one occurrence of STR within the data subset
24 C> definition, then each occurrence can be written via a separate call
25 C> to this subroutine, and by appending the ordinal number of the
26 C> occurrence to STR in each case. For example, if there are 5
27 C> occurrences of mnemonic LSTID within a given data subset definition,
28 C> then 5 separate calls should be made to this subroutine, once each
29 C> with STR set to 'LSTID#1', 'LSTID#2', 'LSTID#3', 'LSTID#4' and
30 C> 'LSTID#5'. However, the first notation is superfluous, because
31 C> omitting the ordinal number always defaults to the first occurrence
32 C> of a particular string, so a user could just specify 'LSTID'
33 C> instead of 'LSTID#1'.
34 C>
35 C> @remarks
36 C> - Character strings which are 8 bytes or less in length can be
37 C> written by converting the string into a real*8 value within the
38 C> application program, and then using the real*8 USR array within a
39 C> call to one of the BUFRLIB
40 C> [values-writing subroutines](@ref hierarchy)
41 C> prior to calling one of the
42 C> [subset-writing subroutines](@ref hierarchy)
43 C> for the data subset.
44 C>
45 C> <b>Program history log:</b>
46 C> - 2003-11-04 J. Woollen -- Original author
47 C> - 2004-08-09 J. Ator -- Maximum message length increased from
48 C> 20,000 to 50,000 bytes
49 C> - 2005-11-29 J. Ator -- Use getlens()
50 C> - 2007-01-19 J. Ator -- Replaced call to parseq with call to
51 C> parstr()
52 C> - 2009-03-23 J. Ator -- Added '#' option for more than one
53 C> occurrence of STR
54 C> - 2009-08-11 J. Woollen -- Added COMMON COMPRS along with logic to
55 C> write long strings into compressed subsets
56 C> - 2012-12-07 J. Ator -- Allow str mnemonic length of up to 14 chars
57 C> when used with '#' occurrence code
58 C> - 2014-10-22 J. Ator -- No longer abort if no subset available for
59 C> writing; just print a warning message
60 C> - 2014-12-10 J. Ator -- USE modules instead of COMMON blocks
61 C> - 2020-09-09 J. Ator -- No longer abort if STR not available within
62 C> subset definition; instead, just print a
63 C> warning message
64 C>
65  SUBROUTINE writlc(LUNIT,CHR,STR)
66 
67  USE moda_usrint
68  USE moda_msgcwd
69  USE moda_bitbuf
70  USE moda_tables
71  USE moda_comprs
72 
73  COMMON /quiet / iprt
74 
75  CHARACTER*(*) chr,str
76  CHARACTER*128 bort_str
77  CHARACTER*128 errstr
78  CHARACTER*10 ctag
79  CHARACTER*14 tgs(10)
80 
81  DATA maxtg /10/
82 
83 C-----------------------------------------------------------------------
84 C-----------------------------------------------------------------------
85 
86 C Check the file status.
87 
88  CALL status(lunit,lun,il,im)
89  IF(il.EQ.0) goto 900
90  IF(il.LT.0) goto 901
91  IF(im.EQ.0) goto 902
92 
93 C Check for tags (mnemonics) in input string (there can only be one)
94 
95  CALL parstr(str,tgs,maxtg,ntg,' ',.true.)
96  IF(ntg.GT.1) goto 903
97 
98 C Check if a specific occurrence of the input string was requested;
99 C if not, then the default is to write the first occurrence.
100 
101  CALL parutg(lun,1,tgs(1),nnod,kon,roid)
102  IF(kon.EQ.6) THEN
103  ioid=nint(roid)
104  IF(ioid.LE.0) ioid = 1
105  ctag = ' '
106  ii = 1
107  DO WHILE((ii.LE.10).AND.(tgs(1)(ii:ii).NE.'#'))
108  ctag(ii:ii)=tgs(1)(ii:ii)
109  ii = ii + 1
110  ENDDO
111  ELSE
112  ioid = 1
113  ctag = tgs(1)(1:10)
114  ENDIF
115 
116  IF(iupbs3(mbay(1,lun),'ICMP').GT.0) THEN
117 
118 C The message is compressed.
119 
120  n = 1
121  itagct = 0
122  CALL usrtpl(lun,n,n)
123  DO WHILE (n+1.LE.nval(lun))
124  n = n+1
125  node = inv(n,lun)
126  IF(itp(node).EQ.1) THEN
127  CALL usrtpl(lun,n,matx(n,ncol))
128  ELSEIF(ctag.EQ.tag(node)) THEN
129  itagct = itagct + 1
130  IF(itagct.EQ.ioid) THEN
131  IF(itp(node).NE.3) goto 904
132  catx(n,ncol)=' '
133 
134 C The following statement enforces a limit of MXLCC
135 C characters per long character string when writing
136 C compressed messages. This limit keeps the array
137 C CATX to a reasonable dimensioned size.
138 
139  nchr=min(mxlcc,ibt(node)/8)
140  catx(n,ncol)=chr(1:nchr)
141  CALL usrtpl(lun,1,1)
142  goto 100
143  ENDIF
144  ENDIF
145  ENDDO
146  ELSE
147 
148 C The message is not compressed. Locate the beginning of the
149 C data (Section 4) in the message.
150 
151  CALL getlens(mbay(1,lun),3,len0,len1,len2,len3,l4,l5)
152  mbyte = len0 + len1 + len2 + len3 + 4
153  nsubs = 1
154 
155 C Find the most recently written subset in the message.
156 
157  DO WHILE(nsubs.LT.nsub(lun))
158  ibit = mbyte*8
159  CALL upb(nbyt,16,mbay(1,lun),ibit)
160  mbyte = mbyte + nbyt
161  nsubs = nsubs + 1
162  ENDDO
163 
164  IF(nsubs.NE.nsub(lun)) THEN
165  IF(iprt.GE.0) THEN
166  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
167  errstr = 'BUFRLIB: WRITLC - COULDN''T WRITE VALUE FOR ' // ctag
168  . // ' INTO SUBSET, BECAUSE NO SUBSET WAS OPEN FOR WRITING'
169  CALL errwrt(errstr)
170  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
171  CALL errwrt(' ')
172  ENDIF
173  goto 100
174  ENDIF
175 
176 C Locate and write the long character string within this subset.
177 
178  itagct = 0
179  mbit = mbyte*8 + 16
180  nbit = 0
181  n = 1
182  CALL usrtpl(lun,n,n)
183  DO WHILE (n+1.LE.nval(lun))
184  n = n+1
185  node = inv(n,lun)
186  mbit = mbit+nbit
187  nbit = ibt(node)
188  IF(itp(node).EQ.1) THEN
189  CALL upbb(ival,nbit,mbit,mbay(1,lun))
190  CALL usrtpl(lun,n,ival)
191  ELSEIF(ctag.EQ.tag(node)) THEN
192  itagct = itagct + 1
193  IF(itagct.EQ.ioid) THEN
194  IF(itp(node).NE.3) goto 904
195  nchr = nbit/8
196  ibit = mbit
197  DO j=1,nchr
198  CALL pkc(' ',1,mbay(1,lun),ibit)
199  ENDDO
200  CALL pkc(chr,nchr,mbay(1,lun),mbit)
201  CALL usrtpl(lun,1,1)
202  goto 100
203  ENDIF
204  ENDIF
205  ENDDO
206  ENDIF
207 
208  IF(iprt.GE.0) THEN
209  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
210  errstr = 'BUFRLIB: WRITLC - COULDN''T WRITE VALUE FOR ' // ctag
211  . // ' INTO SUBSET, BECAUSE IT WASN''T FOUND IN THE SUBSET'
212  . // ' DEFINITION'
213  CALL errwrt(errstr)
214  errstr = '(' // ctag // ' MAY NOT BE IN THE BUFR TABLE(?))'
215  CALL errwrt(errstr)
216  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
217  CALL errwrt(' ')
218  ENDIF
219 
220 C EXITS
221 C -----
222 
223 100 RETURN
224 900 CALL bort('BUFRLIB: WRITLC - OUTPUT BUFR FILE IS CLOSED, IT '//
225  . 'MUST BE OPEN FOR OUTPUT')
226 901 CALL bort('BUFRLIB: WRITLC - OUTPUT BUFR FILE IS OPEN FOR '//
227  . 'INPUT, IT MUST BE OPEN FOR OUTPUT')
228 902 CALL bort('BUFRLIB: WRITLC - A MESSAGE MUST BE OPEN IN OUTPUT '//
229  . 'BUFR FILE, NONE ARE')
230 903 WRITE(bort_str,'("BUFRLIB: WRITLC - THERE CANNOT BE MORE THAN '//
231  . ' ONE MNEMONIC IN THE INPUT STRING (",A,") (HERE THERE ARE",I4'//
232  . ',")")') str,ntg
233  CALL bort(bort_str)
234 904 WRITE(bort_str,'("BUFRLIB: WRITLC - MNEMONIC ",A," DOES NOT '//
235  . 'REPRESENT A CHARACTER ELEMENT (TYP=",A,")")') ctag,typ(node)
236  CALL bort(bort_str)
237 905 WRITE(bort_str,'("BUFRLIB: WRITLC - THE MOST RECENTLY WRITTEN '//
238  . .NE.' SUBSET NO. (",I3,") IN MSG THE STORED VALUE FOR THE NO.'//
239  . ' OF SUBSETS (",I3,") IN MSG")') nsubs,nsub(lun)
240  CALL bort(bort_str)
241  END
subroutine upbb(NVAL, NBITS, IBIT, IBAY)
THIS SUBROUTINE UNPACKS AND RETURNS A BINARY INTEGER CONTAINED WITHIN NBITS BITS OF IBAY...
Definition: upbb.f:42
function iupbs3(MBAY, S3MNEM)
This function returns a specified value from within Section 3 of a BUFR message.
Definition: iupbs3.f:32
subroutine upb(NVAL, NBITS, IBAY, IBIT)
THIS SUBROUTINE UNPACKS AND RETURNS A BINARY INTEGER CONTAINED WITHIN NBITS BITS OF IBAY...
Definition: upb.f:49
subroutine parstr(STR, TAGS, MTAG, NTAG, SEP, LIMIT80)
THIS SUBROUTINE PARSES A STRING CONTAINING ONE OR MORE SUBSTRINGS INTO AN ARRAY OF SUBSTRINGS...
Definition: parstr.f:37
subroutine pkc(CHR, NCHR, IBAY, IBIT)
This subroutine encodes a character string within a specified number of bits of an integer array...
Definition: pkc.f:42
subroutine usrtpl(LUN, INVN, NBMP)
THIS SUBROUTINE STORES THE SUBSET TEMPLATE INTO INTERNAL SUBSET ARRAYS IN MODULE USRINT FOR CASES OF ...
Definition: usrtpl.f:51
subroutine getlens(MBAY, LL, LEN0, LEN1, LEN2, LEN3, LEN4, LEN5)
This subroutine reads the lengths of all of the individual sections of a given BUFR message...
Definition: getlens.f:37
This module contains array and variable declarations used to store the internal jump/link table...
Definition: moda_tables.F:13
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 parutg(LUN, IO, UTG, NOD, KON, VAL)
THIS SUBROUTINE PARSES A USER-SPECIFIED TAG (MNEMONIC) (UTG) THAT REPRESENTS A VALUE EITHER BEING DEC...
Definition: parutg.f:120
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 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
subroutine writlc(LUNIT, CHR, STR)
This subroutine writes a long character string (greater than 8 bytes) to a data subset.
Definition: writlc.f:65