module xdr_files
! f90 interface to XDR routines
! uses library libfxdr.a
! Time-stamp: "03/03/18 08:06:30 cjn"
  use io_units, only: fo
  implicit none

  interface xdr_io
     module procedure xdr_int, xdr_imt, xdr_real
     module procedure xdr_rlmt, xdr_chrs
  end interface

  logical, save :: real64=.false.
  integer, save :: hbufl = 2048 ! xdr file buffer length

  private
  public xdr_io, open_xdr, close_xdr, rewind_xdr, hbufl

contains
   function open_xdr (file, action)
! open xdr file, fortran open syntax style
    integer                          :: open_xdr
    character(len=*), intent(in)     :: file
    character(len=*), intent(in)     :: action
    integer                          :: xdr_open, imode, lenf

    if (action(:1) == 'r' .or. action(:1) == 'R') then
       imode = 1
    elseif (action(:1) == 'w' .or. action(:1) == 'W') then
       imode = 2
    else
       write (fo,'(a,a5)') 'open_xdr error: unknown action =', &
            TRIM(action)
       stop
    endif

    lenf = LEN(TRIM(file))
    open_xdr = xdr_open (lenf, file, imode) + 1
  end function open_xdr

  subroutine close_xdr (xdr)
    integer, intent(in)     :: xdr

    call xdr_close(xdr-1)
  end subroutine close_xdr

  subroutine rewind_xdr (xdr)
    integer, intent(in)     :: xdr

    call xdr_rewind (xdr-1)
  end subroutine rewind_xdr

  subroutine xdr_int (xdr, ival)
    integer, intent(in)      ::  xdr
    integer, intent(inout)   ::  ival

    call xdr_fint (xdr-1, ival)
  end subroutine xdr_int

  subroutine xdr_imt (xdr, ival, nels)
    integer, intent(in)            :: xdr
    integer, intent(in)            :: nels
    integer, intent(inout)         :: ival(:)

    call xdr_imat (xdr-1, nels, ival)
  end subroutine xdr_imt

  subroutine xdr_real (xdr, dval)
    use precisn, only: wp
    integer, intent(in)      :: xdr
    real(wp), intent(inout)   :: dval

    if (real64) then
       call xdr_real64 (xdr-1, dval)
    else
       call xdr_fdouble (xdr-1, dval)
    endif
  end subroutine xdr_real

  subroutine xdr_rlmt (xdr, dval, nels)
    use precisn, only: wp
    integer, intent(in)           :: xdr
    integer, intent(in)           :: nels
    real(wp), intent(inout)        :: dval(nels)

    if (real64) then
       call xdr_rmat64 (xdr-1, nels, dval)
    else
       call xdr_dmat (xdr-1, nels, dval)
    endif
  end subroutine xdr_rlmt

  subroutine xdr_chrs (xdr, string)
    integer, intent(in)         :: xdr
    character(*), intent(inout) :: string

    call xdr_fstring (xdr-1, LEN(string), string)
  end subroutine xdr_chrs

end module xdr_files
