'XbZlib' wrapper library for 'zlib'.
Copyright (C) 2003 Phil Ide.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:
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. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. This notice may not be removed or altered from any source distribution.
Please note that similar restrictions and notices apply to Zlib (see Zlib:Prologue)
XbZLib is a wrapper library for the ZLib library, which is a freely available compression library utilising the Deflate algorithm.
XbZLib supplies wrapper functions for all of the Utility functions exposed by ZLib. This includes the ability to compress/decompress memory variables and open, close, read and write .gzip files.
In addition, XbZLib supplies a class to handle . zip files. This will allow you read and write and perform directory operations on .zip's, as well as decompressing single or all files from a .zip with just a simple method call.
Further, XbZLib also offers the ability to move a file from one .zip archive to another
Note that ZLib (and hence XbZLib) only handle files compressed using the Deflate compression method, or files that have been Store'd.
In addition to in-memory compression/decompression, and handling of .zip and .gzip files, there is also a new archive format called .xip which is native to XbZLib. This archive format uses a smaller local-file and central directory record, and also uses maximum compression. The purpose of .xip is two-fold. Firstly it is better suited to transmission across low-bandwidth networks (such as the internet). Secondly, it shows how to create an archive in an arbitrary format.
On top of all this, it is possible to extend XbZLib to incorporate .tar.gz (tar-balled gzip files) by implementing a class similar to the Zip class.
XbZLibVer()
XbzLibVer() -> cVersionReturns the current XbZLib version.XbZLibZVer()
XbzLibZVer() -> cVersionReturns the current ZLib version.crc32()
crc32( cData ) -> cCRCReturns a 32-bit CRC (cyclic redundancy check) for cData. Since the value is an unsigned long, it cannot be returned as numeric from a C/C++ function (the C-API and the DLL API functions only allow for signed long numbers). Therefore, the value is returned as its U2Bin() equivalent, which is a 4 character string.
xbzCompress()
xbzCompress( cData, @nError ) ->cCompressedData cData - data to compress nError - if an error occurs, the error code is recorded here.xbzUnCompress()
xbzUnCompress( cData, nLen ) ->cUnCompressedData cData - data to decompress nLen - length of uncompressed dataWhen the data is originally compressed, it is necessary to record the length of the uncompressed data and to store this information with the compressed data. When the data is decompressed, it is necessary to allocate a buffer large enough to hold the decompressed data. This function accepts the length of the uncompressed data as the second parameter, allowing it to allocate a buffer sufficient to decompress the data.
XbZlZip()
This returns the class object. The class manages .zip files. There are no CLASS methods or CLASS instance variables.Instance Variables
:zipFile
XbZlZip:zipFile EXPORTED READONLYLow-level file handle to the archive associated with the object. The value of this variable indicates the state of the object:
- < 0
An attempt to associate an archive with the object has failed. The value of the variable correlates to FError() values.- 0
No archive is associated with the object. Either no attempt has been made to associate an archive or the previously associated archive was closed without error.- > 0
File handle to currently associated archive:fileName
XbZlZip:fileName EXPORTED READONLYThe filename of the archive associated with the object.:gComment
XbZlZip:gComment EXPORTEDThis is the global comment associated with an archive. Usually this variable is empty, and only populated when a global comment is found when opening an existing archive.
When an archive is :close()'d, a global comment can be associated with the archive, and if a comment is passed then it overrides any comment held in this variable. If no comment is passed, and this variable is not empty, then the comment in this variable is asserted in the archive.Methods
:new()
XbZlZip:new() -> oSelfCreates a new instance of the Zip class.:open()
XbZlZip:open(cPath, [nOpenMode]) -> oSelf cPath - Path and filename of .zip to open nOpenMode - Mode to open file (default = ZLZIP_OPEN_CREATE)This opens/creates a .zip file, and associates the object with that file. The mode in which the file can be opened should be specified using constants from XbZLib.ch and can be one the following:
To test whether a file was successfully opned, see the :ok() method.
Constant Description ZLZIP_OPEN_CREATE Creates new files, destroys existing files ZLZIP_OPEN_APPEND Opens existing files, preloads the internal directory and prepares to add new files to the archive. If the file does not already exist, a new file is not created. ZLZIP_OPEN_READ Opens a pre-existing file in READ mode. In this mode you can read from and extract from the archive, or copy files from this archive to another, but you cannot add new files. :close()
XbZlZip:close(cGlobalComment) -> oSelf cGlobalComment - a string to be used as the comment for the archiveThis method closes an open .zip archive. If the archive was opened in one of the writeable modes and new files have been added to the archive, then the central directory is updated before the archive is closed. If a comment string is passed, then it is added to the archive as the global comment for the archive, overwriting any existing comment. If a comment string is not used, and there is already a global comment associated with the file, then the existing comment is used.
To remove an existing comment without adding a new one, it is necessary to pass an empty string to this method.
Warning! There is currently a known problem with opening an archive in ZLZIP_OPEN_APPEND mode and closing the file without adding any new files. This will cause a duplicate end-of- central-directory record to be created. Until this is fixed, you should be wary of opening files in this mode unnecessarily.:addFile()
XbZlZip:addFile(cFile, [cRootDir], [cComment]) -> oSelf cFile - path and filename of the file to be added. cRootDir - path that should be considered the root path for files within the archive cComment - a string to be used as the comment for the file being addedWithin an archive, filenames are stored with sufficient path information to rebuild a directory tree when the archive is extracted. Preceding path information is stripped. The rootdir is the physical location on the disk where the file tree begins. Files added to the archive will have some path information as part of the filename, which is stored within the archive. The rootdir is added to the filename to locate the file on disk, but is not added to the archive. For example:/* files on disk C:\Test\ZipTest\archive.prg C:\Test\ZipTest\test.prg C:\Test\ZipTest\data\archive.dbf */ cRoot := "C:\Test\ZipTest" oZip:addFile( "archive.prg", cRoot ) oZip:addFile( "test.prg", cRoot ) oZip:addFile( "data\archive.dbf", cRoot ) /* files in archive archive.prg test.prg data\archive.dbf */:moveToZip()
XbZlZip:moveToZip( oCDRecord, oZip ) -> lSuccess oCDRecord - is an instance of the CentralDirectoryRecord class. To acquire an instance of this class, see XbZlZip:directory() This record refers to the file you wish to move. oZip - is an instance of XbZlZip() associated with the archive you wish to move the file to.This method allows you to move a file from the current archive to another archive. Note that the file is not actually moved, it is copied. Within the target archive, the file data is added along with the Local File Record, and a Central Directory Record is created as appropriate. The target archive must have been opended in ZLZIP_OPEN_CREATE or ZLZIP_OPEN_APPEND mode.:moveFromZip()
XbZlZip:moveToZip( oCDRecord ) -> lSuccess oCDRecord - is an instance of the CentralDirectoryRecord class. To acquire an instance of this class, see XbZlZip:directory() This record refers to the file you wish to move.This method allows you to move a file from another archive into the current archive. Note that the file is not actually moved, it is copied. Within the current archive, the file data is added along with the Local File Record, and a Central Directory Record is created as appropriate. The current archive must have been opened in ZLZIP_OPEN_CREATE or ZLZIP_OPEN_APPEND mode.
The CentralDirectoryRecord object contains information on which archive the file currently exists in. Both archives must be open.:directory()
XbZlZip:directory() -> aDirectoryThis method returns an array of CentralDirectoryRecord objects. Each object refers to an entry in the Central Directory of the archive.
The CentralDirectoryRecord class is implemented as a structure. For more information on this structure, see ZipCentralDirectoryRecord:extract()
XbZlZip:extract( oCDRecord, [cTargetRoot] ) -> nOk oCDRecord - is an instance of the CentralDirectoryRecord class. To acquire an instance of this class, see XbZlZip:directory() This record refers to the file you wish to move. cTargetRoot - If supplied, this is pre-pended to the filename before writing to disk. nOk - this should be 1 for success and 0 for failure. If the value is negative, the compression method used is not supported. The compression method can be determined by taking the absolute value of nOk and comparing it against the constants defined in XbZLib.ch.This method extracts a single file from an archive, decompresses it if necessary, and then writes it to disk. Note that if the filename contains any path information, the subdirectories must exist in the context of cTargetRoot. It is the responsibility of the application to decide whether subdirectories are created or not.
Note that the filename as stored in the archive is a relative path. Using cRootDir you can specify where the directory tree to store the file will be located.
Constant Supported ZLZIP_COMP_STORE Yes ZLZIP_COMP_SHRUNK No ZLZIP_COMP_REDUCED1 No ZLZIP_COMP_REDUCED2 No ZLZIP_COMP_REDUCED3 No ZLZIP_COMP_REDUCED4 No ZLZIP_COMP_IMPLODED No ZLZIP_COMP_TOKENIZED No ZLZIP_COMP_DEFLATED Yes ZLZIP_COMP_DEFLATE64 No ZLZIP_COMP_PKDCL No :extractAll()
XbZlZip:extractAll([cTargetRoot]) -> nOk cTargetRoot - If supplied, this is pre-pended to each filename before writing to disk.This method extracts all files from an archive. This is a super-function of the extract() method.
Note that the filename as stored in the archive is a relative path. Using cRootDir you can specify where the directory tree to store the file will be located.Structures
Structures are implemented via the SmartObject sample classes for implementing C/C++ structures. Structure members can be accessed using either the traditional class member variable syntax (object:member) or using C/C++ style syntax (object.member).
In addition, structures have additional properties. There is a :cargo instance variable, although within the XbZlZip Class you should not make use of this variable since it is used internally.
More important is the :sizeOf() property. This returns the total length of a structure. It should be noted that all of the structures used in the XbZlZip() class have variable length members at the tail end of the structure. Using the :sizeOf() property returns different values depending upon the length (and even status) of these variable length members.ZipLocalFileRecord
STRUCTURE ZipLocalFileRecord CHAR signature SIZE 4 UINT verToExtract UINT gpFlag UINT compMethod CHAR fileTime SIZE 4 CHAR crc SIZE 4 ULONG compSize ULONG unCompSize UINT fNameLen UINT extraFldLen CHAR fileName CHAR extraFld ENDSTRUCTZipCentralDirectoryRecord
STRUCTURE ZipCentralDirectoryRecord CHAR signature SIZE 4 UINT verMadeBy UINT VerToExtract UINT gpFlag UINT compMethod CHAR fileTime SIZE 4 CHAR crc SIZE 4 ULONG compSize ULONG unCompSize UINT fNameLen UINT extraFldLen UINT commentLen UINT diskNumStart UINT internalFAttrib CHAR externalFAttrib SIZE 4 ULONG offset CHAR fileName CHAR extraFld CHAR comment ENDSTRUCTZipEndOfCentralDirectoryRecord
STRUCTURE ZipEndOfCentralDirectoryRecord CHAR signature SIZE 4 UINT diskNumber UINT diskNumWStartCD UINT entriesThisDisk UINT entries ULONG sizeOfCD ULONG startOfCD UINT commentLen CHAR comment ENDSTRUCT