String compression on iSeries using zLib
The public domian zLib product is an excellent tool for compressing and uncompressing data files.
In January 2002, Nick Hobson presented an excellent tip for compressing iSeries data using the DCPDATA & CPRDATA api's. These are great for compressing iSeries data streams but what if you want to compress a string or record before sending it to a non-iSeries system?
The public domain zLib product is an excellent tool for compressing and uncompressing data files or strings on a variety of platforms. Fortunately for the iSeries community, zLib has been ported to the iSeries. You can acquire one of the zLib for iSeries versions at here. Follow the simple installation instructions then you're ready to go!
Out of the box, zLib is like most compression products. It provides a basic command level interface to compress or uncompress files. What zLib also provides is a service program you can "bind" to which contains the appropriate "compress" and "uncompress" string functions! The following ILE RPG program provides the functional prototypes and a simple demonstration on how to use zLib on the iSeries.
Note: I use the "C" function "printf" simply because I find it superior to the DSPLY opcode.
For those interested, I also have a VisualAge for RPG version that, if you e-mail me, Michael Rooney, I'll gladly share with you.H * * Bind with service program ZLIB in Product library and * service program QC2IO in QSYS library. * D iostring C CONST('the rain in spain falls mainl- D y in the rain spain plain') * * Functional Prototype for call to "C" function 'printf' * "printf" used because its superior to RPG's DSPLY opcode. * D printf PR EXTPROC('printf') D Print_string 77 * * Functional Prototype for call to uncompress. * D unCompress PR 10I 0 EXTPROC('uncompress') D unCompressed * value D unCompressdLen 10U 0 D InputString * value D InputStringLen 10U 0 VALUE * * Functional Prototype for call to compress2. * Note: could call "compress" and omit Options parameter. * D Compress PR 10I 0 EXTPROC('compress2') D Compressed * value D CompressedLen 10U 0 D InputString * value D InputStringLen 10U 0 VALUE D CompressionOpt 10I 0 VALUE * * Input String and length parms passed to "compress2". * D Source S 16384A INZ(*blanks) D SourceLong S 10U 0 * * String for "printf" to display on terminal. * D Printf_string S 77 * * Output String and length parms received from "uncompress". * D Uncomp_string S 16384A INZ(*blanks) D UncompLong S 10U 0 * * Output String and length parms received from "compress". * D comp_string S 16384A INZ(*blanks) D compLong S 10U 0 * Return code received from ZLIB. D Reason S 10I 0 * Compression option. D Option S 10I 0 * Pointers to fields passed to/from zLib. D SourcePtr S * inz(%addr(Source)) D Uncomp_str_ptr S * inz(%addr(Uncomp_string)) D comp_str_ptr S * inz(%addr(comp_string)) * Used to convert intergers to character for "printf". D DS D Length 1 5 0 D Length_c 1 5 C eval Source = iostring * define input string length for "compress2" C eval SourceLong = %Len(iostring) * initialize uncompressed length for "uncompress" C eval UncompLong = %Len(iostring) * calculate length of compressed string for "compress2". C eval compLong = (%Len(iostring)* 1.001) + 12 * C eval Printf_string = 'Compressing: ' + iostring * * Display what we are starting with (string, length & target length). * C callp printf (Printf_string) * C z-add SourceLong Length C eval Printf_string = 'SourceLong: ' + Length_c C callp printf (Printf_string) C z-add compLong Length C eval Printf_string = 'compLong: ' + Length_c C callp printf (Printf_string) * * Set compression option. * C eval Option = 6 * * Call "compress2" of ZLIB. * C eval Reason = Compress(comp_str_ptr:compLong: C SourcePtr : SourceLong : Option) * * If "compress2" does not return "0", compression failed! * C Reason ifne *zero C z-add Reason Length C eval Printf_string = 'Compress failed:' + C Length_c C callp printf (Printf_string) C move *on *inlr C return C endif * C eval Printf_string = 'Compression Successful!!!!' C callp printf (Printf_string) * * Display length values being passed to "unCompress". * "compLong" maps to avail_in. * "UncompLong" maps to avail_out. * C z-add compLong Length C eval Printf_string = 'compLong: ' + C Length_c C callp printf (Printf_string) C z-add UncompLong Length C eval Printf_string = 'UncompLong: ' + Length_c C callp printf (Printf_string) * * Call "uncompress" of ZLIB. * C eval Reason = unCompress(uncomp_str_ptr: C UncompLong:comp_str_ptr : compLong) * * If "uncompress" returns negative value, uncompress failed! * C Reason iflt *zero C z-add Reason Length C eval Printf_string = 'Uncompress failed:' + C Length_c C callp printf (Printf_string) C else * * Display string received from uncompress. * C eval Printf_string = 'Decompression Successful!' C callp printf (Printf_string) C eval Printf_string = %trimr(uncomp_string) C callp printf (Printf_string) C endif * C move *on *inlr
==================================
MORE INFORMATION ON THIS TOPIC
==================================
The Best Web Links: tips, tutorials and more.
Ask your programming questions--or help out your peers by answering them--in our live discussion forums.
Ask the Experts yourself: Our application development gurus are waiting to answer your programming questions.