| |||||||||||
Using the 'zlib' library to provide IO driver 'compress' functionality Description This example module uses the 'zlib' library (see: http://www.gzip.org) to provide the
I/O driver 'compress' (e.g. "zlib.compress:model.bim")
for stream compression and 'gzip' (e.g. "zlib.gzip:data.gz")
for handling gzip files. Language extensions provided by this module:
Source Files By clicking on a file name, a preview is opened at the bottom of this page.
zlib.c /****************************************** Mosel NI Examples ================= File zlib.c ``````````` Example module defining an IO driver for (un)compression using zlib library which can be found at http://www.zlib.org (c) 2008 Fair Isaac Corporation author: Y. Colombani, 2003 zlib: (c) 1995-2002 Jean-Loup Gailly and Mark Adler *******************************************/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #define XPRM_NICOMPAT 3004002 /* Compatibility level: Mosel 3.4.2 */ #include "xprm_ni.h" #ifdef _WIN32 #define snprintf _snprintf #define _WINDOWS #define ZLIB_DLL /* for precompiled zlib 1.2.1 */ #define ZLIB_WINAPI #endif #include "zlib.h" #define BUFSIZE 1024 /* buffer size for data transfer */ /**************************************************/ /* gzip driver: to handle files using GZIP format */ /* Example: "zlib.gzip:mydata.gz" */ /**************************************************/ /* Functions of 'gzip' driver */ static void *gzip_open(XPRMcontext ctx,int *mode,const char *fname); static int gzip_close(XPRMcontext ctx,gzFile gzf,int mode); static long gzip_read(XPRMcontext ctx,gzFile gzf,void *buffer, unsigned long size); static long gzip_write(XPRMcontext ctx,gzFile gzf,void *buffer, unsigned long size); static void setgzerror(XPRMcontext ctx,gzFile gzf); static XPRMiofcttab iodrv_gzip[]= { {XPRM_IOCTRL_OPEN,gzip_open}, {XPRM_IOCTRL_CLOSE,gzip_close}, {XPRM_IOCTRL_READ,gzip_read}, {XPRM_IOCTRL_WRITE,gzip_write}, {XPRM_IOCTRL_INFO,"filename"}, {0,NULL} }; /*************************************************/ /* compress driver: to handle compressed streams */ /* As opposed to 'gzip' driver this driver does */ /* not require a physical file */ /* Note also that files produced by this driver */ /* are not compatible with gzip */ /* Example: "zlib.compress:mem:0x1234/256" */ /**************************************************/ /* Functions of 'compress' driver */ static void *comp_open(XPRMcontext ctx,int *mode,const char *fname); static int comp_close(XPRMcontext ctx,z_streamp zstr,int mode); static long comp_read(XPRMcontext ctx,z_streamp zstr,void *buffer, unsigned long size); static long comp_write(XPRMcontext ctx,z_streamp zstr,void *buffer, unsigned long size); static XPRMiofcttab iodrv_compress[]= { {XPRM_IOCTRL_OPEN,comp_open}, {XPRM_IOCTRL_CLOSE,comp_close}, {XPRM_IOCTRL_READ,comp_read}, {XPRM_IOCTRL_WRITE,comp_write}, {XPRM_IOCTRL_INFO,"extended_filename"}, {0,NULL} }; /* Drivers of zlib module: gzip,compress */ static XPRMiodrvtab iodrv_zlib[]= { {"gzip",iodrv_gzip}, {"compress",iodrv_compress}, {NULL,NULL} }; static int chkres(int); /* Table of services: only IO drivers */ static XPRMdsoserv tabserv[]= { {XPRM_SRV_IODRVS,iodrv_zlib}, {XPRM_SRV_CHKRES,(void*)chkres} }; /* DSO interface: only services */ static XPRMdsointer dsointer= { 0,NULL, 0,NULL, 0,NULL, sizeof(tabserv)/sizeof(mm_dsoserv),tabserv }; static XPRMnifct mm; /* For storing Mosel NI function table */ /************************************************/ /* Initialize the library just after loading it */ /************************************************/ DSO_INIT zlib_init(XPRMnifct nifct, int *interver,int *libver, XPRMdsointer **interf) { const char *zlv; mm=nifct; /* Save the table of Mosel NI functions */ *interver=XPRM_NIVERS; /* The interface version we are using */ /* We check ZLIB library version here */ zlv=zlibVersion(); if((zlv==NULL)||(zlv[0]!=ZLIB_VERSION[0])) { mm->dispmsg(NULL,"ZLIB: wrong version (expect %s got %s).\n",ZLIB_VERSION, (zlv!=NULL)?zlv:"0"); return 1; } else { *libver=XPRM_MKVER(0,0,2); /* The version of the module: 0.0.2 */ *interf=&dsointer; /* Our interface */ return 0; } } /****************************************************************/ /* Check restrictions (this module implements all restrictions) */ /****************************************************************/ static int chkres(int r) { return 0; } /****************************************/ /* Open a gzip-file for (de)compression */ /****************************************/ static void *gzip_open(XPRMcontext ctx,int *mode,const char *fname) { char cfname[MM_MAXPATHLEN]; char cmode[16]; int cml; void *gzf; if((fname==NULL)|| (mm->pathcheck(ctx,fname,cfname,MM_MAXPATHLEN, ((*mode)&MM_F_WRITE)?MM_RCHK_WRITE:MM_RCHK_READ)!=0)) { mm->setioerrmsg(ctx,strerror(EACCES),1); return NULL; } else { cml=2; cmode[0]=((*mode)&MM_F_WRITE)?'w':'r'; cmode[1]=((*mode)&MM_F_BINARY)?'b':'t'; if((*mode)&MM_F_APPEND) cmode[cml++]='a'; cmode[cml]='\0'; gzf=gzopen(cfname,cmode); if(gzf==NULL) mm->setioerrmsg(ctx,strerror(errno),2); return gzf; } } /***********************/ /* Close the gzip-file */ /***********************/ static int gzip_close(XPRMcontext ctx,gzFile gzf,int mode) { return gzclose(gzf); } /******************************/ /* Uncompress a block of data */ /******************************/ static long gzip_read(XPRMcontext ctx,gzFile gzf,void *buffer, unsigned long size) { long l; l=gzread(gzf,buffer,size); if(l<0) setgzerror(ctx,gzf); return l; } /****************************/ /* Compress a block of data */ /****************************/ static long gzip_write(XPRMcontext ctx,gzFile gzf,void *buffer, unsigned long size) { long l; l=gzwrite(gzf,buffer,size); if(l<=0) setgzerror(ctx,gzf); return l; } /*********************************/ /* Set message of the last error */ /*********************************/ static void setgzerror(XPRMcontext ctx,gzFile gzf) { int errnum; const char *emsg; if((((emsg=gzerror(gzf,&errnum))!=NULL)&&(errnum==Z_ERRNO))) { errnum=errno; emsg=strerror(errno); } if(errnum!=0) mm->setioerrmsg(ctx,emsg,errnum); } /*************************************/ /* Open a stream for (de)compression */ /*************************************/ static void *comp_open(XPRMcontext ctx,int *mode,const char *fname) { z_streamp zstr; int rts; /* 1st: open actual file */ if(mm->fopen(ctx,((*mode)&XPRM_F_WRITE)|XPRM_F_BINARY,fname)<0) { *mode|=XPRM_F_SILENT; /* Error message already displayed */ /* switch so silent mode */ return NULL; } else { /* If OK, prepare data structures for zlib */ /* Allocate memory for zstream and a buffer */ if((zstr=(z_streamp)malloc(sizeof(z_stream)+BUFSIZE))==NULL) { mm->fclose(ctx,(*mode)&(XPRM_F_READ|XPRM_F_WRITE)); mm->setioerrmsg(ctx,"Not enough memory",1); return NULL; } memset(zstr,0,sizeof(z_stream)); zstr->zalloc=Z_NULL; zstr->zfree=Z_NULL; if(((*mode)&(XPRM_F_READ|XPRM_F_WRITE))==XPRM_F_READ) { /* For reading: 'inflate' algorithm */ rts=inflateInit(zstr); zstr->next_in=(void *)(zstr+1); /* Buffer is after zstream */ } else { /* For writing: 'deflate' algorithm */ rts=deflateInit(zstr,Z_DEFAULT_COMPRESSION); zstr->next_out=(void *)(zstr+1); /* Buffer is after zstream */ zstr->avail_out=BUFSIZE; } if(rts!=Z_OK) { mm->setioerrmsg(ctx,zstr->msg,rts); free(zstr); mm->fclose(ctx,(*mode)&(XPRM_F_READ|XPRM_F_WRITE)); return NULL; } else return zstr; } } /********************/ /* Close the stream */ /********************/ static int comp_close(XPRMcontext ctx,z_stream *zstr,int mode) { int rts1,rts2; Bytef dummy; if((mode&(XPRM_F_READ|XPRM_F_WRITE))==XPRM_F_READ) { /* If reading: just release zstream */ rts1=inflateEnd(zstr); } else { /* If writing: buffers have to be flushed first */ zstr->next_in=&dummy; zstr->avail_in=0; if(zstr->avail_out==0) { mm->fwrite(ctx,zstr+1,BUFSIZE); zstr->next_out=(void *)(zstr+1); zstr->avail_out=BUFSIZE; } do { rts1=deflate(zstr,Z_FINISH); if(BUFSIZE-zstr->avail_out>0) mm->fwrite(ctx,zstr+1,BUFSIZE-zstr->avail_out); zstr->next_out=(void *)(zstr+1); zstr->avail_out=BUFSIZE; } while(rts1==Z_OK); rts1=deflateEnd(zstr); } /* Finally close actual file and release memory */ rts2=mm->fclose(ctx,mode); if(rts1!=Z_OK) mm->setioerrmsg(ctx,zstr->msg,rts1); free(zstr); return (rts1!=Z_OK)||(rts2!=0); } /******************************/ /* Uncompress a block of data */ /******************************/ static long comp_read(XPRMcontext ctx,z_stream *zstr,void *buffer, unsigned long size) { int rts,finish; zstr->next_out=buffer; zstr->avail_out=size; finish=0; do { if(zstr->avail_in==0) { zstr->avail_in=mm->fread(ctx,zstr+1,BUFSIZE); zstr->next_in=(void *)(zstr+1); finish=(zstr->avail_in==0); } rts=inflate(zstr,Z_NO_FLUSH); } while((rts==Z_OK)&&(zstr->avail_out>0) && !finish); if(finish && (zstr->avail_out>0)) rts=inflate(zstr,Z_SYNC_FLUSH); if((rts==Z_OK)||(rts==Z_STREAM_END)) return (long)(size-zstr->avail_out); else { mm->setioerrmsg(ctx,zstr->msg,rts); return -1; } } /****************************/ /* Compress a block of data */ /****************************/ static long comp_write(XPRMcontext ctx,z_stream *zstr,void *buffer, unsigned long size) { int rts; zstr->next_in=buffer; zstr->avail_in=size; do { if(zstr->avail_out==0) { mm->fwrite(ctx,zstr+1,BUFSIZE); zstr->next_out=(void *)(zstr+1); zstr->avail_out=BUFSIZE; } rts=deflate(zstr,Z_NO_FLUSH); } while((rts==Z_OK)&&(zstr->avail_in>0)); if(rts==Z_OK) return 1; else { mm->setioerrmsg(ctx,zstr->msg,rts); return 0; } } | |||||||||||
© Copyright 2024 Fair Isaac Corporation. |