      SUBROUTINE FBUFFIN(IU,IBUF,IMAX,K,LEN) 
C 
C     * FEB 01/05 - F.MAJAESS (ENSURE "LHEAD" IS INITIALIZED BEFORE USE
C     *                        IN THE "DATA RECORD" READ ONLY CASE)
C     * JUL 07/03 - A.IRWIN,F.MAJAESS (REVISED FOR F90 AND LINUX PLATFORMS)
C     * OCT 26/94 - F.MAJAESS (CORRECT FOR NEGATIVE LEVEL VALUES)
C     * JUL 29/93 - S.PIGGOTT (ENABLE OPTIONS TO READ JUST THE LABEL
C     *             E.CHAN     RECORD OR JUST THE DATA RECORD)
C     * NOV 02/92 - E.CHAN (REPLACE READS WITH CALLS TO RDBUF)
C     * JUL 20/92 - E.CHAN (MODIFY FOR NEW 64-BIT IEEE DATA FORMAT) 
C     * MAR 16/92 - E.CHAN 
C     *
C     * FBUFFIN READS STANDARD CCRN RECORDS. CCRN RECORDS ARE STORED IN
C     * A "2-RECORD" FORMAT: THE FIRST RECORD CONTAINS AN 8-WORD LABEL
C     * AND THE SECOND RECORD CONTAINS THE ASSOCIATED DATA.
C     *
C     * IU     = UNIT NUMBER 
C     * IBUF   = INTEGER ARRAY CONTAINING LABEL AND/OR DATA (PACKED)
C     * IMAX   = SPECIFIED MAX SIZE OF IBUF (I.E. 8-WORD LABEL + DATA) 
C     * K      = STATUS OF THE READ OPERATION:
C     *             = -2 : SUCCESSFUL READ 
C     *             = -1 : SUCCESSFUL READ (DATA RECORD CONTAINED
C     *                    FEWER ELEMENTS THAN IMAX SPECIFIED)
C     *             =  0 : END OF FILE ENCOUNTERED (NO MORE RECORDS) 
C     *             =  1 : LENGTH OF DATA RECORD IS LONGER THAN IMAX 
C     *                    SPECIFIED - ONLY IMAX NUMBER OF ELEMENTS READ
C     *             =  2 : ERROR ENCOUNTERED DURING READ OPERATION
C     * LEN    = LENGTH OF DATA RECORD PLUS THE ASSOCIATED 8-WORD LABEL
C     *
C     * THE SIGNS OF IU AND IMAX ARE USED TO ENABLE THE FOLLOWING OPTIONS:
C     * 
C     *   CASE 1: IU > 0
C     *     IMAX > 0 - READ BOTH LABEL AND DATA RECORDS 
C     *     IMAX < 0 - READ THE LABEL AND SKIP OVER THE DATA RECORD
C     *   
C     *   CASE 2: IU < 0
C     *     IMAX > 0 - READ THE DATA RECORD ASSUMING THAT THE ASSOCIATED 
C     *                LABEL HAS ALREADY BEEN READ (IN THIS CASE, IBUF 
C     *                MUST BE SPECIFIED IN THE CALL TO FBUFFIN)
C     *     IMAX < 0 - READ JUST THE LABEL AND LEAVE THE POINTER AT THE     
C     *                BEGINNING OF THE DATA RECORD
C
      IMPLICIT REAL (A-H,O-Z),
     +INTEGER (I-N)
      LOGICAL OK, LENDIAN
      INTEGER IBUF(9),JBUF(16),JBUFPT(8,2)
      COMMON /MACHTYP/ MACHINE,INTSIZE
C
      DATA JBUFPT/1,2,3,4,5,6,7,8,1,4,5,8,10,12,14,16/
C
C ---------------------------------------------------------------------
C
      IF ( IU.EQ.0 ) CALL                             XIT('FBUFFIN',-1)
      JU=ABS(IU)
      JMAX=ABS(IMAX)
      LHEAD = 8 * MACHINE
C
C     * READ THE LABEL UNLESS IU IS NEGATIVE AND IMAX IS POSITIVE.
C
      IF ( IU.LT.0 .AND. IMAX.GT.0 ) GOTO 200

      CALL RDBUF(JU,JBUF,LHEAD,OK)
      IF (.NOT. OK) THEN 
        IF ( LHEAD .LE. 0 ) THEN
          GO TO 900
        ELSE
          GO TO 910
        ENDIF
      ENDIF
C
C     * MAP 64-BIT LABEL INTO IBUF.
C
      DO 100 I=1,8
        IBUF(I) = JBUF(JBUFPT(I,MACHINE))        
  100 CONTINUE
      IF(LENDIAN()) THEN
C        IN THE OVERALL CONVERSION FROM BIG-ENDIAN UNFORMATTED RECORDS TO
C        LITTLE ENDIAN, HOLLERITH CONSTANTS HAVE BEEN INAPPROPRIATELY
C        REVERSED.  REVERSE THEM BACK.
        IF(MACHINE.EQ.2) THEN
          CALL REVERSE(IBUF(1),4)
          CALL REVERSE(IBUF(3),4)
        ELSE
          CALL REVERSE(IBUF(1),8)
          CALL REVERSE(IBUF(3),8)
        ENDIF
      ENDIF
C
C     * MAKE SURE NEGATIVE LEVEL VALUES ARE INTERPRETED CORRECTLY.
C
C     CHECKME! AND CONVERT TO IBSET?
      IF(IBUF(4).GT.(2**30 + ((2**30)-1))) THEN
C     THIS ONLY WORKS FOR 64-BIT REAL TWOTO32 (OTHERWISE ROUNDING ERROR).
      TWOTO32 = 2.D0**32
C     THIS ONLY WORKS FOR 64-BIT NINT AND WILL CAUSE PROBLEMS FOR g77
C     (WHICH ONLY HAS 32-BIT NINT).
      IBUF(4)=IBUF(4)-NINT(TWOTO32)
      ENDIF
C
C     * IF BOTH IU AND IMAX ARE NEGATIVE, RETURN WITH THE LABEL AND
C     * LEAVE THE POINTER AT THE BEGINNING OF THE DATA RECORD.
C     * IF IU IS POSITIVE AND IMAX IS NEGATIVE, SKIP OVER
C     * THE DATA RECORD AND RETURN WITH JUST THE LABEL.
C
      IF ( IMAX.LT.0 ) THEN
        IF ( IU.GT.0 ) THEN
C          READ (JU,END=920,ERR=910)
C          ALWAYS USE RDSKIP TO SKIP RECORDS.
          CALL RDSKIP(JU,NSKIP,OK)
          IF (.NOT. OK) THEN 
            IF ( NSKIP .LE. 0 ) THEN
              GO TO 920
            ELSE
              GO TO 910
            ENDIF
          ENDIF
        ENDIF
        K = -2
        RETURN
      ENDIF
C
C     * CALCULATE THE LENGTH OF THE DATA RECORD.
C
  200 CALL LBLCHK(LEN,NWDS,NPACK,IBUF)
C
C     * SET THE STATUS INFORMATION AND ENSURE THAT THE LENGTH
C     * DOES NOT EXCEED THE MAXIMUM SPECIFIED. JMAX MUST BE
C     * INCREASED BY AN EXTRA 8 WORDS (FOR THE LABEL) IF MACHINE=2.
C
      JMAX = JMAX + (LHEAD - 8)
      IF ( LEN .LT. JMAX ) THEN
        K = -1
      ELSEIF ( LEN .EQ. JMAX ) THEN
        K = -2
      ELSE
        WRITE(6,6000) JMAX,LEN
        K = 1
        LEN = JMAX 
      ENDIF
C
C     * READ THE DATA AND RETURN.
C
      LENGTH = LEN - LHEAD
      LEN    = LENGTH + 8
      CALL RDBUF(JU,IBUF(9),LENGTH,OK)
      IF (.NOT. OK) THEN 
        IF ( LENGTH .LE. 0 ) THEN
          GO TO 920
        ELSE
          GO TO 930
        ENDIF
      ENDIF
      IF(LENDIAN()) THEN
        IF(IBUF(1).EQ.NC4TO8("LABL").OR.IBUF(1).EQ.NC4TO8("CHAR")) THEN
C          IN THE OVERALL CONVERSION FROM BIG-ENDIAN UNFORMATTED RECORDS TO
C          LITTLE ENDIAN, HOLLERITH CONSTANTS HAVE BEEN INAPPROPRIATELY
C          REVERSED.  REVERSE THEM BACK.
          DO 300 I = 9,LENGTH+8
            IF(MACHINE.EQ.2) THEN
              CALL REVERSE(IBUF(I),4)
            ELSE
              CALL REVERSE(IBUF(I),8)
            ENDIF
  300     CONTINUE
        ELSEIF(INTSIZE.EQ.2.AND.(NPACK.EQ.0.OR.NPACK.EQ.1)) THEN
C          IN THE OVERALL CONVERSION FROM BIG-ENDIAN UNFORMATTED RECORDS TO
C          LITTLE ENDIAN FOR INTSIZE = 2, THE BYTE-REVERSAL HAS BEEN DONE
C          FOR INDIVIDUAL 4-BYTE WORDS RATHER THAN THE 8-BYTE WORDS CONTAINING
C          FLOATING-POINT NUMBERS.  TO GET THOSE 8-BYTE NUMBERS IN THE
C          CORRECT ORDER MUST SWAP EVERY SECOND WORD.
          DO 310 I = 9,LENGTH+7,2
            ISWAP = IBUF(I)
            IBUF(I) = IBUF(I+1)
            IBUF(I+1) = ISWAP
  310     CONTINUE
        ELSEIF(NPACK.NE.0.AND.NPACK.NE.1) THEN
          IMAX3 = 8+4
          IF(IBUF(1).EQ.NC4TO8("SPEC")) IMAX3 = IMAX3 + 2
          IF(INTSIZE.EQ.2) THEN
C            IN THE OVERALL CONVERSION FROM BIG-ENDIAN UNFORMATTED RECORDS TO
C            LITTLE ENDIAN FOR INTSIZE = 2, THE BYTE-REVERSAL HAS BEEN DONE
C            FOR INDIVIDUAL 4-BYTE WORDS RATHER THAN THE 8-BYTE WORDS CONTAINING
C            FLOATING-POINT NUMBERS.  TO GET THOSE 8-BYTE NUMBERS IN THE
C            CORRECT ORDER MUST SWAP EVERY SECOND WORD.
            DO 320 I = 9,IMAX3-1,2
              ISWAP = IBUF(I)
              IBUF(I) = IBUF(I+1)
              IBUF(I+1) = ISWAP
  320       CONTINUE
          ENDIF
C          IN THE OVERALL CONVERSION FROM BIG-ENDIAN UNFORMATTED RECORDS TO
C          LITTLE ENDIAN FOR MACHINE = 1, THE BYTE-REVERSAL HAS BEEN DONE
C          FOR INDIVIDUAL 8-BYTE WORDS RATHER THAN THE 4-BYTE WORDS THAT
C          ARE THE STANDARD FOR PACKED DATA.  HOWEVER, IN THIS SAME CASE
C          (LITTLE-ENDIAN, MACHINE=1, SEE GBYTESB TO VERIFY THIS) GBYTESB
C          EFFECTIVELY WORD SWAPS SO EVERYTHING WORKS OUT AND THERE IS NO
C          NEED FOR ADDITIONAL WORD SWAPPING HERE.
        ENDIF
      ENDIF
      RETURN
C
C     * NORMAL END OF FILE CONDITION.
C
  900 K = 0
      LEN = 0
      RETURN
C
C     * UNEXPECTED TERMINATION OF READ OPERATION.
C 
  910 K = 2
      LEN = 0
      WRITE(6,6010)
      RETURN
  920 K = 2
      WRITE(6,6020) 
      RETURN
  930 K = 2
      WRITE(6,6010)
      RETURN
C
C ---------------------------------------------------------------------
C 
 6000 FORMAT('WARNING: SPECIFIED SIZE OF BUFFER ARRAY TOO SMALL',/,
     1       '         SIZE SPECIFIED:',I10,', SIZE REQUIRED:',I10)
 6010 FORMAT('WARNING: ERROR OCCURRED DURING READ')  
 6020 FORMAT('WARNING: UNEXPECTED END OF FILE')
 6025 FORMAT(' ',A4,I10,2X,A4,5I10)
      END
