subroutine read_file(self, file, is_fast, form, iostat, iomsg)
!< Read a file as a single string stream.
!<
!< @note All the lines are stored into the string self as a single ascii stream. Each line (record) is separated by a `new_line`
!< character.
!<
!< @note For unformatted read only `access='stream'` is supported with new_line as line terminator.
!<
!< @note *Fast* file reading allows a very efficient reading of streamed file, but it dumps file as single streamed string.
!<
!<```fortran
!< type(string) :: astring
!< type(string), allocatable :: strings(:)
!< type(string) :: line(3)
!< integer :: iostat
!< character(len=99) :: iomsg
!< integer :: scratch
!< integer :: l
!< logical :: test_passed(9)
!< line(1) = ' Hello World! '
!< line(2) = 'How are you? '
!< line(3) = ' All say: "Fine thanks"'
!< open(newunit=scratch, file='read_file_test.tmp')
!< write(scratch, "(A)") line(1)%chars()
!< write(scratch, "(A)") line(2)%chars()
!< write(scratch, "(A)") line(3)%chars()
!< close(scratch)
!< call astring%read_file(file='read_file_test.tmp', iostat=iostat, iomsg=iomsg)
!< call astring%split(tokens=strings, sep=new_line('a'))
!< test_passed(1) = (size(strings, dim=1)==size(line, dim=1))
!< do l=1, size(strings, dim=1)
!< test_passed(l+1) = (strings(l)==line(l))
!< enddo
!< open(newunit=scratch, file='read_file_test.tmp', form='UNFORMATTED', access='STREAM')
!< write(scratch) line(1)%chars()//new_line('a')
!< write(scratch) line(2)%chars()//new_line('a')
!< write(scratch) line(3)%chars()//new_line('a')
!< close(scratch)
!< call astring%read_file(file='read_file_test.tmp', form='unformatted', iostat=iostat, iomsg=iomsg)
!< call astring%split(tokens=strings, sep=new_line('a'))
!< test_passed(5) = (size(strings, dim=1)==size(line, dim=1))
!< do l=1, size(strings, dim=1)
!< test_passed(l+5) = (strings(l)==line(l))
!< enddo
!< open(newunit=scratch, file='read_file_test.tmp', form='UNFORMATTED', access='STREAM')
!< close(scratch, status='DELETE')
!< call astring%read_file(file='read_file_test.tmp', iostat=iostat)
!< test_passed(9) = (iostat/=0)
!< print '(L1)', all(test_passed)
!<```
!=> T <<<
class(string), intent(inout) :: self !< The string.
character(len=*), intent(in) :: file !< File name.
logical, intent(in), optional :: is_fast !< Flag to enable (super) fast file reading.
character(len=*), intent(in), optional :: form !< Format of unit.
integer, intent(out), optional :: iostat !< IO status code.
character(len=*), intent(inout), optional :: iomsg !< IO status message.
logical :: is_fast_ !< Flag to enable (super) fast file reading, local variable.
type(string) :: form_ !< Format of unit, local variable.
integer :: iostat_ !< IO status code, local variable.
character(len=:), allocatable :: iomsg_ !< IO status message, local variable.
integer :: unit !< Logical unit.
logical :: does_exist !< Check if file exist.
integer(I4P) :: filesize !< Size of the file for fast reading.
iomsg_ = repeat(' ', 99) ; if (present(iomsg)) iomsg_ = iomsg
inquire(file=file, iomsg=iomsg_, iostat=iostat_, exist=does_exist)
if (does_exist) then
is_fast_ = .false. ; if (present(is_fast)) is_fast_ = is_fast
if (is_fast_) then
open(newunit=unit, file=file, access='STREAM', form='UNFORMATTED', iomsg=iomsg_, iostat=iostat_)
inquire(file=file, size=filesize)
if (allocated(self%raw)) deallocate(self%raw)
allocate(character(len=filesize):: self%raw)
read(unit=unit, iostat=iostat_, iomsg=iomsg_) self%raw
close(unit)
else
form_ = 'FORMATTED' ; if (present(form)) form_ = form ; form_ = form_%upper()
select case(form_%chars())
case('FORMATTED')
open(newunit=unit, file=file, status='OLD', action='READ', iomsg=iomsg_, iostat=iostat_, err=10)
case('UNFORMATTED')
open(newunit=unit, file=file, status='OLD', action='READ', form='UNFORMATTED', access='STREAM', &
iomsg=iomsg_, iostat=iostat_, err=10)
endselect
call self%read_lines(unit=unit, form=form, iomsg=iomsg_, iostat=iostat_)
10 close(unit)
endif
else
iostat_ = 1
iomsg_ = 'file not found'
endif
if (present(iostat)) iostat = iostat_
if (present(iomsg)) iomsg = iomsg_
endsubroutine read_file