<?xml version="1.0"?>
<!DOCTYPE riscos-prm PUBLIC "-//Gerph//DTD PRM documentation 1.03//EN"
                            "http://gerph.org/dtd/103/prm.dtd">

<riscos-prm>
<chapter title="Zipper">
<section title="Introduction and Overview">
<p>The Zipper module provides a simple interface for creating and reading
Zip archives, using the ZLib module to provide a means of deflating and
inflating files.
</p>

<p>
Zip archives are collections of files, compressed using the deflate
algorithm. These files originated with PKWare's PKZip and PKUnzip utilities
under DOS. They are now the most widespread means of transferring compressed
data. Zip files consist of a catalogue containing information about the
objects contained in the file.
</p>
<p>
The Zip archives created are compatible with PKZip and Info-Zip, which should
allow them to be used between operating systems.
</p>

<p>
    <version-table>
        <version supplier="RISCOS Ltd" riscos-ge="4.29" state="supported"/>
        <version supplier="RISC OS Pyromaniac" riscos-ge="7.21" state="supported"/>
    </version-table>
</p>
</section>

<section title="Technical Details">
<p>The Zipper module provides two different APIs; one for creating Zip
archives, and one for extracting data.</p>

<subsection title="File name conventions">
<p>Within the Zipper module interface, filenames are referred to with
RISC OS semantics. That is, although the archives themselves use period
and slash (. and /), these will be reversed when creating or extracting
filenames from the archive by the module. Further character translations may
occur in future. Unlike RISC OS, filenames are case sensitive.</p>

</subsection>

<subsection title="Passwords">
<p>Although passwords are supported by the Zipper modules API, the
implementation has presently been left disabled. Passwords should be
a string of characters used to encrypt or decrypt the data in the
associated file. Passwords on Zip archives are known to be weak. Further
information can be obtained on the Internet regarding the security afforded
by such encryption.</p>

</subsection>
</section>

<section title="SWI calls">
<swi-definition name="Zipper_UnZipOpen"
                number="559C0"
                description="Open an archive for extraction"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags :
  <bitfield-table>
   <bit number="31">If set, do not discard this archive handle when the
                    application exits</bit>
   <bit number="0-30">Reserved, must be 0</bit>
  </bitfield-table>
 </register-use>
 <register-use number="1">Pointer to filename of archive to
                          read</register-use>
</entry>
<exit>
 <register-use number="0">Opaque unzip handle, guaranteed not to be
                          0</register-use>
</exit>
<use>
<p>This SWI is opens a Zip archive for reading via the Zipper API. If the
file cannot be opened, an error will be returned.</p>

</use>

<related>
<reference type="swi" name="Zipper_UnZipClose" />
<!-- <reference type="command" name="Com" /> -->
<!-- <reference type="swi" name="thingy" /> -->
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_UnZipClose"
                number="559C1"
                description="Close a file, previously opened for extraction"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags (reserved, must be 0)</register-use>
 <register-use number="1">Unzip handle</register-use>
</entry>
<use>
<p>This SWI is used to close an archive previously opened for extraction.</p>

</use>

<related>
<reference type="swi" name="Zipper_UnZipOpen" />
<!-- <reference type="command" name="Com" /> -->
<!-- <reference type="swi" name="thingy" /> -->
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_UnZipInfo"
                number="559C2"
                description="Read information about an open archive"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags :
  <bitfield-table>
   <bit number="0-7">Requested information type :
    <value-table>
     <value number="0">Read number of entries in the archive</value>
     <value number="1">Read archive comment</value>
    </value-table>
   </bit>
   <bit number="8-31">Reserved, must be 0</bit>
  </bitfield-table>
 </register-use>
 <register-use number="1">Unzip handle</register-use>
 <register-use number="2-3">dependent on request type</register-use>
</entry>
<exit>
 <register-use number="0-3">dependent on request type</register-use>
</exit>

<use>
<p>This SWI is used to read miscellaneous information about an open
archive.</p>

</use>

<related>
<reference type="swi" name="Zipper_UnZipOpen" />
<!-- <reference type="command" name="Com" /> -->
<!-- <reference type="swi" name="thingy" /> -->
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>

<swi-definition name="Zipper_UnZipInfo"
                number="559C2"
                reason="0"
                reasonname="NumberOfObjects"
                description="Read number of objects in the archive"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags :
  <bitfield-table>
   <bit number="0-7">0 (reason code)</bit>
   <bit number="8-31">Reserved, must be 0</bit>
  </bitfield-table>
 </register-use>
 <register-use number="1">Unzip handle</register-use>
</entry>
<exit>
 <register-use number="0">number of objects in archive</register-use>
</exit>
<use>
<p>This SWI is used to read the number of objects in the archive. 'Objects'
includes both files and directories.</p>

</use>

<related>
<reference type="swi" name="Zipper_UnZipInfo" />
<!-- <reference type="command" name="Com" /> -->
<!-- <reference type="swi" name="thingy" /> -->
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_UnZipInfo"
                number="559C2"
                reason="1"
                reasonname="ReadComment"
                description="Read zip archive comment"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">
<entry>
 <register-use number="0">Flags :
  <bitfield-table>
   <bit number="0-7">1 (reason code)</bit>
   <bit number="8-31">Reserved, must be 0</bit>
  </bitfield-table>
 </register-use>
 <register-use number="1">Unzip handle</register-use>
 <register-use number="2">Pointer to buffer for data</register-use>
 <register-use number="3">Length of buffer, or -ve to return buffer size
                          requirements</register-use>
</entry>
<exit>
 <register-use number="0">amount of data read, or required</register-use>
</exit>

<use>
<p>This SWI is used to read the comment from a Zip archive. Zip archives
can have a user-readable 'comment' section included which describes the
content of the archive. This area can be read through this call.</p>

</use>

<related>
<reference type="swi" name="Zipper_UnZipOpen" />
<!-- <reference type="command" name="Com" /> -->
<!-- <reference type="swi" name="thingy" /> -->
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_UnZipEnumerate"
                number="559C3"
                description="Enumerate the objects in an archive"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags :
  <bitfield-table>
   <bit number="0-16">
    <p>Elements to return in to the buffer. For each bit set, an integer
       value will be written into the output buffer (except where stated).
       Where multiple values are given, they will be stored consecutively.
       </p>
    <bitfield-table>
     <bit number="0">Version number of creator<br />
                     Version number required to extract</bit>
     <bit number="1">General purpose flags (refer to Zip specification)</bit>
     <bit number="2">Compression method (refer to Zip specification)</bit>
     <bit number="3">Size of file when compressed</bit>
     <bit number="4">Size of file when expanded</bit>
     <bit number="5">Internal file attributes</bit>
     <bit number="6">External file attributes</bit>
     <bit number="7">Centisecond (0-99)<br />
                     Second (0-59)<br />
                     Minute (0-59)<br />
                     Hour (0-23)<br />
                     Date (1-31)<br />
                     Month (1-12)<br />
                     Year (0...)</bit>
     <bit number="8">RISC OS Load address<br />
                     RISC OS Exec address</bit>
     <bit number="9">RISC OS Uncompressed length (duplicate of b4)</bit>
     <bit number="10">RISC OS Attributes</bit>
     <bit number="11">RISC OS Object type</bit>
     <bit number="12">RISC OS File type</bit>
     <bit number="13">GBPB-style filename length (aligned to a multiple of
                      4)<br />
                      Zero terminated filename, aligned to a word boundary,
                      inline with this data.
                      </bit>
     <bit number="14">Filename length (aligned to a multiple of 4)<br />
                      Zero terminated filename, aligned to a word boundary
                      will be written after the fixed size options.
                      </bit>
     <bit number="15">Extra information length<br />
                      Zero terminated extra information, aligned to a word
                      boundary will be written after the filename.</bit>
     <bit number="16">File comment length<br />
                      Zero terminated comment will be written after the
                      extra information, and will be word aligned.</bit>
    </bitfield-table>
   </bit>
  </bitfield-table>
 </register-use>
 <register-use number="1">Unzip handle</register-use>
 <register-use number="2">pointer to output buffer</register-use>
 <register-use number="3">number of objects to read</register-use>
 <register-use number="4">opaque offset of object to start at, or 0 for first object</register-use>
 <register-use number="5">length of output buffer</register-use>
</entry>
<exit>
 <register-use number="3">number of objects read</register-use>
 <register-use number="4">next opaque offset to use for enumerate
 </register-use>
 <register-use number="5">size of unused data in output buffer
 </register-use>
</exit>

<use>
<p>This SWI is used to enumerate the objects in the archive. Data is written
in the order given in the flags table above. The interface is intentionally
similarly to OS_GBPB. This makes simple its use as a direct replacement for
OS_GBPB.
</p>

</use>

<related>
<!-- <reference type="command" name="Com" /> -->
<reference type="swi" name="Zipper_UnZipOpen" />
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_UnZipFileInfo"
                number="559C4"
                description="Read information on a file"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags</register-use>
 <register-use number="1">Unzip handle</register-use>
 <register-use number="2-3">See sub-reasons</register-use>
</entry>

<use>
<p>This SWI is used to read information on a single object. The call is
available in two forms. The first form reads information on the object in
the same manner as Enumerate. The second form reads information on the
object in a similar manner to OS_File 5.</p>

</use>

<related>
<!-- <reference type="command" name="Com" /> -->
<reference type="swi" name="Zipper_UnZipEnumerate" />
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_UnZipFileInfo"
                number="559C4"
                reason="to buffer"
                reasonname="ToBuffer"
                description="Read information on a file to a buffer"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags :
  <bitfield-table>
   <bit number="0-16">Flags as Zipper_UnZipEnumerate</bit>
  </bitfield-table>
 </register-use>
 <register-use number="1">Unzip handle</register-use>
 <register-use number="2">pointer to filename to read</register-use>
 <register-use number="3">pointer to buffer for data</register-use>
 <register-use number="4">length of buffer</register-use>
</entry>
<exit>
 <register-use number="3">pointer to end of data</register-use>
 <register-use number="4">space remaining, or -ve length if data would not
                          fit</register-use>
</exit>

<use>
<p>This SWI is used to read information on a object, using a similar
interface to UnZipEnumerate.</p>
</use>

<related>
<!-- <reference type="command" name="Com" /> -->
<reference type="swi" name="Zipper_UnZipEnumerate" />
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_UnZipFileInfo"
                number="559C4"
                reason="to registers"
                reasonname="ToRegisters"
                description="Read information on a file to registers, like OS_File 5"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">0 (no flags set)</register-use>
 <register-use number="1">Unzip handle</register-use>
 <register-use number="2">pointer to filename to read</register-use>
</entry>
<exit>
 <register-use number="0">object type (1 = file, 2 = directory)
                          </register-use>
 <register-use number="2">load address</register-use>
 <register-use number="3">exec address</register-use>
 <register-use number="4">object length when decompressed</register-use>
 <register-use number="5">file attributes</register-use>
</exit>

<use>
<p>This SWI is used to read information on a object, using a similar
interface to OS_File 5.</p>
</use>

<related>
<!-- <reference type="command" name="Com" /> -->
<reference type="swi" name="Zipper_UnZipEnumerate" />
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_UnZipFileOpen"
                number="559C5"
                description="Open a file in an archive for input"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags :
  <bitfield-table>
   <bit number="6">Password supplied in R3</bit>
   <bit number="other">Reserved, must be 0</bit>
  </bitfield-table>
 </register-use>
 <register-use number="1">Unzip handle</register-use>
 <register-use number="2">Pointer to filename of file to read</register-use>
 <register-use number="3">Pointer to password to use, if bit 6 set</register-use>
</entry>

<use>
<p>This SWI is used to open a file in an archive for reading.</p>

</use>

<related>
<!-- <reference type="command" name="Com" /> -->
<reference type="swi" name="Zipper_UnZipFileClose" />
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_UnZipFileClose"
                number="559C6"
                description="Close the current opened archive file"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags (reserved, must be 0)</register-use>
 <register-use number="1">Unzip handle</register-use>
</entry>

<use>
<p>This SWI is used to close a file in an archive opened for reading. An
error will be given if a CRC error was encountered.</p>

</use>

<related>
<!-- <reference type="command" name="Com" /> -->
<reference type="swi" name="Zipper_UnZipFileOpen" />
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_UnZipFileRead"
                number="559C7"
                description="Read data from a previously opened input archive"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags (reserved, must be 0)</register-use>
 <register-use number="1">Unzip handle</register-use>
 <register-use number="2">Pointer to buffer to write in to</register-use>
 <register-use number="3">Length of buffer</register-use>
</entry>
<exit>
 <register-use number="0">number of bytes read, or 0 if nothing could be
                          read</register-use>
</exit>

<use>
<p>This SWI is used to read data from the currently opened file in the
archive.</p>

</use>

<related>
<!-- <reference type="command" name="Com" /> -->
<!-- <reference type="swi" name="OS_CRC" /> -->
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_UnZipFileEOF"
                number="559C8"
                description="Check whether end of file has been reached"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags (reserved, must be 0)</register-use>
 <register-use number="1">Unzip handle</register-use>
</entry>
<exit>
 <register-use number="0">1 if 'end of file', 0 if not.</register-use>
</exit>

<use>
<p>This SWI is used to discover whether the end of the currently
opened file in the archive has been reached.</p>

</use>

<related>
<!-- <reference type="command" name="Com" /> -->
<!-- <reference type="swi" name="OS_CRC" /> -->
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>




<swi-definition name="Zipper_ZipOpen"
                number="559D0"
                description="Create an archive"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags :
  <bitfield-table>
   <bit number="0">Append to file, rather than create file (for building
                   self extracting archives</bit>
   <bit number="31">If set, do not discard this archive handle when the
                    application exits</bit>
   <bit number="1-30">Reserved, must be 0</bit>
  </bitfield-table>
 </register-use>
 <register-use number="1">Pointer to filename of archive to
                          create or append to</register-use>
</entry>
<exit>
 <register-use number="0">Opaque zip handle, guaranteed not to be
                          0</register-use>
</exit>
<use>
<p>This SWI opens a Zip archive for writing via the Zipper API. If the
file cannot be opened, an error will be returned.</p>

</use>

<related>
<reference type="swi" name="Zipper_ZipClose" />
<!-- <reference type="command" name="Com" /> -->
<!-- <reference type="swi" name="thingy" /> -->
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_ZipClose"
                number="559D1"
                description="Close a file, previously opened for writing"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags (reserved, must be 0)</register-use>
 <register-use number="1">Zip handle</register-use>
</entry>
<use>
<p>This SWI is used to close an archive previously opened for writing.</p>

</use>

<related>
<reference type="swi" name="Zipper_ZipOpen" />
<!-- <reference type="command" name="Com" /> -->
<!-- <reference type="swi" name="thingy" /> -->
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_ZipFileOpen"
                number="559D2"
                description="Open a file in an archive for input"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags :
  <bitfield-table>
   <bit number="0">Time specifier contains RISC OS details (otherwise it
                   contains a Zip-style time specification)</bit>
   <bit number="1">Object is a directory</bit>
   <bit number="2">Object is text-like</bit>
   <bit number="3">Extra field is present</bit>
   <bit number="4">Comment field is present</bit>
   <bit number="5">File attributes are present</bit>
   <bit number="6">Password supplied in R9</bit>
   <bit number="other">Reserved, must be 0</bit>
  </bitfield-table>
 </register-use>
 <register-use number="1">Zip handle</register-use>
 <register-use number="2">Pointer to filename of file to write in archive
 </register-use>
 <register-use number="3">Compression method and level :
  <bitfield-table>
   <bit number="0-7">Compression method :
     <value-table>
      <value number="0">Store data as-is</value>
      <value number="8">Apply deflate algorithm to compress data</value>
      <value number="other">Undefined</value>
     </value-table>
   </bit>
   <bit number="8-11">Compression level :
     <value-table>
      <value number="1">'Super fast, little compression'</value>
      <value number="2">'Fast, more compression'</value>
      <value number="8">'Normal speed, normal compression'</value>
      <value number="9">'Slowest, maximum compression'</value>
      <value number="other">Undefined</value>
     </value-table>
   </bit>
   <bit number="12-31">Reserved (must be zero)</bit>
  </bitfield-table>
 </register-use>
 <register-use number="4">Pointer to time specifier block; if bit 0 set :
   <offset-table>
    <offset number="0">Load address</offset>
    <offset number="4">Exec address</offset>
    <offset number="8">Attributes</offset>
   </offset-table>
   If bit 0 clear :
   <offset-table>
    <offset number="0">Centiseconds</offset>
    <offset number="4">Seconds</offset>
    <offset number="8">Minutes</offset>
    <offset number="12">Hours</offset>
    <offset number="16">Date</offset>
    <offset number="20">Month</offset>
    <offset number="24">Year</offset>
   </offset-table>
 </register-use>
 <register-use number="5">Pointer to extra field data, if bit 3 set
 </register-use>
 <register-use number="6">Length of extra field, if bit 3 set</register-use>
 <register-use number="7">Pointer to zero terminated comment field, if
   bit 3 set</register-use>
 <register-use number="8">Pointer to block of zip file attributes :
   <offset-table>
    <offset number="0">internal file attributes</offset>
    <offset number="4">external file attributes</offset>
   </offset-table>
 </register-use>
 <register-use number="9">Pointer to password to use, if bit 6 set</register-use>
</entry>

<use>
<p>This SWI is used to open a file in an archive for writing, or to create
a directory.</p>

</use>

<related>
<!-- <reference type="command" name="Com" /> -->
<reference type="swi" name="Zipper_ZipFileClose" />
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_ZipFileClose"
                number="559D3"
                description="Close the current opened archive file"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags (reserved, must be 0)</register-use>
 <register-use number="1">Zip handle</register-use>
</entry>

<exit>
 <register-use number="0">Original (uncompressed) size of file</register-use>
 <register-use number="1">New (compressed) size of file in archive</register-use>
</exit>

<use>
<p>This SWI is used to close a file in an archive opened for writing.</p>

</use>

<related>
<!-- <reference type="command" name="Com" /> -->
<reference type="swi" name="Zipper_ZipFileOpen" />
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>


<swi-definition name="Zipper_ZipFileWrite"
                number="559D4"
                description="Write data to a previously opened archive"
                irqs="disabled"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
 <register-use number="0">Flags (reserved, must be 0)</register-use>
 <register-use number="1">Zip handle</register-use>
 <register-use number="2">Pointer to buffer of data to write</register-use>
 <register-use number="3">Length of buffer</register-use>
</entry>

<use>
<p>This SWI is used to write data to the currently opened file in the
archive.</p>

</use>

<related>
<!-- <reference type="command" name="Com" /> -->
<!-- <reference type="swi" name="OS_CRC" /> -->
<!-- <reference type="vector" name="bingleV" /> -->
</related>

</swi-definition>
</section>

</chapter>

<!-- MetaData -->
<meta>
 <maintainer>
  <email name="RISCOS Ltd" address="developer@riscos.com" />
 </maintainer>
 <disclaimer>
  <import document="http://www.riscos.com/prm/prm-disclaimer.xml" path="root/*" />
 </disclaimer>

 <history>
  <revision number="1" author="ROL" title="Initial version" />
  <revision number="2" author="GW" title="Typos and gramatical check">
    <change>Changed some of the wording to be clearer.</change>
    <change>Corrected a few misspelt words.</change>
  </revision>
  <revision number="3" author="ROL" title="Addition of ZipFileClose sizes">
    <change>ZipFileClose now returns relative sizes of data.</change>
  </revision>
  <revision number="4" author="ROL" title="Updated with details of passwords">
    <change>Password bit now included on UnZipFileOpen and ZipFileOpen.</change>
    <change>Added new 'Passwords' section to the Technical Details.</change>
  </revision>
  <revision number="5" author="Gerph" date="19 Sep 2023" title="Version information">
   <change>Included version table for compatibility info.</change>
  </revision>
 </history>
</meta>
</riscos-prm>

