NCEPLIBS-bufr  12.0.0
cpyupd.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Copy a BUFR data subset.
3 C> pointers.
4 C>
5 C> @author Woollen @date 1994-01-06
6 
7 C> This subroutine copies a BUFR data subset from one unit
8 C> to another within internal memory and resets the pointers.
9 C> If the subset will not fit into the output message, or
10 C> if the subset byte count exceeds 65530 (sufficiently close to the
11 C> 16-bit byte counter upper limit of 65535), then that message is
12 C> flushed to lunit and a new one is created in order to hold the
13 C> copied subset. Any subset with byte count > 65530 will be written
14 C> into its own one-subset message. If the subset to be copied is
15 C> larger than the maximum message length, then a call is issued to
16 C> subroutine bort().
17 C>
18 C> @param[in] LUNIT - integer: Fortran logical unit number for BUFR file
19 C> associated with output unit.
20 C> @param[in] LIN - integer: I/O stream index into internal memory arrays
21 C> for input unit
22 C> @param[in] LUN - integer: I/O stream index into internal memory arrays
23 C> for output unit.
24 C> @param[in] IBYT - integer: length (in bytes) of data subset
25 C>
26 C> @author Woollen @date 1994-01-06
27 
28  SUBROUTINE cpyupd(LUNIT,LIN,LUN,IBYT)
29 
30  USE moda_msgcwd
31  USE moda_bitbuf
32 
33  COMMON /msgptr/ nby0,nby1,nby2,nby3,nby4,nby5
34 
35  COMMON /quiet / iprt
36 
37  CHARACTER*128 BORT_STR, ERRSTR
38 
39  LOGICAL MSGFULL
40 
41 C-----------------------------------------------------------------------
42 C-----------------------------------------------------------------------
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)) GOTO 900
65 
66 C TRANSFER SUBSET FROM ONE MESSAGE TO THE OTHER
67 C ---------------------------------------------
68 
69 C Note that we want to append the data for this subset to the end
70 C of Section 4, but the value in MBYT(LUN) already includes the
71 C length of Section 5 (i.e. 4 bytes). Therefore, we need to begin
72 C writing at the point 3 bytes prior to the byte currently pointed
73 C to by MBYT(LUN).
74 
75  CALL mvb(mbay(1,lin),mbyt(lin)+1,mbay(1,lun),mbyt(lun)-3,ibyt)
76 
77 C UPDATE THE SUBSET AND BYTE COUNTERS
78 C --------------------------------------
79 
80  mbyt(lun) = mbyt(lun) + ibyt
81  nsub(lun) = nsub(lun) + 1
82 
83  lbit = (nby0+nby1+nby2+4)*8
84  CALL pkb(nsub(lun),16,mbay(1,lun),lbit)
85 
86  lbyt = nby0+nby1+nby2+nby3
87  nbyt = iupb(mbay(1,lun),lbyt+1,24)
88  lbit = lbyt*8
89  CALL pkb(nbyt+ibyt,24,mbay(1,lun),lbit)
90 
91 C IF THE SUBSET BYTE COUNT IS > 65530, THEN GIVE IT ITS OWN ONE-SUBSET
92 C MESSAGE (CANNOT HAVE ANY OTHER SUBSETS IN THIS MESSAGE BECAUSE THEIR
93 C BEGINNING WOULD BE BEYOND THE UPPER LIMIT OF 65535 IN THE 16-BIT
94 C BYTE COUNTER, MEANING THEY COULD NOT BE LOCATED!)
95 C --------------------------------------------------------------------
96 
97  IF(ibyt.GT.65530) THEN
98  IF(iprt.GE.1) THEN
99  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
100  WRITE ( unit=errstr, fmt='(A,I7,A,A)')
101  . 'BUFRLIB: CPYUPD - SUBSET HAS BYTE COUNT = ',ibyt,' > UPPER ',
102  . 'LIMIT OF 65535'
103  CALL errwrt(errstr)
104  CALL errwrt('>>>>>>>WILL BE COPIED INTO ITS OWN MESSAGE<<<<<<<<')
105  CALL errwrt('+++++++++++++++++++++WARNING+++++++++++++++++++++++')
106  CALL errwrt(' ')
107  ENDIF
108  CALL msgwrt(lunit,mbay(1,lun),mbyt(lun))
109  CALL msgini(lun)
110  ENDIF
111 
112 C EXITS
113 C -----
114 
115  RETURN
116 900 WRITE(bort_str,'("BUFRLIB: CPYUPD - THE LENGTH OF THIS SUBSET '//
117  . 'EXCEEDS THE MAXIMUM MESSAGE LENGTH (",I6,")")') maxbyt
118  CALL bort(bort_str)
119  END
subroutine bort(STR)
Log one error message and abort application program.
Definition: bort.f:18
subroutine cpyupd(LUNIT, LIN, LUN, IBYT)
This subroutine copies a BUFR data subset from one unit to another within internal memory and resets ...
Definition: cpyupd.f:29
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 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 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 declarations for arrays used to store information about the current BUFR message...
integer, dimension(:), allocatable nsub
Current subset pointer within message.
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