/*-------------- Telecommunications & Signal Processing Lab ---------------
                             McGill University

Routine:
  int AFreadHead (FILE *fp, long int offs, void *buf, int size, int Nelem,
                  int Swapb)

Purpose:
  Read and optionally swap audio file header values

Description:
  This routine reads data from an audio file header.  The information to be
  read is considered to be organized as Nelem elements each of size bytes.
  The information (Nelem * size bytes) is read into memory in file byte order.
  Then, optionally each of the Nelem elements is byte swapped.

  This routine prints an error message and halts if it cannot read all of the
  data requested.

Parameters:
  <-  int AFreadHead
      Number of bytes read (equal to Nelem * size)
   -> long int offs
      Offset in bytes into the file for the data to be read
  <-  void *buf
      Pointer to a buffer of size Nelem * size
   -> int size
      Size of each element in bytes
   -> int Nelem
      Number of elements to be read
   -> int Swapb
      Byte swap flag.  This parameter is not used for size = 1.  If the bytes
      are to be swapped, size must be 2, 4 or 8 bytes.
      DS_EB     - File data is in big-endian byte order.  The data will be
                  swapped if the current host uses little-endian byte order.
      DS_EL     - File data is in little-endian byte order data.  The data will
                  be swapped if the current host uses big-endian byte order.
      DS_NATIVE - File data is in native byte order
      DS_SWAP   - File data is byte-swapped

Author / revision:
  P. Kabal  Copyright (C) 1995
  $Revision: 1.2 $  $Date: 1995/09/14 11:46:17 $

-------------------------------------------------------------------------*/

static char rcsid[] = "$Id: AFreadHead.c 1.2 1995/09/14 AFsp-V2R1 $";

#include <libtsp.h>
#include <libtsp/nucleus.h>
#include <libtsp/AFpar.h>

int
AFreadHead (fp, offs, buf, size, Nelem, Swapb)

     FILE * fp;
     long int offs;
     void *buf;
     int size;
     int Nelem;
     int Swapb;

{
  int Nb, Nbr;
  static int Hbo = DS_UNDEF;

/* Read the data in file byte order */
  Nb = size * Nelem;
  Nbr = FLreadFile (fp, offs, buf, (size_t) 1, (size_t) Nb);
  if (Nbr != Nb)
    UThalt ("AFreadHead: Unexpected end-of-file while reading header");

/* Swap the data if necessary */
  if (size != 1) {
    switch (Swapb) {
    case DS_EB:
    case DS_EL:
      if (Hbo == DS_UNDEF)
	Hbo = UTbyteOrder ();
      if (Hbo == Swapb)
	Swapb = DS_NATIVE;
      else
	Swapb = DS_SWAP;
      break;
    case DS_SWAP:
    case DS_NATIVE:
      break;
    default:
      UThalt ("AFreadHead: Invalid byte swap code");
    }

    if (Swapb == DS_SWAP)
      VRswapBytes (buf, buf, (size_t) size, Nelem);
  }

  return Nb;
}