summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--LICENSE21
-rw-r--r--README.md66
-rw-r--r--Zip.html386
-rw-r--r--Zip/Archive.html472
-rw-r--r--Zip/CompressionMethod.html815
-rw-r--r--Zip/DeflateCompressionHelper.html191
-rw-r--r--Zip/Entry.html636
-rw-r--r--Zip/Error.html179
-rw-r--r--Zip/Extra.html370
-rw-r--r--Zip/GeneralFlags.html649
-rw-r--r--Zip/NoneCompressionHelper.html165
-rw-r--r--Zip/Source.html335
-rw-r--r--Zip/TimeHelper.html165
-rw-r--r--Zip/Version.html312
-rw-r--r--Zip/Writer.html389
-rw-r--r--Zip/WriterEntry.html319
-rw-r--r--css/style.css325
-rw-r--r--index.html160
-rw-r--r--js/doc.js89
-rw-r--r--shard.yml7
-rw-r--r--spec/spec_helper.cr2
-rw-r--r--spec/zip_spec.cr102
-rw-r--r--src/zip.cr1920
24 files changed, 5957 insertions, 2119 deletions
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index ffc7b6a..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1 +0,0 @@
-language: crystal
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 3f522c4..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2016 Paul Duncan
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/README.md b/README.md
deleted file mode 100644
index d378703..0000000
--- a/README.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# zip-crystal
-
-Read and write zip archives natively from
-[Crystal](http://crystal-lang.org/).
-
-## Installation
-
-
-Add this to your application's `shard.yml`:
-
-```yaml
-dependencies:
- zip-crystal:
- github: pablotron/zip-crystal
-```
-
-
-## Usage
-
-
-```crystal
-require "zip-crystal/zip"
-
-# write to "foo.zip"
-Zip.write("foo.zip") do |zip|
- # add "bar.txt" with contents "hello!"
- zip.add("bar.txt", "hello!")
-
- # add local file "/path/to/image.png" as "image.png"
- zip.add_file("image.png", "/path/to/image.png")
-end
-
-# create memory io
-mem_io = MemoryIO.new
-
-# open "/some/other/path/image.png" for writing
-File.open("/some/other/path/image.png", "wb") do |file_io|
- # read from "foo.zip"
- Zip.read("foo.zip") do |zip|
- # extract "bar.txt" to mem_io
- zip["bar.txt"].read(mem_io)
-
- # extract "image.png" to file_io
- zip["image.png"].read(file_io)
- end
-end
-```
-
-See the [API documentation](https://pablotron.github.com/zip-crystal/)
-for additional information.
-
-## Development
-
-TODO: Write development instructions here
-
-## Contributing
-
-1. Fork it ( https://github.com/pablotron/zip-crystal/fork )
-2. Create your feature branch (git checkout -b my-new-feature)
-3. Commit your changes (git commit -am 'Add some feature')
-4. Push to the branch (git push origin my-new-feature)
-5. Create a new Pull Request
-
-## Contributors
-
-- [pablotron](https://github.com/pablotron) Paul Duncan - creator, maintainer
diff --git a/Zip.html b/Zip.html
new file mode 100644
index 0000000..fb7cad4
--- /dev/null
+++ b/Zip.html
@@ -0,0 +1,386 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="js/doc.js"></script>
+ <title>Zip - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">module</span> Zip
+
+</h1>
+
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>Library for reading and writing zip files.</p>
+
+<p>Examples:</p>
+
+<p>Reading from a zip file:</p>
+
+<p># create output MemoryIO
+mem_io = MemoryIO.new</p>
+
+<p># read from "foo.zip"
+Zip.read("foo.zip") do |zip|
+# read contents of "bar.txt" in "foo.zip" into mem_io
+zip["bar.txt"].read(mem_io)
+end</p>
+
+<p>Writing to a zip file:</p>
+
+<p># write to "foo.zip"
+Zip.write("foo.zip") do |zip|
+# create "bar.txt" with contents "hello!"
+zip.add("bar.txt", "hello!")
+end</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+ <h2>Constant Summary</h2>
+
+ <dl>
+
+ <dt class="entry-const" id="BUFFER_SIZE">
+ <strong>BUFFER_SIZE</strong> = <code><span class="n">8192</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Size of internal buffers, in bytes.</p>
+ </dd>
+
+
+ <dt class="entry-const" id="MAGIC">
+ <strong>MAGIC</strong> = <code>{cdr_header: <span class="n">33639248_u32</span>, cdr_footer: <span class="n">101010256_u32</span>, file_header: <span class="n">67324752_u32</span>, file_footer: <span class="n">134695760_u32</span>}</code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Magic numbers for various data in Zip stream.</p>
+ </dd>
+
+
+ <dt class="entry-const" id="VERSION">
+ <strong>VERSION</strong> = <code><span class="s">&quot;0.1.0&quot;</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Version of zip-crystal library.</p>
+ </dd>
+
+
+ </dl>
+
+
+
+ <h2>Class Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#read%28slice%3ABytes%2C%26cb%3AArchive-%3E%29%3AVoid-class-method" class="signature"><strong>.read</strong>(slice : Bytes, &cb : Archive -> ) : Void</a>
+
+ <div class="summary"><p>Read Zip::Archive from Slice and pass it to the given block.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#read%28path%3AString%2C%26cb%3AArchive-%3E%29%3AVoid-class-method" class="signature"><strong>.read</strong>(path : String, &cb : Archive -> ) : Void</a>
+
+ <div class="summary"><p>Read Zip::Archive from File and pass it to the given block.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#read%28io%3AIO%2C%26cb%3AArchive-%3E%29%3AVoid-class-method" class="signature"><strong>.read</strong>(io : IO, &cb : Archive -> ) : Void</a>
+
+ <div class="summary"><p>Read Zip::Archive from seekable IO instance and pass it to the given block.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#write%28io%3AIO%2Cpos%3AUInt32%3D%3Cspanclass%3D%22n%22%3E0_u32%3C%2Fspan%3E%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%2Cversion%3AVersion%3D%3Cspanclass%3D%22t%22%3EVersion%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFAULT%3C%2Fspan%3E%2C%26cb%3AWriter-%3E%29%3AUInt32-class-method" class="signature"><strong>.write</strong>(io : IO, pos : UInt32 = <span class="n">0_u32</span>, comment : String = <span class="s">&quot;&quot;</span>, version : Version = <span class="t">Version</span><span class="t">::</span><span class="t">DEFAULT</span>, &cb : Writer -> ) : UInt32</a>
+
+ <div class="summary"><p>Create a <code><a href="Zip/Writer.html">Zip::Writer</a></code> for the output IO <em>io</em> and yield it to the given block.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#write%28path%3AString%2Cpos%3AUInt32%3D%3Cspanclass%3D%22n%22%3E0_u32%3C%2Fspan%3E%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%2Cversion%3AVersion%3D%3Cspanclass%3D%22t%22%3EVersion%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFAULT%3C%2Fspan%3E%2C%26cb%3AWriter-%3E%29%3AUInt32-class-method" class="signature"><strong>.write</strong>(path : String, pos : UInt32 = <span class="n">0_u32</span>, comment : String = <span class="s">&quot;&quot;</span>, version : Version = <span class="t">Version</span><span class="t">::</span><span class="t">DEFAULT</span>, &cb : Writer -> ) : UInt32</a>
+
+ <div class="summary"><p>Create a <code><a href="Zip/Writer.html">Zip::Writer</a></code> for the output file <em>path</em> and yield it to the given block.</p></div>
+
+ </li>
+
+ </ul>
+
+
+
+
+
+
+
+<div class="methods-inherited">
+
+</div>
+
+
+ <h2>Class Method Detail</h2>
+
+ <div class="entry-detail" id="read&#40;slice:Bytes,&amp;cb:Archive-&gt;&#41;:Void-class-method">
+ <div class="signature">
+
+ def self.<strong>read</strong>(slice : Bytes, &cb : <a href="Zip/Archive.html">Archive</a> -> ) : Void
+
+ <a class="method-permalink" href="#read%28slice%3ABytes%2C%26cb%3AArchive-%3E%29%3AVoid-class-method">#</a>
+ </div>
+
+ <div class="doc"><p>Read Zip::Archive from Slice and pass it to the given block.</p>
+
+<p>Example:</p>
+
+<p># create memory io for contents of "bar.txt"
+io = MemoryIO.new</p>
+
+<p># extract "bar.txt" from zip archive in Slice some_slice and
+# save it to MemoryIO
+Zip.read(some_slice) do |zip|
+zip["bar.txt"].read(io)
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="read&#40;path:String,&amp;cb:Archive-&gt;&#41;:Void-class-method">
+ <div class="signature">
+
+ def self.<strong>read</strong>(path : String, &cb : <a href="Zip/Archive.html">Archive</a> -> ) : Void
+
+ <a class="method-permalink" href="#read%28path%3AString%2C%26cb%3AArchive-%3E%29%3AVoid-class-method">#</a>
+ </div>
+
+ <div class="doc"><p>Read Zip::Archive from File and pass it to the given block.</p>
+
+<p>Example:</p>
+
+<p># create memory io for contents of "bar.txt"
+io = MemoryIO.new</p>
+
+<p># extract "bar.txt" from "./foo.zip" and save it to MemoryIO
+Zip.read("./foo.zip") do |zip|
+zip["bar.txt"].read(io)
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="read&#40;io:IO,&amp;cb:Archive-&gt;&#41;:Void-class-method">
+ <div class="signature">
+
+ def self.<strong>read</strong>(io : IO, &cb : <a href="Zip/Archive.html">Archive</a> -> ) : Void
+
+ <a class="method-permalink" href="#read%28io%3AIO%2C%26cb%3AArchive-%3E%29%3AVoid-class-method">#</a>
+ </div>
+
+ <div class="doc"><p>Read Zip::Archive from seekable IO instance and pass it to the given
+block.</p>
+
+<p>Example:</p>
+
+<p># create memory io for contents of "bar.txt"
+io = MemoryIO.new</p>
+
+<p># read "bar.txt" from "./foo.zip"
+Zip.read(File.open("./foo.zip", "rb")) do |zip|
+zip["bar.txt"].read(io)
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="write&#40;io:IO,pos:UInt32&#61;&lt;spanclass&#61;&quot;n&quot;&gt;0_u32&lt;/span&gt;,comment:String&#61;&lt;spanclass&#61;&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;,version:Version&#61;&lt;spanclass&#61;&quot;t&quot;&gt;Version&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;::&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;DEFAULT&lt;/span&gt;,&amp;cb:Writer-&gt;&#41;:UInt32-class-method">
+ <div class="signature">
+
+ def self.<strong>write</strong>(io : IO, pos : UInt32 = <span class="n">0_u32</span>, comment : String = <span class="s">&quot;&quot;</span>, version : <a href="Zip/Version.html">Version</a> = <span class="t">Version</span><span class="t">::</span><span class="t">DEFAULT</span>, &cb : <a href="Zip/Writer.html">Writer</a> -> ) : UInt32
+
+ <a class="method-permalink" href="#write%28io%3AIO%2Cpos%3AUInt32%3D%3Cspanclass%3D%22n%22%3E0_u32%3C%2Fspan%3E%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%2Cversion%3AVersion%3D%3Cspanclass%3D%22t%22%3EVersion%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFAULT%3C%2Fspan%3E%2C%26cb%3AWriter-%3E%29%3AUInt32-class-method">#</a>
+ </div>
+
+ <div class="doc"><p>Create a <code><a href="Zip/Writer.html">Zip::Writer</a></code> for the output IO <em>io</em> and yield it to
+the given block. Returns number of bytes written.</p>
+
+<p>Example:</p>
+
+<p># create output IO
+File.open("foo.zip", "wb") do |io|
+Zip.write(io) do |zip|
+# add "bar.txt" with contents "hello!"
+zip.add("bar.txt", "hello!")
+end
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="write&#40;path:String,pos:UInt32&#61;&lt;spanclass&#61;&quot;n&quot;&gt;0_u32&lt;/span&gt;,comment:String&#61;&lt;spanclass&#61;&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;,version:Version&#61;&lt;spanclass&#61;&quot;t&quot;&gt;Version&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;::&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;DEFAULT&lt;/span&gt;,&amp;cb:Writer-&gt;&#41;:UInt32-class-method">
+ <div class="signature">
+
+ def self.<strong>write</strong>(path : String, pos : UInt32 = <span class="n">0_u32</span>, comment : String = <span class="s">&quot;&quot;</span>, version : <a href="Zip/Version.html">Version</a> = <span class="t">Version</span><span class="t">::</span><span class="t">DEFAULT</span>, &cb : <a href="Zip/Writer.html">Writer</a> -> ) : UInt32
+
+ <a class="method-permalink" href="#write%28path%3AString%2Cpos%3AUInt32%3D%3Cspanclass%3D%22n%22%3E0_u32%3C%2Fspan%3E%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%2Cversion%3AVersion%3D%3Cspanclass%3D%22t%22%3EVersion%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFAULT%3C%2Fspan%3E%2C%26cb%3AWriter-%3E%29%3AUInt32-class-method">#</a>
+ </div>
+
+ <div class="doc"><p>Create a <code><a href="Zip/Writer.html">Zip::Writer</a></code> for the output file <em>path</em> and yield it to
+the given block. Returns number of bytes written.</p>
+
+<p>Example:</p>
+
+<p># create "foo.zip"
+Zip.write("foo.zip") do |zip|
+# add "bar.txt" with contents "hello!"
+zip.add("bar.txt", "hello!")
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/Archive.html b/Zip/Archive.html
new file mode 100644
index 0000000..ea6e914
--- /dev/null
+++ b/Zip/Archive.html
@@ -0,0 +1,472 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::Archive - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">class</span> Zip::Archive
+
+</h1>
+
+
+ <ul class="superclass-hierarchy"><li class="superclass"><a href="../Zip/Archive.html">Zip::Archive</a></li><li class="superclass">Reference</li><li class="superclass">Object</li></ul>
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>Input archive.</p>
+
+<p>Use <code><a href="../Zip.html#read%28slice%3ABytes%2C%26cb%3AArchive-%3E%29%3AVoid-class-method">Zip.read</a>()</code> instead of instantiating this class directly.</p>
+
+
+
+
+
+ <h2>Included Modules</h2>
+ <ul class="other-types-list">
+
+ <li class="other-type">Enumerable(Entry)</li>
+
+ <li class="other-type">Iterable</li>
+
+ </ul>
+
+
+
+
+
+
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+
+ <h2>Class Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#new%28io%3ASource%29-class-method" class="signature"><strong>.new</strong>(io : Source)</a>
+
+ <div class="summary"><p>Create new Zip::Archive from input Zip::Source.</p></div>
+
+ </li>
+
+ </ul>
+
+
+
+ <h2>Instance Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#%5B%5D%28path%3AString%29%3AEntry-instance-method" class="signature"><strong>#[]</strong>(path : String) : Entry</a>
+
+ <div class="summary"><p>Get Zip::Entry by path.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#%5B%5D%28id%3AInt%29%3AEntry-instance-method" class="signature"><strong>#[]</strong>(id : Int) : Entry</a>
+
+ <div class="summary"><p>Get Zip::Entry by number.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#%5B%5D%3F%28id%3AInt%29%3AEntry%7CNil-instance-method" class="signature"><strong>#[]?</strong>(id : Int) : Entry | Nil</a>
+
+ <div class="summary"><p>Get Zip::Entry by number, or nil if it doesn't exist</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#%5B%5D%3F%28path%3AString%29%3AEntry%7CNil-instance-method" class="signature"><strong>#[]?</strong>(path : String) : Entry | Nil</a>
+
+ <div class="summary"><p>Return Zip::Entry from path, or nil if it doesn't exist.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#comment%3AString-instance-method" class="signature"><strong>#comment</strong> : String</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#each%28%2Aargs%2C%2A%2Aoptions%2C%26block%29-instance-method" class="signature"><strong>#each</strong>(*args, **options, &block)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#each%28%2Aargs%2C%2A%2Aoptions%29-instance-method" class="signature"><strong>#each</strong>(*args, **options)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#entries%3AArray%28Zip%3A%3AEntry%29-instance-method" class="signature"><strong>#entries</strong> : Array(Zip::Entry)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#size%28%2Aargs%2C%2A%2Aoptions%2C%26block%29-instance-method" class="signature"><strong>#size</strong>(*args, **options, &block)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#size%28%2Aargs%2C%2A%2Aoptions%29-instance-method" class="signature"><strong>#size</strong>(*args, **options)</a>
+
+ </li>
+
+ </ul>
+
+
+
+
+
+<div class="methods-inherited">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</div>
+
+
+ <h2>Class Method Detail</h2>
+
+ <div class="entry-detail" id="new&#40;io:Source&#41;-class-method">
+ <div class="signature">
+
+ def self.<strong>new</strong>(io : <a href="../Zip/Source.html">Source</a>)
+
+ <a class="method-permalink" href="#new%28io%3ASource%29-class-method">#</a>
+ </div>
+
+ <div class="doc"><p>Create new Zip::Archive from input Zip::Source.</p>
+
+<p>Use <code><a href="../Zip.html#read%28slice%3ABytes%2C%26cb%3AArchive-%3E%29%3AVoid-class-method">Zip.read</a>()</code> instead of calling this method directly.</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+ <h2>Instance Method Detail</h2>
+
+ <div class="entry-detail" id="&#91;&#93;&#40;path:String&#41;:Entry-instance-method">
+ <div class="signature">
+
+ def <strong>[]</strong>(path : String) : <a href="../Zip/Entry.html">Entry</a>
+
+ <a class="method-permalink" href="#%5B%5D%28path%3AString%29%3AEntry-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Get Zip::Entry by path.</p>
+
+<p>Example:</p>
+
+<p># get bar.txt and read it into memory io
+io = MemoryIO.new
+zip["bar.txt"].read(io)</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="&#91;&#93;&#40;id:Int&#41;:Entry-instance-method">
+ <div class="signature">
+
+ def <strong>[]</strong>(id : Int) : <a href="../Zip/Entry.html">Entry</a>
+
+ <a class="method-permalink" href="#%5B%5D%28id%3AInt%29%3AEntry-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Get Zip::Entry by number.</p>
+
+<p>Example:</p>
+
+<p># read third entry from archive into memory io
+io = MemoryIO.new
+zip[2].read(io)</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="&#91;&#93;?&#40;id:Int&#41;:Entry|Nil-instance-method">
+ <div class="signature">
+
+ def <strong>[]?</strong>(id : Int) : <a href="../Zip/Entry.html">Entry</a> | Nil
+
+ <a class="method-permalink" href="#%5B%5D%3F%28id%3AInt%29%3AEntry%7CNil-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Get Zip::Entry by number, or nil if it doesn't exist</p>
+
+<p>Example:</p>
+
+<p># read third entry from archive into memory io
+if e = zip[2]
+io = MemoryIO.new
+e.read(io)
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="&#91;&#93;?&#40;path:String&#41;:Entry|Nil-instance-method">
+ <div class="signature">
+
+ def <strong>[]?</strong>(path : String) : <a href="../Zip/Entry.html">Entry</a> | Nil
+
+ <a class="method-permalink" href="#%5B%5D%3F%28path%3AString%29%3AEntry%7CNil-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Return Zip::Entry from path, or nil if it doesn't exist.</p>
+
+<p>Example:</p>
+
+<p># read bar.txt into memory io if it exists
+if e = zip["bar.txt"]?
+io = MemoryIO.new
+e.read(io)
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="comment:String-instance-method">
+ <div class="signature">
+
+ def <strong>comment</strong> : String
+
+ <a class="method-permalink" href="#comment%3AString-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="each&#40;*args,**options,&amp;block&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>each</strong>(*args, **options, &block)
+
+ <a class="method-permalink" href="#each%28%2Aargs%2C%2A%2Aoptions%2C%26block%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="each&#40;*args,**options&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>each</strong>(*args, **options)
+
+ <a class="method-permalink" href="#each%28%2Aargs%2C%2A%2Aoptions%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="entries:Array&#40;Zip::Entry&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>entries</strong> : Array(<a href="../Zip/Entry.html">Zip::Entry</a>)
+
+ <a class="method-permalink" href="#entries%3AArray%28Zip%3A%3AEntry%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="size&#40;*args,**options,&amp;block&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>size</strong>(*args, **options, &block)
+
+ <a class="method-permalink" href="#size%28%2Aargs%2C%2A%2Aoptions%2C%26block%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="size&#40;*args,**options&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>size</strong>(*args, **options)
+
+ <a class="method-permalink" href="#size%28%2Aargs%2C%2A%2Aoptions%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/CompressionMethod.html b/Zip/CompressionMethod.html
new file mode 100644
index 0000000..f18b338
--- /dev/null
+++ b/Zip/CompressionMethod.html
@@ -0,0 +1,815 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::CompressionMethod - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">enum</span> Zip::CompressionMethod
+
+</h1>
+
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>Compression methods.</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+ <h2>Enum Members</h2>
+
+ <dl>
+
+ <dt class="entry-const" id="NONE">
+ <strong>NONE</strong> = <code><span class="n">0</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Stored (no compression)</p>
+ </dd>
+
+
+ <dt class="entry-const" id="SHRUNK">
+ <strong>SHRUNK</strong> = <code><span class="n">1</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Shrunk</p>
+ </dd>
+
+
+ <dt class="entry-const" id="REDUCED_1">
+ <strong>REDUCED_1</strong> = <code><span class="n">2</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Reduced with compression factor 1</p>
+ </dd>
+
+
+ <dt class="entry-const" id="REDUCED_2">
+ <strong>REDUCED_2</strong> = <code><span class="n">3</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Reduced with compression factor 2</p>
+ </dd>
+
+
+ <dt class="entry-const" id="REDUCED_3">
+ <strong>REDUCED_3</strong> = <code><span class="n">4</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Reduced with compression factor 3</p>
+ </dd>
+
+
+ <dt class="entry-const" id="REDUCED_4">
+ <strong>REDUCED_4</strong> = <code><span class="n">5</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Reduced with compression factor 4</p>
+ </dd>
+
+
+ <dt class="entry-const" id="IMPLODED">
+ <strong>IMPLODED</strong> = <code><span class="n">6</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Imploded</p>
+ </dd>
+
+
+ <dt class="entry-const" id="TOKENIZED">
+ <strong>TOKENIZED</strong> = <code><span class="n">7</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Reserved for Tokenizing compression algorithm</p>
+ </dd>
+
+
+ <dt class="entry-const" id="DEFLATE">
+ <strong>DEFLATE</strong> = <code><span class="n">8</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Deflated</p>
+ </dd>
+
+
+ <dt class="entry-const" id="DEFLATE64">
+ <strong>DEFLATE64</strong> = <code><span class="n">9</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Enhanced Deflating using Deflate64(tm)</p>
+ </dd>
+
+
+ <dt class="entry-const" id="TERSE_OLD">
+ <strong>TERSE_OLD</strong> = <code><span class="n">10</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>PKWARE Data Compression Library Imploding (old IBM TERSE)</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_11">
+ <strong>RESERVED_11</strong> = <code><span class="n">11</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Reserved by PKWARE</p>
+ </dd>
+
+
+ <dt class="entry-const" id="BZIP2">
+ <strong>BZIP2</strong> = <code><span class="n">12</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>BZIP2</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_13">
+ <strong>RESERVED_13</strong> = <code><span class="n">13</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Reserved by PKWARE</p>
+ </dd>
+
+
+ <dt class="entry-const" id="LZMA">
+ <strong>LZMA</strong> = <code><span class="n">14</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>LZMA (EFS)</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_15">
+ <strong>RESERVED_15</strong> = <code><span class="n">15</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Reserved by PKWARE</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_16">
+ <strong>RESERVED_16</strong> = <code><span class="n">16</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Reserved by PKWARE</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_17">
+ <strong>RESERVED_17</strong> = <code><span class="n">17</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Reserved by PKWARE</p>
+ </dd>
+
+
+ <dt class="entry-const" id="TERSE">
+ <strong>TERSE</strong> = <code><span class="n">18</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>IBM TERSE (new)</p>
+ </dd>
+
+
+ <dt class="entry-const" id="LZ77">
+ <strong>LZ77</strong> = <code><span class="n">19</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>IBM LZ77 z Architecture (PFS)</p>
+ </dd>
+
+
+ <dt class="entry-const" id="WAVPACK">
+ <strong>WAVPACK</strong> = <code><span class="n">97</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>WavPack compressed data</p>
+ </dd>
+
+
+ <dt class="entry-const" id="PPMD">
+ <strong>PPMD</strong> = <code><span class="n">98</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>PPMd version I, Rev 1</p>
+ </dd>
+
+
+ </dl>
+
+
+
+
+
+ <h2>Instance Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#bzi_p2%3F-instance-method" class="signature"><strong>#bzi_p2?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#deflat_e64%3F-instance-method" class="signature"><strong>#deflat_e64?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#deflate%3F-instance-method" class="signature"><strong>#deflate?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#imploded%3F-instance-method" class="signature"><strong>#imploded?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#l_z77%3F-instance-method" class="signature"><strong>#l_z77?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#lzma%3F-instance-method" class="signature"><strong>#lzma?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#none%3F-instance-method" class="signature"><strong>#none?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#ppmd%3F-instance-method" class="signature"><strong>#ppmd?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reduced_1%3F-instance-method" class="signature"><strong>#reduced_1?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reduced_2%3F-instance-method" class="signature"><strong>#reduced_2?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reduced_3%3F-instance-method" class="signature"><strong>#reduced_3?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reduced_4%3F-instance-method" class="signature"><strong>#reduced_4?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_11%3F-instance-method" class="signature"><strong>#reserved_11?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_13%3F-instance-method" class="signature"><strong>#reserved_13?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_15%3F-instance-method" class="signature"><strong>#reserved_15?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_16%3F-instance-method" class="signature"><strong>#reserved_16?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_17%3F-instance-method" class="signature"><strong>#reserved_17?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#shrunk%3F-instance-method" class="signature"><strong>#shrunk?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#terse%3F-instance-method" class="signature"><strong>#terse?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#terse_old%3F-instance-method" class="signature"><strong>#terse_old?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#tokenized%3F-instance-method" class="signature"><strong>#tokenized?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#wavpack%3F-instance-method" class="signature"><strong>#wavpack?</strong></a>
+
+ </li>
+
+ </ul>
+
+
+
+
+
+<div class="methods-inherited">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</div>
+
+
+
+
+ <h2>Instance Method Detail</h2>
+
+ <div class="entry-detail" id="bzi_p2?-instance-method">
+ <div class="signature">
+
+ def <strong>bzi_p2?</strong>
+
+ <a class="method-permalink" href="#bzi_p2%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="deflat_e64?-instance-method">
+ <div class="signature">
+
+ def <strong>deflat_e64?</strong>
+
+ <a class="method-permalink" href="#deflat_e64%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="deflate?-instance-method">
+ <div class="signature">
+
+ def <strong>deflate?</strong>
+
+ <a class="method-permalink" href="#deflate%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="imploded?-instance-method">
+ <div class="signature">
+
+ def <strong>imploded?</strong>
+
+ <a class="method-permalink" href="#imploded%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="l_z77?-instance-method">
+ <div class="signature">
+
+ def <strong>l_z77?</strong>
+
+ <a class="method-permalink" href="#l_z77%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="lzma?-instance-method">
+ <div class="signature">
+
+ def <strong>lzma?</strong>
+
+ <a class="method-permalink" href="#lzma%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="none?-instance-method">
+ <div class="signature">
+
+ def <strong>none?</strong>
+
+ <a class="method-permalink" href="#none%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="ppmd?-instance-method">
+ <div class="signature">
+
+ def <strong>ppmd?</strong>
+
+ <a class="method-permalink" href="#ppmd%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reduced_1?-instance-method">
+ <div class="signature">
+
+ def <strong>reduced_1?</strong>
+
+ <a class="method-permalink" href="#reduced_1%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reduced_2?-instance-method">
+ <div class="signature">
+
+ def <strong>reduced_2?</strong>
+
+ <a class="method-permalink" href="#reduced_2%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reduced_3?-instance-method">
+ <div class="signature">
+
+ def <strong>reduced_3?</strong>
+
+ <a class="method-permalink" href="#reduced_3%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reduced_4?-instance-method">
+ <div class="signature">
+
+ def <strong>reduced_4?</strong>
+
+ <a class="method-permalink" href="#reduced_4%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_11?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_11?</strong>
+
+ <a class="method-permalink" href="#reserved_11%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_13?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_13?</strong>
+
+ <a class="method-permalink" href="#reserved_13%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_15?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_15?</strong>
+
+ <a class="method-permalink" href="#reserved_15%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_16?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_16?</strong>
+
+ <a class="method-permalink" href="#reserved_16%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_17?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_17?</strong>
+
+ <a class="method-permalink" href="#reserved_17%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="shrunk?-instance-method">
+ <div class="signature">
+
+ def <strong>shrunk?</strong>
+
+ <a class="method-permalink" href="#shrunk%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="terse?-instance-method">
+ <div class="signature">
+
+ def <strong>terse?</strong>
+
+ <a class="method-permalink" href="#terse%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="terse_old?-instance-method">
+ <div class="signature">
+
+ def <strong>terse_old?</strong>
+
+ <a class="method-permalink" href="#terse_old%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="tokenized?-instance-method">
+ <div class="signature">
+
+ def <strong>tokenized?</strong>
+
+ <a class="method-permalink" href="#tokenized%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="wavpack?-instance-method">
+ <div class="signature">
+
+ def <strong>wavpack?</strong>
+
+ <a class="method-permalink" href="#wavpack%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/DeflateCompressionHelper.html b/Zip/DeflateCompressionHelper.html
new file mode 100644
index 0000000..0b42f24
--- /dev/null
+++ b/Zip/DeflateCompressionHelper.html
@@ -0,0 +1,191 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::DeflateCompressionHelper - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">module</span> Zip::DeflateCompressionHelper
+
+</h1>
+
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>Helper methods for compressing and decompressing deflated data.</p>
+
+
+
+
+
+
+
+
+
+
+
+ <h2>Direct including types</h2>
+ <ul class="other-types-list">
+
+ <li class="other-type"><a href="../Zip/Entry.html">Zip::Entry</a></li>
+
+ <li class="other-type"><a href="../Zip/WriterEntry.html">Zip::WriterEntry</a></li>
+
+ </ul>
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+ <h2>Constant Summary</h2>
+
+ <dl>
+
+ <dt class="entry-const" id="ZALLOC_PROC">
+ <strong>ZALLOC_PROC</strong> = <code><span class="t">LibZ</span><span class="t">::</span><span class="t">AllocFunc</span>.<span class="k">new</span> <span class="k">do</span> <span class="o">|</span>data, num_items, size<span class="o">|</span>
+ <span class="t">GC</span>.malloc(num_items <span class="o">*</span> size)
+<span class="k">end</span></code>
+ </dt>
+
+
+ <dt class="entry-const" id="ZFREE_PROC">
+ <strong>ZFREE_PROC</strong> = <code><span class="t">LibZ</span><span class="t">::</span><span class="t">FreeFunc</span>.<span class="k">new</span> <span class="k">do</span> <span class="o">|</span>data, addr<span class="o">|</span>
+ <span class="t">GC</span>.free(addr)
+<span class="k">end</span></code>
+ </dt>
+
+
+ <dt class="entry-const" id="ZLIB_VERSION">
+ <strong>ZLIB_VERSION</strong> = <code><span class="t">LibZ</span>.zlibVersion</code>
+ </dt>
+
+
+ </dl>
+
+
+
+
+
+
+
+
+
+<div class="methods-inherited">
+
+</div>
+
+
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/Entry.html b/Zip/Entry.html
new file mode 100644
index 0000000..6626777
--- /dev/null
+++ b/Zip/Entry.html
@@ -0,0 +1,636 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::Entry - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">class</span> Zip::Entry
+
+</h1>
+
+
+ <ul class="superclass-hierarchy"><li class="superclass"><a href="../Zip/Entry.html">Zip::Entry</a></li><li class="superclass">Reference</li><li class="superclass">Object</li></ul>
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>File entry in <code><a href="../Zip/Archive.html">Archive</a></code>.</p>
+
+<p>Use <code><a href="../Zip.html#read%28slice%3ABytes%2C%26cb%3AArchive-%3E%29%3AVoid-class-method">Zip.read</a>()</code> to read a Zip archive, then <code>#[]</code> to fetch a
+specific archive entry.</p>
+
+<p>Example:</p>
+
+<p># create MemoryIO
+io = MemoryIO.new</p>
+
+<p># open "foo.zip"
+Zip.read("foo.zip") do |zip|
+# get "bar.txt" entry from "foo.zip"
+e = zip["bar.txt"]</p>
+
+<pre><code><span class="c"># read contents of &quot;bar.txt&quot; into io</span>
+e.read(io)</code></pre>
+
+<p>end</p>
+
+
+
+
+
+ <h2>Included Modules</h2>
+ <ul class="other-types-list">
+
+ <li class="other-type"><a href="../Zip/DeflateCompressionHelper.html">Zip::DeflateCompressionHelper</a></li>
+
+ <li class="other-type"><a href="../Zip/NoneCompressionHelper.html">Zip::NoneCompressionHelper</a></li>
+
+ <li class="other-type"><a href="../Zip/TimeHelper.html">Zip::TimeHelper</a></li>
+
+ </ul>
+
+
+
+
+
+
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+
+ <h2>Class Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#new%28io%3ASource%29-class-method" class="signature"><strong>.new</strong>(io : Source)</a>
+
+ <div class="summary"><p>Instantiate a new <code><a href="../Zip/Entry.html">Entry</a></code> object from the given IO.</p></div>
+
+ </li>
+
+ </ul>
+
+
+
+ <h2>Instance Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#comment%3AString-instance-method" class="signature"><strong>#comment</strong> : String</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#compressed_size%3AUInt32-instance-method" class="signature"><strong>#compressed_size</strong> : UInt32</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#crc%3AUInt32-instance-method" class="signature"><strong>#crc</strong> : UInt32</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#external_attr%3AUInt32-instance-method" class="signature"><strong>#external_attr</strong> : UInt32</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#extras%3AArray%28Zip%3A%3AExtra%29-instance-method" class="signature"><strong>#extras</strong> : Array(Zip::Extra)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#flags%3AUInt16-instance-method" class="signature"><strong>#flags</strong> : UInt16</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#internal_attr%3AUInt16-instance-method" class="signature"><strong>#internal_attr</strong> : UInt16</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#local_extras%3AArray%28Extra%29-instance-method" class="signature"><strong>#local_extras</strong> : Array(Extra)</a>
+
+ <div class="summary"><p>Returns an array of <code><a href="../Zip/Extra.html">Extra</a></code> attributes for this <code><a href="../Zip/Entry.html">Entry</a></code>.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#method%3AZip%3A%3ACompressionMethod-instance-method" class="signature"><strong>#method</strong> : Zip::CompressionMethod</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#path%3AString-instance-method" class="signature"><strong>#path</strong> : String</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#pos%3AUInt32-instance-method" class="signature"><strong>#pos</strong> : UInt32</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#read%28dst_io%3AIO%29%3AUInt32-instance-method" class="signature"><strong>#read</strong>(dst_io : IO) : UInt32</a>
+
+ <div class="summary"><p>Write contents of <code><a href="../Zip/Entry.html">Entry</a></code> into given <code>IO</code>.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#size%3AUInt32-instance-method" class="signature"><strong>#size</strong> : UInt32</a>
+
+ <div class="summary"><p>Return the uncompressed size of this entry in bytes.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#time%3ATime-instance-method" class="signature"><strong>#time</strong> : Time</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#uncompressed_size%3AUInt32-instance-method" class="signature"><strong>#uncompressed_size</strong> : UInt32</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#version%3AUInt16-instance-method" class="signature"><strong>#version</strong> : UInt16</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#version_needed%3AUInt16-instance-method" class="signature"><strong>#version_needed</strong> : UInt16</a>
+
+ </li>
+
+ </ul>
+
+
+
+
+
+<div class="methods-inherited">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</div>
+
+
+ <h2>Class Method Detail</h2>
+
+ <div class="entry-detail" id="new&#40;io:Source&#41;-class-method">
+ <div class="signature">
+
+ def self.<strong>new</strong>(io : <a href="../Zip/Source.html">Source</a>)
+
+ <a class="method-permalink" href="#new%28io%3ASource%29-class-method">#</a>
+ </div>
+
+ <div class="doc"><p>Instantiate a new <code><a href="../Zip/Entry.html">Entry</a></code> object from the given IO.</p>
+
+<p>You should not need to call this method directly (use
+<code><a href="../Zip/Archive.html#%5B%5D%28path%3AString%29%3AEntry-instance-method">Zip::Archive#[]</a></code> instead).</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+ <h2>Instance Method Detail</h2>
+
+ <div class="entry-detail" id="comment:String-instance-method">
+ <div class="signature">
+
+ def <strong>comment</strong> : String
+
+ <a class="method-permalink" href="#comment%3AString-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="compressed_size:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>compressed_size</strong> : UInt32
+
+ <a class="method-permalink" href="#compressed_size%3AUInt32-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="crc:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>crc</strong> : UInt32
+
+ <a class="method-permalink" href="#crc%3AUInt32-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="external_attr:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>external_attr</strong> : UInt32
+
+ <a class="method-permalink" href="#external_attr%3AUInt32-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="extras:Array&#40;Zip::Extra&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>extras</strong> : Array(<a href="../Zip/Extra.html">Zip::Extra</a>)
+
+ <a class="method-permalink" href="#extras%3AArray%28Zip%3A%3AExtra%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="flags:UInt16-instance-method">
+ <div class="signature">
+
+ def <strong>flags</strong> : UInt16
+
+ <a class="method-permalink" href="#flags%3AUInt16-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="internal_attr:UInt16-instance-method">
+ <div class="signature">
+
+ def <strong>internal_attr</strong> : UInt16
+
+ <a class="method-permalink" href="#internal_attr%3AUInt16-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="local_extras:Array&#40;Extra&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>local_extras</strong> : Array(<a href="../Zip/Extra.html">Extra</a>)
+
+ <a class="method-permalink" href="#local_extras%3AArray%28Extra%29-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Returns an array of <code><a href="../Zip/Extra.html">Extra</a></code> attributes for this <code><a href="../Zip/Entry.html">Entry</a></code>.</p>
+
+<p>Zip archives can (and do) have separate <code><a href="../Zip/Extra.html">Extra</a></code> attributes
+associated with the file entry itself, and the file's entry in the
+Central Directory.</p>
+
+<p>The <code><a href="../Zip/Entry.html#extras%3AArray%28Zip%3A%3AExtra%29-instance-method">#extras</a></code> method returns the <code><a href="../Zip/Extra.html">Extra</a></code> attributes from the
+file's entry in the Central Directory, and this method returns the
+<code><a href="../Zip/Extra.html">Extra</a></code> data from the file entry itself.</p>
+
+<p>Example:</p>
+
+<p># open "./foo.zip"
+Zip.read("./foo.zip") do |zip|
+# get array of local extra attributes from "bar.txt"
+extras = zip["bar.txt"].local_extras
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="method:Zip::CompressionMethod-instance-method">
+ <div class="signature">
+
+ def <strong>method</strong> : <a href="../Zip/CompressionMethod.html">Zip::CompressionMethod</a>
+
+ <a class="method-permalink" href="#method%3AZip%3A%3ACompressionMethod-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="path:String-instance-method">
+ <div class="signature">
+
+ def <strong>path</strong> : String
+
+ <a class="method-permalink" href="#path%3AString-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="pos:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>pos</strong> : UInt32
+
+ <a class="method-permalink" href="#pos%3AUInt32-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="read&#40;dst_io:IO&#41;:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>read</strong>(dst_io : IO) : UInt32
+
+ <a class="method-permalink" href="#read%28dst_io%3AIO%29%3AUInt32-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Write contents of <code><a href="../Zip/Entry.html">Entry</a></code> into given <code>IO</code>.</p>
+
+<p>Raises an <code><a href="../Zip/Error.html">Error</a></code> if the file contents could not be read or if the
+compression method is unsupported.</p>
+
+<p>Example:</p>
+
+<p># open "output-bar.txt" for writing
+File.open("output-bar.txt", "wb") do |io|
+# open archive "./foo.zip"
+Zip.read("foo.zip") do |zip|
+# write contents of "bar.txt" to "output-bar.txt"
+zip["foo.txt"].read(io)
+end
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="size:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>size</strong> : UInt32
+
+ <a class="method-permalink" href="#size%3AUInt32-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Return the uncompressed size of this entry in bytes.</p>
+
+<p>Example:</p>
+
+<p>Zip.read("foo.zip") do |zip|
+size = zip["bar.txt"].size
+puts "bar.txt is #{size} bytes."
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="time:Time-instance-method">
+ <div class="signature">
+
+ def <strong>time</strong> : Time
+
+ <a class="method-permalink" href="#time%3ATime-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="uncompressed_size:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>uncompressed_size</strong> : UInt32
+
+ <a class="method-permalink" href="#uncompressed_size%3AUInt32-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="version:UInt16-instance-method">
+ <div class="signature">
+
+ def <strong>version</strong> : UInt16
+
+ <a class="method-permalink" href="#version%3AUInt16-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="version_needed:UInt16-instance-method">
+ <div class="signature">
+
+ def <strong>version_needed</strong> : UInt16
+
+ <a class="method-permalink" href="#version_needed%3AUInt16-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/Error.html b/Zip/Error.html
new file mode 100644
index 0000000..fc71ef7
--- /dev/null
+++ b/Zip/Error.html
@@ -0,0 +1,179 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::Error - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">class</span> Zip::Error
+
+</h1>
+
+
+ <ul class="superclass-hierarchy"><li class="superclass"><a href="../Zip/Error.html">Zip::Error</a></li><li class="superclass">Exception</li><li class="superclass">Reference</li><li class="superclass">Object</li></ul>
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>Wrapper class for exceptions.</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="methods-inherited">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</div>
+
+
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/Extra.html b/Zip/Extra.html
new file mode 100644
index 0000000..cb489df
--- /dev/null
+++ b/Zip/Extra.html
@@ -0,0 +1,370 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::Extra - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">class</span> Zip::Extra
+
+</h1>
+
+
+ <ul class="superclass-hierarchy"><li class="superclass"><a href="../Zip/Extra.html">Zip::Extra</a></li><li class="superclass">Reference</li><li class="superclass">Object</li></ul>
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>Extra data associated with <code><a href="../Zip/Entry.html">Entry</a></code>.</p>
+
+<p>You should not need to instantiate this class directly; use
+<code><a href="../Zip/Entry.html#extras%3AArray%28Zip%3A%3AExtra%29-instance-method">Zip::Entry#extras</a></code> or <code><a href="../Zip/Entry.html#local_extras%3AArray%28Extra%29-instance-method">Zip::Entry#local_extras</a></code> instead.</p>
+
+<p>Example:</p>
+
+<p># open "foo.zip"
+Zip.read("foo.zip") do |zip|
+# get extra data associated with "bar.txt"
+extras = zip["bar.txt"].extras
+end</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+
+ <h2>Class Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#new%28code%3AUInt16%2Cdata%3ABytes%29-class-method" class="signature"><strong>.new</strong>(code : UInt16, data : Bytes)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#new%28io%29-class-method" class="signature"><strong>.new</strong>(io)</a>
+
+ </li>
+
+ </ul>
+
+
+
+ <h2>Instance Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#code%3AUInt16-instance-method" class="signature"><strong>#code</strong> : UInt16</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#code%3D%28code%29-instance-method" class="signature"><strong>#code=</strong>(code)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#data%3ASlice%28UInt8%29-instance-method" class="signature"><strong>#data</strong> : Slice(UInt8)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#data%3D%28data%29-instance-method" class="signature"><strong>#data=</strong>(data)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#size%28%2Aargs%2C%2A%2Aoptions%2C%26block%29-instance-method" class="signature"><strong>#size</strong>(*args, **options, &block)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#size%28%2Aargs%2C%2A%2Aoptions%29-instance-method" class="signature"><strong>#size</strong>(*args, **options)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#to_s%28io%29%3AUInt32-instance-method" class="signature"><strong>#to_s</strong>(io) : UInt32</a>
+
+ </li>
+
+ </ul>
+
+
+
+
+
+<div class="methods-inherited">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</div>
+
+
+ <h2>Class Method Detail</h2>
+
+ <div class="entry-detail" id="new&#40;code:UInt16,data:Bytes&#41;-class-method">
+ <div class="signature">
+
+ def self.<strong>new</strong>(code : UInt16, data : Bytes)
+
+ <a class="method-permalink" href="#new%28code%3AUInt16%2Cdata%3ABytes%29-class-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="new&#40;io&#41;-class-method">
+ <div class="signature">
+
+ def self.<strong>new</strong>(io)
+
+ <a class="method-permalink" href="#new%28io%29-class-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+ <h2>Instance Method Detail</h2>
+
+ <div class="entry-detail" id="code:UInt16-instance-method">
+ <div class="signature">
+
+ def <strong>code</strong> : UInt16
+
+ <a class="method-permalink" href="#code%3AUInt16-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="code&#61;&#40;code&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>code=</strong>(code)
+
+ <a class="method-permalink" href="#code%3D%28code%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="data:Slice&#40;UInt8&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>data</strong> : Slice(UInt8)
+
+ <a class="method-permalink" href="#data%3ASlice%28UInt8%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="data&#61;&#40;data&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>data=</strong>(data)
+
+ <a class="method-permalink" href="#data%3D%28data%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="size&#40;*args,**options,&amp;block&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>size</strong>(*args, **options, &block)
+
+ <a class="method-permalink" href="#size%28%2Aargs%2C%2A%2Aoptions%2C%26block%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="size&#40;*args,**options&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>size</strong>(*args, **options)
+
+ <a class="method-permalink" href="#size%28%2Aargs%2C%2A%2Aoptions%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="to_s&#40;io&#41;:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>to_s</strong>(io) : UInt32
+
+ <a class="method-permalink" href="#to_s%28io%29%3AUInt32-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/GeneralFlags.html b/Zip/GeneralFlags.html
new file mode 100644
index 0000000..4831e42
--- /dev/null
+++ b/Zip/GeneralFlags.html
@@ -0,0 +1,649 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::GeneralFlags - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">enum</span> Zip::GeneralFlags
+
+</h1>
+
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>General flags.</p>
+
+<p>Used by local header and central directory header.</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+ <h2>Enum Members</h2>
+
+ <dl>
+
+ <dt class="entry-const" id="ENCRYPTION">
+ <strong>ENCRYPTION</strong> = <code><span class="n">1</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>encrypted using weak encryption</p>
+ </dd>
+
+
+ <dt class="entry-const" id="COMPRESSION_OPTION_1">
+ <strong>COMPRESSION_OPTION_1</strong> = <code><span class="n">2</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>compression method-specific flag</p>
+ </dd>
+
+
+ <dt class="entry-const" id="COMPRESSION_OPTION_2">
+ <strong>COMPRESSION_OPTION_2</strong> = <code><span class="n">4</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>compression method-specific flag</p>
+ </dd>
+
+
+ <dt class="entry-const" id="FOOTER">
+ <strong>FOOTER</strong> = <code><span class="n">8</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>this entry has a data descriptor footer</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_4">
+ <strong>RESERVED_4</strong> = <code><span class="n">16</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>reserved flag</p>
+ </dd>
+
+
+ <dt class="entry-const" id="PATCH">
+ <strong>PATCH</strong> = <code><span class="n">32</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>this entry is patch data</p>
+ </dd>
+
+
+ <dt class="entry-const" id="STRONG_ENCRYPTION">
+ <strong>STRONG_ENCRYPTION</strong> = <code><span class="n">64</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>this entry uses strong encryption</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_7">
+ <strong>RESERVED_7</strong> = <code><span class="n">128</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>reserved flag</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_8">
+ <strong>RESERVED_8</strong> = <code><span class="n">256</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>reserved flag</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_9">
+ <strong>RESERVED_9</strong> = <code><span class="n">512</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>reserved flag</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_10">
+ <strong>RESERVED_10</strong> = <code><span class="n">1024</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>reserved flag</p>
+ </dd>
+
+
+ <dt class="entry-const" id="EFS">
+ <strong>EFS</strong> = <code><span class="n">2048</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>the file name and comment for this entry are UTF-8 encoded.</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_12">
+ <strong>RESERVED_12</strong> = <code><span class="n">4096</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>reserved flag</p>
+ </dd>
+
+
+ <dt class="entry-const" id="MASKED_VALUES">
+ <strong>MASKED_VALUES</strong> = <code><span class="n">8192</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Some fields in the local header are masked (that is, empty).</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_14">
+ <strong>RESERVED_14</strong> = <code><span class="n">16384</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>reserved flag</p>
+ </dd>
+
+
+ <dt class="entry-const" id="RESERVED_15">
+ <strong>RESERVED_15</strong> = <code><span class="n">32768</span></code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>reserved flag</p>
+ </dd>
+
+
+ </dl>
+
+
+
+
+
+ <h2>Instance Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#compression_option_1%3F-instance-method" class="signature"><strong>#compression_option_1?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#compression_option_2%3F-instance-method" class="signature"><strong>#compression_option_2?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#efs%3F-instance-method" class="signature"><strong>#efs?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#encryption%3F-instance-method" class="signature"><strong>#encryption?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#footer%3F-instance-method" class="signature"><strong>#footer?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#masked_values%3F-instance-method" class="signature"><strong>#masked_values?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#patch%3F-instance-method" class="signature"><strong>#patch?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_10%3F-instance-method" class="signature"><strong>#reserved_10?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_12%3F-instance-method" class="signature"><strong>#reserved_12?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_14%3F-instance-method" class="signature"><strong>#reserved_14?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_15%3F-instance-method" class="signature"><strong>#reserved_15?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_4%3F-instance-method" class="signature"><strong>#reserved_4?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_7%3F-instance-method" class="signature"><strong>#reserved_7?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_8%3F-instance-method" class="signature"><strong>#reserved_8?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#reserved_9%3F-instance-method" class="signature"><strong>#reserved_9?</strong></a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#strong_encryption%3F-instance-method" class="signature"><strong>#strong_encryption?</strong></a>
+
+ </li>
+
+ </ul>
+
+
+
+
+
+<div class="methods-inherited">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</div>
+
+
+
+
+ <h2>Instance Method Detail</h2>
+
+ <div class="entry-detail" id="compression_option_1?-instance-method">
+ <div class="signature">
+
+ def <strong>compression_option_1?</strong>
+
+ <a class="method-permalink" href="#compression_option_1%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="compression_option_2?-instance-method">
+ <div class="signature">
+
+ def <strong>compression_option_2?</strong>
+
+ <a class="method-permalink" href="#compression_option_2%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="efs?-instance-method">
+ <div class="signature">
+
+ def <strong>efs?</strong>
+
+ <a class="method-permalink" href="#efs%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="encryption?-instance-method">
+ <div class="signature">
+
+ def <strong>encryption?</strong>
+
+ <a class="method-permalink" href="#encryption%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="footer?-instance-method">
+ <div class="signature">
+
+ def <strong>footer?</strong>
+
+ <a class="method-permalink" href="#footer%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="masked_values?-instance-method">
+ <div class="signature">
+
+ def <strong>masked_values?</strong>
+
+ <a class="method-permalink" href="#masked_values%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="patch?-instance-method">
+ <div class="signature">
+
+ def <strong>patch?</strong>
+
+ <a class="method-permalink" href="#patch%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_10?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_10?</strong>
+
+ <a class="method-permalink" href="#reserved_10%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_12?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_12?</strong>
+
+ <a class="method-permalink" href="#reserved_12%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_14?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_14?</strong>
+
+ <a class="method-permalink" href="#reserved_14%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_15?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_15?</strong>
+
+ <a class="method-permalink" href="#reserved_15%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_4?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_4?</strong>
+
+ <a class="method-permalink" href="#reserved_4%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_7?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_7?</strong>
+
+ <a class="method-permalink" href="#reserved_7%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_8?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_8?</strong>
+
+ <a class="method-permalink" href="#reserved_8%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="reserved_9?-instance-method">
+ <div class="signature">
+
+ def <strong>reserved_9?</strong>
+
+ <a class="method-permalink" href="#reserved_9%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="strong_encryption?-instance-method">
+ <div class="signature">
+
+ def <strong>strong_encryption?</strong>
+
+ <a class="method-permalink" href="#strong_encryption%3F-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/NoneCompressionHelper.html b/Zip/NoneCompressionHelper.html
new file mode 100644
index 0000000..f508f52
--- /dev/null
+++ b/Zip/NoneCompressionHelper.html
@@ -0,0 +1,165 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::NoneCompressionHelper - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">module</span> Zip::NoneCompressionHelper
+
+</h1>
+
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>Helper methods for reading and writing uncompressed data.</p>
+
+
+
+
+
+
+
+
+
+
+
+ <h2>Direct including types</h2>
+ <ul class="other-types-list">
+
+ <li class="other-type"><a href="../Zip/Entry.html">Zip::Entry</a></li>
+
+ <li class="other-type"><a href="../Zip/WriterEntry.html">Zip::WriterEntry</a></li>
+
+ </ul>
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="methods-inherited">
+
+</div>
+
+
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/Source.html b/Zip/Source.html
new file mode 100644
index 0000000..6c94cbc
--- /dev/null
+++ b/Zip/Source.html
@@ -0,0 +1,335 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::Source - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">class</span> Zip::Source
+
+</h1>
+
+
+ <ul class="superclass-hierarchy"><li class="superclass"><a href="../Zip/Source.html">Zip::Source</a></li><li class="superclass">Reference</li><li class="superclass">Object</li></ul>
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>Base class for input source for <code><a href="../Zip/Archive.html">Archive</a></code> object.</p>
+
+<p>You should not need to instantiate this class directly; use
+<code><a href="../Zip.html#read%28slice%3ABytes%2C%26cb%3AArchive-%3E%29%3AVoid-class-method">Zip.read</a>()</code> instead.</p>
+
+
+
+
+
+ <h2>Included Modules</h2>
+ <ul class="other-types-list">
+
+ <li class="other-type">IO</li>
+
+ </ul>
+
+
+
+
+
+
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+
+ <h2>Class Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#new%28io%3AIO%3A%3AFileDescriptor%7CMemoryIO%29-class-method" class="signature"><strong>.new</strong>(io : IO::FileDescriptor | MemoryIO)</a>
+
+ <div class="summary"><p>Instantiate a new <code><a href="../Zip/Source.html">Source</a></code> from the given <code>IO::FileDescriptor</code> or <code>MemoryIO</code> object.</p></div>
+
+ </li>
+
+ </ul>
+
+
+
+ <h2>Instance Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#read%28%2Aargs%2C%2A%2Aoptions%2C%26block%29-instance-method" class="signature"><strong>#read</strong>(*args, **options, &block)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#read%28%2Aargs%2C%2A%2Aoptions%29-instance-method" class="signature"><strong>#read</strong>(*args, **options)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#write%28%2Aargs%2C%2A%2Aoptions%2C%26block%29-instance-method" class="signature"><strong>#write</strong>(*args, **options, &block)</a>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#write%28%2Aargs%2C%2A%2Aoptions%29-instance-method" class="signature"><strong>#write</strong>(*args, **options)</a>
+
+ </li>
+
+ </ul>
+
+
+
+ <h2>Macro Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#method_missing%28call%29-macro" class="signature"><strong>method_missing</strong>(call)</a>
+
+ </li>
+
+ </ul>
+
+
+
+<div class="methods-inherited">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</div>
+
+
+ <h2>Class Method Detail</h2>
+
+ <div class="entry-detail" id="new&#40;io:IO::FileDescriptor|MemoryIO&#41;-class-method">
+ <div class="signature">
+
+ def self.<strong>new</strong>(io : IO::FileDescriptor | MemoryIO)
+
+ <a class="method-permalink" href="#new%28io%3AIO%3A%3AFileDescriptor%7CMemoryIO%29-class-method">#</a>
+ </div>
+
+ <div class="doc"><p>Instantiate a new <code><a href="../Zip/Source.html">Source</a></code> from the given <code>IO::FileDescriptor</code> or
+<code>MemoryIO</code> object.</p>
+
+<p>You should not need to instantiate this class directly; use
+<code><a href="../Zip.html#read%28slice%3ABytes%2C%26cb%3AArchive-%3E%29%3AVoid-class-method">Zip.read</a>()</code> instead.</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+ <h2>Instance Method Detail</h2>
+
+ <div class="entry-detail" id="read&#40;*args,**options,&amp;block&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>read</strong>(*args, **options, &block)
+
+ <a class="method-permalink" href="#read%28%2Aargs%2C%2A%2Aoptions%2C%26block%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="read&#40;*args,**options&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>read</strong>(*args, **options)
+
+ <a class="method-permalink" href="#read%28%2Aargs%2C%2A%2Aoptions%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="write&#40;*args,**options,&amp;block&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>write</strong>(*args, **options, &block)
+
+ <a class="method-permalink" href="#write%28%2Aargs%2C%2A%2Aoptions%2C%26block%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="write&#40;*args,**options&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>write</strong>(*args, **options)
+
+ <a class="method-permalink" href="#write%28%2Aargs%2C%2A%2Aoptions%29-instance-method">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+ <h2>Macro Detail</h2>
+
+ <div class="entry-detail" id="method_missing&#40;call&#41;-macro">
+ <div class="signature">
+
+ macro <strong>method_missing</strong>(call)
+
+ <a class="method-permalink" href="#method_missing%28call%29-macro">#</a>
+ </div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/TimeHelper.html b/Zip/TimeHelper.html
new file mode 100644
index 0000000..ed3ffad
--- /dev/null
+++ b/Zip/TimeHelper.html
@@ -0,0 +1,165 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::TimeHelper - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">module</span> Zip::TimeHelper
+
+</h1>
+
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>Helper methods for converting to and from <code>Time</code> objects.</p>
+
+
+
+
+
+
+
+
+
+
+
+ <h2>Direct including types</h2>
+ <ul class="other-types-list">
+
+ <li class="other-type"><a href="../Zip/Entry.html">Zip::Entry</a></li>
+
+ <li class="other-type"><a href="../Zip/WriterEntry.html">Zip::WriterEntry</a></li>
+
+ </ul>
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="methods-inherited">
+
+</div>
+
+
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/Version.html b/Zip/Version.html
new file mode 100644
index 0000000..a555534
--- /dev/null
+++ b/Zip/Version.html
@@ -0,0 +1,312 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::Version - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">class</span> Zip::Version
+
+</h1>
+
+
+ <ul class="superclass-hierarchy"><li class="superclass"><a href="../Zip/Version.html">Zip::Version</a></li><li class="superclass">Reference</li><li class="superclass">Object</li></ul>
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>Version identifier used to identify the version needed to extract a
+given file and to indicate the format of the external file
+attributes.</p>
+
+<p>See section 4.4.3.2 of APPNOTE.TXT for version details.</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+ <h2>Constant Summary</h2>
+
+ <dl>
+
+ <dt class="entry-const" id="DEFAULT">
+ <strong>DEFAULT</strong> = <code><span class="k">new</span>(<span class="n">0</span>, <span class="n">0</span>)</code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Default version made by, if unspecified.</p>
+ </dd>
+
+
+ <dt class="entry-const" id="NEEDED">
+ <strong>NEEDED</strong> = <code><span class="k">new</span>(<span class="n">2</span>, <span class="n">0</span>)</code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Version needed to extract this entry (4.4.3.2).</p>
+ </dd>
+
+
+ </dl>
+
+
+
+ <h2>Class Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#new%28major%3AInt32%2Cminor%3AInt32%2Ccompat%3AInt32%3D%3Cspanclass%3D%22n%22%3E0%3C%2Fspan%3E%29-class-method" class="signature"><strong>.new</strong>(major : Int32, minor : Int32, compat : Int32 = <span class="n">0</span>)</a>
+
+ <div class="summary"><p>Create a version identifier from a major number, minor number, and optional compatability number.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#new%28v%3AUInt16%29-class-method" class="signature"><strong>.new</strong>(v : UInt16)</a>
+
+ <div class="summary"><p>Create a version identifier from a major number, minor number, and optional compatability number.</p></div>
+
+ </li>
+
+ </ul>
+
+
+
+ <h2>Instance Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#to_io%28io%29-instance-method" class="signature"><strong>#to_io</strong>(io)</a>
+
+ <div class="summary"><p>Write version as 16-bit, little-endian integer and return number of bytes written.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#to_s%28io%29-instance-method" class="signature"><strong>#to_s</strong>(io)</a>
+
+ <div class="summary"><p>Write version as string.</p></div>
+
+ </li>
+
+ </ul>
+
+
+
+
+
+<div class="methods-inherited">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</div>
+
+
+ <h2>Class Method Detail</h2>
+
+ <div class="entry-detail" id="new&#40;major:Int32,minor:Int32,compat:Int32&#61;&lt;spanclass&#61;&quot;n&quot;&gt;0&lt;/span&gt;&#41;-class-method">
+ <div class="signature">
+
+ def self.<strong>new</strong>(major : Int32, minor : Int32, compat : Int32 = <span class="n">0</span>)
+
+ <a class="method-permalink" href="#new%28major%3AInt32%2Cminor%3AInt32%2Ccompat%3AInt32%3D%3Cspanclass%3D%22n%22%3E0%3C%2Fspan%3E%29-class-method">#</a>
+ </div>
+
+ <div class="doc"><p>Create a version identifier from a major number, minor number, and
+optional compatability number.</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="new&#40;v:UInt16&#41;-class-method">
+ <div class="signature">
+
+ def self.<strong>new</strong>(v : UInt16)
+
+ <a class="method-permalink" href="#new%28v%3AUInt16%29-class-method">#</a>
+ </div>
+
+ <div class="doc"><p>Create a version identifier from a major number, minor number, and
+optional compatability number.</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+ <h2>Instance Method Detail</h2>
+
+ <div class="entry-detail" id="to_io&#40;io&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>to_io</strong>(io)
+
+ <a class="method-permalink" href="#to_io%28io%29-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Write version as 16-bit, little-endian integer and return number
+of bytes written.</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="to_s&#40;io&#41;-instance-method">
+ <div class="signature">
+
+ def <strong>to_s</strong>(io)
+
+ <a class="method-permalink" href="#to_s%28io%29-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Write version as string.</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/Writer.html b/Zip/Writer.html
new file mode 100644
index 0000000..c28c13e
--- /dev/null
+++ b/Zip/Writer.html
@@ -0,0 +1,389 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::Writer - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">class</span> Zip::Writer
+
+</h1>
+
+
+ <ul class="superclass-hierarchy"><li class="superclass"><a href="../Zip/Writer.html">Zip::Writer</a></li><li class="superclass">Reference</li><li class="superclass">Object</li></ul>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+
+ <h2>Class Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#new%28io%3AIO%2Cpos%3AUInt32%3D%3Cspanclass%3D%22n%22%3E0%3C%2Fspan%3E%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%2Cversion%3AVersion%3D%3Cspanclass%3D%22t%22%3EVersion%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFAULT%3C%2Fspan%3E%29-class-method" class="signature"><strong>.new</strong>(io : IO, pos : UInt32 = <span class="n">0</span>, comment : String = <span class="s">&quot;&quot;</span>, version : Version = <span class="t">Version</span><span class="t">::</span><span class="t">DEFAULT</span>)</a>
+
+ <div class="summary"><p>Create a new <code><a href="../Zip/Writer.html">Writer</a></code> object.</p></div>
+
+ </li>
+
+ </ul>
+
+
+
+ <h2>Instance Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#add%28path%3AString%2Cio%3AIO%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29%3AUInt32-instance-method" class="signature"><strong>#add</strong>(path : String, io : IO, method : CompressionMethod = <span class="t">CompressionMethod</span><span class="t">::</span><span class="t">DEFLATE</span>, time : Time = <span class="t">Time</span>.now, comment : String = <span class="s">&quot;&quot;</span>) : UInt32</a>
+
+ <div class="summary"><p>Read data from <code>IO</code> <em>io</em>, write it to <em>path</em> in archive, then return the number of bytes written.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#add%28path%3AString%2Cdata%3AString%7CBytes%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29%3AUInt32-instance-method" class="signature"><strong>#add</strong>(path : String, data : String | Bytes, method : CompressionMethod = <span class="t">CompressionMethod</span><span class="t">::</span><span class="t">DEFLATE</span>, time : Time = <span class="t">Time</span>.now, comment : String = <span class="s">&quot;&quot;</span>) : UInt32</a>
+
+ <div class="summary"><p>Write <em>data</em> to <em>path</em> in archive and return number of bytes written.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#add_file%28path%3AString%2Cfile_path%3AString%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29%3AUInt32-instance-method" class="signature"><strong>#add_file</strong>(path : String, file_path : String, method : CompressionMethod = <span class="t">CompressionMethod</span><span class="t">::</span><span class="t">DEFLATE</span>, time : Time = <span class="t">Time</span>.now, comment : String = <span class="s">&quot;&quot;</span>) : UInt32</a>
+
+ <div class="summary"><p>Add local file <em>file_path</em> to archive as <em>path</em> and return number of bytes written.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#bytes_written%3AUInt32-instance-method" class="signature"><strong>#bytes_written</strong> : UInt32</a>
+
+ <div class="summary"><p>Return the total number of bytes written so far.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#close-instance-method" class="signature"><strong>#close</strong></a>
+
+ <div class="summary"><p>Close this writer and return the total number of bytes written.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#closed%3F%3ABool-instance-method" class="signature"><strong>#closed?</strong> : Bool</a>
+
+ <div class="summary"><p>Is this <code><a href="../Zip/Writer.html">Writer</a></code> closed? </p></div>
+
+ </li>
+
+ </ul>
+
+
+
+
+
+<div class="methods-inherited">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</div>
+
+
+ <h2>Class Method Detail</h2>
+
+ <div class="entry-detail" id="new&#40;io:IO,pos:UInt32&#61;&lt;spanclass&#61;&quot;n&quot;&gt;0&lt;/span&gt;,comment:String&#61;&lt;spanclass&#61;&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;,version:Version&#61;&lt;spanclass&#61;&quot;t&quot;&gt;Version&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;::&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;DEFAULT&lt;/span&gt;&#41;-class-method">
+ <div class="signature">
+
+ def self.<strong>new</strong>(io : IO, pos : UInt32 = <span class="n">0</span>, comment : String = <span class="s">&quot;&quot;</span>, version : <a href="../Zip/Version.html">Version</a> = <span class="t">Version</span><span class="t">::</span><span class="t">DEFAULT</span>)
+
+ <a class="method-permalink" href="#new%28io%3AIO%2Cpos%3AUInt32%3D%3Cspanclass%3D%22n%22%3E0%3C%2Fspan%3E%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%2Cversion%3AVersion%3D%3Cspanclass%3D%22t%22%3EVersion%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFAULT%3C%2Fspan%3E%29-class-method">#</a>
+ </div>
+
+ <div class="doc"><p>Create a new <code><a href="../Zip/Writer.html">Writer</a></code> object.</p>
+
+<p>You shouldn't need to instantiate this class directly; use
+<code><a href="../Zip.html#write%28io%3AIO%2Cpos%3AUInt32%3D%3Cspanclass%3D%22n%22%3E0_u32%3C%2Fspan%3E%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%2Cversion%3AVersion%3D%3Cspanclass%3D%22t%22%3EVersion%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFAULT%3C%2Fspan%3E%2C%26cb%3AWriter-%3E%29%3AUInt32-class-method">Zip.write</a>()</code> instead.</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+ <h2>Instance Method Detail</h2>
+
+ <div class="entry-detail" id="add&#40;path:String,io:IO,method:CompressionMethod&#61;&lt;spanclass&#61;&quot;t&quot;&gt;CompressionMethod&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;::&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;DEFLATE&lt;/span&gt;,time:Time&#61;&lt;spanclass&#61;&quot;t&quot;&gt;Time&lt;/span&gt;.now,comment:String&#61;&lt;spanclass&#61;&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&#41;:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>add</strong>(path : String, io : IO, method : <a href="../Zip/CompressionMethod.html">CompressionMethod</a> = <span class="t">CompressionMethod</span><span class="t">::</span><span class="t">DEFLATE</span>, time : Time = <span class="t">Time</span>.now, comment : String = <span class="s">&quot;&quot;</span>) : UInt32
+
+ <a class="method-permalink" href="#add%28path%3AString%2Cio%3AIO%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29%3AUInt32-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Read data from <code>IO</code> <em>io</em>, write it to <em>path</em> in archive, then
+return the number of bytes written.</p>
+
+<p>Example:</p>
+
+<p># create IO from "/path/to/bar.txt"
+File.open("/path/to/bar.txt, "rb") do |io|
+# write to "foo.zip"
+Zip.write("foo.zip") do |zip|
+# add "bar.txt" with contents of given IO
+zip.add("bar.txt", io)
+end
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="add&#40;path:String,data:String|Bytes,method:CompressionMethod&#61;&lt;spanclass&#61;&quot;t&quot;&gt;CompressionMethod&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;::&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;DEFLATE&lt;/span&gt;,time:Time&#61;&lt;spanclass&#61;&quot;t&quot;&gt;Time&lt;/span&gt;.now,comment:String&#61;&lt;spanclass&#61;&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&#41;:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>add</strong>(path : String, data : String | Bytes, method : <a href="../Zip/CompressionMethod.html">CompressionMethod</a> = <span class="t">CompressionMethod</span><span class="t">::</span><span class="t">DEFLATE</span>, time : Time = <span class="t">Time</span>.now, comment : String = <span class="s">&quot;&quot;</span>) : UInt32
+
+ <a class="method-permalink" href="#add%28path%3AString%2Cdata%3AString%7CBytes%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29%3AUInt32-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Write <em>data</em> to <em>path</em> in archive and return number of bytes
+written.</p>
+
+<p>Example:</p>
+
+<p># write to "foo.zip"
+Zip.write("foo.zip") do |zip|
+# add "bar.txt" with contents "hello!"
+zip.add("bar.txt", "hello!")
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="add_file&#40;path:String,file_path:String,method:CompressionMethod&#61;&lt;spanclass&#61;&quot;t&quot;&gt;CompressionMethod&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;::&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;DEFLATE&lt;/span&gt;,time:Time&#61;&lt;spanclass&#61;&quot;t&quot;&gt;Time&lt;/span&gt;.now,comment:String&#61;&lt;spanclass&#61;&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&#41;:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>add_file</strong>(path : String, file_path : String, method : <a href="../Zip/CompressionMethod.html">CompressionMethod</a> = <span class="t">CompressionMethod</span><span class="t">::</span><span class="t">DEFLATE</span>, time : Time = <span class="t">Time</span>.now, comment : String = <span class="s">&quot;&quot;</span>) : UInt32
+
+ <a class="method-permalink" href="#add_file%28path%3AString%2Cfile_path%3AString%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29%3AUInt32-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Add local file <em>file_path</em> to archive as <em>path</em> and return number
+of bytes written.</p>
+
+<p>Example:</p>
+
+<p># write to "foo.zip"
+Zip.write("foo.zip") do |zip|
+# add local file "/path/to/bar.txt" as "bar.txt"
+zip.add_file("bar.txt", "/path/to/bar.txt")
+end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="bytes_written:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>bytes_written</strong> : UInt32
+
+ <a class="method-permalink" href="#bytes_written%3AUInt32-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Return the total number of bytes written so far.</p>
+
+<p>Example:</p>
+
+<p>Zip.write("foo.zip") do |zip|
+# add "bar.txt"
+zip.add_file("bar.txt", "/path/to/bar.txt")</p>
+
+<pre><code><span class="c"># print number of bytes written so far</span>
+puts <span class="s">&quot;bytes written so far: </span><span class="i">#{</span></span>zip.bytes_written<span class="s"><span class="i">}</span>&quot;</span></code></pre>
+
+<p>end</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="close-instance-method">
+ <div class="signature">
+
+ def <strong>close</strong>
+
+ <a class="method-permalink" href="#close-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Close this writer and return the total number of bytes written.</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="closed?:Bool-instance-method">
+ <div class="signature">
+
+ def <strong>closed?</strong> : Bool
+
+ <a class="method-permalink" href="#closed%3F%3ABool-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Is this <code><a href="../Zip/Writer.html">Writer</a></code> closed?</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/Zip/WriterEntry.html b/Zip/WriterEntry.html
new file mode 100644
index 0000000..843b04b
--- /dev/null
+++ b/Zip/WriterEntry.html
@@ -0,0 +1,319 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="../css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="../js/doc.js"></script>
+ <title>Zip::WriterEntry - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li><a href="../index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent open current" data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="../Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="../Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="../Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="../Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="../Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="../Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="../Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="../Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="../Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="../Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="../Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="../Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="../Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" current" data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="../Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1 class="type-name">
+
+ <span class="kind">class</span> Zip::WriterEntry
+
+</h1>
+
+
+ <ul class="superclass-hierarchy"><li class="superclass"><a href="../Zip/WriterEntry.html">Zip::WriterEntry</a></li><li class="superclass">Reference</li><li class="superclass">Object</li></ul>
+
+
+
+
+ <h2>Overview</h2>
+
+ <p>Internal class used to store files for <code><a href="../Zip/Writer.html">Writer</a></code> instance.</p>
+
+<p>You should not need to instantiate this class directly; it is called
+automatically by <code><a href="../Zip/Writer.html#add%28path%3AString%2Cio%3AIO%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29%3AUInt32-instance-method">Writer#add</a></code> and <code><a href="../Zip/Writer.html#add_file%28path%3AString%2Cfile_path%3AString%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29%3AUInt32-instance-method">Writer#add_file</a></code>.</p>
+
+
+
+
+
+ <h2>Included Modules</h2>
+ <ul class="other-types-list">
+
+ <li class="other-type"><a href="../Zip/DeflateCompressionHelper.html">Zip::DeflateCompressionHelper</a></li>
+
+ <li class="other-type"><a href="../Zip/NoneCompressionHelper.html">Zip::NoneCompressionHelper</a></li>
+
+ <li class="other-type"><a href="../Zip/TimeHelper.html">Zip::TimeHelper</a></li>
+
+ </ul>
+
+
+
+
+
+
+
+
+
+
+ <h2>Defined in:</h2>
+
+
+
+
+
+ <h2>Constant Summary</h2>
+
+ <dl>
+
+ <dt class="entry-const" id="GENERAL_FLAGS">
+ <strong>GENERAL_FLAGS</strong> = <code><span class="t">GeneralFlags</span>.flags(<span class="t">FOOTER</span>, <span class="t">EFS</span>)</code>
+ </dt>
+
+ <dd class="entry-const-doc">
+ <p>Default flags for local and central header.</p>
+ </dd>
+
+
+ </dl>
+
+
+
+ <h2>Class Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#new%28pos%3AUInt32%2Cpath%3AString%2Cio%3AIO%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29-class-method" class="signature"><strong>.new</strong>(pos : UInt32, path : String, io : IO, method : CompressionMethod = <span class="t">CompressionMethod</span><span class="t">::</span><span class="t">DEFLATE</span>, time : Time = <span class="t">Time</span>.now, comment : String = <span class="s">&quot;&quot;</span>)</a>
+
+ <div class="summary"><p>Create a new WriterEntry instance.</p></div>
+
+ </li>
+
+ </ul>
+
+
+
+ <h2>Instance Method Summary</h2>
+ <ul class="list-summary">
+
+ <li class="entry-summary">
+ <a href="#to_s%28dst_io%29%3AUInt32-instance-method" class="signature"><strong>#to_s</strong>(dst_io) : UInt32</a>
+
+ <div class="summary"><p>Write local file entry to IO and return the number of bytes written.</p></div>
+
+ </li>
+
+ <li class="entry-summary">
+ <a href="#write_central%28io%3AIO%2Cversion%3AVersion%3D%3Cspanclass%3D%22t%22%3EVersion%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFAULT%3C%2Fspan%3E%29%3AUInt32-instance-method" class="signature"><strong>#write_central</strong>(io : IO, version : Version = <span class="t">Version</span><span class="t">::</span><span class="t">DEFAULT</span>) : UInt32</a>
+
+ <div class="summary"><p>Write central directory data for this <code><a href="../Zip/WriterEntry.html">WriterEntry</a></code> and return the number of bytes written.</p></div>
+
+ </li>
+
+ </ul>
+
+
+
+
+
+<div class="methods-inherited">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</div>
+
+
+ <h2>Class Method Detail</h2>
+
+ <div class="entry-detail" id="new&#40;pos:UInt32,path:String,io:IO,method:CompressionMethod&#61;&lt;spanclass&#61;&quot;t&quot;&gt;CompressionMethod&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;::&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;DEFLATE&lt;/span&gt;,time:Time&#61;&lt;spanclass&#61;&quot;t&quot;&gt;Time&lt;/span&gt;.now,comment:String&#61;&lt;spanclass&#61;&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&#41;-class-method">
+ <div class="signature">
+
+ def self.<strong>new</strong>(pos : UInt32, path : String, io : IO, method : <a href="../Zip/CompressionMethod.html">CompressionMethod</a> = <span class="t">CompressionMethod</span><span class="t">::</span><span class="t">DEFLATE</span>, time : Time = <span class="t">Time</span>.now, comment : String = <span class="s">&quot;&quot;</span>)
+
+ <a class="method-permalink" href="#new%28pos%3AUInt32%2Cpath%3AString%2Cio%3AIO%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29-class-method">#</a>
+ </div>
+
+ <div class="doc"><p>Create a new WriterEntry instance.</p>
+
+<p>You should not need to call this method directly; it is called
+automatically by <code><a href="../Zip/Writer.html#add%28path%3AString%2Cio%3AIO%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29%3AUInt32-instance-method">Writer#add</a></code> and <code><a href="../Zip/Writer.html#add_file%28path%3AString%2Cfile_path%3AString%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29%3AUInt32-instance-method">Writer#add_file</a></code>.</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+ <h2>Instance Method Detail</h2>
+
+ <div class="entry-detail" id="to_s&#40;dst_io&#41;:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>to_s</strong>(dst_io) : UInt32
+
+ <a class="method-permalink" href="#to_s%28dst_io%29%3AUInt32-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Write local file entry to IO and return the number of bytes
+written.</p>
+
+<p>You should not need to call this method directly; it is called
+automatically by <code><a href="../Zip/Writer.html#add%28path%3AString%2Cio%3AIO%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29%3AUInt32-instance-method">Writer#add</a></code> and <code><a href="../Zip/Writer.html#add_file%28path%3AString%2Cfile_path%3AString%2Cmethod%3ACompressionMethod%3D%3Cspanclass%3D%22t%22%3ECompressionMethod%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFLATE%3C%2Fspan%3E%2Ctime%3ATime%3D%3Cspanclass%3D%22t%22%3ETime%3C%2Fspan%3E.now%2Ccomment%3AString%3D%3Cspanclass%3D%22s%22%3E%26quot%3B%26quot%3B%3C%2Fspan%3E%29%3AUInt32-instance-method">Writer#add_file</a></code>.</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+ <div class="entry-detail" id="write_central&#40;io:IO,version:Version&#61;&lt;spanclass&#61;&quot;t&quot;&gt;Version&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;::&lt;/span&gt;&lt;spanclass&#61;&quot;t&quot;&gt;DEFAULT&lt;/span&gt;&#41;:UInt32-instance-method">
+ <div class="signature">
+
+ def <strong>write_central</strong>(io : IO, version : <a href="../Zip/Version.html">Version</a> = <span class="t">Version</span><span class="t">::</span><span class="t">DEFAULT</span>) : UInt32
+
+ <a class="method-permalink" href="#write_central%28io%3AIO%2Cversion%3AVersion%3D%3Cspanclass%3D%22t%22%3EVersion%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3E%3A%3A%3C%2Fspan%3E%3Cspanclass%3D%22t%22%3EDEFAULT%3C%2Fspan%3E%29%3AUInt32-instance-method">#</a>
+ </div>
+
+ <div class="doc"><p>Write central directory data for this <code><a href="../Zip/WriterEntry.html">WriterEntry</a></code> and return the
+number of bytes written.</p>
+
+<p>You should not need to call this method directly; it is called
+automatically by <code><a href="../Zip/Writer.html#close-instance-method">Writer#close</a></code>.</p></div>
+
+ <br/>
+ <div>
+
+ </div>
+ </div>
+
+
+
+
+
+</div>
+
+</body>
+</html>
diff --git a/css/style.css b/css/style.css
new file mode 100644
index 0000000..f78f2c7
--- /dev/null
+++ b/css/style.css
@@ -0,0 +1,325 @@
+html, body {
+ position: relative;
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+}
+
+body {
+ font-family: "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif;
+ color: #333;
+}
+
+a {
+ color: #263F6C;
+}
+
+a:visited {
+ color: #112750;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ margin: 30px 0;
+}
+
+h1.type-name {
+ color: #47266E;
+}
+
+#types-list, #main-content {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ overflow: auto;
+}
+
+#types-list {
+ left: 0;
+ width: 20%;
+ background-color: #2E1052;
+}
+
+#types-list #search-box {
+ padding: 5px;
+}
+
+#types-list input {
+ display: block;
+ box-sizing: border-box;
+ margin: 0;
+ padding: 5px;
+ font: inherit;
+ font-family: inherit;
+ line-height: 1.2;
+ width: 100%;
+ border: 0;
+ border-radius: 50px;
+ outline: 0;
+}
+
+#types-list ul {
+ margin: 0;
+ padding: 0;
+ list-style: none outside;
+}
+
+#types-list li {
+ display: block;
+ position: relative;
+}
+
+#types-list li.hide {
+ display: none;
+}
+
+#types-list a {
+ display: block;
+ padding: 5px 15px 5px 30px;
+ text-decoration: none;
+ color: #fff;
+}
+
+#types-list .current > a,
+#types-list a:hover {
+ color: #866BA6;
+}
+
+#types-list li ul {
+ overflow: hidden;
+ height: 0;
+ max-height: 0;
+ transition: 1s ease-in-out;
+}
+
+
+#types-list li.parent {
+ padding-left: 30px;
+}
+
+#types-list li.parent::before {
+ box-sizing: border-box;
+ content: "â–¼";
+ display: block;
+ width: 30px;
+ height: 30px;
+ position: absolute;
+ top: 0;
+ left: 0;
+ text-align: center;
+ color: white;
+ font-size: 8px;
+ line-height: 30px;
+ transform: rotateZ(-90deg);
+ cursor: pointer;
+ transition: .2s linear;
+}
+
+
+#types-list li.parent > a {
+ padding-left: 0;
+}
+
+#types-list li.parent.open::before {
+ transform: rotateZ(0);
+}
+
+#types-list li.open > ul {
+ height: auto;
+ max-height: 1000em;
+}
+
+#main-content {
+ padding: 0 30px 30px 30px;
+ left: 20%;
+ right: 0;
+}
+
+.kind {
+ font-size: 60%;
+ color: #866BA6;
+}
+
+.superclass-hierarchy {
+ margin: -15px 0 30px 0;
+ padding: 0;
+ list-style: none outside;
+ font-size: 80%;
+}
+
+.superclass-hierarchy .superclass {
+ display: inline-block;
+ margin: 0 7px 0 0;
+ padding: 0;
+}
+
+.superclass-hierarchy .superclass + .superclass::before {
+ content: "<";
+ margin-right: 7px;
+}
+
+.other-types-list li {
+ display: inline-block;
+}
+
+.other-types-list,
+.list-summary {
+ margin: 0 0 30px 0;
+ padding: 0;
+ list-style: none outside;
+}
+
+.entry-const {
+ font-family: Consolas, 'Courier New', Courier, Monaco, monospace;
+}
+
+.entry-summary {
+ padding-bottom: 4px;
+}
+
+.superclass-hierarchy .superclass a,
+.other-type a,
+.entry-summary .signature {
+ padding: 4px 8px;
+ margin-bottom: 4px;
+ display: inline-block;
+ background-color: #f8f8f8;
+ color: #47266E;
+ border: 1px solid #f0f0f0;
+ text-decoration: none;
+ border-radius: 3px;
+}
+
+.superclass-hierarchy .superclass a:hover,
+.other-type a:hover,
+.entry-summary .signature:hover {
+ background: #D5CAE3;
+ border-color: #624288;
+}
+
+.entry-summary .summary {
+ padding-left: 32px;
+}
+
+.entry-summary a {
+ text-decoration: none;
+}
+
+.entry-detail {
+ padding: 30px 0;
+}
+
+.entry-detail .signature {
+ position: relative;
+ padding: 5px 15px;
+ margin-bottom: 10px;
+ display: block;
+ border-radius: 5px;
+ background-color: #f8f8f8;
+ color: #47266E;
+ border: 1px solid #f0f0f0;
+ transition: .2s ease-in-out;
+}
+
+.entry-detail:target .signature {
+ background-color: #D5CAE3;
+ border: 1px solid #624288;
+}
+
+.entry-detail .signature .method-permalink {
+ position: absolute;
+ top: 0;
+ right: 0;
+ padding: 5px 15px;
+ text-decoration: none;
+ font-weight: bold;
+ color: #624288;
+}
+
+.methods-inherited {
+ padding-right: 10%;
+ line-height: 1.5em;
+}
+
+.methods-inherited h3 {
+ margin-bottom: 4px;
+}
+
+.methods-inherited a {
+ display: inline-block;
+ text-decoration: none;
+ color: #47266E;
+}
+
+.methods-inherited a:hover {
+ text-decoration: underline;
+ color: #6C518B;
+}
+
+.methods-inherited .tooltip span {
+ background: #D5CAE3;
+ color: #47266E;
+ padding: 4px 8px;
+ border-radius: 3px;
+ margin: -4px -8px;
+}
+
+pre {
+ padding: 10px 20px;
+ margin-top: 4px;
+ border-radius: 3px;
+ line-height: 1.45;
+ overflow: auto;
+ color: #333;
+ background: #f7f7f7;
+ font-size: 14px;
+}
+
+code {
+ font-family: Consolas, 'Courier New', Courier, Monaco, monospace;
+}
+
+.tooltip span {
+ position: absolute;
+ opacity: 0;
+ display: none;
+ pointer-events: none;
+}
+
+.tooltip:hover span {
+ display: inline-block;
+ opacity: 1;
+}
+
+.c {
+ color: #969896;
+}
+
+.n {
+ color: #0086b3;
+}
+
+.t {
+ color: #0086b3;
+}
+
+.s {
+ color: #183691;
+}
+
+.i {
+ color: #7f5030;
+}
+
+.k {
+ color: #a71d5d;
+}
+
+.o {
+ color: #a71d5d;
+}
+
+.m {
+ color: #795da3;
+}
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..0314d29
--- /dev/null
+++ b/index.html
@@ -0,0 +1,160 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta id="repository-name" content="github.com/pablotron/zip-crystal">
+ <link href="css/style.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="js/doc.js"></script>
+ <title>README - github.com/pablotron/zip-crystal</title>
+</head>
+<body>
+
+<div id="types-list">
+ <div id="search-box">
+ <input type="search" id="search-input" placeholder="Search...">
+ </div>
+
+ <ul>
+ <li class="current"><a href="index.html">README</a></li>
+ </ul>
+
+ <ul>
+
+ <li class="parent " data-id="github.com/pablotron/zip-crystal/Zip" data-name="zip">
+ <a href="Zip.html">Zip</a>
+
+ <ul>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Archive" data-name="zip::archive">
+ <a href="Zip/Archive.html">Archive</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/CompressionMethod" data-name="zip::compressionmethod">
+ <a href="Zip/CompressionMethod.html">CompressionMethod</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/DeflateCompressionHelper" data-name="zip::deflatecompressionhelper">
+ <a href="Zip/DeflateCompressionHelper.html">DeflateCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Entry" data-name="zip::entry">
+ <a href="Zip/Entry.html">Entry</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Error" data-name="zip::error">
+ <a href="Zip/Error.html">Error</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Extra" data-name="zip::extra">
+ <a href="Zip/Extra.html">Extra</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/GeneralFlags" data-name="zip::generalflags">
+ <a href="Zip/GeneralFlags.html">GeneralFlags</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/NoneCompressionHelper" data-name="zip::nonecompressionhelper">
+ <a href="Zip/NoneCompressionHelper.html">NoneCompressionHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Source" data-name="zip::source">
+ <a href="Zip/Source.html">Source</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/TimeHelper" data-name="zip::timehelper">
+ <a href="Zip/TimeHelper.html">TimeHelper</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Version" data-name="zip::version">
+ <a href="Zip/Version.html">Version</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/Writer" data-name="zip::writer">
+ <a href="Zip/Writer.html">Writer</a>
+
+ </li>
+
+ <li class=" " data-id="github.com/pablotron/zip-crystal/Zip/WriterEntry" data-name="zip::writerentry">
+ <a href="Zip/WriterEntry.html">WriterEntry</a>
+
+ </li>
+
+</ul>
+
+
+ </li>
+
+</ul>
+
+</div>
+
+<div id="main-content">
+<h1>zip-crystal</h1>
+
+<p>Read and write zip archives natively from
+<a href="http://crystal-lang.org/" target="_blank">Crystal</a>.</p>
+
+<h2>Installation</h2>
+
+<p>Add this to your application's <code>shard.yml</code>:</p>
+
+<pre><code class='language-yaml'>dependencies:
+ zip-crystal:
+ github: pablotron/zip-crystal</code></pre>
+
+<h2>Usage</h2>
+
+<pre><code class='language-crystal'><span class="k">require</span> <span class="s">&quot;zip-crystal/zip&quot;</span>
+
+<span class="c"># write to &quot;foo.zip&quot;</span>
+<span class="t">Zip</span>.write(<span class="s">&quot;foo.zip&quot;</span>) <span class="k">do</span> <span class="o">|</span>zip<span class="o">|</span>
+ <span class="c"># add &quot;bar.txt&quot; with contents &quot;hello&#33;&quot;</span>
+ zip.add(<span class="s">&quot;bar.txt&quot;</span>, <span class="s">&quot;hello&#33;&quot;</span>)
+
+ <span class="c"># add local file &quot;/path/to/image.png&quot; as &quot;image.png&quot;</span>
+ zip.add_file(<span class="s">&quot;image.png&quot;</span>, <span class="s">&quot;/path/to/image.png&quot;</span>)
+<span class="k">end</span>
+
+<span class="c"># create memory io</span>
+mem_io <span class="o">=</span> <span class="t">MemoryIO</span>.<span class="k">new</span>
+
+<span class="c"># open &quot;/some/other/path/image.png&quot; for writing</span>
+<span class="t">File</span>.open(<span class="s">&quot;/some/other/path/image.png&quot;</span>, <span class="s">&quot;wb&quot;</span>) <span class="k">do</span> <span class="o">|</span>file_io<span class="o">|</span>
+ <span class="c"># read from &quot;foo.zip&quot;</span>
+ <span class="t">Zip</span>.read(<span class="s">&quot;foo.zip&quot;</span>) <span class="k">do</span> <span class="o">|</span>zip<span class="o">|</span>
+ <span class="c"># extract &quot;bar.txt&quot; to mem_io</span>
+ zip[<span class="s">&quot;bar.txt&quot;</span>].read(mem_io)
+
+ <span class="c"># extract &quot;image.png&quot; to file_io</span>
+ zip[<span class="s">&quot;image.png&quot;</span>].read(file_io)
+ <span class="k">end</span>
+<span class="k">end</span></code></pre>
+
+<p>See the <a href="https://pablotron.github.com/zip-crystal/" target="_blank">API documentation</a>
+for additional information.</p>
+
+<h2>Development</h2>
+
+<p>TODO: Write development instructions here</p>
+
+<h2>Contributing</h2>
+
+<ol><li>Fork it ( https://github.com/pablotron/zip-crystal/fork )</li><li>Create your feature branch (git checkout -b my-new-feature)</li><li>Commit your changes (git commit -am 'Add some feature')</li><li>Push to the branch (git push origin my-new-feature)</li><li>Create a new Pull Request</li></ol>
+
+<h2>Contributors</h2>
+
+<ul><li><a href="https://github.com/pablotron" target="_blank">pablotron</a> Paul Duncan - creator, maintainer</li></ul>
+</div>
+</body>
+</html>
diff --git a/js/doc.js b/js/doc.js
new file mode 100644
index 0000000..8846c54
--- /dev/null
+++ b/js/doc.js
@@ -0,0 +1,89 @@
+document.addEventListener('DOMContentLoaded', function() {
+ var sessionStorage = window.sessionStorage;
+ if(!sessionStorage) {
+ sessionStorage = {
+ setItem: function() {},
+ getItem: function() {},
+ removeItem: function() {}
+ };
+ }
+
+ var repositoryName = document.getElementById('repository-name').getAttribute('content');
+ var typesList = document.getElementById('types-list');
+ var searchInput = document.getElementById('search-input');
+ var parents = document.querySelectorAll('#types-list li.parent');
+
+ for(var i = 0; i < parents.length; i++) {
+ var _parent = parents[i];
+ _parent.addEventListener('click', function(e) {
+ e.stopPropagation();
+
+ if(e.target.tagName.toLowerCase() == 'li') {
+ if(e.target.className.match(/open/)) {
+ sessionStorage.removeItem(e.target.getAttribute('data-id'));
+ e.target.className = e.target.className.replace(/ +open/g, '');
+ } else {
+ sessionStorage.setItem(e.target.getAttribute('data-id'), '1');
+ if(e.target.className.indexOf('open') == -1) {
+ e.target.className += ' open';
+ }
+ }
+ }
+ });
+
+ if(sessionStorage.getItem(_parent.getAttribute('data-id')) == '1') {
+ _parent.className += ' open';
+ }
+ };
+
+ var childMatch = function(type, regexp){
+ var types = type.querySelectorAll("ul li");
+ for (var j = 0; j < types.length; j ++) {
+ var t = types[j];
+ if(regexp.exec(t.getAttribute('data-name'))){ return true; };
+ };
+ return false;
+ };
+
+ var searchTimeout;
+ searchInput.addEventListener('keyup', function() {
+ clearTimeout(searchTimeout);
+ searchTimeout = setTimeout(function() {
+ var text = searchInput.value;
+ var types = document.querySelectorAll('#types-list li');
+ var words = text.toLowerCase().split(/\s+/).filter(function(word) {
+ return word.length > 0;
+ });
+ var regexp = new RegExp(words.join('|'));
+
+ for(var i = 0; i < types.length; i++) {
+ var type = types[i];
+ if(words.length == 0 || regexp.exec(type.getAttribute('data-name')) || childMatch(type, regexp)) {
+ type.className = type.className.replace(/ +hide/g, '');
+ var is_parent = new RegExp("parent").exec(type.className);
+ var is_not_opened = !(new RegExp("open").exec(type.className));
+ if(childMatch(type,regexp) && is_parent && is_not_opened){
+ type.className += " open";
+ };
+ } else {
+ if(type.className.indexOf('hide') == -1) {
+ type.className += ' hide';
+ };
+ };
+ if(words.length == 0){
+ type.className = type.className.replace(/ +open/g, '');
+ };
+ }
+ }, 200);
+ });
+
+ typesList.onscroll = function() {
+ var y = typesList.scrollTop;
+ sessionStorage.setItem(repositoryName + '::types-list:scrollTop', y);
+ };
+
+ var initialY = parseInt(sessionStorage.getItem(repositoryName + '::types-list:scrollTop') + "", 10);
+ if(initialY > 0) {
+ typesList.scrollTop = initialY;
+ }
+});
diff --git a/shard.yml b/shard.yml
deleted file mode 100644
index 3a73c95..0000000
--- a/shard.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: zip-crystal
-version: 0.1.0
-
-authors:
- - Paul Duncan <pabs@pablotron.org>
-
-license: MIT
diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr
deleted file mode 100644
index 3e86b5e..0000000
--- a/spec/spec_helper.cr
+++ /dev/null
@@ -1,2 +0,0 @@
-require "spec"
-require "../src/zip"
diff --git a/spec/zip_spec.cr b/spec/zip_spec.cr
deleted file mode 100644
index 6503a65..0000000
--- a/spec/zip_spec.cr
+++ /dev/null
@@ -1,102 +0,0 @@
-require "./spec_helper"
-
-TEST_DIR = File.dirname(__FILE__)
-TEST_FILE_PATH = File.join(TEST_DIR, "..", "src", "zip.cr")
-
-describe Zip do
- # TODO: Write tests
-
- it "works" do
- Zip::VERSION.should eq(Zip::VERSION)
- end
-
- ###############
- # write tests #
- ###############
-
- it "creates an empty archive" do
- Zip.write(File.join(TEST_DIR, "test-empty.zip")) do |zip|
- # do nothing
- end
- end
-
- it "creates an entry from a String" do
- Zip.write(File.join(TEST_DIR, "test-string.zip")) do |zip|
- zip.add("bar.txt", "bar")
- end
- end
-
- it "creates an entry from a String with no compression" do
- Zip.write(File.join(TEST_DIR, "test-string-none.zip")) do |zip|
- zip.add(
- path: "bar.txt",
- data: "bar",
- method: Zip::CompressionMethod::NONE
- )
- end
- end
-
- it "creates an entry from a MemoryIO" do
- Zip.write(File.join(TEST_DIR, "test-memio.zip")) do |zip|
- zip.add("bar.txt", "bar")
- end
- end
-
- it "creates an entry from a File" do
- Zip.write(File.join(TEST_DIR, "test-file.zip")) do |zip|
- zip.add_file("test.cr", TEST_FILE_PATH)
- end
- end
-
- it "creates an archive from a MemoryIO, String, and File" do
- Zip.write(File.join(TEST_DIR, "test-many.zip")) do |zip|
- zip.add("foo.txt", MemoryIO.new("foo"))
- zip.add("bar.txt", "bar")
- zip.add_file("test.cr", TEST_FILE_PATH)
- end
- end
-
- ##############
- # read tests #
- ##############
-
- it "reads an archive" do
- Zip.read(File.join(TEST_DIR, "test-string.zip")) do |zip|
- zip.entries.each do |e|
- pp e.path
- end
- end
- end
-
- it "reads an archive created by an external program" do
- Zip.read(File.join(TEST_DIR, "real.zip")) do |zip|
- zip.each do |e|
- pp e.path
- end
- end
- end
-
- it "reads an archive created by an external program" do
- Zip.read(File.join(TEST_DIR, "real.zip")) do |zip|
- zip.each do |e|
- e.read(File.open("/dev/null", "wb"))
-
- # p e.extras.map { |e| { e.code, e.size } }
- # p e.local_extras.map { |e| { e.code, e.size } }
- end
- end
- end
-
- it "reads all an archive's compressed entries" do
- Zip.read(File.join(TEST_DIR, "test-many.zip")) do |zip|
- zip.each do |e|
- pp e.path
-
- io = MemoryIO.new
- # e.read(STDOUT)
- e.read(io)
- io.close
- end
- end
- end
-end
diff --git a/src/zip.cr b/src/zip.cr
deleted file mode 100644
index 0037d0e..0000000
--- a/src/zip.cr
+++ /dev/null
@@ -1,1920 +0,0 @@
-require "./zip/*"
-require "zlib"
-
-# :nodoc:
-#
-# TODO:
-# [x] date/time
-# [x] reader (store and deflate only)
-# [x] documentation
-# [-] extras (at least infozip)
-# [x] convert datetime to Time
-# [x] add size to Entry
-# [x] Version
-# [ ] directories
-# [ ] full tests
-# [ ] zip64
-# [ ] legacy unicode (e.g., non-bit 11) path/comment support
-# [ ] unix uids
-# [ ] bzip2/lzma support
-#
-# References:
-# https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
-# http://www.onicos.com/staff/iz/formats/zip.html
-#
-# :nodoc:
-
-#
-# Library for reading and writing zip files.
-#
-# Examples:
-#
-# Reading from a zip file:
-#
-# # create output MemoryIO
-# mem_io = MemoryIO.new
-#
-# # read from "foo.zip"
-# Zip.read("foo.zip") do |zip|
-# # read contents of "bar.txt" in "foo.zip" into mem_io
-# zip["bar.txt"].read(mem_io)
-# end
-#
-# Writing to a zip file:
-#
-# # write to "foo.zip"
-# Zip.write("foo.zip") do |zip|
-# # create "bar.txt" with contents "hello!"
-# zip.add("bar.txt", "hello!")
-# end
-#
-module Zip
- #
- # Version of zip-crystal library.
- #
- VERSION = "0.1.0"
-
- #
- # Magic numbers for various data in Zip stream.
- #
- MAGIC = {
- cdr_header: 0x02014b50_u32,
- cdr_footer: 0x06054b50_u32,
- file_header: 0x04034b50_u32,
- file_footer: 0x08074b50_u32,
- }
-
- # :nodoc:
- LE = IO::ByteFormat::LittleEndian
-
- #
- # Size of internal buffers, in bytes.
- #
- BUFFER_SIZE = 8192
-
- # :nodoc:
- # 4.4.4 general purpose bit flag: (2 bytes)
- #
- # Bit 0: If set, indicates that the file is encrypted.
- #
- # (For Method 6 - Imploding)
- # Bit 1: If the compression method used was type 6,
- # Imploding, then this bit, if set, indicates
- # an 8K sliding dictionary was used. If clear,
- # then a 4K sliding dictionary was used.
- #
- # Bit 2: If the compression method used was type 6,
- # Imploding, then this bit, if set, indicates
- # 3 Shannon-Fano trees were used to encode the
- # sliding dictionary output. If clear, then 2
- # Shannon-Fano trees were used.
- #
- # (For Methods 8 and 9 - Deflating)
- # Bit 2 Bit 1
- # 0 0 Normal (-en) compression option was used.
- # 0 1 Maximum (-exx/-ex) compression option was used.
- # 1 0 Fast (-ef) compression option was used.
- # 1 1 Super Fast (-es) compression option was used.
- #
- # (For Method 14 - LZMA)
- # Bit 1: If the compression method used was type 14,
- # LZMA, then this bit, if set, indicates
- # an end-of-stream (EOS) marker is used to
- # mark the end of the compressed data stream.
- # If clear, then an EOS marker is not present
- # and the compressed data size must be known
- # to extract.
- #
- # Note: Bits 1 and 2 are undefined if the compression
- # method is any other.
- #
- # Bit 3: If this bit is set, the fields crc-32, compressed
- # size and uncompressed size are set to zero in the
- # local header. The correct values are put in the
- # data descriptor immediately following the compressed
- # data. (Note: PKZIP version 2.04g for DOS only
- # recognizes this bit for method 8 compression, newer
- # versions of PKZIP recognize this bit for any
- # compression method.)
- #
- # Bit 4: Reserved for use with method 8, for enhanced
- # deflating.
- #
- # Bit 5: If this bit is set, this indicates that the file is
- # compressed patched data. (Note: Requires PKZIP
- # version 2.70 or greater)
- #
- # Bit 6: Strong encryption. If this bit is set, you MUST
- # set the version needed to extract value to at least
- # 50 and you MUST also set bit 0. If AES encryption
- # is used, the version needed to extract value MUST
- # be at least 51. See the section describing the Strong
- # Encryption Specification for details. Refer to the
- # section in this document entitled "Incorporating PKWARE
- # Proprietary Technology into Your Product" for more
- # information.
- #
- # Bit 7: Currently unused.
- #
- # Bit 8: Currently unused.
- #
- # Bit 9: Currently unused.
- #
- # Bit 10: Currently unused.
- #
- # Bit 11: Language encoding flag (EFS). If this bit is set,
- # the filename and comment fields for this file
- # MUST be encoded using UTF-8. (see APPENDIX D)
- #
- # Bit 12: Reserved by PKWARE for enhanced compression.
- #
- # Bit 13: Set when encrypting the Central Directory to indicate
- # selected data values in the Local Header are masked to
- # hide their actual values. See the section describing
- # the Strong Encryption Specification for details. Refer
- # to the section in this document entitled "Incorporating
- # PKWARE Proprietary Technology into Your Product" for
- # more information.
- #
- # Bit 14: Reserved by PKWARE.
- #
- # Bit 15: Reserved by PKWARE.
- # :nodoc:
-
- #
- # General flags.
- #
- # Used by local header and central directory header.
- #
- @[Flags]
- enum GeneralFlags
- # encrypted using weak encryption
- ENCRYPTION
-
- # compression method-specific flag
- COMPRESSION_OPTION_1
-
- # compression method-specific flag
- COMPRESSION_OPTION_2
-
- # this entry has a data descriptor footer
- FOOTER
-
- # reserved flag
- RESERVED_4
-
- # this entry is patch data
- PATCH
-
- # this entry uses strong encryption
- STRONG_ENCRYPTION
-
- # reserved flag
- RESERVED_7
-
- # reserved flag
- RESERVED_8
-
- # reserved flag
- RESERVED_9
-
- # reserved flag
- RESERVED_10
-
- # the file name and comment for this entry are UTF-8 encoded.
- EFS
-
- # reserved flag
- RESERVED_12
-
- # Some fields in the local header are masked (that is, empty).
- MASKED_VALUES
-
- # reserved flag
- RESERVED_14
-
- # reserved flag
- RESERVED_15
- end
-
- #
- # Compression methods.
- #
- enum CompressionMethod
- # Stored (no compression)
- NONE = 0
-
- # Shrunk
- SHRUNK = 1
-
- # Reduced with compression factor 1
- REDUCED_1 = 2
-
- # Reduced with compression factor 2
- REDUCED_2 = 3
-
- # Reduced with compression factor 3
- REDUCED_3 = 4
-
- # Reduced with compression factor 4
- REDUCED_4 = 5
-
- # Imploded
- IMPLODED = 6
-
- # Reserved for Tokenizing compression algorithm
- TOKENIZED = 7
-
- # Deflated
- DEFLATE = 8
-
- # Enhanced Deflating using Deflate64(tm)
- DEFLATE64 = 9
-
- # PKWARE Data Compression Library Imploding (old IBM TERSE)
- TERSE_OLD = 10
-
- # Reserved by PKWARE
- RESERVED_11 = 11
-
- # BZIP2
- BZIP2 = 12
-
- # Reserved by PKWARE
- RESERVED_13 = 13
-
- # LZMA (EFS)
- LZMA = 14
-
- # Reserved by PKWARE
- RESERVED_15 = 15
-
- # Reserved by PKWARE
- RESERVED_16 = 16
-
- # Reserved by PKWARE
- RESERVED_17 = 17
-
- # IBM TERSE (new)
- TERSE = 18
-
- # IBM LZ77 z Architecture (PFS)
- LZ77 = 19
-
- # WavPack compressed data
- WAVPACK = 97
-
- # PPMd version I, Rev 1
- PPMD = 98
- end
-
- #
- # Wrapper class for exceptions.
- #
- class Error < Exception
- end
-
- #
- # Helper methods for converting to and from `Time` objects.
- #
- module TimeHelper
- #
- # Convert given `Time` to a DOS-style datetime, write the result to
- # the given IO, and return the number of bytes written.
- #
- private def write_time(io : IO, time : Time) : UInt32
- year = Math.max(1980, time.year) - 1980
-
- # convert to dos timestamp
- ((
- (year << 25) | (time.month << 21) | (time.day << 16) |
- (time.hour << 11) | (time.minute << 5) | (time.second >> 1)
- ) & UInt32::MAX).to_u32.to_io(io, LE)
-
- # return number of bytes written
- 4_u32
- end
-
- #
- # Convert given DOS datetime to a `Time` object.
- #
- private def from_dos_time(v : UInt32) : Time
- Time.new(
- year: (v >> 25) + 1980,
- month: (v >> 21) & 0b0000_1111,
- day: (v >> 16) & 0b0001_1111,
- hour: (v >> 11) & 0b0001_1111,
- minute: (v >> 5) & 0b0011_1111,
- second: (v << 1) & 0b0011_1110,
- )
- end
- end
-
- #
- # Version identifier used to identify the version needed to extract a
- # given file and to indicate the format of the external file
- # attributes.
- #
- # See section 4.4.3.2 of APPNOTE.TXT for version details.
- #
- class Version
- #
- # Version needed to extract this entry (4.4.3.2).
- #
- NEEDED = new(2, 0)
-
- #
- # Default version made by, if unspecified.
- #
- DEFAULT = new(0, 0)
-
- #
- # Create a version identifier from a major number, minor number, and
- # optional compatability number.
- #
- def initialize(
- @major : Int32,
- @minor : Int32,
- @compat : Int32 = 0
- )
- end
-
- #
- # Create a version identifier from a major number, minor number, and
- # optional compatability number.
- #
- def initialize(v : UInt16)
- @compat = v >> 8
- @major = (v & 0xff) / 10
- @minor = (v & 0xff) % 10
- end
-
- #
- # Write version as string.
- #
- def to_s(io)
- io << @major << "." << @minor
- end
-
- #
- # Write version as 16-bit, little-endian integer and return number
- # of bytes written.
- #
- def to_io(io)
- (
- ((@compat & 0xff) << 8) +
- ((@major * 10) + (@minor % 10)) & 0xff
- ).to_u16.to_io(io, LE)
- end
- end
-
- #
- # Helper methods for reading and writing uncompressed data.
- #
- module NoneCompressionHelper
- private def compress_none(src_io, dst_io)
- crc = 0_u32
-
- buf = Bytes.new(BUFFER_SIZE)
- src_len = 0_u32
-
- while ((len = src_io.read(buf)) > 0)
- # build output slice
- dst_buf = (len < buf.size) ? buf[0, len] : buf
- dst_crc = Zlib.crc32(dst_buf)
-
- # update crc
- crc = if crc != 0
- Zlib.crc32_combine(crc, dst_crc, dst_buf.size)
- else
- Zlib.crc32(dst_buf)
- end
-
-
- # write to output buffer
- dst_io.write(dst_buf)
- src_len += len
- end
-
- # return results
- { crc.to_u32, src_len, src_len }
- end
-
- private def decompress_none(src_io, dst_io, src_len, dst_len)
- # TODO: verify CRC
- IO.copy(src_io, dst_io, src_len)
-
- # return number of bytes read
- dst_len
- end
- end
-
- #
- # Helper methods for compressing and decompressing deflated data.
- #
- module DeflateCompressionHelper
- ZALLOC_PROC = LibZ::AllocFunc.new do |data, num_items, size|
- GC.malloc(num_items * size)
- end
-
- ZFREE_PROC = LibZ::FreeFunc.new do |data, addr|
- GC.free(addr)
- end
-
- ZLIB_VERSION = LibZ.zlibVersion
-
- #
- # Read data from src_io, and write the compressed result to dst_io.
- #
- private def compress_deflate(src_io, dst_io)
- crc = 0_u32
-
- # create read and compress buffers
- src_buf = Bytes.new(BUFFER_SIZE)
- dst_buf = Bytes.new(BUFFER_SIZE)
-
- # create deflate stream
- z = LibZ::ZStream.new(
- zalloc: ZALLOC_PROC,
- zfree: ZFREE_PROC,
- )
-
- # init stream
- err = LibZ.deflateInit2(
- pointerof(z),
- LibZ::DEFAULT_COMPRESSION, # FIXME: make this configurable
- LibZ::Z_DEFLATED,
- -15, # raw deflate, window bits = 15
- LibZ::DEF_MEM_LEVEL,
- LibZ::Strategy::DEFAULT_STRATEGY,
- ZLIB_VERSION,
- sizeof(LibZ::ZStream)
- )
-
- # check for error
- if err != LibZ::Error::OK
- # raise zlib error
- raise Zlib::Error.new(err, z)
- end
-
- # loop and compress input data
- while ((len = src_io.read(src_buf)) > 0)
- # build temp slice (if necessary)
- tmp_buf = (len < src_buf.size) ? src_buf[0, len] : src_buf
- tmp_crc = Zlib.crc32(tmp_buf)
-
- # update crc
- crc = if crc != 0
- Zlib.crc32_combine(crc, tmp_crc, tmp_buf.size)
- else
- Zlib.crc32(tmp_buf)
- end
-
- # set zlib input buffer
- z.next_in = tmp_buf.to_unsafe
- z.avail_in = tmp_buf.size.to_u32
-
- # write compressed data to dst io
- write_compressed(dst_io, dst_buf, pointerof(z), false)
- end
-
- # set zlib input buffer to null
- z.next_in = Pointer(UInt8).null
- z.avail_in = 0_u32
-
- # flush remaining data
- write_compressed(dst_io, dst_buf, pointerof(z), true)
-
- # free stream
- LibZ.deflateEnd(pointerof(z))
-
- # return results
- { crc.to_u32, z.total_in.to_u32, z.total_out.to_u32 }
- end
-
- #
- # Deflate data in ZStream and write it to given IO.
- #
- private def write_compressed(
- io : IO,
- buf : Bytes,
- zp : Pointer(LibZ::ZStream),
- flush : Bool,
- )
- zf = flush ? LibZ::Flush::FINISH : LibZ::Flush::NO_FLUSH
-
- loop do
- # set zlib output buffer
- zp.value.next_out = buf.to_unsafe
- zp.value.avail_out = buf.size.to_u32
-
- # compress data (TODO: check for error)
- LibZ.deflate(zp, zf)
-
- if ((len = buf.size - zp.value.avail_out) > 0)
- # write compressed buffer to dst io
- io.write((len < buf.size) ? buf[0, len] : buf)
- end
-
- # exit loop if there is no remaining space
- break if zp.value.avail_out != 0
- end
- end
-
- #
- # Decompress src_len bytes of DEFLATEd data from src_io and write it
- # to dst_io.
- #
- private def decompress_deflate(src_io, dst_io, src_len, dst_len)
- crc = 0_u32
-
- # create read and compress buffers
- src_buf = Bytes.new(BUFFER_SIZE)
- dst_buf = Bytes.new(BUFFER_SIZE)
-
- # create deflate stream
- z = LibZ::ZStream.new(
- zalloc: ZALLOC_PROC,
- zfree: ZFREE_PROC,
- )
-
- # init stream
- err = LibZ.inflateInit2(
- pointerof(z),
- -15, # raw deflate, window bits = 15
- ZLIB_VERSION,
- sizeof(LibZ::ZStream)
- )
-
- # check for error
- if err != LibZ::Error::OK
- # raise zlib error
- raise Zlib::Error.new(err, z)
- end
-
- src_ofs, left = 0_u32, src_len
- while left > 0
- # calculate read buffer size
- tmp_len = Math.min(BUFFER_SIZE - src_ofs, left)
-
- # decriment remaining bytes
- left -= tmp_len
-
- # create read buffer (if necessary)
- tmp_buf = (tmp_len < BUFFER_SIZE) ? src_buf[src_ofs, tmp_len] : src_buf
-
- # read from source into buffer
- if ((len = src_io.read(tmp_buf)) != tmp_len)
- raise Error.new("truncated read (got #{len}, expected #{tmp_len})")
- end
-
- # calculate crc
- tmp_crc = Zlib.crc32(tmp_buf)
-
- # update crc
- crc = if crc != 0
- Zlib.crc32_combine(crc, tmp_crc, tmp_buf.size)
- else
- tmp_crc
- end
-
- # set zlib input buffer
- z.next_in = src_buf.to_unsafe
- z.avail_in = src_ofs + tmp_buf.size.to_u32
-
- # read compressed data to dst io
- read_compressed(dst_io, dst_buf, pointerof(z), false)
- end
-
- # set zlib input buffer to null
- z.next_in = Pointer(UInt8).null
- z.avail_in = 0_u32
-
- # flush remaining data
- read_compressed(dst_io, dst_buf, pointerof(z), true)
-
- # free stream
- LibZ.inflateEnd(pointerof(z))
-
- # check crc
- if false && crc != @crc
- raise Error.new("crc mismatch (got #{crc}, expected #{@crc}")
- end
-
- # check input size
- if z.total_in != src_len
- raise Error.new("read length mismatch (got #{z.total_in}, expected #{src_len}")
- end
-
- # check output size
- if z.total_out != dst_len
- raise Error.new("write length mismatch (got #{z.total_out}, expected #{dst_len}")
- end
-
- # return number of bytes read
- dst_len
- end
-
- #
- # Inflate compressed data from ZStream and write it to given IO.
- #
- private def read_compressed(
- io : IO,
- buf : Bytes,
- zp : Pointer(LibZ::ZStream),
- flush : Bool,
- )
- zf = flush ? LibZ::Flush::FINISH : LibZ::Flush::NO_FLUSH
-
- r, done = 0_u32, false
- while zp.value.avail_in > 0
- # set zlib output buffer
- zp.value.next_out = buf.to_unsafe
- zp.value.avail_out = buf.size.to_u32
-
- # inflate data, check for error
- case err = LibZ.inflate(zp, zf)
- when LibZ::Error::DATA_ERROR,
- LibZ::Error::NEED_DICT,
- LibZ::Error::MEM_ERROR
- # pp zp.value
- raise Zlib::Error.new(err, zp.value)
- when LibZ::Error::OK
- # do nothing
- when LibZ::Error::STREAM_END
- done = true
- end
-
- if ((len = buf.size - zp.value.avail_out) > 0)
- # write uncompressed data to io
- io.write((len < buf.size) ? Bytes.new(zp.value.next_out, len) : buf)
- end
- end
-
- # return number of unread bytes
- nil
- end
- end
-
- #
- # Internal class used to store files for `Writer` instance.
- #
- # You should not need to instantiate this class directly; it is called
- # automatically by `Writer#add` and `Writer#add_file`.
- #
- class WriterEntry
- include TimeHelper
- include NoneCompressionHelper
- include DeflateCompressionHelper
-
- #
- # Default flags for local and central header.
- #
- GENERAL_FLAGS = GeneralFlags.flags(FOOTER, EFS)
-
- #
- # Create a new WriterEntry instance.
- #
- # You should not need to call this method directly; it is called
- # automatically by `Writer#add` and `Writer#add_file`.
- #
- def initialize(
- @pos : UInt32,
- @path : String,
- @io : IO,
- @method : CompressionMethod = CompressionMethod::DEFLATE,
- @time : Time = Time.now,
- @comment : String = "",
- )
- @crc = 0_u32
- @src_len = 0_u32
- @dst_len = 0_u32
- end
-
- #
- # Write local file entry to IO and return the number of bytes
- # written.
- #
- # You should not need to call this method directly; it is called
- # automatically by `Writer#add` and `Writer#add_file`.
- #
- def to_s(dst_io) : UInt32
- # write header
- r = write_header(dst_io, @path, @method, @time)
-
- # write body
- @crc, @src_len, @dst_len = write_body(dst_io)
- r += @dst_len
-
- # write footer
- r += write_footer(dst_io, @crc, @src_len, @dst_len)
-
- # return number of bytes written
- r
- end
-
- # :nodoc:
- # local file header signature 4 bytes (0x04034b50)
- # version needed to extract 2 bytes
- # general purpose bit flag 2 bytes
- # compression method 2 bytes
- # last mod file time 2 bytes
- # last mod file date 2 bytes
- # crc-32 4 bytes
- # compressed size 4 bytes
- # uncompressed size 4 bytes
- # file name length 2 bytes
- # extra field length 2 bytes
- # file name (variable size)
- # extra field (variable size)
- # :nodoc:
-
- #
- # Write file header and return the number of bytes written.
- #
- private def write_header(
- io : IO,
- path : String,
- method : CompressionMethod,
- time : Time,
- ) : UInt32
- # get path length, in bytes
- path_len = path.bytesize
-
- # check file path
- raise Error.new("empty file path") if path_len == 0
- raise Error.new("file path too long") if path_len >= UInt16::MAX
- raise Error.new("file path contains leading slash") if path[0] == '/'
-
- # write magic (u32), version needed (u16), flags (u16), and
- # compression method (u16)
- MAGIC[:file_header].to_u32.to_io(io, LE)
- Version::NEEDED.to_io(io)
- GENERAL_FLAGS.to_u16.to_io(io, LE)
- method.to_u16.to_io(io, LE)
-
- # write time (u32)
- write_time(io, time)
-
- # crc (u32), compressed size (u32), uncompressed size (u32)
- # (these will be populated in the footer)
- 0_u32.to_u32.to_io(io, LE)
- 0_u32.to_u32.to_io(io, LE)
- 0_u32.to_u32.to_io(io, LE)
-
- # write file path length (u16)
- path_len.to_u16.to_io(io, LE)
-
- # write extras field length (u16)
- extras_len = 0_u32
- extras_len.to_u16.to_io(io, LE)
-
- # write path field
- path.to_s(io)
-
- # write extra fields
- # TODO: implement this
-
- # return number of bytes written
- 30_u32 + path_len + extras_len
- end
-
- #
- # Write file contents and return the number of bytes written.
- #
- private def write_body(dst_io : IO)
- case @method
- when CompressionMethod::NONE
- compress_none(@io, dst_io)
- when CompressionMethod::DEFLATE
- compress_deflate(@io, dst_io)
- else
- raise Error.new("unsupported compression method: #{@method}")
- end
- end
-
- # :nodoc:
- # 4.3.9 Data descriptor:
- # MAGIC = 0x08074b50 4 bytes
- # crc-32 4 bytes
- # compressed size 4 bytes
- # uncompressed size 4 bytes
- #
- # 4.3.9.3 Although not originally assigned a signature, the value
- # 0x08074b50 has commonly been adopted as a signature value
- # :nodoc:
-
- #
- # Write file footer (data descriptor) and return the number of bytes
- # written.
- #
- private def write_footer(
- io : IO,
- crc : UInt32,
- src_len : UInt32,
- dst_len : UInt32,
- ) : UInt32
- # write magic (u32)
- MAGIC[:file_footer].to_u32.to_io(io, LE)
-
- # write crc (u32), compressed size (u32), and full size (u32)
- crc.to_u32.to_io(io, LE)
- dst_len.to_u32.to_io(io, LE)
- src_len.to_u32.to_io(io, LE)
-
- # return number of bytes written
- 16_u32
- end
-
- # :nodoc:
- # central file header signature 4 bytes (0x02014b50)
- # version made by 2 bytes
- # version needed to extract 2 bytes
- # general purpose bit flag 2 bytes
- # compression method 2 bytes
- # last mod file time 2 bytes
- # last mod file date 2 bytes
- # crc-32 4 bytes
- # compressed size 4 bytes
- # uncompressed size 4 bytes
- # file name length 2 bytes
- # extra field length 2 bytes
- # file comment length 2 bytes
- # disk number start 2 bytes
- # internal file attributes 2 bytes
- # external file attributes 4 bytes
- # relative offset of local header 4 bytes
- #
- # file name (variable size)
- # extra field (variable size)
- # file comment (variable size)
- # :nodoc:
-
- #
- # Write central directory data for this `WriterEntry` and return the
- # number of bytes written.
- #
- # You should not need to call this method directly; it is called
- # automatically by `Writer#close`.
- #
- def write_central(
- io : IO,
- version : Version = Version::DEFAULT,
- ) : UInt32
- MAGIC[:cdr_header].to_u32.to_io(io, LE)
- version.to_io(io)
- Version::NEEDED.to_io(io)
- GENERAL_FLAGS.to_u16.to_io(io, LE)
- @method.to_u16.to_io(io, LE)
-
- # write time
- write_time(io, @time)
-
- @crc.to_u32.to_io(io, LE)
- @dst_len.to_u32.to_io(io, LE)
- @src_len.to_u32.to_io(io, LE)
-
- # get path length and write it
- path_len = @path.bytesize
- path_len.to_u16.to_io(io, LE)
-
- # write extras field length (u16)
- extras_len = 0_u32
- extras_len.to_u16.to_io(io, LE)
-
- # write comment field length (u16)
- comment_len = @comment.bytesize
- comment_len.to_u16.to_io(io, LE)
-
- # write disk number
- 0_u32.to_u16.to_io(io, LE)
-
- # write file attributes (internal, external)
- # TODO
- 0_u32.to_u16.to_io(io, LE)
- 0_u32.to_u32.to_io(io, LE)
-
- # write local header offset
- @pos.to_u32.to_io(io, LE)
-
- # write path field
- @path.to_s(io)
-
- # write extra fields
- # TODO: implement this
-
- # write comment
- @comment.to_s(io)
-
- # return number of bytes written
- 46_u32 + path_len + extras_len + comment_len
- end
- end
-
- class Writer
- #
- # Is this `Writer` closed?
- #
- getter? :closed
-
- #
- # Create a new `Writer` object.
- #
- # You shouldn't need to instantiate this class directly; use
- # `Zip.write()` instead.
- #
- def initialize(
- @io : IO,
- @pos : UInt32 = 0,
- @comment : String = "",
- @version : Version = Version::DEFAULT,
- )
- @entries = [] of WriterEntry
- @closed = false
- @src_pos = @pos
- end
-
- private def assert_open
- raise Error.new("already closed") if closed?
- end
-
- #
- # Return the total number of bytes written so far.
- #
- # Example:
- #
- # Zip.write("foo.zip") do |zip|
- # # add "bar.txt"
- # zip.add_file("bar.txt", "/path/to/bar.txt")
- #
- # # print number of bytes written so far
- # puts "bytes written so far: #{zip.bytes_written}"
- # end
- #
- def bytes_written : UInt32
- # return total number of bytes written
- @src_pos - @pos
- end
-
- #
- # Close this writer and return the total number of bytes written.
- #
- def close
- assert_open
-
- # cache cdr position
- cdr_pos = @pos
-
- @entries.each do |entry|
- @pos += entry.write_central(@io, @version)
- end
-
- # write zip footer
- @pos += write_footer(cdr_pos, @pos - cdr_pos)
-
- # flag as closed
- @closed = true
-
- # return total number of bytes written
- bytes_written
- end
-
- #
- # Read data from `IO` *io*, write it to *path* in archive, then
- # return the number of bytes written.
- #
- # Example:
- #
- # # create IO from "/path/to/bar.txt"
- # File.open("/path/to/bar.txt, "rb") do |io|
- # # write to "foo.zip"
- # Zip.write("foo.zip") do |zip|
- # # add "bar.txt" with contents of given IO
- # zip.add("bar.txt", io)
- # end
- # end
- #
- def add(
- path : String,
- io : IO,
- method : CompressionMethod = CompressionMethod::DEFLATE,
- time : Time = Time.now,
- comment : String = "",
- ) : UInt32
- # make sure writer is still open
- assert_open
-
- # create entry
- entry = WriterEntry.new(
- pos: @pos,
- path: path,
- io: io,
- method: method,
- time: time,
- comment: comment,
- )
-
- # add to list of entries
- @entries << entry
-
- # cache offset
- src_pos = @pos
-
- # write entry, update offset
- @pos += entry.to_s(@io)
-
- # return number of bytes written
- @pos - src_pos
- end
-
- #
- # Write *data* to *path* in archive and return number of bytes
- # written.
- #
- # Example:
- #
- # # write to "foo.zip"
- # Zip.write("foo.zip") do |zip|
- # # add "bar.txt" with contents "hello!"
- # zip.add("bar.txt", "hello!")
- # end
- #
- def add(
- path : String,
- data : String | Bytes,
- method : CompressionMethod = CompressionMethod::DEFLATE,
- time : Time = Time.now,
- comment : String = "",
- ) : UInt32
- add(path, MemoryIO.new(data), method, time, comment)
- end
-
- #
- # Add local file *file_path* to archive as *path* and return number
- # of bytes written.
- #
- # Example:
- #
- # # write to "foo.zip"
- # Zip.write("foo.zip") do |zip|
- # # add local file "/path/to/bar.txt" as "bar.txt"
- # zip.add_file("bar.txt", "/path/to/bar.txt")
- # end
- #
- def add_file(
- path : String,
- file_path : String,
- method : CompressionMethod = CompressionMethod::DEFLATE,
- time : Time = Time.now,
- comment : String = "",
- ) : UInt32
- File.open(file_path, "rb") do |io|
- add(path, io, method, time, comment)
- end
- end
-
- # :nodoc:
- # 4.3.16 End of central directory record:
- #
- # * end of central dir signature 4 bytes (0x06054b50)
- # * number of this disk 2 bytes
- # * number of the disk with the
- # start of the central directory 2 bytes
- # * total number of entries in the
- # central directory on this disk 2 bytes
- # * total number of entries in
- # the central directory 2 bytes
- # * size of the central directory 4 bytes
- # * offset of start of central
- # directory with respect to
- # the starting disk number 4 bytes
- # * .ZIP file comment length 2 bytes
- # * .ZIP file comment (variable size)
- # :nodoc:
-
- private def write_footer(
- cdr_pos : UInt32,
- cdr_len : UInt32,
- ) : UInt32
- # write magic (u32)
- MAGIC[:cdr_footer].to_io(@io, LE)
-
- # write disk num (u16) and footer start disk (u16)
- 0_u32.to_u16.to_io(@io, LE)
- 0_u32.to_u16.to_io(@io, LE)
-
- # write num entries (u16) and total entries (u16)
- num_entries = @entries.size
- num_entries.to_u16.to_io(@io, LE)
- num_entries.to_u16.to_io(@io, LE)
-
- # write cdr offset (u32) and cdr length (u32)
- cdr_len.to_io(@io, LE)
- cdr_pos.to_io(@io, LE)
-
- # get comment length (u16)
- comment_len = @comment.bytesize
-
- # write comment length (u16) and comment
- comment_len.to_u16.to_io(@io, LE)
- @comment.to_s(@io)
-
- # return number of bytes written
- 22_u32 + comment_len
- end
- end
-
- #
- # Create a `Zip::Writer` for the output IO *io* and yield it to
- # the given block. Returns number of bytes written.
- #
- # Example:
- #
- # # create output IO
- # File.open("foo.zip", "wb") do |io|
- # Zip.write(io) do |zip|
- # # add "bar.txt" with contents "hello!"
- # zip.add("bar.txt", "hello!")
- # end
- # end
- #
- def self.write(
- io : IO,
- pos : UInt32 = 0_u32,
- comment : String = "",
- version : Version = Version::DEFAULT,
- &cb : Writer -> \
- ) : UInt32
- r = 0_u32
-
- begin
- w = Writer.new(io, pos, comment, version)
- cb.call(w)
- ensure
- if w
- w.close unless w.closed?
- r = w.bytes_written
- end
- end
-
- # return total number of bytes written
- r
- end
-
- #
- # Create a `Zip::Writer` for the output file *path* and yield it to
- # the given block. Returns number of bytes written.
- #
- # Example:
- #
- # # create "foo.zip"
- # Zip.write("foo.zip") do |zip|
- # # add "bar.txt" with contents "hello!"
- # zip.add("bar.txt", "hello!")
- # end
- #
- def self.write(
- path : String,
- pos : UInt32 = 0_u32,
- comment : String = "",
- version : Version = Version::DEFAULT,
- &cb : Writer -> \
- ) : UInt32
- File.open(path, "wb") do |io|
- write(io, pos, comment, version, &cb)
- end
- end
-
- #
- # Base class for input source for `Archive` object.
- #
- # You should not need to instantiate this class directly; use
- # `Zip.read()` instead.
- #
- class Source
- include IO
-
- #
- # Instantiate a new `Source` from the given `IO::FileDescriptor` or
- # `MemoryIO` object.
- #
- # You should not need to instantiate this class directly; use
- # `Zip.read()` instead.
- #
- def initialize(@io : IO::FileDescriptor | MemoryIO)
- end
-
- delegate read, to: @io
- delegate write, to: @io
- forward_missing_to @io
- end
-
- #
- # Extra data associated with `Entry`.
- #
- # You should not need to instantiate this class directly; use
- # `Zip::Entry#extras` or `Zip::Entry#local_extras` instead.
- #
- # Example:
- #
- # # open "foo.zip"
- # Zip.read("foo.zip") do |zip|
- # # get extra data associated with "bar.txt"
- # extras = zip["bar.txt"].extras
- # end
- #
- class Extra
- property :code, :data
-
- def initialize(@code : UInt16, @data : Bytes)
- end
-
- def initialize(io)
- @code = UInt16.from_io(io, LE).as(UInt16)
- size = UInt16.from_io(io, LE).as(UInt16)
- @data = Bytes.new(size)
- io.read(@data)
- end
-
- delegate size, to: @data
-
- def to_s(io) : UInt32
- @code.to_s(io, LE)
- @data.size.to_u16.to_s(io, LE)
- @data.to_s(io)
- end
- end
-
- #
- # File entry in `Archive`.
- #
- # Use `Zip.read()` to read a Zip archive, then `#[]` to fetch a
- # specific archive entry.
- #
- # Example:
- #
- # # create MemoryIO
- # io = MemoryIO.new
- #
- # # open "foo.zip"
- # Zip.read("foo.zip") do |zip|
- # # get "bar.txt" entry from "foo.zip"
- # e = zip["bar.txt"]
- #
- # # read contents of "bar.txt" into io
- # e.read(io)
- # end
- #
- class Entry
- include TimeHelper
- include NoneCompressionHelper
- include DeflateCompressionHelper
-
- getter :version, :version_needed, :flags, :method, :time, :crc,
- :compressed_size, :uncompressed_size, :path, :extras,
- :comment, :internal_attr, :external_attr, :pos
-
- # :nodoc:
- # central file header signature 4 bytes (0x02014b50)
- # version made by 2 bytes
- # version needed to extract 2 bytes
- # general purpose bit flag 2 bytes
- # compression method 2 bytes
- # last mod file time 2 bytes
- # last mod file date 2 bytes
- # crc-32 4 bytes
- # compressed size 4 bytes
- # uncompressed size 4 bytes
- # file name length 2 bytes
- # extra field length 2 bytes
- # file comment length 2 bytes
- # disk number start 2 bytes
- # internal file attributes 2 bytes
- # external file attributes 4 bytes
- # relative offset of local header 4 bytes
- #
- # file name (variable size)
- # extra field (variable size)
- # file comment (variable size)
- # :nodoc:
-
- #
- # Instantiate a new `Entry` object from the given IO.
- #
- # You should not need to call this method directly (use
- # `Zip::Archive#[]` instead).
- #
- def initialize(@io : Source)
- # allocate slice for header data
- head_buf = Bytes.new(46)
-
- # read entry
- if ((head_len = io.read(head_buf)) != 46)
- raise Error.new("couldn't read full CDR entry (#{head_len} != 46)")
- end
-
- # create memory io for slice
- head_mem_io = MemoryIO.new(head_buf, false)
-
- magic = UInt32.from_io(head_mem_io, LE)
- if magic != MAGIC[:cdr_header]
- raise Error.new("invalid CDR header magic")
- end
-
- # read versions
- @version = UInt16.from_io(head_mem_io, LE).as(UInt16)
- @version_needed = UInt16.from_io(head_mem_io, LE).as(UInt16)
-
- # TODO: check versions
-
- # read flags, method, and date
- @flags = UInt16.from_io(head_mem_io, LE).as(UInt16)
- @method = CompressionMethod.new(
- UInt16.from_io(head_mem_io, LE).as(UInt16).to_i32
- )
-
- # TODO: convert to Time object
- @time = from_dos_time(UInt32.from_io(head_mem_io, LE)).as(Time)
-
- # read crc and lengths
- @crc = UInt32.from_io(head_mem_io, LE).as(UInt32)
- @compressed_size = UInt32.from_io(head_mem_io, LE).as(UInt32)
- @uncompressed_size = UInt32.from_io(head_mem_io, LE).as(UInt32)
-
- # read lengths
- @path_len = UInt16.from_io(head_mem_io, LE).not_nil!.as(UInt16)
- @extras_len = UInt16.from_io(head_mem_io, LE).as(UInt16)
- @comment_len = UInt16.from_io(head_mem_io, LE).as(UInt16)
-
- # read starting disk
- @disk_start = UInt16.from_io(head_mem_io, LE).as(UInt16)
-
- # read attributes and position
- @internal_attr = UInt16.from_io(head_mem_io, LE).as(UInt16)
- @external_attr = UInt32.from_io(head_mem_io, LE).as(UInt32)
- @pos = UInt32.from_io(head_mem_io, LE).as(UInt32)
-
- # close memory io
- head_mem_io.close
-
- # create and populate data buffer
- # (holds path, extras, and comment data)
- data_len = @path_len + @extras_len + @comment_len
- data_buf = Bytes.new(data_len)
- if io.read(data_buf) != data_len
- raise Error.new("couldn't read entry CDR name, extras, and comment")
- end
-
- # create data memory io
- data_mem_io = MemoryIO.new(data_buf)
-
- # read path, extras, and comment from data memory io
- @path = read_string(data_mem_io, @path_len, "name") as String
- @extras = read_extras(data_mem_io, @extras_len) as Array(Extra)
- @comment = read_string(data_mem_io, @comment_len, "comment") as String
-
- # close data memory io
- data_mem_io.close
- end
-
- #
- # Return the uncompressed size of this entry in bytes.
- #
- # Example:
- #
- # Zip.read("foo.zip") do |zip|
- # size = zip["bar.txt"].size
- # puts "bar.txt is #{size} bytes."
- # end
- #
- def size : UInt32
- @uncompressed_size
- end
-
- # :nodoc:
- # local file header signature 4 bytes (0x04034b50)
- # version needed to extract 2 bytes
- # general purpose bit flag 2 bytes
- # compression method 2 bytes
- # last mod file time 2 bytes
- # last mod file date 2 bytes
- # crc-32 4 bytes
- # compressed size 4 bytes
- # uncompressed size 4 bytes
- # file name length 2 bytes
- # extra field length 2 bytes
- # file name (variable size)
- # extra field (variable size)
- # :nodoc:
-
- #
- # Write contents of `Entry` into given `IO`.
- #
- # Raises an `Error` if the file contents could not be read or if the
- # compression method is unsupported.
- #
- # Example:
- #
- # # open "output-bar.txt" for writing
- # File.open("output-bar.txt", "wb") do |io|
- # # open archive "./foo.zip"
- # Zip.read("foo.zip") do |zip|
- # # write contents of "bar.txt" to "output-bar.txt"
- # zip["foo.txt"].read(io)
- # end
- # end
- #
- def read(dst_io : IO) : UInt32
- # create buffer for local header
- buf = Bytes.new(30)
-
- # move to local header
- @io.pos = @pos
-
- # read local header into buffer
- @io.read(buf)
-
- # create memory io from buffer
- mem_io = MemoryIO.new(buf, false)
-
- # check magic header
- magic = UInt32.from_io(mem_io, LE)
- if magic != MAGIC[:file_header]
- raise Error.new("invalid file header magic")
- end
-
- # skip local header
- mem_io.pos = 26_u32
-
- # read local name and extras length
- path_len = UInt16.from_io(mem_io, LE)
- extras_len = UInt16.from_io(mem_io, LE)
-
- # close memory io
- mem_io.close
-
- # skip name and extras
- @io.pos = @pos + 30_u32 + path_len + extras_len
-
- case @method
- when CompressionMethod::NONE
- decompress_none(@io, dst_io, @compressed_size, @uncompressed_size)
- when CompressionMethod::DEFLATE
- decompress_deflate(@io, dst_io, @compressed_size, @uncompressed_size)
- else
- raise Error.new("unsupported method: #{@method}")
- end
-
- # return number of bytes written
- @uncompressed_size
- end
-
- #
- # Returns an array of `Extra` attributes for this `Entry`.
- #
- # Zip archives can (and do) have separate `Extra` attributes
- # associated with the file entry itself, and the file's entry in the
- # Central Directory.
- #
- # The `#extras` method returns the `Extra` attributes from the
- # file's entry in the Central Directory, and this method returns the
- # `Extra` data from the file entry itself.
- #
- # Example:
- #
- # # open "./foo.zip"
- # Zip.read("./foo.zip") do |zip|
- # # get array of local extra attributes from "bar.txt"
- # extras = zip["bar.txt"].local_extras
- # end
- #
- def local_extras : Array(Extra)
- unless @local_extras
- # move to extras_len in local header
- @io.pos = @pos + 26_u32
-
- # read name and extras lengths
- name_len = UInt16.from_io(@io, LE)
- extras_len = UInt16.from_io(@io, LE)
-
- # move to extras_len in local header
- @io.pos = @pos + 30_u32 + name_len
-
- # read local extras
- @local_extras = read_extras(@io, extras_len) as Array(Extra)
- end
-
- # return results
- @local_extras.not_nil!
- end
-
- #
- # Returns an array of `Extra` attributes of length `len` from IO `io`.
- #
- private def read_extras(io, len : UInt16) : Array(Extra)
- # read extras
- r = [] of Extra
-
- if len > 0
- # create buffer of extras data
- buf = Bytes.new(len)
- if io.read(buf) != len
- raise Error.new("couldn't read CDR entry extras")
- end
-
- # create memory io over buffer
- mem_io = MemoryIO.new(buf, false)
-
- # read extras from io
- while mem_io.pos != mem_io.size
- r << Extra.new(mem_io)
- end
-
- # close memory io
- mem_io.close
- end
-
- # return results
- r
- end
-
- #
- # Read String of length bytes from IO.
- #
- # Note: At the moment this assumes UTF-8 encoding, but we should
- # make this configurable via a parameter to `#read()`.
- #
- private def read_string(io, len : UInt16, name : String) : String
- if len > 0
- buf = Bytes.new(len)
-
- if io.read(buf) != len
- raise Error.new("couldn't read CDR entry #{name}")
- end
-
- # FIXME: should handle encoding here?
- String.new(buf)
- else
- ""
- end
- end
- end
-
- # :nodoc:
- # 4.3.16 End of central directory record:
- #
- # * end of central dir signature 4 bytes (0x06054b50)
- # * number of this disk 2 bytes
- # * number of the disk with the
- # start of the central directory 2 bytes
- # * total number of entries in the
- # central directory on this disk 2 bytes
- # * total number of entries in
- # the central directory 2 bytes
- # * size of the central directory 4 bytes
- # * offset of start of central
- # directory with respect to
- # the starting disk number 4 bytes
- # * .ZIP file comment length 2 bytes
- # * .ZIP file comment (variable size)
- # :nodoc:
-
- #
- # Input archive.
- #
- # Use `Zip.read()` instead of instantiating this class directly.
- #
- class Archive
- include Enumerable(Entry)
- include Iterable
-
- getter :entries, :comment
-
- #
- # Create new Zip::Archive from input Zip::Source.
- #
- # Use `Zip.read()` instead of calling this method directly.
- #
- def initialize(@io : Source)
- # initialize entries
- # find footer and end of io
- footer_pos, end_pos = find_footer_and_eof(@io)
-
- # skip magic
- @io.pos = footer_pos + 4
-
- # create slice and memory io
- mem = Bytes.new(18)
-
- # read footer into memory io
- @io.pos = footer_pos + 4
- if ((len = @io.read(mem)) < mem.size)
- raise Error.new("couldn't read zip footer")
- end
-
- # create memory io for slice
- mem_io = MemoryIO.new(mem, false)
-
- # read disk numbers
- @disk_num = mem_io.read_bytes(UInt16, LE).as(UInt16)
- @cdr_disk = mem_io.read_bytes(UInt16, LE).as(UInt16)
-
- # check disk numbers
- if @disk_num != @cdr_disk
- raise Error.new("multi-disk archives not supported")
- end
-
- # read entry counts
- @num_disk_entries = mem_io.read_bytes(UInt16, LE).as(UInt16)
- @num_entries = mem_io.read_bytes(UInt16, LE).not_nil!.as(UInt16)
-
- # check entry counts
- if @num_disk_entries != @num_entries
- raise Error.new("multi-disk archives not supported")
- end
-
- # read cdr position and length
- @cdr_len = mem_io.read_bytes(UInt32, LE).not_nil!.as(UInt32)
- @cdr_pos = mem_io.read_bytes(UInt32, LE).not_nil!.as(UInt32)
-
- # check cdr position
- if @cdr_pos.not_nil! + @cdr_len.not_nil! >= end_pos
- raise Error.new("invalid CDR offset: #{@cdr_pos}")
- end
-
- # read comment length and comment body
- @comment_len = mem_io.read_bytes(UInt16, LE).not_nil!.as(UInt16)
- @comment = if @comment_len.not_nil! > 0
- # allocate space for comment
- slice = Bytes.new(@comment_len.not_nil!)
-
- # seek to comment position
- @io.pos = footer_pos + 22
-
- # read comment data
- if ((len = @io.read(slice)) != @comment_len)
- raise Error.new("archive comment read truncated")
- end
-
- # FIXME: shouldn't assume UTF-8 here
- String.new(slice, "UTF-8")
- else
- ""
- end
-
- # close memory io
- mem_io.close
-
- # read entries
- @entries = [] of Entry
- read_entries(@entries, @io, @cdr_pos, @cdr_len, @num_entries)
- end
-
- #################################
- # enumeration/iteration methods #
- #################################
-
- #
- # Get hash of path -> Zip::Entries
- #
- private def paths
- @paths ||= @entries.reduce({} of String => Entry) do |r, e|
- r[e.path] = e
- r
- end.as(Hash(String, Entry))
- end
-
- #
- # Get Zip::Entry by path.
- #
- # Example:
- #
- # # get bar.txt and read it into memory io
- # io = MemoryIO.new
- # zip["bar.txt"].read(io)
- #
- def [](path : String) : Entry
- paths[path]
- end
-
- #
- # Return Zip::Entry from path, or nil if it doesn't exist.
- #
- # Example:
- #
- # # read bar.txt into memory io if it exists
- # if e = zip["bar.txt"]?
- # io = MemoryIO.new
- # e.read(io)
- # end
- #
- def []?(path : String) : Entry?
- paths[path]?
- end
-
- #
- # Get Zip::Entry by number.
- #
- # Example:
- #
- # # read third entry from archive into memory io
- # io = MemoryIO.new
- # zip[2].read(io)
- #
- def [](id : Int) : Entry
- @entries[id]
- end
-
- #
- # Get Zip::Entry by number, or nil if it doesn't exist
- #
- # Example:
- #
- # # read third entry from archive into memory io
- # if e = zip[2]
- # io = MemoryIO.new
- # e.read(io)
- # end
- #
- def []?(id : Int) : Entry?
- @entries[id]?
- end
-
- delegate each, to: @entries
- delegate size, to: @entries
-
- ###################
- # loading methods #
- ###################
-
- #
- # Read CDR entries from given `Zip::Source`.
- #
- private def read_entries(
- entries : Array(Entry),
- io : Source,
- cdr_pos : UInt32,
- cdr_len : UInt32,
- num_entries : UInt16,
- )
- # get end position
- end_cdr_pos = cdr_pos + cdr_len
-
- # seek to start of entries
- io.pos = cdr_pos
-
- # read entries
- num_entries.times do
- # create new entry
- entry = Entry.new(io)
-
- # add to list of entries
- entries << entry
-
- # check position
- if io.pos > end_cdr_pos
- raise Error.new("read past CDR")
- end
- end
- end
-
- #
- # Find EOF and end of CDR for archive.
- #
- private def find_footer_and_eof(io : Source)
- # seek to end of file
- io.seek(0, IO::Seek::End)
- end_pos = io.pos
-
- if end_pos < 22
- raise Error.new("too small for end of central directory")
- end
-
- # create buffer and memory io around it
- buf = Bytes.new(22)
- mem_io = MemoryIO.new(buf, false)
-
- curr_pos = end_pos - 22
- while curr_pos >= 0
- # seek to current position and load possible cdr into buffer
- io.pos = curr_pos
- io.read(buf)
-
- # rewind memory io
- mem_io.rewind
-
- # read what might be the end_cdr magic
- maybe_end_magic = UInt32.from_io(mem_io, LE)
-
- if maybe_end_magic == MAGIC[:cdr_footer]
- # jump to archive commment len (maybe)
- mem_io.pos = 20
-
- # get archive commment len (maybe)
- maybe_comment_len = UInt16.from_io(mem_io, LE)
-
- if curr_pos + 22 + maybe_comment_len == end_pos
- # close memio
- mem_io.close
-
- # magic and comment line up: probably found end_cdr
- return { curr_pos, end_pos }
- end
- end
-
- # step back one byte
- curr_pos -= 1
- end
-
- # throw error
- raise Error.new("couldn't find end of central directory")
- end
- end
-
-
- #
- # Read Zip::Archive from seekable IO instance and pass it to the given
- # block.
- #
- # Example:
- #
- # # create memory io for contents of "bar.txt"
- # io = MemoryIO.new
- #
- # # read "bar.txt" from "./foo.zip"
- # Zip.read(File.open("./foo.zip", "rb")) do |zip|
- # zip["bar.txt"].read(io)
- # end
- #
- def self.read(
- io : IO,
- &cb : Archive -> \
- ) : Void
- r = Archive.new(Source.new(io))
- cb.call(r)
- end
-
- #
- # Read Zip::Archive from Slice and pass it to the given block.
- #
- # Example:
- #
- # # create memory io for contents of "bar.txt"
- # io = MemoryIO.new
- #
- # # extract "bar.txt" from zip archive in Slice some_slice and
- # # save it to MemoryIO
- # Zip.read(some_slice) do |zip|
- # zip["bar.txt"].read(io)
- # end
- #
- def self.read(
- slice : Bytes,
- &cb : Archive -> \
- ) : Void
- src = Source.new(MemoryIO.new(slice, false))
- read(src, &cb)
- end
-
- #
- # Read Zip::Archive from File and pass it to the given block.
- #
- # Example:
- #
- # # create memory io for contents of "bar.txt"
- # io = MemoryIO.new
- #
- # # extract "bar.txt" from "./foo.zip" and save it to MemoryIO
- # Zip.read("./foo.zip") do |zip|
- # zip["bar.txt"].read(io)
- # end
- #
- def self.read(
- path : String,
- &cb : Archive -> \
- ) : Void
- File.open(path, "rb") do |io|
- read(io, &cb)
- end
- end
-end