MODULE MOD_IOF

CONTAINS
	!>	\brief Read a volume from a file which has already been opened
	SUBROUTINE READ_VOL(LUN,ARRAY,DIMX,DIMY,DIMZ)
		USE, INTRINSIC	::	ISO_C_BINDING
		IMPLICIT NONE
		! Arguments
		INTEGER,							INTENT(IN)		::	LUN			!<	The logical unit number of the opened file to read from
		REAL,		TARGET,	ALLOCATABLE,	INTENT(INOUT)	::	ARRAY(:)	!<	The array (with allocated memory) to read into
		INTEGER,							INTENT(IN)		::	DIMX,DIMY,DIMZ	!<	Expected dimensions
		! Private variables
		INTEGER*1,POINTER	::	D(:)
		TYPE(C_PTR)			::	CPTR
		! Start work

		! Check memory is allocated
		IF (.NOT. ALLOCATED(ARRAY)) THEN
			WRITE(*,'(A)') '**ERROR(READ_VOL): no memory allocated to array'
			STOP 'Fatal error in READ_VOL'
		ENDIF
		! Check enough memory is allocated
		IF (DIMX*DIMY*DIMZ .GT. SIZE(ARRAY)) THEN
			WRITE(*,'(A)') '**ERROR(READ_VOL): not enough memory allocated to array'
			WRITE(*,*) '**debug(READ_VOL): SIZE(ARRAY) = ', SIZE(ARRAY)
			WRITE(*,*) '**debug(READ_VOL): DIMX,DIMY,DIMZ = ', DIMX,DIMY,DIMZ
			STOP 'Fatal error in READ_VOL'
		ENDIF
		! Zero the array
		ARRAY(1:DIMX*DIMY*DIMZ) = 0.0
		! The C pointer needs to point to the real array
		CPTR = C_LOC(ARRAY)
		! The C pointer is converted to a Fortran pointer of the type which the old subroutines expect
		CALL C_F_POINTER(CPTR,D,[4*SIZE(ARRAY,1)])
		! Call the actual IOF subroutine
		CALL IRDVOL(LUN,D)

	END SUBROUTINE READ_VOL

	!>	\brief Write a volume to a file which has already been opened
	SUBROUTINE WRITE_VOL(LUN,ARRAY,DIMX,DIMY,DIMZ)
		USE, INTRINSIC	::	ISO_C_BINDING
		IMPLICIT NONE
		! Arguments
		INTEGER,							INTENT(IN)		::	LUN			!<	The logical unit number of the opened file to read from
		REAL,		TARGET,	ALLOCATABLE,	INTENT(IN)		::	ARRAY(:)	!<	The array (with allocated memory) to read into
		INTEGER,							INTENT(IN)		::	DIMX,DIMY,DIMZ	!<	Expected dimensions
		! Private variables
		INTEGER*1,POINTER	::	D(:)
		TYPE(C_PTR)			::	CPTR
		! Start work

		! Check memory is allocated
		IF (.NOT. ALLOCATED(ARRAY)) THEN
			WRITE(*,'(A)') '**ERROR(WRITE_VOL): no memory allocated to array'
			STOP 'Fatal error in WRITE_VOL'
		ENDIF
		! Check enough memory is allocated
		IF (DIMX*DIMY*DIMZ .GT. SIZE(ARRAY)) THEN
			WRITE(*,'(A)') '**ERROR(WRITE_VOL): not enough memory allocated to array'
			STOP 'Fatal error in WRITE_VOL'
		ENDIF
		! The C pointer needs to point to the real array
		CPTR = C_LOC(ARRAY)
		! The C pointer is converted to a Fortran pointer of the type which the old subroutines expect
		CALL C_F_POINTER(CPTR,D,[4*SIZE(ARRAY,1)])
		! Call the actual IOF subroutine
		CALL IWRTVL(LUN,D)

	END SUBROUTINE WRITE_VOL

	!>	\brief interface to IWRITE routine
	SUBROUTINE IWRITE2(LUN,ARRAY,DIM,LINE)
		USE, INTRINSIC	::	ISO_C_BINDING
		IMPLICIT NONE
		! Arguments
		INTEGER,							INTENT(IN)		::	LUN			!<	The logical unit number of the opened file to read from
		INTEGER,							INTENT(IN)		::	DIM	!< Dimension of the line (ie. number of elements in array)
		REAL,		TARGET,					INTENT(IN)		::	ARRAY(DIM)	!<	The array (with allocated memory) to read into
		INTEGER,							INTENT(IN)		::	LINE	!<	Line/record number
		! Private variables
		INTEGER*1,POINTER	::	D(:)
		TYPE(C_PTR)			::	CPTR
		! The C pointer needs to point to the real array
		CPTR = C_LOC(ARRAY)
		! Convert the pointer from C to F
		CALL C_F_POINTER(CPTR,D,[4*DIM])
		! Call IWRITE
		CALL IWRITE(LUN,D,LINE)
	END SUBROUTINE IWRITE2

END MODULE MOD_IOF
