Modula-2 home

  Home  
  Tutorial  
  Win32 API  
  Reference  
  Projects  
  Source code  
  Links  
Shows printer-friendly 
version in new window  

 

Zip/Unzip library

For Stony Brook Modula-2

By Frank Schoonjans (frank.schoonjans@ugent.be)

 

This is an implementation for Modula-2 (including dll, lib, def and test files) of the zip/unzip libraries by Jean-loup Gailly and Mark Adler, version 1.1.4, March 11th, 2002 (http://www.gzip.org/zlib/)

The download ZipLib.zip contains a complete Stony Brook project including a ziplib.dll, ziplib.lib, ziplib.def and a test program file test.mod.

This is the ziplib DEFINITION MODULE:

DEFINITION MODULE ziplib;

(*   Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
     version 1.1.4, March 11th, 2002

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.

  Jean-loup Gailly        Mark Adler
  jloup@gzip.org          madler@alumni.caltech.edu


  The data format used by the zlib library is described by RFCs (Request for
  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
*)

(* Modula-2 Definition, implementation, modification for current DLL and lib
   by Frank Schoonjans - February 2003
   Implementation for Stony Brook Modula-2, 32-bit (Windows)         *)

FROM SYSTEM IMPORT BYTE;

TYPE HRESULT = INTEGER32;

CONST Z_OK            =  0;
      Z_DATA_ERROR    = -3;
      Z_MEM_ERROR     = -4;
      Z_BUF_ERROR     = -5;

<*/PUSH*>
<*/CALLS:StdCall*>
<*/NOHIGH*>
<*/ALIGN:8/NOPACK*>

PROCEDURE Zip(VAR dest : ARRAY OF BYTE; VAR destLen : CARDINAL;
              VAR source : ARRAY OF BYTE; sourceLen : CARDINAL) : HRESULT;

(* Compresses the source buffer into the destination buffer.  sourceLen is
   the byte length of the source buffer. Upon entry, destLen is the total
   size of the destination buffer, which must be at least 0.1% larger than
   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
   compressed buffer.
   This function can be used to compress a whole file at once if the
   input file is mmap'ed.
   Returns Z_OK if success, Z_MEM_ERROR if there was not
   enough memory, Z_BUF_ERROR if there was not enough room in the output
   buffer. *)

PROCEDURE UnZip(VAR dest : ARRAY OF BYTE; VAR destLen : CARDINAL;
                VAR source : ARRAY OF BYTE; sourceLen : CARDINAL) : HRESULT;

(* Decompresses the source buffer into the destination buffer.  sourceLen is
   the byte length of the source buffer. Upon entry, destLen is the total
   size of the destination buffer, which must be large enough to hold the
   entire uncompressed data. (The size of the uncompressed data must have
   been saved previously by the compressor and transmitted to the decompressor
   by some mechanism outside the scope of this compression library.)
   Upon exit, destLen is the actual size of the compressed buffer.
   This function can be used to decompress a whole file at once if the
   input file is mmap'ed.
   Uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
   enough memory, Z_BUF_ERROR if there was not enough room in the output
   buffer, or Z_DATA_ERROR if the input data was corrupted. *)
<*/POP*>

END ziplib.

This is the TEST.MOD test program that illustrates the use of the libray - it should be selfexplanatory:

MODULE Test;

(* Simple program to test the ziplib libray
   - Frank Schoonjans - http://www.modula2.org    *)

IMPORT ziplib;             (* module of intrest   *)
IMPORT Terminal;           (* Stony Brook modules *)
IMPORT WholeStr;           (* ISO *)

FROM Storage IMPORT ALLOCATE,DEALLOCATE;  (* ISO *)
FROM SYSTEM  IMPORT BYTE,FUNC;


PROCEDURE IsError(res : ziplib.HRESULT): BOOLEAN;
BEGIN
    CASE res OF
    | ziplib.Z_OK         : RETURN FALSE;
    | ziplib.Z_DATA_ERROR : Terminal.WriteString("Z_DATA_ERROR");
    | ziplib.Z_MEM_ERROR  : Terminal.WriteString("Z_MEM_ERROR");
    | ziplib.Z_BUF_ERROR  : Terminal.WriteString("Z_BUF_ERROR");
    ELSE (* should not happen *)
         Terminal.WriteString("Undefined ZIPLIB error");
    END;
    FUNC Terminal.ReadChar();
    RETURN TRUE;
END IsError;

VAR data1,data2 : ARRAY [0..1000] OF CARDINAL;
    buf   : POINTER TO ARRAY OF BYTE;
    res   : ziplib.HRESULT;
    str   : ARRAY [0..80] OF CHAR;
    csize : CARDINAL;
    rsize : CARDINAL;
    i     : CARDINAL;
    ok    : BOOLEAN;
BEGIN
    Terminal.WriteString("Test ziplib library."); Terminal.WriteLn;
    (* init data *)
    FOR i:=0 TO HIGH(data1) DO
      data1[i]:=i;
    END;
    WholeStr.CardToStr(SIZE(data1),str);
    Terminal.WriteString("Original data size     : ");
       Terminal.WriteString(str);
       Terminal.WriteLn;
    (* allocate enough space in receiving buffer *)
    NEW(buf, SIZE(data1) + SIZE(data1) DIV 1000 + 12);
    csize:=SIZE(buf^);
    (* Compress data from data1 array into buf^
       csize receives size of compressed data in buf^ *)
    res:=ziplib.Zip(buf^,csize,data1,SIZE(data1));
    IF IsError(res) THEN HALT(1) END;
    WholeStr.CardToStr(csize,str);
    Terminal.WriteString("Size after compression : ");
       Terminal.WriteString(str);
       Terminal.WriteLn;
    (* Uncompress data from buf^ into data1 array
       csize receives size of compressed data in buf^ *)
    rsize:=SIZE(data2);
    res:=ziplib.UnZip(data2,rsize,buf^,csize);
    IF IsError(res) THEN HALT(1) END;
    (* compare uncompressed data in data2 array to original
       data in array 1 *);
    Terminal.WriteString("Comparing arrays ... ");
       Terminal.WriteLn;
       ok:=TRUE;
    FOR i:=0 TO HIGH (data1) DO
      ok:=ok AND (data1[i]=data2[i])
    END;
    IF ok THEN
      Terminal.WriteString("No errors.");
    ELSE
      Terminal.WriteString("Error in zip/unzip procedure.");
    END;
    Terminal.WriteLn;
    DISPOSE(buf);
    FUNC Terminal.ReadChar();
END Test.