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.

This was first published in November 2002

0 comments

Oldest 

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

-ADS BY GOOGLE

SearchEnterpriseLinux

SearchDataCenter

Close