View source with raw comments or as raw
    1/*  Part of SWI-Prolog
    2
    3    Author:        Jan Wielemaker
    4    E-mail:        J.Wielemaker@vu.nl
    5    WWW:           http://www.swi-prolog.org
    6    Copyright (c)  2018, VU University Amsterdam
    7    All rights reserved.
    8
    9    Redistribution and use in source and binary forms, with or without
   10    modification, are permitted provided that the following conditions
   11    are met:
   12
   13    1. Redistributions of source code must retain the above copyright
   14       notice, this list of conditions and the following disclaimer.
   15
   16    2. Redistributions in binary form must reproduce the above copyright
   17       notice, this list of conditions and the following disclaimer in
   18       the documentation and/or other materials provided with the
   19       distribution.
   20
   21    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   24    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   25    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   26    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   27    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   28    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   29    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   31    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   32    POSSIBILITY OF SUCH DAMAGE.
   33*/
   34
   35:- module(zip,
   36          [ zip_open/4,                    % +File, +Mode, -Zipper, +Options
   37            zip_close/1,                   % +Zipper
   38            zip_close/2,                   % +Zipper, +Comment
   39                                           % Entry predicates
   40            with_zipper/2,                 % +Zipper, :Goal
   41            zipper_open_new_file_in_zip/4, % +Zipper, +File, -Stream, +Options
   42            zipper_goto/2,                 % +Zipper, +Where
   43            zipper_open_current/3,         % +Zipper, -Stream, +Options
   44            zipper_members/2,              % +Zipper, -Entries
   45            zipper_file_info/3             % +Zipper, -Name, -Attrs
   46          ]).   47:- autoload(library(error),[must_be/2]).   48:- autoload(library(option),[option/3]).   49
   50
   51:- meta_predicate
   52    with_zipper(+, 0).

Access resource ZIP archives

This library provides access to ZIP files. ZIP files are used to store SWI-Prolog resources. Ths library provides more high level access and documentation in addition to the low level access provided as built in as it is needed to bootstrap SWI-Prolog.

Access to a zip file is provided by means of a zipper object. This is a blob that is subject to atom garbage collection. Collecting a zipper closes the underlying OS access.

A zipper is a stateful object. We recognise the following states: idle, scan, read_entry, write_entry and close. The interface raise a permission_error when trying to make an illegal state transition.

Being stateful, a zipper cannot be used simultaneously from multiple threads. The zipper becomes owned by a thread when moving to scan using zipper_goto/2. It is released after zipper_open_current/3 followed by closing the stream. */

 zip_open(+File, +Mode, -Zipper, +Options) is det
Create a Zipper, providing access to File. Mode is one of read or write. The Options list is currently ignored.
   81zip_open(File, Mode, Zipper, _Options) :-
   82    must_be(oneof([read,write]), Mode),
   83    open(File, Mode, Stream, [type(binary)]),
   84    zip_open_stream(Stream, Zipper, [close_parent(true)]).
 zip_close(+Zipper) is det
 zip_close(+Zipper, +Options) is det
Close a zipper. Options processed:
comment(+Comment)
If the zipper is open for writing, set the global comment for the zip file.
   95zip_close(Zipper) :-
   96    zip_close_(Zipper, _).
   97zip_close(Zipper, Options) :-
   98    option(comment(Comment), Options, _),
   99    zip_close_(Zipper, Comment).
 zipper_goto(+Zipper, +Where) is semidet
Seek Zipper to a specified entry. Where is one of
first
Go to the first entry. Fails if the zip is empty.
next
Go to the next entry. Fails if there is no next entry.
file(Name)
Go to the entry with the specified name.
 zipper_open_current(+Zipper, -Stream, +Options) is det
Open the current entry as an input stream. Before this call the caller must use zipper_goto/2 to position to archive. Options:
type(+Type)
encoding(+Encoding)
bom(+Boolean)
Determine type and encoding of the stream. The semantics is the same as for open/4.
release(+Boolean)
If true (default), release te archive for access by other threads after the entry is closed.

It is allowed to call zip_close/1 immediately after this call, in which case the archive is closed when the entry is closed.

 with_zipper(+Zipper, :Goal)
Run Goal while holding ownership over Zipper.
  134with_zipper(Zipper, Goal) :-
  135    setup_call_cleanup(
  136        zip_lock(Zipper),
  137        Goal,
  138        zip_unlock(Zipper)).
 zipper_members(+Zipper, -Members:list(atom)) is det
True when Members is the list of file names in the Zipper.
  144zipper_members(Zipper, Members) :-
  145    with_zipper(Zipper,
  146                ( zipper_goto(Zipper, first),
  147                  zip_members_(Zipper, Members)
  148                )).
  149
  150zip_members_(Zipper, [Name|T]) :-
  151    zip_file_info_(Zipper, Name, _Attrs),
  152    (   zipper_goto(Zipper, next)
  153    ->  zip_members_(Zipper, T)
  154    ;   T = []
  155    ).
 zipper_file_info(+Zipper, -Name, -Attrs) is det
Obtain information about the current zip entry. Name is an atom representing the name of the entry. Attrs is a dict holding:
compressed_size:Bytes
Size in the archive
uncompressed_size:Bytes
Bytes after decompression
time:Stamp
Numeric time stamp in Prolog native format (float expressing seconds since Jan 1, 1970). Note that the resolution of time in zip archives is one second.
extra:Extra
comment:Extra
Optional additional fields.
offset:Offset
Direct pointer to this entry. May be used with zip_goto/2.
  177zipper_file_info(Zipper, Name, Attrs) :-
  178    zip_file_info_(Zipper, Name,
  179                   info(CompressedSize, UnCompressedSize,
  180                        Extra, Comment,
  181                        Time, Offset)),
  182    Attrs0 = zip{compressed_size:CompressedSize,
  183                 uncompressed_size:UnCompressedSize,
  184                 offset:Offset
  185                },
  186    zip_attr(Extra,   extra,   Attrs0, Attrs1),
  187    zip_attr(Comment, comment, Attrs1, Attrs2),
  188    zip_attr(Time,    time,    Attrs2, Attrs).
  189
  190zip_attr("", _, Attrs, Attrs) :- !.
  191zip_attr('', _, Attrs, Attrs) :- !.
  192zip_attr(Value, Name, Attrs0, Attrs) :-
  193    put_dict(Name, Attrs0, Value, Attrs).
 zipper_open_new_file_in_zip(+Zipper, +Name, -Stream, +Options) is det
Create a new file in a zip archive. Options provided are:
extra(+Text)
Additional meta-data
comment(+Text)
Comment for the entry.
time(+Stamp)
Last modified time claimed for the entry.
method(+Method)
One of deflated (default) or store (store uncompressed)
level(+Compression)
Compression level (0..9, default 6).
zip64(+Boolean)
When true (default false), allow the entry to grow above 4Gb.