source: trunk/WRF.COMMON/WRFV2/external/io_grib2/g2lib/ixgb2.F

Last change on this file was 11, checked in by aslmd, 14 years ago

spiga@svn-planeto:ajoute le modele meso-echelle martien

File size: 8.7 KB
Line 
1C-----------------------------------------------------------------------
2      SUBROUTINE IXGB2(LUGB,LSKIP,LGRIB,CBUF,NUMFLD,MLEN,IRET)
3C$$$  SUBPROGRAM DOCUMENTATION BLOCK
4C
5C SUBPROGRAM: IXGB2          MAKE INDEX RECORDS FOR FIELDS IN A GRIB2 MESSAGE
6C   PRGMMR: GILBERT          ORG: W/NP11      DATE: 2001-12-10
7C
8C ABSTRACT: THIS SUBPROGRAM GENERATES AN INDEX RECORD FOR EACH FIELD IN A
9C           GRIB2 MESSAGE.  THE INDEX RECORDS ARE WRITTEN TO INDEX BUFFER
10C           POINTED TO BY CBUF.
11C
12C           EACH INDEX RECORD HAS THE FOLLOWING FORM:
13C       BYTE 001 - 004: LENGTH OF INDEX RECORD
14C       BYTE 005 - 008: BYTES TO SKIP IN DATA FILE BEFORE GRIB MESSAGE
15C       BYTE 009 - 012: BYTES TO SKIP IN MESSAGE BEFORE LUS (LOCAL USE)
16C                       SET = 0, IF NO LOCAL USE SECTION IN GRIB2 MESSAGE.
17C       BYTE 013 - 016: BYTES TO SKIP IN MESSAGE BEFORE GDS
18C       BYTE 017 - 020: BYTES TO SKIP IN MESSAGE BEFORE PDS
19C       BYTE 021 - 024: BYTES TO SKIP IN MESSAGE BEFORE DRS
20C       BYTE 025 - 028: BYTES TO SKIP IN MESSAGE BEFORE BMS
21C       BYTE 029 - 032: BYTES TO SKIP IN MESSAGE BEFORE DATA SECTION
22C       BYTE 033 - 040: BYTES TOTAL IN THE MESSAGE
23C       BYTE 041 - 041: GRIB VERSION NUMBER ( CURRENTLY 2 )
24C       BYTE 042 - 042: MESSAGE DISCIPLINE
25C       BYTE 043 - 044: FIELD NUMBER WITHIN GRIB2 MESSAGE
26C       BYTE 045 -  II: IDENTIFICATION SECTION (IDS)
27C       BYTE II+1-  JJ: GRID DEFINITION SECTION (GDS)
28C       BYTE JJ+1-  KK: PRODUCT DEFINITION SECTION (PDS)
29C       BYTE KK+1-  LL: THE DATA REPRESENTATION SECTION (DRS)
30C       BYTE LL+1-LL+6: FIRST 6 BYTES OF THE BIT MAP SECTION (BMS)
31C
32C PROGRAM HISTORY LOG:
33C   95-10-31  IREDELL
34C   96-10-31  IREDELL   AUGMENTED OPTIONAL DEFINITIONS TO BYTE 320
35C 2001-12-10  GILBERT   MODIFIED FROM IXGB TO CREATE GRIB2 INDEXES
36C 2002-01-31  GILBERT   ADDED IDENTIFICATION SECTION TO INDEX RECORD
37C
38C USAGE:    CALL IXGB2(LUGB,LSKIP,LGRIB,CBUF,NUMFLD,MLEN,IRET)
39C   INPUT ARGUMENTS:
40C     LUGB         INTEGER LOGICAL UNIT OF INPUT GRIB FILE
41C     LSKIP        INTEGER NUMBER OF BYTES TO SKIP BEFORE GRIB MESSAGE
42C     LGRIB        INTEGER NUMBER OF BYTES IN GRIB MESSAGE
43C   OUTPUT ARGUMENTS:
44C     CBUF         CHARACTER*1 POINTER TO A BUFFER THAT CONTAINS INDEX RECORDS.
45C                  USERS SHOULD FREE MEMORY THAT CBUF POINTS TO
46C                  USING DEALLOCATE(CBUF) WHEN CBUF IS NO LONGER NEEDED.
47C     NUMFLD       INTEGER NUMBER OF INDEX RECORDS CREATED.
48C                  = 0, IF PROBLEMS
49C     MLEN         INTEGER TOTAL LENGTH OF ALL INDEX RECORDS
50C     IRET         INTEGER RETURN CODE
51C                  =0, ALL OK
52C                  =1, NOT ENOUGH MEMORY TO ALLOCATE INITIAL INDEX BUFFER
53C                  =2, I/O ERROR IN READ
54C                  =3, GRIB MESSAGE IS NOT EDITION 2
55C                  =4, NOT ENOUGH MEMORY TO ALLOCATE EXTENT TO INDEX BUFFER
56C                  =5, UNIDENTIFIED GRIB SECTION ENCOUNTERED...PROBLEM
57C                      SOMEWHERE.
58C
59C SUBPROGRAMS CALLED:
60C   G2LIB_GBYTE        GET INTEGER DATA FROM BYTES
61C   G2LIB_SBYTE        STORE INTEGER DATA IN BYTES
62C   BAREAD       BYTE-ADDRESSABLE READ
63C   REALLOC      RE-ALLOCATES MORE MEMORY
64C
65C ATTRIBUTES:
66C   LANGUAGE: FORTRAN 90
67C
68C$$$
69      USE RE_ALLOC          ! NEEDED FOR SUBROUTINE REALLOC
70      CHARACTER(LEN=1),POINTER,DIMENSION(:) :: CBUF
71      PARAMETER(LINMAX=5000,INIT=50000,NEXT=10000)
72      PARAMETER(IXSKP=4,IXLUS=8,IXSGD=12,IXSPD=16,IXSDR=20,IXSBM=24,
73     &          IXDS=28,IXLEN=36,IXFLD=42,IXIDS=44)
74      PARAMETER(MXSKP=4,MXLUS=4,MXSGD=4,MXSPD=4,MXSDR=4,MXSBM=4,
75     &          MXDS=4,MXLEN=4,MXFLD=2,MXBMS=6)
76      CHARACTER CBREAD(LINMAX),CINDEX(LINMAX)
77      CHARACTER CVER,CDISC
78      CHARACTER CIDS(LINMAX),CGDS(LINMAX),CBMS(6)
79      CHARACTER(LEN=4) :: CTEMP
80      INTEGER LOCLUS,LOCGDS,LENGDS,LOCBMS
81C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
82      LOCLUS=0
83      IRET=0
84      MLEN=0
85      NUMFLD=0
86      IF (ASSOCIATED(CBUF)) NULLIFY(CBUF)
87      MBUF=INIT
88      ALLOCATE(CBUF(MBUF),STAT=ISTAT)    ! ALLOCATE INITIAL SPACE FOR CBUF
89      IF (ISTAT.NE.0) THEN
90         IRET=1
91         RETURN
92      ENDIF
93C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
94C  READ SECTIONS 0 AND 1 FOR VERSIN NUMBER AND DISCIPLINE
95      IBREAD=MIN(LGRIB,LINMAX)
96      CALL BAREAD(LUGB,LSKIP,IBREAD,LBREAD,CBREAD)
97      IF(LBREAD.NE.IBREAD) THEN
98         IRET=2
99         RETURN
100      ENDIF
101      IF(CBREAD(8).NE.CHAR(2)) THEN          !  NOT GRIB EDITION 2
102         IRET=3
103         RETURN
104      ENDIF
105      CVER=CBREAD(8)
106      CDISC=CBREAD(7)
107      CALL G2LIB_GBYTE(CBREAD,LENSEC1,16*8,4*8)
108      LENSEC1=MIN(LENSEC1,IBREAD)
109      CIDS(1:LENSEC1)=CBREAD(17:16+LENSEC1)
110      IBSKIP=LSKIP+16+LENSEC1
111C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
112C  LOOP THROUGH REMAINING SECTIONS CREATING AN INDEX FOR EACH FIELD
113      IBREAD=MAX(5,MXBMS)
114      DO
115         CALL BAREAD(LUGB,IBSKIP,IBREAD,LBREAD,CBREAD)     
116         CTEMP=CBREAD(1)//CBREAD(2)//CBREAD(3)//CBREAD(4)
117         IF (CTEMP.EQ.'7777') RETURN        ! END OF MESSAGE FOUND
118         IF(LBREAD.NE.IBREAD) THEN
119            IRET=2
120            RETURN
121         ENDIF
122         CALL G2LIB_GBYTE(CBREAD,LENSEC,0*8,4*8)
123         CALL G2LIB_GBYTE(CBREAD,NUMSEC,4*8,1*8)
124
125         IF (NUMSEC.EQ.2) THEN                 ! SAVE LOCAL USE LOCATION
126            LOCLUS=IBSKIP-LSKIP
127         ELSEIF (NUMSEC.EQ.3) THEN                 ! SAVE GDS INFO
128            LENGDS=LENSEC
129            CGDS=CHAR(0)
130            CALL BAREAD(LUGB,IBSKIP,LENGDS,LBREAD,CGDS)     
131            IF(LBREAD.NE.LENGDS) THEN
132               IRET=2
133               RETURN
134            ENDIF
135            LOCGDS=IBSKIP-LSKIP
136         ELSEIF (NUMSEC.EQ.4) THEN                 ! FOUND PDS
137            CINDEX=CHAR(0)
138            CALL G2LIB_SBYTE(CINDEX,LSKIP,8*IXSKP,8*MXSKP)    ! BYTES TO SKIP
139            CALL G2LIB_SBYTE(CINDEX,LOCLUS,8*IXLUS,8*MXLUS)   ! LOCATION OF LOCAL USE
140            CALL G2LIB_SBYTE(CINDEX,LOCGDS,8*IXSGD,8*MXSGD)   ! LOCATION OF GDS
141            CALL G2LIB_SBYTE(CINDEX,IBSKIP-LSKIP,8*IXSPD,8*MXSPD)  ! LOCATION OF PDS
142            CALL G2LIB_SBYTE(CINDEX,LGRIB,8*IXLEN,8*MXLEN)    ! LEN OF GRIB2
143            CINDEX(41)=CVER
144            CINDEX(42)=CDISC
145            CALL G2LIB_SBYTE(CINDEX,NUMFLD+1,8*IXFLD,8*MXFLD)   ! FIELD NUM
146            CINDEX(IXIDS+1:IXIDS+LENSEC1)=CIDS(1:LENSEC1)
147            LINDEX=IXIDS+LENSEC1
148            CINDEX(LINDEX+1:LINDEX+LENGDS)=CGDS(1:LENGDS)
149            LINDEX=LINDEX+LENGDS
150            ILNPDS=LENSEC
151            CALL BAREAD(LUGB,IBSKIP,ILNPDS,LBREAD,CINDEX(LINDEX+1))     
152            IF(LBREAD.NE.ILNPDS) THEN
153               IRET=2
154               RETURN
155            ENDIF
156            !   CINDEX(LINDEX+1:LINDEX+ILNPDS)=CBREAD(1:ILNPDS)
157            LINDEX=LINDEX+ILNPDS
158         ELSEIF (NUMSEC.EQ.5) THEN                 ! FOUND DRS
159            CALL G2LIB_SBYTE(CINDEX,IBSKIP-LSKIP,8*IXSDR,8*MXSDR)  ! LOCATION OF DRS
160            ILNDRS=LENSEC
161            CALL BAREAD(LUGB,IBSKIP,ILNDRS,LBREAD,CINDEX(LINDEX+1))     
162            IF(LBREAD.NE.ILNDRS) THEN
163               IRET=2
164               RETURN
165            ENDIF
166            !   CINDEX(LINDEX+1:LINDEX+ILNDRS)=CBREAD(1:ILNDRS)
167            LINDEX=LINDEX+ILNDRS
168         ELSEIF (NUMSEC.EQ.6) THEN                 ! FOUND BMS
169            INDBMP=MOVA2I(CBREAD(6))
170            IF ( INDBMP.LT.254 ) THEN
171               LOCBMS=IBSKIP-LSKIP
172               CALL G2LIB_SBYTE(CINDEX,LOCBMS,8*IXSBM,8*MXSBM)  ! LOC. OF BMS
173            ELSEIF ( INDBMP.EQ.254 ) THEN
174               CALL G2LIB_SBYTE(CINDEX,LOCBMS,8*IXSBM,8*MXSBM)  ! LOC. OF BMS
175            ELSEIF ( INDBMP.EQ.255 ) THEN
176               CALL G2LIB_SBYTE(CINDEX,IBSKIP-LSKIP,8*IXSBM,8*MXSBM)  ! LOC. OF BMS
177            ENDIF
178            CINDEX(LINDEX+1:LINDEX+MXBMS)=CBREAD(1:MXBMS)
179            LINDEX=LINDEX+MXBMS
180            CALL G2LIB_SBYTE(CINDEX,LINDEX,0,8*4)    ! NUM BYTES IN INDEX RECORD
181         ELSEIF (NUMSEC.EQ.7) THEN                 ! FOUND DATA SECTION
182            CALL G2LIB_SBYTE(CINDEX,IBSKIP-LSKIP,8*IXDS,8*MXDS)   ! LOC. OF DATA SEC.
183            NUMFLD=NUMFLD+1
184            IF ((LINDEX+MLEN).GT.MBUF) THEN        ! ALLOCATE MORE SPACE IF
185                                                   ! NECESSARY
186               NEWSIZE=MAX(MBUF+NEXT,MBUF+LINDEX)
187               CALL REALLOC(CBUF,MLEN,NEWSIZE,ISTAT)
188               IF ( ISTAT .NE. 0 ) THEN
189                  NUMFLD=NUMFLD-1
190                  IRET=4
191                  RETURN
192               ENDIF
193               MBUF=NEWSIZE
194            ENDIF
195            CBUF(MLEN+1:MLEN+LINDEX)=CINDEX(1:LINDEX)
196            MLEN=MLEN+LINDEX
197         ELSE                           ! UNRECOGNIZED SECTION
198            IRET=5
199            RETURN
200         ENDIF
201         IBSKIP=IBSKIP+LENSEC
202      ENDDO
203
204C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
205      RETURN
206      END
Note: See TracBrowser for help on using the repository browser.