NCEPLIBS-bufr  12.0.0
msgupd.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Write an uncompressed BUFR data subset.
3 C>
4 C> @author Woollen @date 1994-01-06
5 
6 C> This subroutine packs up the current subset within memory
7 C> (array ibay in module @ref moda_bitbuf) and then tries to add it to
8 C> the BUFR message that is currently open within memory for LUNIT
9 C> (array mbay in module @ref moda_bitbuf). If the subset will not fit
10 C> into the currently open message, or if the subset byte count exceeds
11 C> 65530 (sufficiently close to the 16-bit byte counter upper limit of
12 C> 65535), then that message is flushed to LUNIT and a new one is
13 C> created in order to hold the current subset. Any subset with byte
14 C> count > 65530 will be written into its own one-subset message.
15 C> if the current subset is larger than the maximum message length,
16 C> then the subset is discarded and a diagnostic is printed.
17 C>
18 C> @param[in] LUNIT - integer: fortran logical unit number for BUFR file.
19 C> @param[in] LUN - integer: I/O stream index into internal memory arrays
20 C> (associated with file connected to logical unit LUNIT).
21 C>
22 C> @author Woollen @date 1994-01-06
23  SUBROUTINE msgupd(LUNIT,LUN)
24 
25  USE moda_msgcwd
26  USE moda_bitbuf
27  USE moda_h4wlc
28 
29  COMMON /msgptr/ nby0,nby1,nby2,nby3,nby4,nby5
30  COMMON /quiet / iprt
31 
32  LOGICAL MSGFULL
33 
34  CHARACTER*128 ERRSTR
35 
36 C-----------------------------------------------------------------------
37 C-----------------------------------------------------------------------
38 
39 C PAD THE SUBSET BUFFER
40 C ---------------------
41 
42  CALL pad(ibay,ibit,ibyt,8)
43 
44 C CHECK WHETHER THE NEW SUBSET SHOULD BE WRITTEN INTO THE CURRENTLY
45 C OPEN MESSAGE
46 C -----------------------------------------------------------------
47 
48  IF(msgfull(mbyt(lun),ibyt,maxbyt)
49  . .OR.
50  . ((ibyt.GT.65530).AND.(nsub(lun).GT.0))) THEN
51 c NO it should not, either because:
52 c 1) it doesn't fit,
53 c -- OR --
54 c 2) it has byte count > 65530 (sufficiently close to the
55 c upper limit for the 16 bit byte counter placed at the
56 c beginning of each subset), AND the current message has
57 c at least one subset in it,
58 c SO write the current message out and create a new one to
59 c hold the current subset
60  CALL msgwrt(lunit,mbay(1,lun),mbyt(lun))
61  CALL msgini(lun)
62  ENDIF
63 
64  IF(msgfull(mbyt(lun),ibyt,maxbyt)) THEN
65 c This is an overlarge subset that won't fit in any message
66 c given the current value of MAXBYT, so discard the subset
67 c and exit gracefully.
68  IF(iprt.GE.0) THEN
69  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
70  WRITE ( unit=errstr, fmt='(A,A,I7,A)')
71  . 'BUFRLIB: MSGUPD - SUBSET LONGER THAN ANY POSSIBLE MESSAGE ',
72  . '{MAXIMUM MESSAGE LENGTH = ', maxbyt, '}'
73  CALL errwrt(errstr)
74  CALL errwrt('>>>>>>>OVERLARGE SUBSET DISCARDED FROM FILE<<<<<<<<')
75  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
76  CALL errwrt(' ')
77  ENDIF
78  GOTO 100
79  ENDIF
80 
81 C SET A BYTE COUNT AND TRANSFER THE SUBSET BUFFER INTO THE MESSAGE
82 C ----------------------------------------------------------------
83 
84  lbit = 0
85  CALL pkb(ibyt,16,ibay,lbit)
86 
87 C Note that we want to append the data for this subset to the end
88 C of Section 4, but the value in MBYT(LUN) already includes the
89 C length of Section 5 (i.e. 4 bytes). Therefore, we need to begin
90 C writing at the point 3 bytes prior to the byte currently pointed
91 C to by MBYT(LUN).
92 
93  CALL mvb(ibay,1,mbay(1,lun),mbyt(lun)-3,ibyt)
94 
95 C UPDATE THE SUBSET AND BYTE COUNTERS
96 C --------------------------------------
97 
98  mbyt(lun) = mbyt(lun) + ibyt
99  nsub(lun) = nsub(lun) + 1
100 
101  lbit = (nby0+nby1+nby2+4)*8
102  CALL pkb(nsub(lun),16,mbay(1,lun),lbit)
103 
104  lbyt = nby0+nby1+nby2+nby3
105  nbyt = iupb(mbay(1,lun),lbyt+1,24)
106  lbit = lbyt*8
107  CALL pkb(nbyt+ibyt,24,mbay(1,lun),lbit)
108 
109 C IF ANY LONG CHARACTER STRINGS ARE BEING HELD INTERNALLY FOR STORAGE
110 C INTO THIS SUBSET, STORE THEM NOW.
111 C -------------------------------------------------------------------
112 
113  IF(nh4wlc.GT.0) THEN
114  DO ii = 1, nh4wlc
115  CALL writlc(luh4wlc(ii),chh4wlc(ii),sth4wlc(ii))
116  ENDDO
117  nh4wlc = 0
118  ENDIF
119 
120 C IF THE SUBSET BYTE COUNT IS > 65530, THEN GIVE IT ITS OWN ONE-SUBSET
121 C MESSAGE (CANNOT HAVE ANY OTHER SUBSETS IN THIS MESSAGE BECAUSE THEIR
122 C BEGINNING WOULD BE BEYOND THE UPPER LIMIT OF 65535 IN THE 16-BIT
123 C BYTE COUNTER, MEANING THEY COULD NOT BE LOCATED!)
124 C --------------------------------------------------------------------
125 
126  IF(ibyt.GT.65530) THEN
127  IF(iprt.GE.1) THEN
128  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
129  WRITE ( unit=errstr, fmt='(A,I7,A,A)')
130  . 'BUFRLIB: MSGUPD - SUBSET HAS BYTE COUNT = ',ibyt,' > UPPER ',
131  . 'LIMIT OF 65535'
132  CALL errwrt(errstr)
133  CALL errwrt('>>>>>>>WILL BE WRITTEN INTO ITS OWN MESSAGE<<<<<<<<')
134  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
135  CALL errwrt(' ')
136  ENDIF
137  CALL msgwrt(lunit,mbay(1,lun),mbyt(lun))
138  CALL msgini(lun)
139  ENDIF
140 
141 C RESET THE USER ARRAYS AND EXIT NORMALLY
142 C ---------------------------------------
143 
144 100 CALL usrtpl(lun,1,1)
145 
146 C EXIT
147 C ----
148 
149  RETURN
150  END
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 iupb(MBAY, NBYT, NBIT)
Decode an integer value from an integer array.
Definition: iupb.f:21
subroutine msgini(LUN)
This subroutine initializes, within the internal arrays, a new uncompressed BUFR message for output.
Definition: msgini.f:14
subroutine msgupd(LUNIT, LUN)
This subroutine packs up the current subset within memory (array ibay in module moda_bitbuf) and then...
Definition: msgupd.f:24
subroutine msgwrt(LUNIT, MESG, MGBYT)
Perform final checks and updates on a BUFR message before writing it to a specified Fortran logical u...
Definition: msgwrt.f:38
subroutine mvb(IB1, NB1, IB2, NB2, NBM)
This subroutine copies a specified number of bytes from one packed binary array to another.
Definition: mvb.f:18
This module contains array and variable declarations used to store BUFR messages internally for multi...
integer, dimension(:), allocatable ibay
Current data subset.
integer ibit
Bit pointer within IBAY.
integer, dimension(:,:), allocatable mbay
Current BUFR message for each internal I/O stream.
integer, dimension(:), allocatable mbyt
Length (in bytes) of current BUFR message for each internal I/O stream.
integer maxbyt
Maximum length of an output BUFR message.
This module contains array and variable declarations needed to store long character strings (greater ...
integer nh4wlc
Number of long character strings being stored.
character *14, dimension(:), allocatable sth4wlc
Table B mnemonics associated with long character strings.
integer, dimension(:), allocatable luh4wlc
I/O stream index into internal arrays for associated output file.
character *120, dimension(:), allocatable chh4wlc
Long character strings.
This module contains declarations for arrays used to store information about the current BUFR message...
integer, dimension(:), allocatable nsub
Current subset pointer within message.
subroutine pad(IBAY, IBIT, IBYT, IPADB)
This subroutine first packs the value for the number of bits being "padded" (we'll get to that later)...
Definition: pad.f:35
subroutine pkb(NVAL, NBITS, IBAY, IBIT)
This subroutine encodes an integer value within a specified number of bits of an integer array,...
Definition: pkb.f:28
subroutine usrtpl(LUN, INVN, NBMP)
Store the subset template into internal arrays.
Definition: usrtpl.f:22
recursive subroutine writlc(LUNIT, CHR, STR)
Write a long character string (greater than 8 bytes) to a data subset.
Definition: writlc.f:40