doc.txt

zip

_zip_
_zip_

This collection provides two files:

 _unzip.ss_: unzip utility.
 _zip.ss_: zip utility.

The zip collection provides libraries for manipulating zip files.

KNOWN LIMITATIONS:

- only supports `deflate' compression/decompression algorithm
- cannot span multiple disks
- zip marks all files as binary

======================================================================

TYPES ----------------------------------------------------------------

> (define-struct (exn:fail:unzip exn:fail) ())

Raised when an error occurs in unzipping a file.

> (define-struct (exn:fail:unzip:no-such-entry exn:fail:unzip) (entry))

Raised when a requested entry cannot be found in a zip file. The `entry'
parameter is a byte string representing the entry's path name.

> type entry-parser a
     ::= (bytes boolean -> (union output-port #f))
      |  (bytes boolean input-port -> a)

Entry parsers are procedures that can work with either the _unzip_ or
_unzip-entry_ procedures to read the contents of individual entries in a zip
file.

> type output-flag
     ::= 'error | 'replace | 'truncate | 'truncate/replace | 'append | 'update

Arguments that can be used as a mode flag for writing to output files. See
_open-output-file_ in the mzscheme library documentation for details.

> type zip-directory

A _zip-directory_ is an abstract datatype that encapsulates the information
stored in the central directory of a zip file. The _read-zip-directory_
procedure produces a zip-directory, which can then be used by _unzip-entry_ to
extract individual entries from the file, and by the following library
procedures to query the directory for information about the contents of the zip
file.

None of the following procedures performs I/O.

> (zip-directory? x) :: any -> boolean

Determines whether `x' is a zip-directory.

> (zip-directory-entries zd) :: zip-directory -> (listof bytes)

Extracts the list of zip entries from a zip file.

> (zip-directory-contains? name zd) :: (union string path bytes) zip-directory -> boolean

Determines whether the given entry name occurs in the zip directory. If `name'
is provided as a string or path, it is automatically converted to a byte string
with _path->zip-path_.

Directory entries match with or without trailing slashes.

> (zip-directory-includes-directory? name zd) :: (union string path bytes) zip-directory -> boolean

Determines whether the given name is included anywhere in the zip directory as a
filesystem directory, either as an entry itself or as the containing directory
of other entries. If `name' is provided as a string or path, it is automatically
converted to a byte string with _path->zip-path_.

> output-flag/c :: contract
> entry-parser/c :: contract

Contracts for their respective types.

ZIP UTILITIES --------------------------------------------------------

zip.ss
------

> (zip files [out]) :: (listof relative-path) [output-port] -> any

Zips a list of files and directories to the given output port, which defaults to
the value of the _current-output-port_ parameter. The files must be given as
relative paths from the current working directory associated with the
_current-directory_ parameter. The zip file is created with all subdirectories
and files contained in the subdirectory structure to match their structure on
disk. The output port is not closed afterwards.

For files in subdirectories, it is permitted, but not necessary, to include
their containing directories in the list. If the containing directories are not
included, the directories are not given entries in the zip file. This should not
interfere with unzip clients that unzip entries in subdirectories. However,
empty directories must be included explicitly in order to appear in the zip
file.

UNZIP UTILITIES ------------------------------------------------------

unzip.ss
--------

> (unzip [in build-port close-when-done?]) :: [input-port (bytes boolean -> (union output-port #f)) boolean] -> any

Unzips an entire zip file from the given input port, which defaults to the value
of the _current-input-port_ parameter. Each entry is written to an output port
generated by the value returned by `build-port', which defaults to the value of
(build-filesystem-entry-parser). If `build-port' returns #f, the entry is
skipped. If `close-when-done?' is #t, each output port is closed after the entry
is written. The default value of `close-when-done?' is #t.

The `build-port' procedure accepts two values, the byte string representing the
filename path of the entry, and a boolean indicating whether the entry
represents a directory.

> (read-zip-directory path) :: (union string path) -> zip-directory

Reads the central directory of a zip file and generates a _zip-directory_
representing the zip file's contents. The `path' parameter must refer to a
readable file.

This procedure performs limited I/O: it reads the list of entries from the zip
file but does not inflate any of their contents. This procedure does not leave
any new ports open.

> (unzip-entry path zipdir entry [parse-entry]) :: (union string path) zip-directory bytes [(bytes boolean input-port -> a)] -> a

Unzips a single entry from a zip file. The `path' parameter must refer to a
readable file, and the `zipdir' argument must be a zip-directory representing
the zip file's contents, as created by _read-zip-directory_. The `entry'
parameter is a byte string whose name must be found in the zip file's central
directory.

The `parse-entry' parameter is used to read the contents of the zip entry. Its
arguments are the zip entry name, a boolean flag indicating whether the entry
represents a directory, and an input port from which the procedure can read the
contents of the entry. The result of _unzip-entry_ is the result of the
`parse-entry' procedure.

> (path->zip-path path) :: (union string path) -> bytes

Converts a file name potentially containing path separators in the current
operating system's format to use path separators recognized by the zip file
format, namely the '/' character.

The following procedures can be used to create values for the `parse-entry'
parameter to _unzip_ or _unzip-entry_:

> (build-filesystem-entry-parser [sym]) :: output-flag -> (entry-parser void)

Creates a zip entry parser that can be used with either _unzip_ or _unzip-entry_
and whose behavior is to save entries to disk. Intermediate directories are
always created if necessary before creating files. Directory entries are created
as directories in the filesystem, and their entry contents are ignored.

If the input-port argument is provided to the entry parser (i.e., by
_unzip-entry_), it reads the contents of the input port and saves them to the
local file. Otherwise, it returns an output port that can be used by _unzip_ to
save the contents of the entry to the local file.

> (build-piped-entry-parser out) :: output-port -> (entry-parser void)

Creates a zip entry parser for _unzip_ or _read-zip-file_ whose behavior is to
pipe the contents of a zip entry to the specified output stream.