I'm trying to read a gzip file in Fortran using the C functions gzopen, gzread, and gzclose from the zlib library. My subroutine works properly when it contains a print statement, but gives a Z_STREAM_ERROR (-2)
without it. What is causing this to happen, and how can I fix it?
module gzmodule
use :: iso_c_binding
implicit none
private
public fastunzip
interface
type(c_ptr) function gzopen(filename,mode) bind(c)
use :: iso_c_binding
character(kind=c_char), dimension(*) :: filename
character(kind=c_char), dimension(*) :: mode
end function gzopen
end interface
interface
integer(c_int) function gzread(gzfile,buffer,length) bind(c)
use :: iso_c_binding
type(c_ptr), value :: gzfile
character(len=1,kind=c_char) :: buffer(*)
integer(c_int) :: length
end function gzread
end interface
interface
integer(c_int) function gzclose(gzfile) bind(c)
use :: iso_c_binding
type(c_ptr), value :: gzfile
end function
end interface
contains
subroutine fastunzip(filename, isize,abuf,ierr)
use :: iso_c_binding
character(len=*,kind=c_char), intent(in) :: filename
integer(c_int), intent(out) :: isize
character(len=1,kind=c_char), intent(inout) :: abuf(:,:,:,:)
integer(4), intent(out) :: ierr
type(c_ptr) :: gzfile
integer(c_int) :: iclose
logical :: c_associated
ierr = 1 !! indicates that an error has occured
isize = 0
gzfile = gzopen(trim(filename)//c_null_char,"rb")
if (.not.c_associated(gzfile)) return
isize = gzread(gzfile,abuf,size(abuf))
print*,isize !! why do I need this for it to work?
if (isize.ne.size(abuf)) return
iclose = gzclose(gzfile)
if (iclose.ne.0) return
ierr = 0 !! success
end subroutine fastunzip
end module gzmodule
program main
use gzmodule
implicit none
character(100) :: filename = './f10_19950120v7.gz'
integer(4) :: isize
integer(4) :: ierr
logical(4) :: exists
integer(4), parameter :: nlon = 1440
integer(4), parameter :: nlat = 720
integer(4), parameter :: nvar = 5
integer(4), parameter :: nasc = 2
character(1) :: abuf(nlon,nlat,nvar,nasc)
inquire(file=filename,exist=exists)
if (.not.exists) stop 'file not found'
call fastunzip(filename, isize,abuf,ierr)
print*,'return value of isize ',isize
if (ierr.ne.0) stop 'error in fastunzip'
print*,'done'
end program main
I'm on CentOS and compiling with:
gfortran -o example_usage.exe example_usage.f90 /lib64/libz.so.1
and the data file is available at this site.
In subroutine fastunzip
you declare logical :: c_associated
. However, you get this function by use association (of iso_c_binding
), so you should remove that line.
My installed gfortran (4.8) marks that as an error, so I guess you have an older version? But once I remove that line your code appears to work even without the print
, so perhaps that is worth trying for you.
On a style note, I'd recommend use, intrinsic :: iso_c_binding
, perhaps even with only
(which would also flag to you that the c_associated
is through use association).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With