1 SUBROUTINE STNDRD(LUNIT,MSGIN,LMSGOT,MSGOT)
3 !$$$ SUBPROGRAM DOCUMENTATION BLOCK
6 ! PRGMMR: ATOR ORG: NP12 DATE: 2004-08-18
8 ! ABSTRACT: THIS SUBROUTINE READS AN INPUT NCEP BUFR MESSAGE CONTAINED
9 ! WITHIN ARRAY MSGIN AND, USING THE BUFR TABLES INFORMATION ASSOCIATED
10 ! WITH LOGICAL UNIT LUNIT, OUTPUTS A "STANDARDIZED" VERSION OF THIS
11 ! SAME MESSAGE WITHIN ARRAY MSGOT. THIS "STANDARDIZATION" INVOLVES
12 ! REMOVING ALL OCCURRENCES OF NCEP BUFRLIB-SPECIFIC BYTE COUNTERS AND
13 ! BIT PADS IN SECTION 4 AS WELL AS REPLACING THE TOP-LEVEL TABLE A FXY
14 ! NUMBER IN SECTION 3 WITH AN EQUIVALENT SEQUENCE OF LOWER-LEVEL
15 ! TABLE B, TABLE C, TABLE D AND/OR REPLICATION FXY NUMBERS WHICH
16 ! DIRECTLY CONSTITUTE THAT TABLE A FXY NUMBER AND WHICH THEMSELVES ARE
17 ! ALL WMO-STANDARD. THE RESULT IS THAT THE OUTPUT MESSAGE IN MSGOT IS
18 ! NOW ENTIRELY COMPLIANT WITH WMO FM-94 BUFR REGULATIONS (I.E. IT IS
19 ! NOW "STANDARD"). IT IS IMPORTANT TO NOTE THAT THE SEQUENCE EXPANSION
20 ! WITHIN SECTION 3 MAY CAUSE THE FINAL "STANDARDIZED" BUFR MESSAGE TO
21 ! BE LONGER THAN THE ORIGINAL INPUT NCEP BUFR MESSAGE BY AS MANY AS
22 ! 1000 BYTES, SO THE USER MUST ALLOW FOR ENOUGH SPACE TO ACCOMODATE
23 ! SUCH AN EXPANSION WITHIN THE MSGOT ARRAY.
25 ! PROGRAM HISTORY LOG:
26 ! 2004-08-18 J. ATOR -- ORIGINAL AUTHOR
27 ! THIS SUBROUTINE IS MODELED AFTER SUBROUTINE
28 ! STANDARD; HOWEVER, IT USES SUBROUTINE RESTD
29 ! TO EXPAND SECTION 3 AS MANY LEVELS AS
30 ! NECESSARY IN ORDER TO ATTAIN TRUE WMO
31 ! STANDARDIZATION (WHEREAS STANDARD ONLY
32 ! EXPANDED THE TOP-LEVEL TABLE A FXY NUMBER
33 ! ONE LEVEL DEEP), AND IT ALSO CONTAINS AN
34 ! EXTRA INPUT ARGUMENT LMSGOT WHICH PREVENTS
35 ! OVERFLOW OF THE MSGOT ARRAY
36 ! 2005-11-29 J. ATOR -- USE GETLENS AND IUPBS01; ENSURE THAT BYTE 4
37 ! OF SECTION 4 IS ZEROED OUT IN MSGOT; CHECK
38 ! EDITION NUMBER OF BUFR MESSAGE BEFORE
39 ! PADDING TO AN EVEN BYTE COUNT
41 ! USAGE: CALL STNDRD (LUNIT, MSGIN, LMSGOT, MSGOT)
42 ! INPUT ARGUMENT LIST:
43 ! LUNIT - INTEGER: FORTRAN LOGICAL UNIT NUMBER FOR BUFR FILE
44 ! MSGIN - INTEGER: *-WORD ARRAY CONTAINING BUFR MESSAGE IN NCEP
46 ! LMSGOT - INTEGER: DIMENSIONED SIZE (IN INTEGER WORDS) OF MSGOT;
47 ! USED BY THE SUBROUTINE TO ENSURE THAT IT DOES NOT
48 ! OVERFLOW THE MSGOT ARRAY
50 ! OUTPUT ARGUMENT LIST:
51 ! MSGOT - INTEGER: *-WORD ARRAY CONTAINING INPUT BUFR MESSAGE
52 ! NOW IN STANDARDIZED BUFR
55 ! MSGIN AND MSGOT MUST BE SEPARATE ARRAYS.
57 ! THIS ROUTINE CALLS: BORT GETLENS ISTDESC IUPB
58 ! IUPBS01 MVB NUMTAB PKB
59 ! PKC RESTD STATUS UPB
61 ! THIS ROUTINE IS CALLED BY: MSGWRT
62 ! Also called by application programs.
65 ! LANGUAGE: FORTRAN 77
66 ! MACHINE: PORTABLE TO ALL PLATFORMS
74 COMMON /HRDWRD/ NBYTW,NBITW,NREV,IORD(8)
76 DIMENSION MSGIN(*),MSGOT(*)
78 CHARACTER*128 BORT_STR
83 !-----------------------------------------------------------------------
84 !-----------------------------------------------------------------------
86 ! LUNIT MUST POINT TO AN OPEN BUFR FILE
87 ! -------------------------------------
89 CALL STATUS(LUNIT,LUN,IL,IM)
92 ! IDENTIFY THE SECTION LENGTHS AND ADDRESSES IN MSGIN
93 ! ---------------------------------------------------
95 CALL GETLENS(MSGIN,5,LEN0,LEN1,LEN2,LEN3,LEN4,LEN5)
100 LENN = LEN0+LEN1+LEN2+LEN3+LEN4+LEN5
102 LENM = IUPBS01(MSGIN,'LENM')
104 IF(LENN.NE.LENM) GOTO 901
107 CALL UPC(SEVN,4,MSGIN,MBIT)
108 IF(SEVN.NE.'7777') GOTO 902
110 ! COPY SECTIONS 0 THROUGH PART OF SECTION 3 INTO MSGOT
111 ! ----------------------------------------------------
113 MXBYTO = (LMSGOT*NBYTW) - 8
116 IF(LBYTO.GT.MXBYTO) GOTO 905
117 CALL MVB(MSGIN,1,MSGOT,1,LBYTO)
119 ! REWRITE NEW SECTION 3 IN A "STANDARD" FORM
120 ! ------------------------------------------
122 NSUB = IUPB(MSGIN,IAD3+ 5,16)
123 ISUB = IUPB(MSGIN,IAD3+10,16)
126 CALL NUMTAB(LUN,ISUB,SUBSET,TAB,ITAB)
127 IF(ITAB.EQ.0) GOTO 903
129 IF (ISTDESC(ISUB).EQ.0) THEN
131 ! ISUB IS A NON-STANDARD TABLE A DESCRIPTOR AND NEEDS
132 ! TO BE EXPANDED INTO AN EQUIVALENT STANDARD SEQUENCE
134 CALL RESTD(LUN,ISUB,NCD,ICD)
137 ! ISUB IS ALREADY A STANDARD DESCRIPTOR, SO JUST COPY
138 ! IT "AS IS" INTO THE NEW SECTION 3 (I.E. NO EXPANSION
145 ! USE THE EDITION NUMBER TO DETERMINE THE LENGTH OF THE
149 IBEN = IUPBS01(MSGIN,'BEN')
153 LBYTO = LBYTO + LEN3 - 7
154 IF(LBYTO.GT.MXBYTO) GOTO 905
156 ! STORE THE DESCRIPTORS INTO THE NEW SECTION 3
159 CALL PKB(ICD(N),16,MSGOT,IBIT)
162 ! DEPENDING ON THE EDITION NUMBER, PAD OUT THE NEW SECTION 3 WITH AN
163 ! ADDITIONAL ZEROED-OUT BYTE IN ORDER TO ENSURE AN EVEN BYTE COUNT
166 CALL PKB(0,8,MSGOT,IBIT)
169 ! STORE THE LENGTH OF THE NEW SECTION 3
172 CALL PKB(LEN3,24,MSGOT,IBIT)
174 ! NOW THE TRICKY PART - NEW SECTION 4
175 ! -----------------------------------
184 ! COPY THE SUBSETS, MINUS THE BYTE COUNTERS AND BIT PADS,
185 ! INTO THE NEW SECTION 4
188 CALL UPB(LSUB,16,MSGIN,IBIT)
191 CALL UPB(NVAL_S,8,MSGIN,IBIT)
193 IF(LBYTO.GT.MXBYTO) GOTO 905
194 CALL PKB(NVAL_S,8,MSGOT,JBIT)
199 CALL UPB(KVAL,8,MSGIN,KBIT)
209 ! FROM THIS POINT ON, WE WILL NEED (AT MOST) 6 MORE BYTES OF SPACE
210 ! WITHIN MSGOT IN ORDER TO BE ABLE TO STORE THE ENTIRE STANDARDIZED
211 ! MESSAGE (I.E. WE WILL NEED (AT MOST) 2 MORE ZEROED-OUT BYTES IN
212 ! SECTION 4 PLUS THE 4 BYTES '7777' IN SECTION 5), SO DO A FINAL
213 ! MSGOT OVERFLOW CHECK NOW.
215 IF(LBYTO+6.GT.MXBYTO) GOTO 905
217 ! PAD THE NEW SECTION 4 WITH ZEROES UP TO THE NEXT WHOLE BYTE
220 DO WHILE(.NOT.(MOD(JBIT,8).EQ.0))
221 CALL PKB(0,1,MSGOT,JBIT)
224 ! DEPENDING ON THE EDITION NUMBER, WE MAY NEED TO FURTHER PAD THE
225 ! NEW SECTION 4 WITH AN ADDITIONAL ZEROED-OUT BYTE IN ORDER TO
226 ! ENSURE THAT THE PADDING IS UP TO AN EVEN BYTE BOUNDARY.
228 IF( (IBEN.LT.4) .AND. (MOD(JBIT/8,2).NE.0) ) THEN
229 CALL PKB(0,8,MSGOT,JBIT)
234 CALL PKB(LEN4,24,MSGOT,IBIT)
235 CALL PKB(0,8,MSGOT,IBIT)
237 ! FINISH THE NEW MESSAGE WITH AN UPDATED SECTION 0 BYTE COUNT
238 ! -----------------------------------------------------------
241 LENN = LEN0+LEN1+LEN2+LEN3+LEN4+LEN5
242 CALL PKB(LENN,24,MSGOT,IBIT)
244 CALL PKC('7777',4,MSGOT,JBIT)
250 900 CALL BORT('BUFRLIB: STNDRD - BUFR FILE IS CLOSED, IT MUST BE'// &
252 901 WRITE(BORT_STR,'("BUFRLIB: STNDRD - INPUT MESSAGE LENGTH FROM'// &
253 ' SECTION 0",I6," DOES NOT EQUAL SUM OF ALL INDIVIDUAL SECTION'// &
254 ' LENGTHS (",I6,")")') LENM,LENN
256 902 WRITE(BORT_STR,'("BUFRLIB: STNDRD - INPUT MESSAGE DOES NOT '// &
257 'END WITH ""7777"" (ENDS WITH ",A)') SEVN
259 903 CALL BORT('BUFRLIB: STNDRD - INPUT MESSAGE TABLE D SUBSET '// &
260 'DESCRIPTOR NOT FOUND IN INTERNAL TABLE D')
261 904 CALL BORT('BUFRLIB: STNDRD - BIT MISMATCH COPYING SECTION 4 '// &
262 'FROM INPUT TO OUTPUT (STANDARD) MESSAGE')
263 905 CALL BORT('BUFRLIB: STNDRD - OVERFLOW OF OUTPUT (STANDARD) '// &
264 'MESSAGE ARRAY; TRY A LARGER DIMENSION FOR THIS ARRAY')
265 END SUBROUTINE STNDRD