Skip to content

Commit

Permalink
add fortran 90 function interface and demo code
Browse files Browse the repository at this point in the history
  • Loading branch information
fangq committed May 25, 2020
1 parent f0cbcf5 commit b333987
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
116 changes: 116 additions & 0 deletions fortran90/zmatlib.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
!------------------------------------------------------------------------------
! ZMat - A portable C-library and MATLAB/Octave toolbox for inline data compression
!------------------------------------------------------------------------------
!
! module: zmatlib
!
!> @author Qianqian Fang <q.fang at neu.edu>
!
!> @brief An interface to call the zmatlib C-library
!
! DESCRIPTION:
!> ZMat provides an easy-to-use interface for stream compression and decompression.
!>
!> It can be compiled as a MATLAB/Octave mex function (zipmat.mex/zmat.m) and compresses
!> arrays and strings in MATLAB/Octave. It can also be compiled as a lightweight
!> C-library (libzmat.a/libzmat.so) that can be called in C/C++/FORTRAN etc to
!> provide stream-level compression and decompression.
!>
!> Currently, zmat/libzmat supports 6 different compression algorthms, including
!> - zlib and gzip : the most widely used algorithm algorithms for .zip and .gz files
!> - lzma and lzip : high compression ratio LZMA based algorithms for .lzma and .lzip files
!> - lz4 and lz4hc : real-time compression based on LZ4 and LZ4HC algorithms
!> - base64 : base64 encoding and decoding
!
!> @section slicense License
!> GPL v3, see LICENSE.txt for details
!------------------------------------------------------------------------------

module zmatlib
use iso_c_binding, only: c_char,c_size_t,c_int,c_ptr, c_f_pointer
implicit none

!------------------------------------------------------------------------------
!> @brief Compression/encoding methods
!
! DESCRIPTION:
!> 0: zmZlib
!> 1: zmGzip
!> 2: zmBase64
!> 3: zmLzip
!> 4: zmLzma
!> 5: zmLz4
!> 6: zmLz4hc
!------------------------------------------------------------------------------

integer(c_int), parameter :: zmZlib=0, zmGzip=1, zmBase64=2, zmLzip=3, zmLzma=4, zmLz4=5, zmLz4hc=6

interface

!------------------------------------------------------------------------------
!> @brief Main interface to perform compression/decompression
!
!> @param[in] inputsize: input stream buffer length
!> @param[in] inputstr: input stream buffer pointer
!> @param[in] outputsize: output stream buffer length
!> @param[in] outputbuf: output stream buffer pointer
!> @param[in] ret: encoder/decoder specific detailed error code (if error occurs)
!> @param[in] iscompress: 0: decompression, 1: use default compression level;
!> negative interger: set compression level (-1, less, to -9, more compression)
!> @return return the coarse grained zmat error code; detailed error code is in ret.
!------------------------------------------------------------------------------

integer(c_int) function zmat_run(inputsize, inputbuf, outputsize, outputbuf, zipid, ret, level) bind(C)
use iso_c_binding, only: c_char,c_size_t,c_int,c_ptr
integer(c_size_t), value :: inputsize
integer(c_int), value :: zipid, level
integer(c_size_t), intent(out) :: outputsize
integer(c_int), intent(out) :: ret
character(kind=c_char), intent(in) :: inputbuf(*)
type(c_ptr),intent(out) :: outputbuf
end function zmat_run

!------------------------------------------------------------------------------
!> @brief Simplified interface to perform compression, same as zmat_run(...,1)
!
!> @param[in] inputsize: input stream buffer length
!> @param[in] inputstr: input stream buffer pointer
!> @param[in] outputsize: output stream buffer length
!> @param[in] outputbuf: output stream buffer pointer
!> @param[in] ret: encoder/decoder specific detailed error code (if error occurs)
!> @return return the coarse grained zmat error code; detailed error code is in ret.
!------------------------------------------------------------------------------

integer(c_int) function zmat_encode(inputsize, inputbuf, outputsize, outputbuf, zipid, ret) bind(C)
use iso_c_binding, only: c_char,c_size_t,c_int,c_ptr
integer(c_size_t), value :: inputsize
integer(c_int), value :: zipid
integer(c_size_t), intent(out) :: outputsize
integer(c_int), intent(out) :: ret
character(kind=c_char), intent(in) :: inputbuf(*)
type(c_ptr),intent(out) :: outputbuf
end function zmat_encode

!------------------------------------------------------------------------------
!> @brief Simplified interface to perform decompression, same as zmat_run(...,0)
!
!> @param[in] inputsize: input stream buffer length
!> @param[in] inputstr: input stream buffer pointer
!> @param[in] outputsize: output stream buffer length
!> @param[in] outputbuf: output stream buffer pointer
!> @param[in] ret: encoder/decoder specific detailed error code (if error occurs)
!> @return return the coarse grained zmat error code; detailed error code is in ret.
!------------------------------------------------------------------------------

integer(c_int) function zmat_decode(inputsize, inputbuf, outputsize, outputbuf, zipid, ret) bind(C)
use iso_c_binding, only: c_char,c_size_t,c_int,c_ptr
integer(c_size_t), value :: inputsize
integer(c_int), value :: zipid
integer(c_size_t), intent(out) :: outputsize
integer(c_int), intent(out) :: ret
character(kind=c_char), intent(in) :: inputbuf(*)
type(c_ptr),intent(out) :: outputbuf
end function zmat_decode

end interface
end module
7 changes: 7 additions & 0 deletions test/f90/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
F90 :=gfortran

all:
$(F90) -g -Wall -pedantic -c ../../fortran90/zmatlib.f90
$(F90) -g -Wall -pedantic testzmat.f90 -o testzmat -L../../lib -lzmat -lz
clean:
-rm -f testzmat *.o *.mod
35 changes: 35 additions & 0 deletions test/f90/testzmat.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
!------------------------------------------------------------------------------
! ZMatLib test program
!------------------------------------------------------------------------------
!
!> @author Qianqian Fang <q.fang at neu.edu>
!> @brief A demo program to call zmatlib functions to encode and decode
!
! DESCRIPTION:
!> This demo program shows how to call zmat_run/zmat_encode/zmat_decode to
!> perform buffer encoding and decoding
!------------------------------------------------------------------------------

program zmatdemo

! step 1: add the below line to use zmatlib unit
use zmatlib
implicit none

character (len=128) inputstr
integer :: ret, res
integer(kind=8) :: inputlen, outputlen
type(c_ptr) :: outputbuf
character(kind=c_char),pointer :: myout(:)

inputstr="__o000o__(o)(o)__o000o__ =^_^= __o000o__(o)(o)__o000o__"
inputlen=len(trim(inputstr))

print *, trim(inputstr)

res=zmat_run(inputlen,inputstr,outputlen, outputbuf, zmBase64, ret, 1);

call c_f_pointer(outputbuf, myout, [outputlen])
print *, myout

end program

0 comments on commit b333987

Please sign in to comment.