LiteZip

A wrapper for LiteZip, a free and easy-to-use zip file handler, as originally published at https://www.codeproject.com/Articles/13370/LiteZip-and-LiteUnzip.

Allows the creation of and extraction from standard zip archives.

The emphasis is very much on the ability to extract from compatible archives automatically, as opposed to the ability to extract from any old weird format archive.
If something (from afar) does not work, you are expected to pull it apart by hand and reconstruct it (perhaps with a different tool) into something that does work.
All the files that I have created with 7-Zip have, so far, proved perfectly compatible.

One use of this, of particular importance for me, is software distribution.

Requires LiteUnZip.dll (44K) and/or LiteZip.dll (40K) to be installed/distributed, but either may be absent, as long as only a subset of these routines are actually invoked.
They can be left in the builtins\ directory, or copied to the application directory.

Note: Currently 32-bit Windows only. However it is open source, I assume 64-bit and/or linux .so files could probably be built from it reasonably easily.
All versions of linux have an ‘unzip’ command line utility, which can be used instead, however, no such luck on Windows.

Fully-fledged utilities such as 7-Zip produce slightly smaller archives, and in my tests they were about 2 or 3% smaller (personally I had always planned to use those anyway).
In reality the compression routines are provided for completeness only, however in theory the decompression routines might work better when the same code base originally did the compression, not that I have any direct evidence of that. On the plus side, the compression routines (as well as the decompression routines) are really rather easy to use, perhaps even easier than any other way.

Example 1:

include builtins\LiteZip.e

atom hzip = UnzipOpenFile("phix.0.7.7.1.zip")

ZIPENTRY ze = new_ZIPENTRY()
integer numitems = UnzipGetItems(hzip,ze)
?{"numitems",numitems}  -- prints {"numitems",1156}

UnzipSetBaseDir(hzip,current_dir()&"\\test")

?UnzipFindItem(hzip,ze,"readme.txt")    -- prints 0 (ZR_OK)
?UnzipGetFileName(ze) -- prints current_dir()&"\\test\\readme.txt"

for i=1 to numitems do
    integer res = UnzipGetItem(hzip, ze, i-1)
    res = UnzipItemToFile(hzip, ze)
    printf(1,"\r%2d%%",{(i/numitems)*100})
end for

UnzipClose(hzip)
puts(1,"\ndone\n")

Example 2:

include builtins\LiteZip.e

atom hzip = ZipCreateFile("test.zip")
integer res
res = ZipAddFile(hzip,"LiteZip.dll")
res = ZipAddFile(hzip,"LiteUnzip.dll")
res = ZipAddDir(hzip,"test\\LiteZip",5)
res = ZipAddFolder(hzip,"empty")
ZipClose(hzip)
It does not get any simpler than that. You may prefer to declare res as an object, and test it for string after each step.

Not [yet] attempted:

UnzipItemToBuffer
UnzipItemToHandle
UnzipOpenBuffer[Raw]
UnzipOpenFileRaw
UnzipOpenHandle[Raw]

ZipAddBuffer[Raw]
ZipAddFileRaw
ZipAddHandle[Raw]
ZipAddPipe[Raw]
ZipCreateHandle
ZipCreateBuffer
ZipGetMemory
ZipResetMemory
ZipOptions (options are TZIP_OPTION_GZIP and TZIP_OPTION_ABORT only anyway)

None of those are particularly important for dealing with real files and real .zip files, but may have uses for eg ipc or embedded resources.

Note this wrapper uses an internal ZR_MESSAGES constant instead of (Unz|Z)ipFormatMessage().

I have also deliberately omitted support for passwords, but adding that should not be difficult, if ever needed, though that I frankly doubt, given how many programs now exist that can easily crack them.