CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      SUBROUTINE READ_QAC(UNIT, QAC)
C+
C
C FUNCTIONAL DESCRIPTION:
C
C     This routine gets the next Quality and Accounting information.
C
C FORMAL ARGUMENTS:
C
C     UNIT:
C	INT	  I	The stream identifier of the input stream.  This must
C			have already been opened and positioned before the
C			first QAC in the file.
C
C     QAC:
C	/QUAL_ACCT_CAPS/  I/O  Upon return will contain the next Quality and
C			Accounting Capsule (QAC) from the input file.
C
C INTERFACE:
C
!	INTERFACE
!	  SUBROUTINE READ_QAC(UNIT, QAC)
!	    INTEGER, INTENT(IN) :: UNIT
!	    RECORD /QUAL_ACCT_CAPS/ QAC
!	    INTENT(INOUT) QAC
!	  END SUBROUTINE READ_QAC
!	END INTERFACE
C
C IMPLICIT INPUTS:
C
C     Argument QAC, field QAC.COUNTER is assummed to carry over from one call
C     to the next.  It is used as a counter to know when to stop reading QACs.
C
C     The variable LEN_QAC in common block HEADER_INFO contains the number of
C     QACs in the current data file.  If there are none it is 0.
C
C IMPLICIT OUTPUTS:
C
C     None
C
C SIDE EFFECTS:
C
C     If end of file is reached the input stream is closed.
C
C     If there are no more QACs to be read QAC.SEQ_CNTR is set ot -1 to prevent
C     a sequence counter match in other routines using this data structure. 
C     The input stream is also closed. 
C
C     If not all QACs are read the input stream will remain open.  This may be
C     a problem if another routine then wants to switch data files and start
C     processing another file.
C
C DESIGN:
C
C     increment QAC counter
C     if there are no packets left then
C       set Data Unit Sequence Counter to -1 to prevent any possible matches
C       close input stream
C       return
C     endif
C     if number of QACs in file is nonzero then
C	read next QAC from input file (14 bytes)
C	if read error or end of file (fewer than 14 bytes were read) then
C	  display error message
C	  set Data Unit Sequence Counter to -1 to prevent any possible matches
C	  close input stream
C	  return
C	endif
C     endif
C     fill in components of QAC structure; this includes offset of Data Unit in
C      Data Set, Data Unit Sequence Count, error type flags, Count of Segment
C      CRC/RS Errors, and Data Unit Fill Start Location
C     return
C
C COMMON BLOCKS:
C
C     HEADER_INFO	contains the variable LEN_QAC
C
C INCLUDE FILES:
C
C     EDBDEF.INC
C
C CREATED:
C
C     21-FEB-1996    John Paquette
C
C This version:   1.5   22-JUL-1999
C
C DEVELOPMENT HISTORY:
C 
C  Author       Date		Description of Change 
C  --------	-----------	--------------------- 
C  J. PAQUETTE  21-FEB-1996     Created
C  J. PAQUETTE   6-MAR-1996     Close the file when the last QAC element is
C				read
C  J. PAQUETTE  16-APR-1996     Handle case when file has not been completely
C				transmitted
C  J. PAQUETTE  17-JUN-1996     If we run out of QAC's prematurely, close
C				current QAC file 
C  J. PAQUETTE  16-APR-1997     Do not attempt to read beyond end of QAC list
C  L. Bleau	22-JUL-1999 1.5	added IMPLICIT NONE, comments
C  L. Bleau	10-NOV-1999	added comments
C-
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CDEC$ IDENT '1.5'
      IMPLICIT NONE
      INCLUDE 'INC_DIR:EDBDEF.INC'
      BYTE BQAC(14)
      INTEGER*4 UNIT, NBYTES, LEN_QAC
      RECORD /QUAL_ACCT_CAPS/ QAC
      COMMON /HEADER_INFO/ LEN_QAC
C
C Increment QAC counter; check to see if there are any packets left.  Note that
C if LEN_QAC is 0, then no QAC information is present, so we will close file
C and return.
C
      QAC.COUNTER = QAC.COUNTER + 1
      IF(QAC.COUNTER .GT. LEN_QAC)THEN
C
C There are no more elements in the QAC list.  Set the Sequence Counter to -1
C (a value that will never match one that has been read from a data packet, so
C that this routine will never be called again), close the file, and RETURN.
C
        QAC.SEQ_CNTR = -1
        CALL CLOSE_STREAM(UNIT)
        RETURN
      ENDIF
C
C Read next QAC packet from file, which is 14 bytes long.
C Save it in BQAC; we'll transfer its parts into QAC later.
C
      IF (LEN_QAC .NE. 0) THEN
        CALL READ_STREAM(UNIT, BQAC, 14, NBYTES)
C
C Error trapping.  Almost always this means we reached the end of file.
C
        IF (NBYTES .NE. 14) THEN
          PRINT 50, LEN_QAC, QAC.COUNTER+1
  50      FORMAT(' Expected ',I6,' QAC elements, but EOF detected while trying to read element ',I6)
C
C There are no more elements in the QAC list.  Set the Sequence Counter to -1
C (a value that will never match one that has been read from a data packet, so
C that this routine will never be called again), close the file, and RETURN.
C
          QAC.SEQ_CNTR = -1
          CALL CLOSE_STREAM(UNIT)
          RETURN
        ENDIF
      ENDIF
C
C Assemble QAC components
C
C The first item in the QAC list element is the Offset of Data Unit in Data
C Set.  This is an offset (in bytes, measured from the end of the header) of
C the data unit (i.e. packet) whose errors are described by this QAC list
C element. It is 4 bytes long. 
C
      QAC.OFFSET = ISHFT(ZEXT(BQAC(1)), 24) + ISHFT(ZEXT(BQAC(2)), 16) + 
     &		   ISHFT(ZEXT(BQAC(3)), 8) + ZEXT(BQAC(4))
C
C Next is the Data Unit Sequence Count (2 bytes). This gives the sequence
C counter of the packet to which this QAC element refers.
C
      QAC.SEQ_CNTR = 0
      CALL MVBITS( ZEXT(BQAC(5)), 0, 6, QAC.SEQ_CNTR, 8 )
      CALL MVBITS( ZEXT(BQAC(6)), 0, 8, QAC.SEQ_CNTR, 0 )
C
C Next comes Error Type Flags, an 8 bit field.  The bits are to be interpreted
C as follows: 
C  Bit          Error Type
C -----         -------------
C   0           Not used
C   1           Reed-Solomon Header Errors
C   2           Data Unit Length Code Wrong
C   3           Reed-Solomon Frame Errors 
C   4           CRC Frame Errors
C   5           Data Unit Sequence Count Error/Discontinuity ! BYTE= 20 HEX 
C   6           Detected Frame Errors During the Genereation of this Data Unit
C   7           Data Unit Containds Fill Data
C
      QAC.ERROR_TYPE_FLAGS = ZEXT(BQAC(7))
C
C The next item is the Count of Segment CRC/RS Errors (1 byte). CRC stands for
C Cycle Redundancy Check, RS stands for Reed-Solomon.
C
      QAC.COUNT_CRC_RS = ZEXT(BQAC(8))
C
C Bytes 9-12 are currently spares. The next item is the Data Unit Fill Start
C Location is 2 bytes.  If it's 0, the relevant data packet contains no fill
C data.  If its any other number, that is the byte within the packet at which
C fill data begins. 
C
      QAC.FILL_START = ISHFT(ZEXT(BQAC(13)), 8) + ZEXT(BQAC(14))
C
C Return.
C
      RETURN
      END
