├── .gitignore
├── BZip2
├── BZip2Compressor.cs
├── BZip2InputStream.cs
├── BZip2OutputStream.cs
├── BitWriter.cs
├── NOTICE.txt
├── ParallelBZip2OutputStream.cs
└── Rand.cs
├── Binaries
├── Debug
│ ├── Ionic.Zip.Unity.XML
│ ├── Ionic.Zip.Unity.dll
│ └── Ionic.Zip.Unity.pdb
└── Release
│ ├── Ionic.Zip.Unity.XML
│ ├── Ionic.Zip.Unity.dll
│ └── Ionic.Zip.Unity.pdb
├── CommonSrc
├── CRC32.cs
└── Iso8859Dash1Encoding.cs
├── DotNetZip.sln
├── License.BZip2.txt
├── License.Combined.rtf
├── License.txt
├── License.zlib.txt
├── README.md
├── Readme.txt
├── SolutionInfo.cs
├── Zip Reduced
├── Properties
│ └── AssemblyInfo.cs
└── Zip Reduced.csproj
├── Zip
├── ComHelper.cs
├── EncryptionAlgorithm.cs
├── Events.cs
├── Exceptions.cs
├── ExtractExistingFileAction.cs
├── FileSelector.cs
├── OffsetStream.cs
├── Shared.cs
├── WinZipAes.cs
├── ZipConstants.cs
├── ZipCrypto.cs
├── ZipDirEntry.cs
├── ZipEntry.Extract.cs
├── ZipEntry.Read.cs
├── ZipEntry.Write.cs
├── ZipEntry.cs
├── ZipEntrySource.cs
├── ZipErrorAction.cs
├── ZipFile.AddUpdate.cs
├── ZipFile.Check.cs
├── ZipFile.Events.cs
├── ZipFile.Extract.cs
├── ZipFile.Read.cs
├── ZipFile.Save.cs
├── ZipFile.SaveSelfExtractor.cs
├── ZipFile.Selector.cs
├── ZipFile.cs
├── ZipFile.x-IEnumerable.cs
├── ZipInputStream.cs
├── ZipOutputStream.cs
└── ZipSegmentedStream.cs
└── Zlib
├── Deflate.cs
├── DeflateStream.cs
├── GZipStream.cs
├── InfTree.cs
├── Inflate.cs
├── LICENSE.jzlib.txt
├── License.zlib.txt
├── ParallelDeflateOutputStream.cs
├── Tree.cs
├── Zlib.cs
├── ZlibBaseStream.cs
├── ZlibCodec.cs
├── ZlibConstants.cs
└── ZlibStream.cs
/.gitignore:
--------------------------------------------------------------------------------
1 | bin
2 | obj
3 | TestResults
4 | notused
5 | _UpgradeReport_Files
6 | Backup
7 | UpgradeLog.XML
8 | CodePlex-Readme.txt
9 | License.rtf
10 | FixProps.ps1
11 | makeSrcZip.bat
12 | MakeReleaseZips.bat
13 | clean.ps1
14 | AppNote.txt
15 | Todo.txt
16 | MakeZipUtils.ps1
17 | SetVersion.ps1
18 | Help
19 | LastBuild.log
20 | _Resharper*
21 | *.resharper
22 | *.cache
23 | *.suo
24 | *.user
25 | #*.*#
26 | *.*~
27 | *.zip
28 |
--------------------------------------------------------------------------------
/BZip2/BZip2OutputStream.cs:
--------------------------------------------------------------------------------
1 | //#define Trace
2 |
3 | // BZip2OutputStream.cs
4 | // ------------------------------------------------------------------
5 | //
6 | // Copyright (c) 2011 Dino Chiesa.
7 | // All rights reserved.
8 | //
9 | // This code module is part of DotNetZip, a zipfile class library.
10 | //
11 | // ------------------------------------------------------------------
12 | //
13 | // This code is licensed under the Microsoft Public License.
14 | // See the file License.txt for the license details.
15 | // More info on: http://dotnetzip.codeplex.com
16 | //
17 | // ------------------------------------------------------------------
18 | //
19 | // Last Saved: <2011-August-02 16:44:11>
20 | //
21 | // ------------------------------------------------------------------
22 | //
23 | // This module defines the BZip2OutputStream class, which is a
24 | // compressing stream that handles BZIP2. This code may have been
25 | // derived in part from Apache commons source code. The license below
26 | // applies to the original Apache code.
27 | //
28 | // ------------------------------------------------------------------
29 | // flymake: csc.exe /t:module BZip2InputStream.cs BZip2Compressor.cs Rand.cs BCRC32.cs @@FILE@@
30 |
31 | /*
32 | * Licensed to the Apache Software Foundation (ASF) under one
33 | * or more contributor license agreements. See the NOTICE file
34 | * distributed with this work for additional information
35 | * regarding copyright ownership. The ASF licenses this file
36 | * to you under the Apache License, Version 2.0 (the
37 | * "License"); you may not use this file except in compliance
38 | * with the License. You may obtain a copy of the License at
39 | *
40 | * http://www.apache.org/licenses/LICENSE-2.0
41 | *
42 | * Unless required by applicable law or agreed to in writing,
43 | * software distributed under the License is distributed on an
44 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
45 | * KIND, either express or implied. See the License for the
46 | * specific language governing permissions and limitations
47 | * under the License.
48 | */
49 |
50 |
51 | // Design Notes:
52 | //
53 | // This class follows the classic Decorator pattern: it is a Stream that
54 | // wraps itself around a Stream, and in doing so provides bzip2
55 | // compression as callers Write into it.
56 | //
57 | // BZip2 is a straightforward data format: there are 4 magic bytes at
58 | // the top of the file, followed by 1 or more compressed blocks. There
59 | // is a small "magic byte" trailer after all compressed blocks. This
60 | // class emits the magic bytes for the header and trailer, and relies on
61 | // a BZip2Compressor to generate each of the compressed data blocks.
62 | //
63 | // BZip2 does byte-shredding - it uses partial fractions of bytes to
64 | // represent independent pieces of information. This class relies on the
65 | // BitWriter to adapt the bit-oriented BZip2 output to the byte-oriented
66 | // model of the .NET Stream class.
67 | //
68 | // ----
69 | //
70 | // Regarding the Apache code base: Most of the code in this particular
71 | // class is related to stream operations, and is my own code. It largely
72 | // does not rely on any code obtained from Apache commons. If you
73 | // compare this code with the Apache commons BZip2OutputStream, you will
74 | // see very little code that is common, except for the
75 | // nearly-boilerplate structure that is common to all subtypes of
76 | // System.IO.Stream. There may be some small remnants of code in this
77 | // module derived from the Apache stuff, which is why I left the license
78 | // in here. Most of the Apache commons compressor magic has been ported
79 | // into the BZip2Compressor class.
80 | //
81 |
82 | using System;
83 | using System.IO;
84 |
85 |
86 | namespace Ionic.BZip2
87 | {
88 | ///
89 | /// A write-only decorator stream that compresses data as it is
90 | /// written using the BZip2 algorithm.
91 | ///
92 | public class BZip2OutputStream : System.IO.Stream
93 | {
94 | int totalBytesWrittenIn;
95 | bool leaveOpen;
96 | BZip2Compressor compressor;
97 | uint combinedCRC;
98 | Stream output;
99 | BitWriter bw;
100 | int blockSize100k; // 0...9
101 |
102 | private TraceBits desiredTrace = TraceBits.Crc | TraceBits.Write;
103 |
104 | ///
105 | /// Constructs a new BZip2OutputStream, that sends its
106 | /// compressed output to the given output stream.
107 | ///
108 | ///
109 | ///
110 | /// The destination stream, to which compressed output will be sent.
111 | ///
112 | ///
113 | ///
114 | ///
115 | /// This example reads a file, then compresses it with bzip2 file,
116 | /// and writes the compressed data into a newly created file.
117 | ///
118 | ///
119 | /// var fname = "logfile.log";
120 | /// using (var fs = File.OpenRead(fname))
121 | /// {
122 | /// var outFname = fname + ".bz2";
123 | /// using (var output = File.Create(outFname))
124 | /// {
125 | /// using (var compressor = new Ionic.BZip2.BZip2OutputStream(output))
126 | /// {
127 | /// byte[] buffer = new byte[2048];
128 | /// int n;
129 | /// while ((n = fs.Read(buffer, 0, buffer.Length)) > 0)
130 | /// {
131 | /// compressor.Write(buffer, 0, n);
132 | /// }
133 | /// }
134 | /// }
135 | /// }
136 | ///
137 | ///
138 | public BZip2OutputStream(Stream output)
139 | : this(output, BZip2.MaxBlockSize, false)
140 | {
141 | }
142 |
143 |
144 | ///
145 | /// Constructs a new BZip2OutputStream with specified blocksize.
146 | ///
147 | /// the destination stream.
148 | ///
149 | /// The blockSize in units of 100000 bytes.
150 | /// The valid range is 1..9.
151 | ///
152 | public BZip2OutputStream(Stream output, int blockSize)
153 | : this(output, blockSize, false)
154 | {
155 | }
156 |
157 |
158 | ///
159 | /// Constructs a new BZip2OutputStream.
160 | ///
161 | /// the destination stream.
162 | ///
163 | /// whether to leave the captive stream open upon closing this stream.
164 | ///
165 | public BZip2OutputStream(Stream output, bool leaveOpen)
166 | : this(output, BZip2.MaxBlockSize, leaveOpen)
167 | {
168 | }
169 |
170 |
171 | ///
172 | /// Constructs a new BZip2OutputStream with specified blocksize,
173 | /// and explicitly specifies whether to leave the wrapped stream open.
174 | ///
175 | ///
176 | /// the destination stream.
177 | ///
178 | /// The blockSize in units of 100000 bytes.
179 | /// The valid range is 1..9.
180 | ///
181 | ///
182 | /// whether to leave the captive stream open upon closing this stream.
183 | ///
184 | public BZip2OutputStream(Stream output, int blockSize, bool leaveOpen)
185 | {
186 | if (blockSize < BZip2.MinBlockSize ||
187 | blockSize > BZip2.MaxBlockSize)
188 | {
189 | var msg = String.Format("blockSize={0} is out of range; must be between {1} and {2}",
190 | blockSize,
191 | BZip2.MinBlockSize, BZip2.MaxBlockSize);
192 | throw new ArgumentException(msg, "blockSize");
193 | }
194 |
195 | this.output = output;
196 | if (!this.output.CanWrite)
197 | throw new ArgumentException("The stream is not writable.", "output");
198 |
199 | this.bw = new BitWriter(this.output);
200 | this.blockSize100k = blockSize;
201 | this.compressor = new BZip2Compressor(this.bw, blockSize);
202 | this.leaveOpen = leaveOpen;
203 | this.combinedCRC = 0;
204 | EmitHeader();
205 | }
206 |
207 |
208 |
209 |
210 | ///
211 | /// Close the stream.
212 | ///
213 | ///
214 | ///
215 | /// This may or may not close the underlying stream. Check the
216 | /// constructors that accept a bool value.
217 | ///
218 | ///
219 | public override void Close()
220 | {
221 | if (output != null)
222 | {
223 | Stream o = this.output;
224 | Finish();
225 | if (!leaveOpen)
226 | o.Close();
227 | }
228 | }
229 |
230 |
231 | ///
232 | /// Flush the stream.
233 | ///
234 | public override void Flush()
235 | {
236 | if (this.output != null)
237 | {
238 | this.bw.Flush();
239 | this.output.Flush();
240 | }
241 | }
242 |
243 | private void EmitHeader()
244 | {
245 | var magic = new byte[] {
246 | (byte) 'B',
247 | (byte) 'Z',
248 | (byte) 'h',
249 | (byte) ('0' + this.blockSize100k)
250 | };
251 |
252 | // not necessary to shred the initial magic bytes
253 | this.output.Write(magic, 0, magic.Length);
254 | }
255 |
256 | private void EmitTrailer()
257 | {
258 | // A magic 48-bit number, 0x177245385090, to indicate the end
259 | // of the last block. (sqrt(pi), if you want to know)
260 |
261 | TraceOutput(TraceBits.Write, "total written out: {0} (0x{0:X})",
262 | this.bw.TotalBytesWrittenOut);
263 |
264 | // must shred
265 | this.bw.WriteByte(0x17);
266 | this.bw.WriteByte(0x72);
267 | this.bw.WriteByte(0x45);
268 | this.bw.WriteByte(0x38);
269 | this.bw.WriteByte(0x50);
270 | this.bw.WriteByte(0x90);
271 |
272 | this.bw.WriteInt(this.combinedCRC);
273 |
274 | this.bw.FinishAndPad();
275 |
276 | TraceOutput(TraceBits.Write, "final total: {0} (0x{0:X})",
277 | this.bw.TotalBytesWrittenOut);
278 | }
279 |
280 | void Finish()
281 | {
282 | // Console.WriteLine("BZip2:Finish");
283 |
284 | try
285 | {
286 | var totalBefore = this.bw.TotalBytesWrittenOut;
287 | this.compressor.CompressAndWrite();
288 | TraceOutput(TraceBits.Write,"out block length (bytes): {0} (0x{0:X})",
289 | this.bw.TotalBytesWrittenOut - totalBefore);
290 |
291 | TraceOutput(TraceBits.Crc, " combined CRC (before): {0:X8}",
292 | this.combinedCRC);
293 | this.combinedCRC = (this.combinedCRC << 1) | (this.combinedCRC >> 31);
294 | this.combinedCRC ^= (uint) compressor.Crc32;
295 | TraceOutput(TraceBits.Crc, " block CRC : {0:X8}",
296 | this.compressor.Crc32);
297 | TraceOutput(TraceBits.Crc, " combined CRC (final) : {0:X8}",
298 | this.combinedCRC);
299 |
300 | EmitTrailer();
301 | }
302 | finally
303 | {
304 | this.output = null;
305 | this.compressor = null;
306 | this.bw = null;
307 | }
308 | }
309 |
310 |
311 | ///
312 | /// The blocksize parameter specified at construction time.
313 | ///
314 | public int BlockSize
315 | {
316 | get { return this.blockSize100k; }
317 | }
318 |
319 |
320 | ///
321 | /// Write data to the stream.
322 | ///
323 | ///
324 | ///
325 | ///
326 | /// Use the BZip2OutputStream to compress data while writing:
327 | /// create a BZip2OutputStream with a writable output stream.
328 | /// Then call Write() on that BZip2OutputStream, providing
329 | /// uncompressed data as input. The data sent to the output stream will
330 | /// be the compressed form of the input data.
331 | ///
332 | ///
333 | ///
334 | /// A BZip2OutputStream can be used only for Write() not for Read().
335 | ///
336 | ///
337 | ///
338 | ///
339 | /// The buffer holding data to write to the stream.
340 | /// the offset within that data array to find the first byte to write.
341 | /// the number of bytes to write.
342 | public override void Write(byte[] buffer, int offset, int count)
343 | {
344 | if (offset < 0)
345 | throw new IndexOutOfRangeException(String.Format("offset ({0}) must be > 0", offset));
346 | if (count < 0)
347 | throw new IndexOutOfRangeException(String.Format("count ({0}) must be > 0", count));
348 | if (offset + count > buffer.Length)
349 | throw new IndexOutOfRangeException(String.Format("offset({0}) count({1}) bLength({2})",
350 | offset, count, buffer.Length));
351 | if (this.output == null)
352 | throw new IOException("the stream is not open");
353 |
354 | if (count == 0) return; // nothing to do
355 |
356 | int bytesWritten = 0;
357 | int bytesRemaining = count;
358 |
359 | do
360 | {
361 | int n = compressor.Fill(buffer, offset, bytesRemaining);
362 | if (n != bytesRemaining)
363 | {
364 | // The compressor data block is full. Compress and
365 | // write out the compressed data, then reset the
366 | // compressor and continue.
367 |
368 | var totalBefore = this.bw.TotalBytesWrittenOut;
369 | this.compressor.CompressAndWrite();
370 | TraceOutput(TraceBits.Write,"out block length (bytes): {0} (0x{0:X})",
371 | this.bw.TotalBytesWrittenOut - totalBefore);
372 |
373 | // and now any remaining bits
374 | TraceOutput(TraceBits.Write,
375 | " remaining: {0} 0x{1:X}",
376 | this.bw.NumRemainingBits,
377 | this.bw.RemainingBits);
378 |
379 | TraceOutput(TraceBits.Crc, " combined CRC (before): {0:X8}",
380 | this.combinedCRC);
381 | this.combinedCRC = (this.combinedCRC << 1) | (this.combinedCRC >> 31);
382 | this.combinedCRC ^= (uint) compressor.Crc32;
383 | TraceOutput(TraceBits.Crc, " block CRC : {0:X8}",
384 | compressor.Crc32);
385 | TraceOutput(TraceBits.Crc, " combined CRC (after) : {0:X8}",
386 | this.combinedCRC);
387 | offset += n;
388 | }
389 | bytesRemaining -= n;
390 | bytesWritten += n;
391 | } while (bytesRemaining > 0);
392 |
393 | totalBytesWrittenIn += bytesWritten;
394 | }
395 |
396 |
397 |
398 |
399 | ///
400 | /// Indicates whether the stream can be read.
401 | ///
402 | ///
403 | /// The return value is always false.
404 | ///
405 | public override bool CanRead
406 | {
407 | get { return false; }
408 | }
409 |
410 | ///
411 | /// Indicates whether the stream supports Seek operations.
412 | ///
413 | ///
414 | /// Always returns false.
415 | ///
416 | public override bool CanSeek
417 | {
418 | get { return false; }
419 | }
420 |
421 | ///
422 | /// Indicates whether the stream can be written.
423 | ///
424 | ///
425 | /// The return value should always be true, unless and until the
426 | /// object is disposed and closed.
427 | ///
428 | public override bool CanWrite
429 | {
430 | get
431 | {
432 | if (this.output == null) throw new ObjectDisposedException("BZip2Stream");
433 | return this.output.CanWrite;
434 | }
435 | }
436 |
437 | ///
438 | /// Reading this property always throws a .
439 | ///
440 | public override long Length
441 | {
442 | get { throw new NotImplementedException(); }
443 | }
444 |
445 | ///
446 | /// The position of the stream pointer.
447 | ///
448 | ///
449 | ///
450 | /// Setting this property always throws a . Reading will return the
452 | /// total number of uncompressed bytes written through.
453 | ///
454 | public override long Position
455 | {
456 | get
457 | {
458 | return this.totalBytesWrittenIn;
459 | }
460 | set { throw new NotImplementedException(); }
461 | }
462 |
463 | ///
464 | /// Calling this method always throws a .
465 | ///
466 | /// this is irrelevant, since it will always throw!
467 | /// this is irrelevant, since it will always throw!
468 | /// irrelevant!
469 | public override long Seek(long offset, System.IO.SeekOrigin origin)
470 | {
471 | throw new NotImplementedException();
472 | }
473 |
474 | ///
475 | /// Calling this method always throws a .
476 | ///
477 | /// this is irrelevant, since it will always throw!
478 | public override void SetLength(long value)
479 | {
480 | throw new NotImplementedException();
481 | }
482 |
483 | ///
484 | /// Calling this method always throws a .
485 | ///
486 | /// this parameter is never used
487 | /// this parameter is never used
488 | /// this parameter is never used
489 | /// never returns anything; always throws
490 | public override int Read(byte[] buffer, int offset, int count)
491 | {
492 | throw new NotImplementedException();
493 | }
494 |
495 |
496 | // used only when Trace is defined
497 | [Flags]
498 | enum TraceBits : uint
499 | {
500 | None = 0,
501 | Crc = 1,
502 | Write = 2,
503 | All = 0xffffffff,
504 | }
505 |
506 |
507 | [System.Diagnostics.ConditionalAttribute("Trace")]
508 | private void TraceOutput(TraceBits bits, string format, params object[] varParams)
509 | {
510 | if ((bits & this.desiredTrace) != 0)
511 | {
512 | //lock(outputLock)
513 | {
514 | int tid = System.Threading.Thread.CurrentThread.GetHashCode();
515 | #if !SILVERLIGHT && !NETCF
516 | Console.ForegroundColor = (ConsoleColor) (tid % 8 + 10);
517 | #endif
518 | Console.Write("{0:000} PBOS ", tid);
519 | Console.WriteLine(format, varParams);
520 | #if !SILVERLIGHT && !NETCF
521 | Console.ResetColor();
522 | #endif
523 | }
524 | }
525 | }
526 |
527 |
528 | }
529 |
530 | }
531 |
--------------------------------------------------------------------------------
/BZip2/BitWriter.cs:
--------------------------------------------------------------------------------
1 | // BitWriter.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2011 Dino Chiesa.
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // Last Saved: <2011-July-25 18:57:31>
18 | //
19 | // ------------------------------------------------------------------
20 | //
21 | // This module defines the BitWriter class, which writes bits at a time
22 | // to an output stream. It's used by the BZip2Compressor class, and by
23 | // the BZip2OutputStream class and its parallel variant,
24 | // ParallelBZip2OutputStream.
25 | //
26 | // ------------------------------------------------------------------
27 |
28 | //
29 | // Design notes:
30 | //
31 | // BZip2 employs byte-shredding in its data format - rather than
32 | // aligning all data items in a compressed .bz2 file on byte barriers,
33 | // the BZip2 format uses portions of bytes to represent independent
34 | // pieces of information. This "shredding" starts with the first
35 | // "randomised" bit - just 12 bytes or so into a bz2 file or stream. But
36 | // the approach is used extensively in bzip2 files - sometimes 5 bits
37 | // are used, sometimes 24 or 3 bits, sometimes just 1 bit, and so on.
38 | // It's not possible to send this information directly to a stream in
39 | // this form; Streams in .NET accept byte-oriented input. Therefore,
40 | // when actually writing a bz2 file, the output data must be organized
41 | // into a byte-aligned format before being written to the output stream.
42 | //
43 | // This BitWriter class provides the byte-shredding necessary for BZip2
44 | // output. Think of this class as an Adapter that enables Bit-oriented
45 | // output to a standard byte-oriented .NET stream. This class writes
46 | // data out to the captive output stream only after the data bits have
47 | // been accumulated and aligned. For example, suppose that during
48 | // operation, the BZip2 compressor emits 5 bits, then 24 bits, then 32
49 | // bits. When the first 5 bits are sent to the BitWriter, nothing is
50 | // written to the output stream; instead these 5 bits are simply stored
51 | // in the internal accumulator. When the next 24 bits are written, the
52 | // first 3 bits are gathered with the accumulated bits. The resulting
53 | // 5+3 constitutes an entire byte; the BitWriter then actually writes
54 | // that byte to the output stream. This leaves 21 bits. BitWriter writes
55 | // 2 more whole bytes (16 more bits), in 8-bit chunks, leaving 5 in the
56 | // accumulator. BitWriter then follows the same procedure with the 32
57 | // new bits. And so on.
58 | //
59 | // A quick tour of the implementation:
60 | //
61 | // The accumulator is a uint - so it can accumulate at most 4 bytes of
62 | // information. In practice because of the design of this class, it
63 | // never accumulates more than 3 bytes.
64 | //
65 | // The Flush() method emits all whole bytes available. After calling
66 | // Flush(), there may be between 0-7 bits yet to be emitted into the
67 | // output stream.
68 | //
69 | // FinishAndPad() emits all data, including the last partial byte and
70 | // any necessary padding. In effect, it establishes a byte-alignment
71 | // barrier. To support bzip2, FinishAndPad() should be called only once
72 | // for a bz2 file, after the last bit of data has been written through
73 | // this adapter. Other binary file formats may use byte-alignment at
74 | // various points within the file, and FinishAndPad() would support that
75 | // scenario.
76 | //
77 | // The internal fn Reset() is used to reset the state of the adapter;
78 | // this class is used by BZip2Compressor, instances of which get re-used
79 | // by multiple distinct threads, for different blocks of data.
80 | //
81 |
82 |
83 | using System;
84 | using System.IO;
85 |
86 | namespace Ionic.BZip2
87 | {
88 |
89 | internal class BitWriter
90 | {
91 | uint accumulator;
92 | int nAccumulatedBits;
93 | Stream output;
94 | int totalBytesWrittenOut;
95 |
96 | public BitWriter(Stream s)
97 | {
98 | this.output = s;
99 | }
100 |
101 | ///
102 | /// Delivers the remaining bits, left-aligned, in a byte.
103 | ///
104 | ///
105 | ///
106 | /// This is valid only if NumRemainingBits is less than 8;
107 | /// in other words it is valid only after a call to Flush().
108 | ///
109 | ///
110 | public byte RemainingBits
111 | {
112 | get
113 | {
114 | return (byte) (this.accumulator >> (32 - this.nAccumulatedBits) & 0xff);
115 | }
116 | }
117 |
118 | public int NumRemainingBits
119 | {
120 | get
121 | {
122 | return this.nAccumulatedBits;
123 | }
124 | }
125 |
126 | public int TotalBytesWrittenOut
127 | {
128 | get
129 | {
130 | return this.totalBytesWrittenOut;
131 | }
132 | }
133 |
134 | ///
135 | /// Reset the BitWriter.
136 | ///
137 | ///
138 | ///
139 | /// This is useful when the BitWriter writes into a MemoryStream, and
140 | /// is used by a BZip2Compressor, which itself is re-used for multiple
141 | /// distinct data blocks.
142 | ///
143 | ///
144 | public void Reset()
145 | {
146 | this.accumulator = 0;
147 | this.nAccumulatedBits = 0;
148 | this.totalBytesWrittenOut = 0;
149 | this.output.Seek(0, SeekOrigin.Begin);
150 | this.output.SetLength(0);
151 | }
152 |
153 | ///
154 | /// Write some number of bits from the given value, into the output.
155 | ///
156 | ///
157 | ///
158 | /// The nbits value should be a max of 25, for safety. For performance
159 | /// reasons, this method does not check!
160 | ///
161 | ///
162 | public void WriteBits(int nbits, uint value)
163 | {
164 | int nAccumulated = this.nAccumulatedBits;
165 | uint u = this.accumulator;
166 |
167 | while (nAccumulated >= 8)
168 | {
169 | this.output.WriteByte ((byte)(u >> 24 & 0xff));
170 | this.totalBytesWrittenOut++;
171 | u <<= 8;
172 | nAccumulated -= 8;
173 | }
174 |
175 | this.accumulator = u | (value << (32 - nAccumulated - nbits));
176 | this.nAccumulatedBits = nAccumulated + nbits;
177 |
178 | // Console.WriteLine("WriteBits({0}, 0x{1:X2}) => {2:X8} n({3})",
179 | // nbits, value, accumulator, nAccumulatedBits);
180 | // Console.ReadLine();
181 |
182 | // At this point the accumulator may contain up to 31 bits waiting for
183 | // output.
184 | }
185 |
186 |
187 | ///
188 | /// Write a full 8-bit byte into the output.
189 | ///
190 | public void WriteByte(byte b)
191 | {
192 | WriteBits(8, b);
193 | }
194 |
195 | ///
196 | /// Write four 8-bit bytes into the output.
197 | ///
198 | public void WriteInt(uint u)
199 | {
200 | WriteBits(8, (u >> 24) & 0xff);
201 | WriteBits(8, (u >> 16) & 0xff);
202 | WriteBits(8, (u >> 8) & 0xff);
203 | WriteBits(8, u & 0xff);
204 | }
205 |
206 | ///
207 | /// Write all available byte-aligned bytes.
208 | ///
209 | ///
210 | ///
211 | /// This method writes no new output, but flushes any accumulated
212 | /// bits. At completion, the accumulator may contain up to 7
213 | /// bits.
214 | ///
215 | ///
216 | /// This is necessary when re-assembling output from N independent
217 | /// compressors, one for each of N blocks. The output of any
218 | /// particular compressor will in general have some fragment of a byte
219 | /// remaining. This fragment needs to be accumulated into the
220 | /// parent BZip2OutputStream.
221 | ///
222 | ///
223 | public void Flush()
224 | {
225 | WriteBits(0,0);
226 | }
227 |
228 |
229 | ///
230 | /// Writes all available bytes, and emits padding for the final byte as
231 | /// necessary. This must be the last method invoked on an instance of
232 | /// BitWriter.
233 | ///
234 | public void FinishAndPad()
235 | {
236 | Flush();
237 |
238 | if (this.NumRemainingBits > 0)
239 | {
240 | byte b = (byte)((this.accumulator >> 24) & 0xff);
241 | this.output.WriteByte(b);
242 | this.totalBytesWrittenOut++;
243 | }
244 | }
245 |
246 | }
247 |
248 | }
--------------------------------------------------------------------------------
/BZip2/NOTICE.txt:
--------------------------------------------------------------------------------
1 | Apache Commons Compress
2 | Copyright 2002-2010 The Apache Software Foundation
3 |
4 | This product includes software developed by
5 | The Apache Software Foundation (http://www.apache.org/).
6 |
--------------------------------------------------------------------------------
/BZip2/Rand.cs:
--------------------------------------------------------------------------------
1 | // Rand.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2011 Dino Chiesa.
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // Last Saved: <2011-July-31 15:09:16>
18 | //
19 | // ------------------------------------------------------------------
20 | //
21 | // This module defines a helper class for the BZip2 classes. This code
22 | // is derived from the original BZip2 source code.
23 | //
24 | // ------------------------------------------------------------------
25 |
26 |
27 | namespace Ionic.BZip2
28 | {
29 | internal static class Rand
30 | {
31 | private static int[] RNUMS =
32 | {
33 | 619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
34 | 985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
35 | 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
36 | 419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
37 | 878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
38 | 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
39 | 150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
40 | 170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
41 | 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
42 | 909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
43 | 641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
44 | 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
45 | 382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
46 | 98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
47 | 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
48 | 469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
49 | 184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
50 | 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
51 | 951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
52 | 652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
53 | 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
54 | 609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
55 | 653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
56 | 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
57 | 170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
58 | 857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
59 | 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
60 | 944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
61 | 344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
62 | 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
63 | 433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
64 | 686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
65 | 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
66 | 978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
67 | 680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
68 | 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
69 | 297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
70 | 134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
71 | 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
72 | 140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
73 | 170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
74 | 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
75 | 804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
76 | 896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
77 | 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
78 | 768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
79 | 61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
80 | 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
81 | 780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
82 | 920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
83 | 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
84 | 936, 638
85 | };
86 |
87 |
88 | ///
89 | /// Returns the "random" number at a specific index.
90 | ///
91 | /// the index
92 | /// the random number
93 | internal static int Rnums(int i)
94 | {
95 | return RNUMS[i];
96 | }
97 | }
98 |
99 | }
--------------------------------------------------------------------------------
/Binaries/Debug/Ionic.Zip.Unity.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r2d2rigo/dotnetzip-for-unity/b6e3951d18a9d28f7ef329c2065b284bd869451a/Binaries/Debug/Ionic.Zip.Unity.dll
--------------------------------------------------------------------------------
/Binaries/Debug/Ionic.Zip.Unity.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r2d2rigo/dotnetzip-for-unity/b6e3951d18a9d28f7ef329c2065b284bd869451a/Binaries/Debug/Ionic.Zip.Unity.pdb
--------------------------------------------------------------------------------
/Binaries/Release/Ionic.Zip.Unity.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r2d2rigo/dotnetzip-for-unity/b6e3951d18a9d28f7ef329c2065b284bd869451a/Binaries/Release/Ionic.Zip.Unity.dll
--------------------------------------------------------------------------------
/Binaries/Release/Ionic.Zip.Unity.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r2d2rigo/dotnetzip-for-unity/b6e3951d18a9d28f7ef329c2065b284bd869451a/Binaries/Release/Ionic.Zip.Unity.pdb
--------------------------------------------------------------------------------
/CommonSrc/Iso8859Dash1Encoding.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Ionic.Encoding
6 | {
7 | ///
8 | /// Provides a text encoder for the iso-8859-1 encoding, aka Latin1 encoding,
9 | /// for platforms that do not support it, for example on Silverlight or some
10 | /// Compact Framework platforms.
11 | ///
12 | public class Iso8859Dash1Encoding : System.Text.Encoding
13 | {
14 | ///
15 | /// Gets the name registered with the
16 | /// Internet Assigned Numbers Authority (IANA) for the current encoding.
17 | ///
18 | ///
19 | /// Always returns "iso-8859-1".
20 | ///
21 | public override string WebName
22 | {
23 | get { return "iso-8859-1"; }
24 | }
25 |
26 | ///
27 | /// Encodes a set of characters from a character array into
28 | /// a byte array.
29 | ///
30 | ///
31 | /// The actual number of bytes written into .
32 | ///
33 | /// The character array containing the set of characters to encode.
34 | /// The index of the first character to encode.
35 | /// The number of characters to encode.
36 | /// The byte array to contain the resulting sequence of bytes.
37 | /// The index at which to start writing the resulting sequence of bytes.
38 | ///
39 | public override int GetBytes(char[] chars, int start, int count, byte[] bytes, int byteIndex)
40 | {
41 | if (chars == null)
42 | throw new ArgumentNullException("chars", "null array");
43 |
44 | if (bytes == null)
45 | throw new ArgumentNullException("bytes", "null array");
46 |
47 | if (start < 0)
48 | throw new ArgumentOutOfRangeException("start");
49 | if (count < 0)
50 | throw new ArgumentOutOfRangeException("charCount");
51 |
52 | if ((chars.Length - start) < count)
53 | throw new ArgumentOutOfRangeException("chars");
54 |
55 | if ((byteIndex < 0) || (byteIndex > bytes.Length))
56 | throw new ArgumentOutOfRangeException("byteIndex");
57 |
58 | // iso-8859-1 is special in that it was adopted as the first page of
59 | // UCS - ISO's Universal Coding Standard, described in ISO 10646,
60 | // which is the same as Unicode. This means that a a Unicode
61 | // character in the range of 0 to FF maps to the iso-8859-1 character
62 | // with the same value. Because of that the encoding and decoding is
63 | // trivial.
64 | for (int i=0; i < count; i++)
65 | {
66 | char c = chars[start+i]; // get the unicode char
67 |
68 | if (c >= '\x00FF') // out of range?
69 | bytes[byteIndex+i] = (byte) '?';
70 | else
71 | bytes[byteIndex+i] = (byte) c;
72 | }
73 | return count;
74 | }
75 |
76 |
77 | ///
78 | /// Decodes a sequence of bytes from the specified byte array into the specified character array.
79 | ///
80 | ///
81 | /// The actual number of characters written into .
82 | ///
83 | /// The byte array containing the sequence of bytes to decode.
84 | /// The index of the first byte to decode.
85 | /// The number of bytes to decode.
86 | /// The character array to contain the resulting set of characters.
87 | /// The index at which to start writing the resulting set of characters.
88 | ///
89 | public override int GetChars(byte[] bytes, int start, int count, char[] chars, int charIndex)
90 | {
91 | if (chars == null)
92 | throw new ArgumentNullException("chars", "null array");
93 |
94 | if (bytes == null)
95 | throw new ArgumentNullException("bytes", "null array");
96 |
97 | if (start < 0)
98 | throw new ArgumentOutOfRangeException("start");
99 | if (count < 0)
100 | throw new ArgumentOutOfRangeException("charCount");
101 |
102 | if ((bytes.Length - start) < count)
103 | throw new ArgumentOutOfRangeException("bytes");
104 |
105 | if ((charIndex < 0) || (charIndex > chars.Length))
106 | throw new ArgumentOutOfRangeException("charIndex");
107 |
108 | // In the range 00 to FF, the Unicode characters are the same as the
109 | // iso-8859-1 characters; because of that, decoding is trivial.
110 | for (int i = 0; i < count; i++)
111 | chars[charIndex + i] = (char) bytes[i + start];
112 |
113 | return count;
114 | }
115 |
116 |
117 | ///
118 | /// Calculates the number of bytes produced by encoding a set of characters
119 | /// from the specified character array.
120 | ///
121 | ///
122 | /// The number of bytes produced by encoding the specified characters. This class
123 | /// alwas returns the value of .
124 | ///
125 | public override int GetByteCount(char[] chars, int index, int count)
126 | {
127 | return count;
128 | }
129 |
130 |
131 | ///
132 | /// Calculates the number of characters produced by decoding a sequence
133 | /// of bytes from the specified byte array.
134 | ///
135 | ///
136 | /// The number of characters produced by decoding the specified sequence of bytes. This class
137 | /// alwas returns the value of .
138 | ///
139 | public override int GetCharCount(byte[] bytes, int index, int count)
140 | {
141 | return count;
142 | }
143 |
144 |
145 | ///
146 | /// Calculates the maximum number of bytes produced by encoding the specified number of characters.
147 | ///
148 | ///
149 | /// The maximum number of bytes produced by encoding the specified number of characters. This
150 | /// class alwas returns the value of .
151 | ///
152 | /// The number of characters to encode.
153 | ///
154 | public override int GetMaxByteCount(int charCount)
155 | {
156 | return charCount;
157 | }
158 |
159 | ///
160 | /// Calculates the maximum number of characters produced by decoding the specified number of bytes.
161 | ///
162 | ///
163 | /// The maximum number of characters produced by decoding the specified number of bytes. This class
164 | /// alwas returns the value of .
165 | ///
166 | /// The number of bytes to decode.
167 | public override int GetMaxCharCount(int byteCount)
168 | {
169 | return byteCount;
170 | }
171 |
172 | ///
173 | /// Gets the number of characters that are supported by this encoding.
174 | /// This property returns a maximum value of 256, as the encoding class
175 | /// only supports single byte encodings (1 byte == 256 possible values).
176 | ///
177 | public static int CharacterCount
178 | {
179 | get { return 256; }
180 | }
181 |
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/DotNetZip.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Zip Reduced", "Zip Reduced\Zip Reduced.csproj", "{49A128D3-C3F2-46B1-8F7A-EECD209EA860}"
5 | EndProject
6 | Global
7 | GlobalSection(TestCaseManagementSettings) = postSolution
8 | CategoryFile = DotNetZip.vsmdi
9 | EndGlobalSection
10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
11 | Debug|Any CPU = Debug|Any CPU
12 | Debug|Mixed Platforms = Debug|Mixed Platforms
13 | Debug|x86 = Debug|x86
14 | Release|Any CPU = Release|Any CPU
15 | Release|Mixed Platforms = Release|Mixed Platforms
16 | Release|x86 = Release|x86
17 | EndGlobalSection
18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
19 | {49A128D3-C3F2-46B1-8F7A-EECD209EA860}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20 | {49A128D3-C3F2-46B1-8F7A-EECD209EA860}.Debug|Any CPU.Build.0 = Debug|Any CPU
21 | {49A128D3-C3F2-46B1-8F7A-EECD209EA860}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
22 | {49A128D3-C3F2-46B1-8F7A-EECD209EA860}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
23 | {49A128D3-C3F2-46B1-8F7A-EECD209EA860}.Debug|x86.ActiveCfg = Debug|Any CPU
24 | {49A128D3-C3F2-46B1-8F7A-EECD209EA860}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {49A128D3-C3F2-46B1-8F7A-EECD209EA860}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {49A128D3-C3F2-46B1-8F7A-EECD209EA860}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
27 | {49A128D3-C3F2-46B1-8F7A-EECD209EA860}.Release|Mixed Platforms.Build.0 = Release|Any CPU
28 | {49A128D3-C3F2-46B1-8F7A-EECD209EA860}.Release|x86.ActiveCfg = Release|Any CPU
29 | EndGlobalSection
30 | GlobalSection(SolutionProperties) = preSolution
31 | HideSolutionNode = FALSE
32 | EndGlobalSection
33 | EndGlobal
34 |
--------------------------------------------------------------------------------
/License.BZip2.txt:
--------------------------------------------------------------------------------
1 |
2 | The managed BZIP2 code included in Ionic.BZip2.dll and Ionic.Zip.dll is
3 | modified code, based on the bzip2 code in the Apache commons compress
4 | library.
5 |
6 | The original BZip2 was created by Julian Seward, and is licensed under
7 | the BSD license.
8 |
9 | The following license applies to the Apache code:
10 | -----------------------------------------------------------------------
11 |
12 | /*
13 | * Licensed to the Apache Software Foundation (ASF) under one
14 | * or more contributor license agreements. See the NOTICE file
15 | * distributed with this work for additional information
16 | * regarding copyright ownership. The ASF licenses this file
17 | * to you under the Apache License, Version 2.0 (the
18 | * "License"); you may not use this file except in compliance
19 | * with the License. You may obtain a copy of the License at
20 | *
21 | * http://www.apache.org/licenses/LICENSE-2.0
22 | *
23 | * Unless required by applicable law or agreed to in writing,
24 | * software distributed under the License is distributed on an
25 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
26 | * KIND, either express or implied. See the License for the
27 | * specific language governing permissions and limitations
28 | * under the License.
29 | */
30 |
--------------------------------------------------------------------------------
/License.txt:
--------------------------------------------------------------------------------
1 | Microsoft Public License (Ms-PL)
2 |
3 | This license governs use of the accompanying software, the DotNetZip library ("the software"). If you use the software, you accept this license. If you do not accept the license, do not use the software.
4 |
5 | 1. Definitions
6 |
7 | The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
8 |
9 | A "contribution" is the original software, or any additions or changes to the software.
10 |
11 | A "contributor" is any person that distributes its contribution under this license.
12 |
13 | "Licensed patents" are a contributor's patent claims that read directly on its contribution.
14 |
15 | 2. Grant of Rights
16 |
17 | (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
18 |
19 | (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
20 |
21 | 3. Conditions and Limitations
22 |
23 | (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
24 |
25 | (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
26 |
27 | (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
28 |
29 | (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
30 |
31 | (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
32 |
33 |
34 |
--------------------------------------------------------------------------------
/License.zlib.txt:
--------------------------------------------------------------------------------
1 |
2 | The following licenses govern use of the accompanying software, the
3 | DotNetZip library ("the software"). If you use the software, you accept
4 | these licenses. If you do not accept the license, do not use the software.
5 |
6 | The managed ZLIB code included in Ionic.Zlib.dll and Ionic.Zip.dll is
7 | modified code, based on jzlib.
8 |
9 |
10 |
11 | The following notice applies to jzlib:
12 | -----------------------------------------------------------------------
13 |
14 | Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
15 |
16 | Redistribution and use in source and binary forms, with or without
17 | modification, are permitted provided that the following conditions are met:
18 |
19 | 1. Redistributions of source code must retain the above copyright notice,
20 | this list of conditions and the following disclaimer.
21 |
22 | 2. Redistributions in binary form must reproduce the above copyright
23 | notice, this list of conditions and the following disclaimer in
24 | the documentation and/or other materials provided with the distribution.
25 |
26 | 3. The names of the authors may not be used to endorse or promote products
27 | derived from this software without specific prior written permission.
28 |
29 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
30 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
32 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
33 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
35 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
36 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
37 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
38 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 |
40 | -----------------------------------------------------------------------
41 |
42 | jzlib is based on zlib-1.1.3.
43 |
44 | The following notice applies to zlib:
45 |
46 | -----------------------------------------------------------------------
47 |
48 | Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
49 |
50 | The ZLIB software is provided 'as-is', without any express or implied
51 | warranty. In no event will the authors be held liable for any damages
52 | arising from the use of this software.
53 |
54 | Permission is granted to anyone to use this software for any purpose,
55 | including commercial applications, and to alter it and redistribute it
56 | freely, subject to the following restrictions:
57 |
58 | 1. The origin of this software must not be misrepresented; you must not
59 | claim that you wrote the original software. If you use this software
60 | in a product, an acknowledgment in the product documentation would be
61 | appreciated but is not required.
62 | 2. Altered source versions must be plainly marked as such, and must not be
63 | misrepresented as being the original software.
64 | 3. This notice may not be removed or altered from any source distribution.
65 |
66 | Jean-loup Gailly jloup@gzip.org
67 | Mark Adler madler@alumni.caltech.edu
68 |
69 |
70 | -----------------------------------------------------------------------
71 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # dotnetzip-for-unity #
2 | This is a stripped-down version of DotNetZip (no BZip2/GZip support for now) with some fixes so it can be used on Unity projects, including those that target Android and iOS.
3 |
4 | This project is licensed under the Ms-PL, packaged within this project as
5 | "License.txt".
6 |
7 | Thanks to Ed Ropple for the original GitHub mirror of DotNetZip.
8 |
9 | ## How to use ##
10 | Clone the repository and compile the project, or download the already compiled libraries from the __Binaries__ folder. Drop them in your Unity project's __Assets/Plugins__ folder and you are good to go.
11 |
12 | The library has been extensively tested in Android devices, however, some issues can arise when targetting iOS devices. Feel free to report any bugs you find.
13 |
--------------------------------------------------------------------------------
/SolutionInfo.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r2d2rigo/dotnetzip-for-unity/b6e3951d18a9d28f7ef329c2065b284bd869451a/SolutionInfo.cs
--------------------------------------------------------------------------------
/Zip Reduced/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r2d2rigo/dotnetzip-for-unity/b6e3951d18a9d28f7ef329c2065b284bd869451a/Zip Reduced/Properties/AssemblyInfo.cs
--------------------------------------------------------------------------------
/Zip Reduced/Zip Reduced.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.30729
7 | 2.0
8 | {49A128D3-C3F2-46B1-8F7A-EECD209EA860}
9 | Library
10 | Properties
11 | Ionic.Zip
12 | Ionic.Zip.Unity
13 | v2.0
14 | 512
15 |
16 |
17 | SAK
18 | SAK
19 | SAK
20 | SAK
21 | false
22 | ..\Ionic.snk
23 |
24 |
25 | 3.5
26 |
27 | publish\
28 | true
29 | Disk
30 | false
31 | Foreground
32 | 7
33 | Days
34 | false
35 | false
36 | true
37 | 0
38 | 1.0.0.%2a
39 | false
40 | false
41 | true
42 |
43 |
44 | true
45 | full
46 | false
47 | bin\Debug\
48 | TRACE;DEBUG;AESCRYPTO;BZIP;SILVERLIGHT;NO_LINQ;NO_SFX
49 | prompt
50 | 4
51 | bin\Debug\Ionic.Zip.Unity.XML
52 | AllRules.ruleset
53 |
54 |
55 | pdbonly
56 | true
57 | bin\Release\
58 | TRACE;AESCRYPTO;BZIP;SILVERLIGHT;NO_LINQ;NO_SFX
59 | prompt
60 | 4
61 | AllRules.ruleset
62 | bin\Release\Ionic.Zip.Unity.XML
63 |
64 |
65 |
72 |
73 |
74 | Zip\%(FileName)
75 |
76 |
77 | BZip2\%(FileName)
78 |
79 |
80 | Zlib\%(FileName)
81 |
82 |
83 | CRC32.cs
84 |
85 |
86 |
87 | Properties\SolutionInfo.cs
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | False
96 | .NET Framework 3.5 SP1 Client Profile
97 | false
98 |
99 |
100 | False
101 | .NET Framework 3.5 SP1
102 | true
103 |
104 |
105 | False
106 | Windows Installer 3.1
107 | true
108 |
109 |
110 |
--------------------------------------------------------------------------------
/Zip/ComHelper.cs:
--------------------------------------------------------------------------------
1 | // ComHelper.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2009 Dino Chiesa.
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2011-June-13 17:04:06>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines a COM Helper class.
23 | //
24 | // Created: Tue, 08 Sep 2009 22:03
25 | //
26 |
27 | using Interop=System.Runtime.InteropServices;
28 |
29 | namespace Ionic.Zip
30 | {
31 | ///
32 | /// This class exposes a set of COM-accessible wrappers for static
33 | /// methods available on the ZipFile class. You don't need this
34 | /// class unless you are using DotNetZip from a COM environment.
35 | ///
36 | [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000F")]
37 | [System.Runtime.InteropServices.ComVisible(true)]
38 | #if !NETCF
39 | [System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDispatch)]
40 | #endif
41 |
42 | public class ComHelper
43 | {
44 | ///
45 | /// A wrapper for ZipFile.IsZipFile(string)
46 | ///
47 | /// The filename to of the zip file to check.
48 | /// true if the file contains a valid zip file.
49 | public bool IsZipFile(string filename)
50 | {
51 | return ZipFile.IsZipFile(filename);
52 | }
53 |
54 | ///
55 | /// A wrapper for ZipFile.IsZipFile(string, bool)
56 | ///
57 | ///
58 | /// We cannot use "overloaded" Method names in COM interop.
59 | /// So, here, we use a unique name.
60 | ///
61 | /// The filename to of the zip file to check.
62 | /// true if the file contains a valid zip file.
63 | public bool IsZipFileWithExtract(string filename)
64 | {
65 | return ZipFile.IsZipFile(filename, true);
66 | }
67 |
68 | #if !NETCF
69 | ///
70 | /// A wrapper for ZipFile.CheckZip(string)
71 | ///
72 | /// The filename to of the zip file to check.
73 | ///
74 | /// true if the named zip file checks OK. Otherwise, false.
75 | public bool CheckZip(string filename)
76 | {
77 | return ZipFile.CheckZip(filename);
78 | }
79 |
80 | ///
81 | /// A COM-friendly wrapper for the static method .
82 | ///
83 | ///
84 | /// The filename to of the zip file to check.
85 | ///
86 | /// The password to check.
87 | ///
88 | /// true if the named zip file checks OK. Otherwise, false.
89 | public bool CheckZipPassword(string filename, string password)
90 | {
91 | return ZipFile.CheckZipPassword(filename, password);
92 | }
93 |
94 | ///
95 | /// A wrapper for ZipFile.FixZipDirectory(string)
96 | ///
97 | /// The filename to of the zip file to fix.
98 | public void FixZipDirectory(string filename)
99 | {
100 | ZipFile.FixZipDirectory(filename);
101 | }
102 | #endif
103 |
104 | ///
105 | /// A wrapper for ZipFile.LibraryVersion
106 | ///
107 | ///
108 | /// the version number on the DotNetZip assembly, formatted as a string.
109 | ///
110 | public string GetZipLibraryVersion()
111 | {
112 | return ZipFile.LibraryVersion.ToString();
113 | }
114 |
115 | }
116 | }
--------------------------------------------------------------------------------
/Zip/EncryptionAlgorithm.cs:
--------------------------------------------------------------------------------
1 | // EncryptionAlgorithm.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2009 Dino Chiesa
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2009-October-21 17:24:45>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines the EncryptionAgorithm enum
23 | //
24 | //
25 | // ------------------------------------------------------------------
26 |
27 |
28 | namespace Ionic.Zip
29 | {
30 | ///
31 | /// An enum that provides the various encryption algorithms supported by this
32 | /// library.
33 | ///
34 | ///
35 | ///
36 | ///
37 | ///
38 | /// PkzipWeak implies the use of Zip 2.0 encryption, which is known to be
39 | /// weak and subvertible.
40 | ///
41 | ///
42 | ///
43 | /// A note on interoperability: Values of PkzipWeak and None are
44 | /// specified in PKWARE's zip
46 | /// specification, and are considered to be "standard". Zip archives
47 | /// produced using these options will be interoperable with many other zip tools
48 | /// and libraries, including Windows Explorer.
49 | ///
50 | ///
51 | ///
52 | /// Values of WinZipAes128 and WinZipAes256 are not part of the Zip
53 | /// specification, but rather imply the use of a vendor-specific extension from
54 | /// WinZip. If you want to produce interoperable Zip archives, do not use these
55 | /// values. For example, if you produce a zip archive using WinZipAes256, you
56 | /// will be able to open it in Windows Explorer on Windows XP and Vista, but you
57 | /// will not be able to extract entries; trying this will lead to an "unspecified
58 | /// error". For this reason, some people have said that a zip archive that uses
59 | /// WinZip's AES encryption is not actually a zip archive at all. A zip archive
60 | /// produced this way will be readable with the WinZip tool (Version 11 and
61 | /// beyond).
62 | ///
63 | ///
64 | ///
65 | /// There are other third-party tools and libraries, both commercial and
66 | /// otherwise, that support WinZip's AES encryption. These will be able to read
67 | /// AES-encrypted zip archives produced by DotNetZip, and conversely applications
68 | /// that use DotNetZip to read zip archives will be able to read AES-encrypted
69 | /// archives produced by those tools or libraries. Consult the documentation for
70 | /// those other tools and libraries to find out if WinZip's AES encryption is
71 | /// supported.
72 | ///
73 | ///
74 | ///
75 | /// In case you care: According to the WinZip specification, the
77 | /// actual AES key used is derived from the via an
78 | /// algorithm that complies with RFC 2898, using an iteration
80 | /// count of 1000. The algorithm is sometimes referred to as PBKDF2, which stands
81 | /// for "Password Based Key Derivation Function #2".
82 | ///
83 | ///
84 | ///
85 | /// A word about password strength and length: The AES encryption technology is
86 | /// very good, but any system is only as secure as the weakest link. If you want
87 | /// to secure your data, be sure to use a password that is hard to guess. To make
88 | /// it harder to guess (increase its "entropy"), you should make it longer. If
89 | /// you use normal characters from an ASCII keyboard, a password of length 20 will
90 | /// be strong enough that it will be impossible to guess. For more information on
91 | /// that, I'd encourage you to read this
93 | /// article.
94 | ///
95 | ///
96 | ///
97 | /// The WinZip AES algorithms are not supported with the version of DotNetZip that
98 | /// runs on the .NET Compact Framework. This is because .NET CF lacks the
99 | /// HMACSHA1 class that is required for producing the archive.
100 | ///
101 | ///
102 | public enum EncryptionAlgorithm
103 | {
104 | ///
105 | /// No encryption at all.
106 | ///
107 | None = 0,
108 |
109 | ///
110 | /// Traditional or Classic pkzip encryption.
111 | ///
112 | PkzipWeak,
113 |
114 | #if AESCRYPTO
115 | ///
116 | /// WinZip AES encryption (128 key bits).
117 | ///
118 | WinZipAes128,
119 |
120 | ///
121 | /// WinZip AES encryption (256 key bits).
122 | ///
123 | WinZipAes256,
124 | #endif
125 |
126 | ///
127 | /// An encryption algorithm that is not supported by DotNetZip.
128 | ///
129 | Unsupported = 4,
130 |
131 |
132 | // others... not implemented (yet?)
133 | }
134 |
135 | }
136 |
--------------------------------------------------------------------------------
/Zip/Exceptions.cs:
--------------------------------------------------------------------------------
1 | // Exceptions.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2008, 2009 Dino Chiesa and Microsoft Corporation.
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2011-July-12 12:19:10>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines exceptions used in the class library.
23 | //
24 |
25 |
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Text;
30 | #if !NETCF
31 | using System.Runtime.Serialization;
32 | #endif
33 |
34 | namespace Ionic.Zip
35 | {
36 | /////
37 | ///// Base exception type for all custom exceptions in the Zip library. It acts as a marker class.
38 | /////
39 | //[AttributeUsage(AttributeTargets.Class)]
40 | //public class ZipExceptionAttribute : Attribute { }
41 |
42 |
43 |
44 | ///
45 | /// Issued when an ZipEntry.ExtractWithPassword() method is invoked
46 | /// with an incorrect password.
47 | ///
48 | #if !SILVERLIGHT
49 | [Serializable]
50 | #endif
51 | [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000B")]
52 | public class BadPasswordException : ZipException
53 | {
54 | ///
55 | /// Default ctor.
56 | ///
57 | public BadPasswordException() { }
58 |
59 | ///
60 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
61 | ///
62 | /// The message in the exception.
63 | public BadPasswordException(String message)
64 | : base(message)
65 | { }
66 |
67 | ///
68 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
69 | ///
70 | /// The message in the exception.
71 | /// The innerException for this exception.
72 | public BadPasswordException(String message, Exception innerException)
73 | : base(message, innerException)
74 | {
75 | }
76 |
77 |
78 | #if ! (NETCF || SILVERLIGHT)
79 | ///
80 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
81 | ///
82 | /// The serialization info for the exception.
83 | /// The streaming context from which to deserialize.
84 | protected BadPasswordException(SerializationInfo info, StreamingContext context)
85 | : base(info, context)
86 | { }
87 | #endif
88 |
89 | }
90 |
91 | ///
92 | /// Indicates that a read was attempted on a stream, and bad or incomplete data was
93 | /// received.
94 | ///
95 | #if !SILVERLIGHT
96 | [Serializable]
97 | #endif
98 | [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000A")]
99 | public class BadReadException : ZipException
100 | {
101 | ///
102 | /// Default ctor.
103 | ///
104 | public BadReadException() { }
105 |
106 | ///
107 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
108 | ///
109 | /// The message in the exception.
110 | public BadReadException(String message)
111 | : base(message)
112 | { }
113 |
114 | ///
115 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
116 | ///
117 | /// The message in the exception.
118 | /// The innerException for this exception.
119 | public BadReadException(String message, Exception innerException)
120 | : base(message, innerException)
121 | {
122 | }
123 |
124 | #if ! (NETCF || SILVERLIGHT)
125 | ///
126 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
127 | ///
128 | /// The serialization info for the exception.
129 | /// The streaming context from which to deserialize.
130 | protected BadReadException(SerializationInfo info, StreamingContext context)
131 | : base(info, context)
132 | { }
133 | #endif
134 |
135 | }
136 |
137 |
138 |
139 | ///
140 | /// Issued when an CRC check fails upon extracting an entry from a zip archive.
141 | ///
142 | #if !SILVERLIGHT
143 | [Serializable]
144 | #endif
145 | [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00009")]
146 | public class BadCrcException : ZipException
147 | {
148 | ///
149 | /// Default ctor.
150 | ///
151 | public BadCrcException() { }
152 |
153 | ///
154 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
155 | ///
156 | /// The message in the exception.
157 | public BadCrcException(String message)
158 | : base(message)
159 | { }
160 |
161 |
162 | #if ! (NETCF || SILVERLIGHT)
163 | ///
164 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
165 | ///
166 | /// The serialization info for the exception.
167 | /// The streaming context from which to deserialize.
168 | protected BadCrcException(SerializationInfo info, StreamingContext context)
169 | : base(info, context)
170 | { }
171 | #endif
172 |
173 | }
174 |
175 |
176 | ///
177 | /// Issued when errors occur saving a self-extracting archive.
178 | ///
179 | #if !SILVERLIGHT
180 | [Serializable]
181 | #endif
182 | [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00008")]
183 | public class SfxGenerationException : ZipException
184 | {
185 | ///
186 | /// Default ctor.
187 | ///
188 | public SfxGenerationException() { }
189 |
190 | ///
191 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
192 | ///
193 | /// The message in the exception.
194 | public SfxGenerationException(String message)
195 | : base(message)
196 | { }
197 |
198 | #if ! (NETCF || SILVERLIGHT)
199 | ///
200 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
201 | ///
202 | /// The serialization info for the exception.
203 | /// The streaming context from which to deserialize.
204 | protected SfxGenerationException(SerializationInfo info, StreamingContext context)
205 | : base(info, context)
206 | { }
207 | #endif
208 |
209 | }
210 |
211 |
212 | ///
213 | /// Indicates that an operation was attempted on a ZipFile which was not possible
214 | /// given the state of the instance. For example, if you call Save() on a ZipFile
215 | /// which has no filename set, you can get this exception.
216 | ///
217 | #if !SILVERLIGHT
218 | [Serializable]
219 | #endif
220 | [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00007")]
221 | public class BadStateException : ZipException
222 | {
223 | ///
224 | /// Default ctor.
225 | ///
226 | public BadStateException() { }
227 |
228 | ///
229 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
230 | ///
231 | /// The message in the exception.
232 | public BadStateException(String message)
233 | : base(message)
234 | { }
235 |
236 | ///
237 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
238 | ///
239 | /// The message in the exception.
240 | /// The innerException for this exception.
241 | public BadStateException(String message, Exception innerException)
242 | : base(message, innerException)
243 | {}
244 |
245 | #if ! (NETCF || SILVERLIGHT)
246 | ///
247 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
248 | ///
249 | /// The serialization info for the exception.
250 | /// The streaming context from which to deserialize.
251 | protected BadStateException(SerializationInfo info, StreamingContext context)
252 | : base(info, context)
253 | { }
254 | #endif
255 |
256 | }
257 |
258 | ///
259 | /// Base class for all exceptions defined by and throw by the Zip library.
260 | ///
261 | #if !SILVERLIGHT
262 | [Serializable]
263 | #endif
264 | [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00006")]
265 | public class ZipException : Exception
266 | {
267 | ///
268 | /// Default ctor.
269 | ///
270 | public ZipException() { }
271 |
272 | ///
273 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
274 | ///
275 | /// The message in the exception.
276 | public ZipException(String message) : base(message) { }
277 |
278 | ///
279 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
280 | ///
281 | /// The message in the exception.
282 | /// The innerException for this exception.
283 | public ZipException(String message, Exception innerException)
284 | : base(message, innerException)
285 | { }
286 |
287 | #if ! (NETCF || SILVERLIGHT)
288 | ///
289 | /// Come on, you know how exceptions work. Why are you looking at this documentation?
290 | ///
291 | /// The serialization info for the exception.
292 | /// The streaming context from which to deserialize.
293 | protected ZipException(SerializationInfo info, StreamingContext context)
294 | : base(info, context)
295 | { }
296 | #endif
297 |
298 | }
299 |
300 | }
301 |
--------------------------------------------------------------------------------
/Zip/ExtractExistingFileAction.cs:
--------------------------------------------------------------------------------
1 | // ExtractExistingFileAction.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2009 Dino Chiesa
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2009-August-25 08:44:37>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines the ExtractExistingFileAction enum
23 | //
24 | //
25 | // ------------------------------------------------------------------
26 |
27 |
28 | namespace Ionic.Zip
29 | {
30 |
31 | ///
32 | /// An enum for the options when extracting an entry would overwrite an existing file.
33 | ///
34 | ///
35 | ///
36 | ///
37 | /// This enum describes the actions that the library can take when an
38 | /// Extract() or ExtractWithPassword() method is called to extract an
39 | /// entry to a filesystem, and the extraction would overwrite an existing filesystem
40 | /// file.
41 | ///
42 | ///
43 | ///
44 | public enum ExtractExistingFileAction
45 | {
46 | ///
47 | /// Throw an exception when extraction would overwrite an existing file. (For
48 | /// COM clients, this is a 0 (zero).)
49 | ///
50 | Throw,
51 |
52 | ///
53 | /// When extraction would overwrite an existing file, overwrite the file silently.
54 | /// The overwrite will happen even if the target file is marked as read-only.
55 | /// (For COM clients, this is a 1.)
56 | ///
57 | OverwriteSilently,
58 |
59 | ///
60 | /// When extraction would overwrite an existing file, don't overwrite the file, silently.
61 | /// (For COM clients, this is a 2.)
62 | ///
63 | DoNotOverwrite,
64 |
65 | ///
66 | /// When extraction would overwrite an existing file, invoke the ExtractProgress
67 | /// event, using an event type of . In
69 | /// this way, the application can decide, just-in-time, whether to overwrite the
70 | /// file. For example, a GUI application may wish to pop up a dialog to allow
71 | /// the user to choose. You may want to examine the property before making
73 | /// the decision. If, after your processing in the Extract progress event, you
74 | /// want to NOT extract the file, set
75 | /// on the ZipProgressEventArgs.CurrentEntry to DoNotOverwrite.
76 | /// If you do want to extract the file, set ZipEntry.ExtractExistingFile
77 | /// to OverwriteSilently. If you want to cancel the Extraction, set
78 | /// ZipProgressEventArgs.Cancel to true. Cancelling differs from using
79 | /// DoNotOverwrite in that a cancel will not extract any further entries, if
80 | /// there are any. (For COM clients, the value of this enum is a 3.)
81 | ///
82 | InvokeExtractProgressEvent,
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/Zip/OffsetStream.cs:
--------------------------------------------------------------------------------
1 | // OffsetStream.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2009 Dino Chiesa
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2009-August-27 12:50:35>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines logic for handling reading of zip archives embedded
23 | // into larger streams. The initial position of the stream serves as
24 | // the base offset for all future Seek() operations.
25 | //
26 | // ------------------------------------------------------------------
27 |
28 |
29 | using System;
30 | using System.IO;
31 |
32 | namespace Ionic.Zip
33 | {
34 | internal class OffsetStream : System.IO.Stream, System.IDisposable
35 | {
36 | private Int64 _originalPosition;
37 | private Stream _innerStream;
38 |
39 | public OffsetStream(Stream s)
40 | : base()
41 | {
42 | _originalPosition = s.Position;
43 | _innerStream = s;
44 | }
45 |
46 | public override int Read(byte[] buffer, int offset, int count)
47 | {
48 | return _innerStream.Read(buffer, offset, count);
49 | }
50 |
51 | public override void Write(byte[] buffer, int offset, int count)
52 | {
53 | throw new NotImplementedException();
54 | }
55 |
56 | public override bool CanRead
57 | {
58 | get { return _innerStream.CanRead; }
59 | }
60 |
61 | public override bool CanSeek
62 | {
63 | get { return _innerStream.CanSeek; }
64 | }
65 |
66 | public override bool CanWrite
67 | {
68 | get { return false; }
69 | }
70 |
71 | public override void Flush()
72 | {
73 | _innerStream.Flush();
74 | }
75 |
76 | public override long Length
77 | {
78 | get
79 | {
80 | return _innerStream.Length;
81 | }
82 | }
83 |
84 | public override long Position
85 | {
86 | get { return _innerStream.Position - _originalPosition; }
87 | set { _innerStream.Position = _originalPosition + value; }
88 | }
89 |
90 |
91 | public override long Seek(long offset, System.IO.SeekOrigin origin)
92 | {
93 | return _innerStream.Seek(_originalPosition + offset, origin) - _originalPosition;
94 | }
95 |
96 |
97 | public override void SetLength(long value)
98 | {
99 | throw new NotImplementedException();
100 | }
101 |
102 | void IDisposable.Dispose()
103 | {
104 | Close();
105 | }
106 |
107 | public override void Close()
108 | {
109 | base.Close();
110 | }
111 |
112 | }
113 |
114 | }
--------------------------------------------------------------------------------
/Zip/ZipConstants.cs:
--------------------------------------------------------------------------------
1 | // ZipConstants.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2006, 2007, 2008, 2009 Dino Chiesa and Microsoft Corporation.
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2009-August-27 23:22:32>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines a few constants that are used in the project.
23 | //
24 | // ------------------------------------------------------------------
25 |
26 | using System;
27 |
28 | namespace Ionic.Zip
29 | {
30 | static class ZipConstants
31 | {
32 | public const UInt32 PackedToRemovableMedia = 0x30304b50;
33 | public const UInt32 Zip64EndOfCentralDirectoryRecordSignature = 0x06064b50;
34 | public const UInt32 Zip64EndOfCentralDirectoryLocatorSignature = 0x07064b50;
35 | public const UInt32 EndOfCentralDirectorySignature = 0x06054b50;
36 | public const int ZipEntrySignature = 0x04034b50;
37 | public const int ZipEntryDataDescriptorSignature = 0x08074b50;
38 | public const int SplitArchiveSignature = 0x08074b50;
39 | public const int ZipDirEntrySignature = 0x02014b50;
40 |
41 |
42 | // These are dictated by the Zip Spec.See APPNOTE.txt
43 | public const int AesKeySize = 192; // 128, 192, 256
44 | public const int AesBlockSize = 128; // ???
45 |
46 | public const UInt16 AesAlgId128 = 0x660E;
47 | public const UInt16 AesAlgId192 = 0x660F;
48 | public const UInt16 AesAlgId256 = 0x6610;
49 |
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Zip/ZipCrypto.cs:
--------------------------------------------------------------------------------
1 | // ZipCrypto.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2008, 2009, 2011 Dino Chiesa
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2011-July-28 06:30:59>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module provides the implementation for "traditional" Zip encryption.
23 | //
24 | // Created Tue Apr 15 17:39:56 2008
25 | //
26 | // ------------------------------------------------------------------
27 |
28 | using System;
29 |
30 | namespace Ionic.Zip
31 | {
32 | ///
33 | /// This class implements the "traditional" or "classic" PKZip encryption,
34 | /// which today is considered to be weak. On the other hand it is
35 | /// ubiquitous. This class is intended for use only by the DotNetZip
36 | /// library.
37 | ///
38 | ///
39 | ///
40 | /// Most uses of the DotNetZip library will not involve direct calls into
41 | /// the ZipCrypto class. Instead, the ZipCrypto class is instantiated and
42 | /// used by the ZipEntry() class when encryption or decryption on an entry
43 | /// is employed. If for some reason you really wanted to use a weak
44 | /// encryption algorithm in some other application, you might use this
45 | /// library. But you would be much better off using one of the built-in
46 | /// strong encryption libraries in the .NET Framework, like the AES
47 | /// algorithm or SHA.
48 | ///
49 | internal class ZipCrypto
50 | {
51 | ///
52 | /// The default constructor for ZipCrypto.
53 | ///
54 | ///
55 | ///
56 | /// This class is intended for internal use by the library only. It's
57 | /// probably not useful to you. Seriously. Stop reading this
58 | /// documentation. It's a waste of your time. Go do something else.
59 | /// Check the football scores. Go get an ice cream with a friend.
60 | /// Seriously.
61 | ///
62 | ///
63 | private ZipCrypto() { }
64 |
65 | public static ZipCrypto ForWrite(string password)
66 | {
67 | ZipCrypto z = new ZipCrypto();
68 | if (password == null)
69 | throw new BadPasswordException("This entry requires a password.");
70 | z.InitCipher(password);
71 | return z;
72 | }
73 |
74 |
75 | public static ZipCrypto ForRead(string password, ZipEntry e)
76 | {
77 | System.IO.Stream s = e._archiveStream;
78 | e._WeakEncryptionHeader = new byte[12];
79 | byte[] eh = e._WeakEncryptionHeader;
80 | ZipCrypto z = new ZipCrypto();
81 |
82 | if (password == null)
83 | throw new BadPasswordException("This entry requires a password.");
84 |
85 | z.InitCipher(password);
86 |
87 | ZipEntry.ReadWeakEncryptionHeader(s, eh);
88 |
89 | // Decrypt the header. This has a side effect of "further initializing the
90 | // encryption keys" in the traditional zip encryption.
91 | byte[] DecryptedHeader = z.DecryptMessage(eh, eh.Length);
92 |
93 | // CRC check
94 | // According to the pkzip spec, the final byte in the decrypted header
95 | // is the highest-order byte in the CRC. We check it here.
96 | if (DecryptedHeader[11] != (byte)((e._Crc32 >> 24) & 0xff))
97 | {
98 | // In the case that bit 3 of the general purpose bit flag is set to
99 | // indicate the presence of an 'Extended File Header' or a 'data
100 | // descriptor' (signature 0x08074b50), the last byte of the decrypted
101 | // header is sometimes compared with the high-order byte of the
102 | // lastmodified time, rather than the high-order byte of the CRC, to
103 | // verify the password.
104 | //
105 | // This is not documented in the PKWare Appnote.txt. It was
106 | // discovered this by analysis of the Crypt.c source file in the
107 | // InfoZip library http://www.info-zip.org/pub/infozip/
108 | //
109 | // The reason for this is that the CRC for a file cannot be known
110 | // until the entire contents of the file have been streamed. This
111 | // means a tool would have to read the file content TWICE in its
112 | // entirety in order to perform PKZIP encryption - once to compute
113 | // the CRC, and again to actually encrypt.
114 | //
115 | // This is so important for performance that using the timeblob as
116 | // the verification should be the standard practice for DotNetZip
117 | // when using PKZIP encryption. This implies that bit 3 must be
118 | // set. The downside is that some tools still cannot cope with ZIP
119 | // files that use bit 3. Therefore, DotNetZip DOES NOT force bit 3
120 | // when PKZIP encryption is in use, and instead, reads the stream
121 | // twice.
122 | //
123 |
124 | if ((e._BitField & 0x0008) != 0x0008)
125 | {
126 | throw new BadPasswordException("The password did not match.");
127 | }
128 | else if (DecryptedHeader[11] != (byte)((e._TimeBlob >> 8) & 0xff))
129 | {
130 | throw new BadPasswordException("The password did not match.");
131 | }
132 |
133 | // We have a good password.
134 | }
135 | else
136 | {
137 | // A-OK
138 | }
139 | return z;
140 | }
141 |
142 |
143 |
144 |
145 | ///
146 | /// From AppNote.txt:
147 | /// unsigned char decrypt_byte()
148 | /// local unsigned short temp
149 | /// temp :=- Key(2) | 2
150 | /// decrypt_byte := (temp * (temp ^ 1)) bitshift-right 8
151 | /// end decrypt_byte
152 | ///
153 | private byte MagicByte
154 | {
155 | get
156 | {
157 | UInt16 t = (UInt16)((UInt16)(_Keys[2] & 0xFFFF) | 2);
158 | return (byte)((t * (t ^ 1)) >> 8);
159 | }
160 | }
161 |
162 | // Decrypting:
163 | // From AppNote.txt:
164 | // loop for i from 0 to 11
165 | // C := buffer(i) ^ decrypt_byte()
166 | // update_keys(C)
167 | // buffer(i) := C
168 | // end loop
169 |
170 |
171 | ///
172 | /// Call this method on a cipher text to render the plaintext. You must
173 | /// first initialize the cipher with a call to InitCipher.
174 | ///
175 | ///
176 | ///
177 | ///
178 | /// var cipher = new ZipCrypto();
179 | /// cipher.InitCipher(Password);
180 | /// // Decrypt the header. This has a side effect of "further initializing the
181 | /// // encryption keys" in the traditional zip encryption.
182 | /// byte[] DecryptedMessage = cipher.DecryptMessage(EncryptedMessage);
183 | ///
184 | ///
185 | ///
186 | /// The encrypted buffer.
187 | ///
188 | /// The number of bytes to encrypt.
189 | /// Should be less than or equal to CipherText.Length.
190 | ///
191 | ///
192 | /// The plaintext.
193 | public byte[] DecryptMessage(byte[] cipherText, int length)
194 | {
195 | if (cipherText == null)
196 | throw new ArgumentNullException("cipherText");
197 |
198 | if (length > cipherText.Length)
199 | throw new ArgumentOutOfRangeException("length",
200 | "Bad length during Decryption: the length parameter must be smaller than or equal to the size of the destination array.");
201 |
202 | byte[] plainText = new byte[length];
203 | for (int i = 0; i < length; i++)
204 | {
205 | byte C = (byte)(cipherText[i] ^ MagicByte);
206 | UpdateKeys(C);
207 | plainText[i] = C;
208 | }
209 | return plainText;
210 | }
211 |
212 | ///
213 | /// This is the converse of DecryptMessage. It encrypts the plaintext
214 | /// and produces a ciphertext.
215 | ///
216 | ///
217 | /// The plain text buffer.
218 | ///
219 | ///
220 | /// The number of bytes to encrypt.
221 | /// Should be less than or equal to plainText.Length.
222 | ///
223 | ///
224 | /// The ciphertext.
225 | public byte[] EncryptMessage(byte[] plainText, int length)
226 | {
227 | if (plainText == null)
228 | throw new ArgumentNullException("plaintext");
229 |
230 | if (length > plainText.Length)
231 | throw new ArgumentOutOfRangeException("length",
232 | "Bad length during Encryption: The length parameter must be smaller than or equal to the size of the destination array.");
233 |
234 | byte[] cipherText = new byte[length];
235 | for (int i = 0; i < length; i++)
236 | {
237 | byte C = plainText[i];
238 | cipherText[i] = (byte)(plainText[i] ^ MagicByte);
239 | UpdateKeys(C);
240 | }
241 | return cipherText;
242 | }
243 |
244 |
245 | ///
246 | /// This initializes the cipher with the given password.
247 | /// See AppNote.txt for details.
248 | ///
249 | ///
250 | ///
251 | /// The passphrase for encrypting or decrypting with this cipher.
252 | ///
253 | ///
254 | ///
255 | ///
256 | /// Step 1 - Initializing the encryption keys
257 | /// -----------------------------------------
258 | /// Start with these keys:
259 | /// Key(0) := 305419896 (0x12345678)
260 | /// Key(1) := 591751049 (0x23456789)
261 | /// Key(2) := 878082192 (0x34567890)
262 | ///
263 | /// Then, initialize the keys with a password:
264 | ///
265 | /// loop for i from 0 to length(password)-1
266 | /// update_keys(password(i))
267 | /// end loop
268 | ///
269 | /// Where update_keys() is defined as:
270 | ///
271 | /// update_keys(char):
272 | /// Key(0) := crc32(key(0),char)
273 | /// Key(1) := Key(1) + (Key(0) bitwiseAND 000000ffH)
274 | /// Key(1) := Key(1) * 134775813 + 1
275 | /// Key(2) := crc32(key(2),key(1) rightshift 24)
276 | /// end update_keys
277 | ///
278 | /// Where crc32(old_crc,char) is a routine that given a CRC value and a
279 | /// character, returns an updated CRC value after applying the CRC-32
280 | /// algorithm described elsewhere in this document.
281 | ///
282 | ///
283 | ///
284 | ///
285 | /// After the keys are initialized, then you can use the cipher to
286 | /// encrypt the plaintext.
287 | ///
288 | ///
289 | ///
290 | /// Essentially we encrypt the password with the keys, then discard the
291 | /// ciphertext for the password. This initializes the keys for later use.
292 | ///
293 | ///
294 | ///
295 | public void InitCipher(string passphrase)
296 | {
297 | byte[] p = SharedUtilities.StringToByteArray(passphrase);
298 | for (int i = 0; i < passphrase.Length; i++)
299 | UpdateKeys(p[i]);
300 | }
301 |
302 |
303 | private void UpdateKeys(byte byteValue)
304 | {
305 | _Keys[0] = (UInt32)crc32.ComputeCrc32((int)_Keys[0], byteValue);
306 | _Keys[1] = _Keys[1] + (byte)_Keys[0];
307 | _Keys[1] = _Keys[1] * 0x08088405 + 1;
308 | _Keys[2] = (UInt32)crc32.ComputeCrc32((int)_Keys[2], (byte)(_Keys[1] >> 24));
309 | }
310 |
311 | /////
312 | ///// The byte array representing the seed keys used.
313 | ///// Get this after calling InitCipher. The 12 bytes represents
314 | ///// what the zip spec calls the "EncryptionHeader".
315 | /////
316 | //public byte[] KeyHeader
317 | //{
318 | // get
319 | // {
320 | // byte[] result = new byte[12];
321 | // result[0] = (byte)(_Keys[0] & 0xff);
322 | // result[1] = (byte)((_Keys[0] >> 8) & 0xff);
323 | // result[2] = (byte)((_Keys[0] >> 16) & 0xff);
324 | // result[3] = (byte)((_Keys[0] >> 24) & 0xff);
325 | // result[4] = (byte)(_Keys[1] & 0xff);
326 | // result[5] = (byte)((_Keys[1] >> 8) & 0xff);
327 | // result[6] = (byte)((_Keys[1] >> 16) & 0xff);
328 | // result[7] = (byte)((_Keys[1] >> 24) & 0xff);
329 | // result[8] = (byte)(_Keys[2] & 0xff);
330 | // result[9] = (byte)((_Keys[2] >> 8) & 0xff);
331 | // result[10] = (byte)((_Keys[2] >> 16) & 0xff);
332 | // result[11] = (byte)((_Keys[2] >> 24) & 0xff);
333 | // return result;
334 | // }
335 | //}
336 |
337 | // private fields for the crypto stuff:
338 | private UInt32[] _Keys = { 0x12345678, 0x23456789, 0x34567890 };
339 | private Ionic.Crc.CRC32 crc32 = new Ionic.Crc.CRC32();
340 |
341 | }
342 |
343 | internal enum CryptoMode
344 | {
345 | Encrypt,
346 | Decrypt
347 | }
348 |
349 | ///
350 | /// A Stream for reading and concurrently decrypting data from a zip file,
351 | /// or for writing and concurrently encrypting data to a zip file.
352 | ///
353 | internal class ZipCipherStream : System.IO.Stream
354 | {
355 | private ZipCrypto _cipher;
356 | private System.IO.Stream _s;
357 | private CryptoMode _mode;
358 |
359 | /// The constructor.
360 | /// The underlying stream
361 | /// To either encrypt or decrypt.
362 | /// The pre-initialized ZipCrypto object.
363 | public ZipCipherStream(System.IO.Stream s, ZipCrypto cipher, CryptoMode mode)
364 | : base()
365 | {
366 | _cipher = cipher;
367 | _s = s;
368 | _mode = mode;
369 | }
370 |
371 | public override int Read(byte[] buffer, int offset, int count)
372 | {
373 | if (_mode == CryptoMode.Encrypt)
374 | throw new NotSupportedException("This stream does not encrypt via Read()");
375 |
376 | if (buffer == null)
377 | throw new ArgumentNullException("buffer");
378 |
379 | byte[] db = new byte[count];
380 | int n = _s.Read(db, 0, count);
381 | byte[] decrypted = _cipher.DecryptMessage(db, n);
382 | for (int i = 0; i < n; i++)
383 | {
384 | buffer[offset + i] = decrypted[i];
385 | }
386 | return n;
387 | }
388 |
389 | public override void Write(byte[] buffer, int offset, int count)
390 | {
391 | if (_mode == CryptoMode.Decrypt)
392 | throw new NotSupportedException("This stream does not Decrypt via Write()");
393 |
394 | if (buffer == null)
395 | throw new ArgumentNullException("buffer");
396 |
397 | // workitem 7696
398 | if (count == 0) return;
399 |
400 | byte[] plaintext = null;
401 | if (offset != 0)
402 | {
403 | plaintext = new byte[count];
404 | for (int i = 0; i < count; i++)
405 | {
406 | plaintext[i] = buffer[offset + i];
407 | }
408 | }
409 | else plaintext = buffer;
410 |
411 | byte[] encrypted = _cipher.EncryptMessage(plaintext, count);
412 | _s.Write(encrypted, 0, encrypted.Length);
413 | }
414 |
415 |
416 | public override bool CanRead
417 | {
418 | get { return (_mode == CryptoMode.Decrypt); }
419 | }
420 | public override bool CanSeek
421 | {
422 | get { return false; }
423 | }
424 |
425 | public override bool CanWrite
426 | {
427 | get { return (_mode == CryptoMode.Encrypt); }
428 | }
429 |
430 | public override void Flush()
431 | {
432 | //throw new NotSupportedException();
433 | }
434 |
435 | public override long Length
436 | {
437 | get { throw new NotSupportedException(); }
438 | }
439 |
440 | public override long Position
441 | {
442 | get { throw new NotSupportedException(); }
443 | set { throw new NotSupportedException(); }
444 | }
445 | public override long Seek(long offset, System.IO.SeekOrigin origin)
446 | {
447 | throw new NotSupportedException();
448 | }
449 |
450 | public override void SetLength(long value)
451 | {
452 | throw new NotSupportedException();
453 | }
454 | }
455 | }
456 |
--------------------------------------------------------------------------------
/Zip/ZipDirEntry.cs:
--------------------------------------------------------------------------------
1 | // ZipDirEntry.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2006-2011 Dino Chiesa .
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2011-July-11 12:03:03>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines members of the ZipEntry class for reading the
23 | // Zip file central directory.
24 | //
25 | // Created: Tue, 27 Mar 2007 15:30
26 | //
27 | // ------------------------------------------------------------------
28 |
29 |
30 | using System;
31 | using System.Collections.Generic;
32 |
33 | namespace Ionic.Zip
34 | {
35 |
36 | partial class ZipEntry
37 | {
38 | ///
39 | /// True if the referenced entry is a directory.
40 | ///
41 | internal bool AttributesIndicateDirectory
42 | {
43 | get { return ((_InternalFileAttrs == 0) && ((_ExternalFileAttrs & 0x0010) == 0x0010)); }
44 | }
45 |
46 |
47 | internal void ResetDirEntry()
48 | {
49 | // __FileDataPosition is the position of the file data for an entry.
50 | // It is _RelativeOffsetOfLocalHeader + size of local header.
51 |
52 | // We cannot know the __FileDataPosition until we read the local
53 | // header.
54 |
55 | // The local header is not necessarily the same length as the record
56 | // in the central directory.
57 |
58 | // Set to -1, to indicate we need to read this later.
59 | this.__FileDataPosition = -1;
60 |
61 | // set _LengthOfHeader to 0, to indicate we need to read later.
62 | this._LengthOfHeader = 0;
63 | }
64 |
65 | ///
66 | /// Provides a human-readable string with information about the ZipEntry.
67 | ///
68 | public string Info
69 | {
70 | get
71 | {
72 | var builder = new System.Text.StringBuilder();
73 | builder
74 | .Append(string.Format(" ZipEntry: {0}\n", this.FileName))
75 | .Append(string.Format(" Version Made By: {0}\n", this._VersionMadeBy))
76 | .Append(string.Format(" Needed to extract: {0}\n", this.VersionNeeded));
77 |
78 | if (this._IsDirectory)
79 | builder.Append(" Entry type: directory\n");
80 | else
81 | {
82 | builder.Append(string.Format(" File type: {0}\n", this._IsText? "text":"binary"))
83 | .Append(string.Format(" Compression: {0}\n", this.CompressionMethod))
84 | .Append(string.Format(" Compressed: 0x{0:X}\n", this.CompressedSize))
85 | .Append(string.Format(" Uncompressed: 0x{0:X}\n", this.UncompressedSize))
86 | .Append(string.Format(" CRC32: 0x{0:X8}\n", this._Crc32));
87 | }
88 | builder.Append(string.Format(" Disk Number: {0}\n", this._diskNumber));
89 | if (this._RelativeOffsetOfLocalHeader > 0xFFFFFFFF)
90 | builder
91 | .Append(string.Format(" Relative Offset: 0x{0:X16}\n", this._RelativeOffsetOfLocalHeader));
92 | else
93 | builder
94 | .Append(string.Format(" Relative Offset: 0x{0:X8}\n", this._RelativeOffsetOfLocalHeader));
95 |
96 | builder
97 | .Append(string.Format(" Bit Field: 0x{0:X4}\n", this._BitField))
98 | .Append(string.Format(" Encrypted?: {0}\n", this._sourceIsEncrypted))
99 | .Append(string.Format(" Timeblob: 0x{0:X8}\n", this._TimeBlob))
100 | .Append(string.Format(" Time: {0}\n", Ionic.Zip.SharedUtilities.PackedToDateTime(this._TimeBlob)));
101 |
102 | builder.Append(string.Format(" Is Zip64?: {0}\n", this._InputUsesZip64));
103 | if (!string.IsNullOrEmpty(this._Comment))
104 | {
105 | builder.Append(string.Format(" Comment: {0}\n", this._Comment));
106 | }
107 | builder.Append("\n");
108 | return builder.ToString();
109 | }
110 | }
111 |
112 |
113 | // workitem 10330
114 | private class CopyHelper
115 | {
116 | private static System.Text.RegularExpressions.Regex re =
117 | new System.Text.RegularExpressions.Regex(" \\(copy (\\d+)\\)$");
118 |
119 | private static int callCount = 0;
120 |
121 | internal static string AppendCopyToFileName(string f)
122 | {
123 | callCount++;
124 | if (callCount > 25)
125 | throw new OverflowException("overflow while creating filename");
126 |
127 | int n = 1;
128 | int r = f.LastIndexOf(".");
129 |
130 | if (r == -1)
131 | {
132 | // there is no extension
133 | System.Text.RegularExpressions.Match m = re.Match(f);
134 | if (m.Success)
135 | {
136 | n = Int32.Parse(m.Groups[1].Value) + 1;
137 | string copy = String.Format(" (copy {0})", n);
138 | f = f.Substring(0, m.Index) + copy;
139 | }
140 | else
141 | {
142 | string copy = String.Format(" (copy {0})", n);
143 | f = f + copy;
144 | }
145 | }
146 | else
147 | {
148 | //System.Console.WriteLine("HasExtension");
149 | System.Text.RegularExpressions.Match m = re.Match(f.Substring(0, r));
150 | if (m.Success)
151 | {
152 | n = Int32.Parse(m.Groups[1].Value) + 1;
153 | string copy = String.Format(" (copy {0})", n);
154 | f = f.Substring(0, m.Index) + copy + f.Substring(r);
155 | }
156 | else
157 | {
158 | string copy = String.Format(" (copy {0})", n);
159 | f = f.Substring(0, r) + copy + f.Substring(r);
160 | }
161 |
162 | //System.Console.WriteLine("returning f({0})", f);
163 | }
164 | return f;
165 | }
166 | }
167 |
168 |
169 |
170 | ///
171 | /// Reads one entry from the zip directory structure in the zip file.
172 | ///
173 | ///
174 | ///
175 | /// The zipfile for which a directory entry will be read. From this param, the
176 | /// method gets the ReadStream and the expected text encoding
177 | /// (ProvisionalAlternateEncoding) which is used if the entry is not marked
178 | /// UTF-8.
179 | ///
180 | ///
181 | ///
182 | /// a list of previously seen entry names; used to prevent duplicates.
183 | ///
184 | ///
185 | /// the entry read from the archive.
186 | internal static ZipEntry ReadDirEntry(ZipFile zf,
187 | Dictionary previouslySeen)
188 | {
189 | System.IO.Stream s = zf.ReadStream;
190 | System.Text.Encoding expectedEncoding = (zf.AlternateEncodingUsage == ZipOption.Always)
191 | ? zf.AlternateEncoding
192 | : ZipFile.DefaultEncoding;
193 |
194 | int signature = Ionic.Zip.SharedUtilities.ReadSignature(s);
195 | // return null if this is not a local file header signature
196 | if (IsNotValidZipDirEntrySig(signature))
197 | {
198 | s.Seek(-4, System.IO.SeekOrigin.Current);
199 | // workitem 10178
200 | Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
201 |
202 | // Getting "not a ZipDirEntry signature" here is not always wrong or an
203 | // error. This can happen when walking through a zipfile. After the
204 | // last ZipDirEntry, we expect to read an
205 | // EndOfCentralDirectorySignature. When we get this is how we know
206 | // we've reached the end of the central directory.
207 | if (signature != ZipConstants.EndOfCentralDirectorySignature &&
208 | signature != ZipConstants.Zip64EndOfCentralDirectoryRecordSignature &&
209 | signature != ZipConstants.ZipEntrySignature // workitem 8299
210 | )
211 | {
212 | throw new BadReadException(String.Format(" Bad signature (0x{0:X8}) at position 0x{1:X8}", signature, s.Position));
213 | }
214 | return null;
215 | }
216 |
217 | int bytesRead = 42 + 4;
218 | byte[] block = new byte[42];
219 | int n = s.Read(block, 0, block.Length);
220 | if (n != block.Length) return null;
221 |
222 | int i = 0;
223 | ZipEntry zde = new ZipEntry();
224 | zde.AlternateEncoding = expectedEncoding;
225 | zde._Source = ZipEntrySource.ZipFile;
226 | zde._container = new ZipContainer(zf);
227 |
228 | unchecked
229 | {
230 | zde._VersionMadeBy = (short)(block[i++] + block[i++] * 256);
231 | zde._VersionNeeded = (short)(block[i++] + block[i++] * 256);
232 | zde._BitField = (short)(block[i++] + block[i++] * 256);
233 | zde._CompressionMethod = (Int16)(block[i++] + block[i++] * 256);
234 | zde._TimeBlob = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256;
235 | zde._LastModified = Ionic.Zip.SharedUtilities.PackedToDateTime(zde._TimeBlob);
236 | zde._timestamp |= ZipEntryTimestamp.DOS;
237 |
238 | zde._Crc32 = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256;
239 | zde._CompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
240 | zde._UncompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
241 | }
242 |
243 | // preserve
244 | zde._CompressionMethod_FromZipFile = zde._CompressionMethod;
245 |
246 | zde._filenameLength = (short)(block[i++] + block[i++] * 256);
247 | zde._extraFieldLength = (short)(block[i++] + block[i++] * 256);
248 | zde._commentLength = (short)(block[i++] + block[i++] * 256);
249 | zde._diskNumber = (UInt32)(block[i++] + block[i++] * 256);
250 |
251 | zde._InternalFileAttrs = (short)(block[i++] + block[i++] * 256);
252 | zde._ExternalFileAttrs = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256;
253 |
254 | zde._RelativeOffsetOfLocalHeader = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
255 |
256 | // workitem 7801
257 | zde.IsText = ((zde._InternalFileAttrs & 0x01) == 0x01);
258 |
259 | block = new byte[zde._filenameLength];
260 | n = s.Read(block, 0, block.Length);
261 | bytesRead += n;
262 | if ((zde._BitField & 0x0800) == 0x0800)
263 | {
264 | // UTF-8 is in use
265 | zde._FileNameInArchive = Ionic.Zip.SharedUtilities.Utf8StringFromBuffer(block);
266 | }
267 | else
268 | {
269 | zde._FileNameInArchive = Ionic.Zip.SharedUtilities.StringFromBuffer(block, expectedEncoding);
270 | }
271 |
272 | // workitem 10330
273 | // insure unique entry names
274 | while (previouslySeen.ContainsKey(zde._FileNameInArchive))
275 | {
276 | zde._FileNameInArchive = CopyHelper.AppendCopyToFileName(zde._FileNameInArchive);
277 | zde._metadataChanged = true;
278 | }
279 |
280 | if (zde.AttributesIndicateDirectory)
281 | zde.MarkAsDirectory(); // may append a slash to filename if nec.
282 | // workitem 6898
283 | else if (zde._FileNameInArchive.EndsWith("/")) zde.MarkAsDirectory();
284 |
285 | zde._CompressedFileDataSize = zde._CompressedSize;
286 | if ((zde._BitField & 0x01) == 0x01)
287 | {
288 | // this may change after processing the Extra field
289 | zde._Encryption_FromZipFile = zde._Encryption =
290 | EncryptionAlgorithm.PkzipWeak;
291 | zde._sourceIsEncrypted = true;
292 | }
293 |
294 | if (zde._extraFieldLength > 0)
295 | {
296 | zde._InputUsesZip64 = (zde._CompressedSize == 0xFFFFFFFF ||
297 | zde._UncompressedSize == 0xFFFFFFFF ||
298 | zde._RelativeOffsetOfLocalHeader == 0xFFFFFFFF);
299 |
300 | // Console.WriteLine(" Input uses Z64?: {0}", zde._InputUsesZip64);
301 |
302 | bytesRead += zde.ProcessExtraField(s, zde._extraFieldLength);
303 | zde._CompressedFileDataSize = zde._CompressedSize;
304 | }
305 |
306 | // we've processed the extra field, so we know the encryption method is set now.
307 | if (zde._Encryption == EncryptionAlgorithm.PkzipWeak)
308 | {
309 | // the "encryption header" of 12 bytes precedes the file data
310 | zde._CompressedFileDataSize -= 12;
311 | }
312 | #if AESCRYPTO
313 | else if (zde.Encryption == EncryptionAlgorithm.WinZipAes128 ||
314 | zde.Encryption == EncryptionAlgorithm.WinZipAes256)
315 | {
316 | zde._CompressedFileDataSize = zde.CompressedSize -
317 | (ZipEntry.GetLengthOfCryptoHeaderBytes(zde.Encryption) + 10);
318 | zde._LengthOfTrailer = 10;
319 | }
320 | #endif
321 |
322 | // tally the trailing descriptor
323 | if ((zde._BitField & 0x0008) == 0x0008)
324 | {
325 | // sig, CRC, Comp and Uncomp sizes
326 | if (zde._InputUsesZip64)
327 | zde._LengthOfTrailer += 24;
328 | else
329 | zde._LengthOfTrailer += 16;
330 | }
331 |
332 | // workitem 12744
333 | zde.AlternateEncoding = ((zde._BitField & 0x0800) == 0x0800)
334 | ? System.Text.Encoding.UTF8
335 | :expectedEncoding;
336 |
337 | zde.AlternateEncodingUsage = ZipOption.Always;
338 |
339 | if (zde._commentLength > 0)
340 | {
341 | block = new byte[zde._commentLength];
342 | n = s.Read(block, 0, block.Length);
343 | bytesRead += n;
344 | if ((zde._BitField & 0x0800) == 0x0800)
345 | {
346 | // UTF-8 is in use
347 | zde._Comment = Ionic.Zip.SharedUtilities.Utf8StringFromBuffer(block);
348 | }
349 | else
350 | {
351 | zde._Comment = Ionic.Zip.SharedUtilities.StringFromBuffer(block, expectedEncoding);
352 | }
353 | }
354 | //zde._LengthOfDirEntry = bytesRead;
355 | return zde;
356 | }
357 |
358 |
359 | ///
360 | /// Returns true if the passed-in value is a valid signature for a ZipDirEntry.
361 | ///
362 | /// the candidate 4-byte signature value.
363 | /// true, if the signature is valid according to the PKWare spec.
364 | internal static bool IsNotValidZipDirEntrySig(int signature)
365 | {
366 | return (signature != ZipConstants.ZipDirEntrySignature);
367 | }
368 |
369 |
370 | private Int16 _VersionMadeBy;
371 | private Int16 _InternalFileAttrs;
372 | private Int32 _ExternalFileAttrs;
373 |
374 | //private Int32 _LengthOfDirEntry;
375 | private Int16 _filenameLength;
376 | private Int16 _extraFieldLength;
377 | private Int16 _commentLength;
378 | }
379 |
380 |
381 | }
382 |
--------------------------------------------------------------------------------
/Zip/ZipEntrySource.cs:
--------------------------------------------------------------------------------
1 | // ZipEntrySource.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2009 Dino Chiesa
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2009-November-19 11:18:42>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 |
23 | namespace Ionic.Zip
24 | {
25 | ///
26 | /// An enum that specifies the source of the ZipEntry.
27 | ///
28 | public enum ZipEntrySource
29 | {
30 | ///
31 | /// Default value. Invalid on a bonafide ZipEntry.
32 | ///
33 | None = 0,
34 |
35 | ///
36 | /// The entry was instantiated by calling AddFile() or another method that
37 | /// added an entry from the filesystem.
38 | ///
39 | FileSystem,
40 |
41 | ///
42 | /// The entry was instantiated via or
43 | /// .
44 | ///
45 | Stream,
46 |
47 | ///
48 | /// The ZipEntry was instantiated by reading a zipfile.
49 | ///
50 | ZipFile,
51 |
52 | ///
53 | /// The content for the ZipEntry will be or was provided by the WriteDelegate.
54 | ///
55 | WriteDelegate,
56 |
57 | ///
58 | /// The content for the ZipEntry will be obtained from the stream dispensed by the OpenDelegate.
59 | /// The entry was instantiated via .
60 | ///
61 | JitStream,
62 |
63 | ///
64 | /// The content for the ZipEntry will be or was obtained from a ZipOutputStream.
65 | ///
66 | ZipOutputStream,
67 | }
68 |
69 | }
--------------------------------------------------------------------------------
/Zip/ZipErrorAction.cs:
--------------------------------------------------------------------------------
1 | // ZipErrorAction.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2009 Dino Chiesa
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2009-September-01 18:43:20>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines the ZipErrorAction enum, which provides
23 | // an action to take when errors occur when opening or reading
24 | // files to be added to a zip file.
25 | //
26 | // ------------------------------------------------------------------
27 |
28 |
29 | namespace Ionic.Zip
30 | {
31 | ///
32 | /// An enum providing the options when an error occurs during opening or reading
33 | /// of a file or directory that is being saved to a zip file.
34 | ///
35 | ///
36 | ///
37 | ///
38 | /// This enum describes the actions that the library can take when an error occurs
39 | /// opening or reading a file, as it is being saved into a Zip archive.
40 | ///
41 | ///
42 | ///
43 | /// In some cases an error will occur when DotNetZip tries to open a file to be
44 | /// added to the zip archive. In other cases, an error might occur after the
45 | /// file has been successfully opened, while DotNetZip is reading the file.
46 | ///
47 | ///
48 | ///
49 | /// The first problem might occur when calling AddDirectory() on a directory
50 | /// that contains a Clipper .dbf file; the file is locked by Clipper and
51 | /// cannot be opened by another process. An example of the second problem is
52 | /// the ERROR_LOCK_VIOLATION that results when a file is opened by another
53 | /// process, but not locked, and a range lock has been taken on the file.
54 | /// Microsoft Outlook takes range locks on .PST files.
55 | ///
56 | ///
57 | public enum ZipErrorAction
58 | {
59 | ///
60 | /// Throw an exception when an error occurs while zipping. This is the default
61 | /// behavior. (For COM clients, this is a 0 (zero).)
62 | ///
63 | Throw,
64 |
65 | ///
66 | /// When an error occurs during zipping, for example a file cannot be opened,
67 | /// skip the file causing the error, and continue zipping. (For COM clients,
68 | /// this is a 1.)
69 | ///
70 | Skip,
71 |
72 | ///
73 | /// When an error occurs during zipping, for example a file cannot be opened,
74 | /// retry the operation that caused the error. Be careful with this option. If
75 | /// the error is not temporary, the library will retry forever. (For COM
76 | /// clients, this is a 2.)
77 | ///
78 | Retry,
79 |
80 | ///
81 | /// When an error occurs, invoke the zipError event. The event type used is
82 | /// . A typical use of this option:
83 | /// a GUI application may wish to pop up a dialog to allow the user to view the
84 | /// error that occurred, and choose an appropriate action. After your
85 | /// processing in the error event, if you want to skip the file, set on the
87 | /// ZipProgressEventArgs.CurrentEntry to Skip. If you want the
88 | /// exception to be thrown, set ZipErrorAction on the CurrentEntry
89 | /// to Throw. If you want to cancel the zip, set
90 | /// ZipProgressEventArgs.Cancel to true. Cancelling differs from using
91 | /// Skip in that a cancel will not save any further entries, if there are any.
92 | /// (For COM clients, the value of this enum is a 3.)
93 | ///
94 | InvokeErrorEvent,
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/Zip/ZipFile.Check.cs:
--------------------------------------------------------------------------------
1 | // ZipFile.Check.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2009-2011 Dino Chiesa.
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2011-July-31 14:40:50>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines the methods for doing Checks on zip files.
23 | // These are not necessary to include in the Reduced or CF
24 | // version of the library.
25 | //
26 | // ------------------------------------------------------------------
27 | //
28 |
29 |
30 | using System;
31 | using System.IO;
32 | using System.Collections.Generic;
33 |
34 | namespace Ionic.Zip
35 | {
36 | public partial class ZipFile
37 | {
38 | ///
39 | /// Checks a zip file to see if its directory is consistent.
40 | ///
41 | ///
42 | ///
43 | ///
44 | ///
45 | /// In cases of data error, the directory within a zip file can get out
46 | /// of synch with the entries in the zip file. This method checks the
47 | /// given zip file and returns true if this has occurred.
48 | ///
49 | ///
50 | /// This method may take a long time to run for large zip files.
51 | ///
52 | ///
53 | /// This method is not supported in the Reduced or Compact Framework
54 | /// versions of DotNetZip.
55 | ///
56 | ///
57 | ///
58 | /// Developers using COM can use the ComHelper.CheckZip(String)
60 | /// method.
61 | ///
62 | ///
63 | ///
64 | ///
65 | /// The filename to of the zip file to check.
66 | ///
67 | /// true if the named zip file checks OK. Otherwise, false.
68 | ///
69 | ///
70 | ///
71 | public static bool CheckZip(string zipFileName)
72 | {
73 | return CheckZip(zipFileName, false, null);
74 | }
75 |
76 |
77 | ///
78 | /// Checks a zip file to see if its directory is consistent,
79 | /// and optionally fixes the directory if necessary.
80 | ///
81 | ///
82 | ///
83 | ///
84 | ///
85 | /// In cases of data error, the directory within a zip file can get out of
86 | /// synch with the entries in the zip file. This method checks the given
87 | /// zip file, and returns true if this has occurred. It also optionally
88 | /// fixes the zipfile, saving the fixed copy in Name_Fixed.zip.
89 | ///
90 | ///
91 | ///
92 | /// This method may take a long time to run for large zip files. It
93 | /// will take even longer if the file actually needs to be fixed, and if
94 | /// fixIfNecessary is true.
95 | ///
96 | ///
97 | ///
98 | /// This method is not supported in the Reduced or Compact
99 | /// Framework versions of DotNetZip.
100 | ///
101 | ///
102 | ///
103 | ///
104 | /// The filename to of the zip file to check.
105 | ///
106 | /// If true, the method will fix the zip file if
107 | /// necessary.
108 | ///
109 | ///
110 | /// a TextWriter in which messages generated while checking will be written.
111 | ///
112 | ///
113 | /// true if the named zip is OK; false if the file needs to be fixed.
114 | ///
115 | ///
116 | ///
117 | public static bool CheckZip(string zipFileName, bool fixIfNecessary,
118 | TextWriter writer)
119 |
120 | {
121 | ZipFile zip1 = null, zip2 = null;
122 | bool isOk = true;
123 | try
124 | {
125 | zip1 = new ZipFile();
126 | zip1.FullScan = true;
127 | zip1.Initialize(zipFileName);
128 |
129 | zip2 = ZipFile.Read(zipFileName);
130 |
131 | foreach (var e1 in zip1)
132 | {
133 | foreach (var e2 in zip2)
134 | {
135 | if (e1.FileName == e2.FileName)
136 | {
137 | if (e1._RelativeOffsetOfLocalHeader != e2._RelativeOffsetOfLocalHeader)
138 | {
139 | isOk = false;
140 | if (writer != null)
141 | writer.WriteLine("{0}: mismatch in RelativeOffsetOfLocalHeader (0x{1:X16} != 0x{2:X16})",
142 | e1.FileName, e1._RelativeOffsetOfLocalHeader,
143 | e2._RelativeOffsetOfLocalHeader);
144 | }
145 | if (e1._CompressedSize != e2._CompressedSize)
146 | {
147 | isOk = false;
148 | if (writer != null)
149 | writer.WriteLine("{0}: mismatch in CompressedSize (0x{1:X16} != 0x{2:X16})",
150 | e1.FileName, e1._CompressedSize,
151 | e2._CompressedSize);
152 | }
153 | if (e1._UncompressedSize != e2._UncompressedSize)
154 | {
155 | isOk = false;
156 | if (writer != null)
157 | writer.WriteLine("{0}: mismatch in UncompressedSize (0x{1:X16} != 0x{2:X16})",
158 | e1.FileName, e1._UncompressedSize,
159 | e2._UncompressedSize);
160 | }
161 | if (e1.CompressionMethod != e2.CompressionMethod)
162 | {
163 | isOk = false;
164 | if (writer != null)
165 | writer.WriteLine("{0}: mismatch in CompressionMethod (0x{1:X4} != 0x{2:X4})",
166 | e1.FileName, e1.CompressionMethod,
167 | e2.CompressionMethod);
168 | }
169 | if (e1.Crc != e2.Crc)
170 | {
171 | isOk = false;
172 | if (writer != null)
173 | writer.WriteLine("{0}: mismatch in Crc32 (0x{1:X4} != 0x{2:X4})",
174 | e1.FileName, e1.Crc,
175 | e2.Crc);
176 | }
177 |
178 | // found a match, so stop the inside loop
179 | break;
180 | }
181 | }
182 | }
183 |
184 | zip2.Dispose();
185 | zip2 = null;
186 |
187 | if (!isOk && fixIfNecessary)
188 | {
189 | string newFileName = Path.GetFileNameWithoutExtension(zipFileName);
190 | newFileName = System.String.Format("{0}_fixed.zip", newFileName);
191 | zip1.Save(newFileName);
192 | }
193 | }
194 | finally
195 | {
196 | if (zip1 != null) zip1.Dispose();
197 | if (zip2 != null) zip2.Dispose();
198 | }
199 | return isOk;
200 | }
201 |
202 |
203 |
204 | ///
205 | /// Rewrite the directory within a zipfile.
206 | ///
207 | ///
208 | ///
209 | ///
210 | ///
211 | /// In cases of data error, the directory in a zip file can get out of
212 | /// synch with the entries in the zip file. This method attempts to fix
213 | /// the zip file if this has occurred.
214 | ///
215 | ///
216 | /// This can take a long time for large zip files.
217 | ///
218 | /// This won't work if the zip file uses a non-standard
219 | /// code page - neither IBM437 nor UTF-8.
220 | ///
221 | ///
222 | /// This method is not supported in the Reduced or Compact Framework
223 | /// versions of DotNetZip.
224 | ///
225 | ///
226 | ///
227 | /// Developers using COM can use the ComHelper.FixZipDirectory(String)
229 | /// method.
230 | ///
231 | ///
232 | ///
233 | ///
234 | /// The filename to of the zip file to fix.
235 | ///
236 | ///
237 | ///
238 | public static void FixZipDirectory(string zipFileName)
239 | {
240 | using (var zip = new ZipFile())
241 | {
242 | zip.FullScan = true;
243 | zip.Initialize(zipFileName);
244 | zip.Save(zipFileName);
245 | }
246 | }
247 |
248 |
249 |
250 | ///
251 | /// Verify the password on a zip file.
252 | ///
253 | ///
254 | ///
255 | ///
256 | /// Keep in mind that passwords in zipfiles are applied to
257 | /// zip entries, not to the entire zip file. So testing a
258 | /// zipfile for a particular password doesn't work in the
259 | /// general case. On the other hand, it's often the case
260 | /// that a single password will be used on all entries in a
261 | /// zip file. This method works for that case.
262 | ///
263 | ///
264 | /// There is no way to check a password without doing the
265 | /// decryption. So this code decrypts and extracts the given
266 | /// zipfile into
267 | ///
268 | ///
269 | ///
270 | /// The filename to of the zip file to fix.
271 | ///
272 | /// The password to check.
273 | ///
274 | /// a bool indicating whether the password matches.
275 | public static bool CheckZipPassword(string zipFileName, string password)
276 | {
277 | // workitem 13664
278 | bool success = false;
279 | try
280 | {
281 | using (ZipFile zip1 = ZipFile.Read(zipFileName))
282 | {
283 | foreach (var e in zip1)
284 | {
285 | if (!e.IsDirectory && e.UsesEncryption)
286 | {
287 | e.ExtractWithPassword(System.IO.Stream.Null, password);
288 | }
289 | }
290 | }
291 | success = true;
292 | }
293 | catch(Ionic.Zip.BadPasswordException) { }
294 | return success;
295 | }
296 |
297 |
298 | ///
299 | /// Provides a human-readable string with information about the ZipFile.
300 | ///
301 | ///
302 | ///
303 | ///
304 | /// The information string contains 10 lines or so, about each ZipEntry,
305 | /// describing whether encryption is in use, the compressed and uncompressed
306 | /// length of the entry, the offset of the entry, and so on. As a result the
307 | /// information string can be very long for zip files that contain many
308 | /// entries.
309 | ///
310 | ///
311 | /// This information is mostly useful for diagnostic purposes.
312 | ///
313 | ///
314 | public string Info
315 | {
316 | get
317 | {
318 | var builder = new System.Text.StringBuilder();
319 | builder.Append(string.Format(" ZipFile: {0}\n", this.Name));
320 | if (!string.IsNullOrEmpty(this._Comment))
321 | {
322 | builder.Append(string.Format(" Comment: {0}\n", this._Comment));
323 | }
324 | if (this._versionMadeBy != 0)
325 | {
326 | builder.Append(string.Format(" version made by: 0x{0:X4}\n", this._versionMadeBy));
327 | }
328 | if (this._versionNeededToExtract != 0)
329 | {
330 | builder.Append(string.Format("needed to extract: 0x{0:X4}\n", this._versionNeededToExtract));
331 | }
332 |
333 | builder.Append(string.Format(" uses ZIP64: {0}\n", this.InputUsesZip64));
334 |
335 | builder.Append(string.Format(" disk with CD: {0}\n", this._diskNumberWithCd));
336 | if (this._OffsetOfCentralDirectory == 0xFFFFFFFF)
337 | builder.Append(string.Format(" CD64 offset: 0x{0:X16}\n", this._OffsetOfCentralDirectory64));
338 | else
339 | builder.Append(string.Format(" CD offset: 0x{0:X8}\n", this._OffsetOfCentralDirectory));
340 | builder.Append("\n");
341 | foreach (ZipEntry entry in this._entries.Values)
342 | {
343 | builder.Append(entry.Info);
344 | }
345 | return builder.ToString();
346 | }
347 | }
348 |
349 |
350 | }
351 |
352 | }
--------------------------------------------------------------------------------
/Zip/ZipFile.Extract.cs:
--------------------------------------------------------------------------------
1 | // ZipFile.Extract.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2009 Dino Chiesa.
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2011-July-31 14:45:18>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines the methods for Extract operations on zip files.
23 | //
24 | // ------------------------------------------------------------------
25 | //
26 |
27 |
28 | using System;
29 | using System.IO;
30 | using System.Collections.Generic;
31 |
32 | namespace Ionic.Zip
33 | {
34 |
35 | public partial class ZipFile
36 | {
37 |
38 | ///
39 | /// Extracts all of the items in the zip archive, to the specified path in the
40 | /// filesystem. The path can be relative or fully-qualified.
41 | ///
42 | ///
43 | ///
44 | ///
45 | /// This method will extract all entries in the ZipFile to the
46 | /// specified path.
47 | ///
48 | ///
49 | ///
50 | /// If an extraction of a file from the zip archive would overwrite an
51 | /// existing file in the filesystem, the action taken is dictated by the
52 | /// ExtractExistingFile property, which overrides any setting you may have
53 | /// made on individual ZipEntry instances. By default, if you have not
54 | /// set that property on the ZipFile instance, the entry will not
55 | /// be extracted, the existing file will not be overwritten and an
56 | /// exception will be thrown. To change this, set the property, or use the
57 | /// overload that allows you to
59 | /// specify an ExtractExistingFileAction parameter.
60 | ///
61 | ///
62 | ///
63 | /// The action to take when an extract would overwrite an existing file
64 | /// applies to all entries. If you want to set this on a per-entry basis,
65 | /// then you must use one of the ZipEntry.Extract methods.
67 | ///
68 | ///
69 | ///
70 | /// This method will send verbose output messages to the , if it is set on the ZipFile
72 | /// instance.
73 | ///
74 | ///
75 | ///
76 | /// You may wish to take advantage of the ExtractProgress event.
77 | ///
78 | ///
79 | ///
80 | /// About timestamps: When extracting a file entry from a zip archive, the
81 | /// extracted file gets the last modified time of the entry as stored in
82 | /// the archive. The archive may also store extended file timestamp
83 | /// information, including last accessed and created times. If these are
84 | /// present in the ZipEntry, then the extracted file will also get
85 | /// these times.
86 | ///
87 | ///
88 | ///
89 | /// A Directory entry is somewhat different. It will get the times as
90 | /// described for a file entry, but, if there are file entries in the zip
91 | /// archive that, when extracted, appear in the just-created directory,
92 | /// then when those file entries are extracted, the last modified and last
93 | /// accessed times of the directory will change, as a side effect. The
94 | /// result is that after an extraction of a directory and a number of
95 | /// files within the directory, the last modified and last accessed
96 | /// timestamps on the directory will reflect the time that the last file
97 | /// was extracted into the directory, rather than the time stored in the
98 | /// zip archive for the directory.
99 | ///
100 | ///
101 | ///
102 | /// To compensate, when extracting an archive with ExtractAll,
103 | /// DotNetZip will extract all the file and directory entries as described
104 | /// above, but it will then make a second pass on the directories, and
105 | /// reset the times on the directories to reflect what is stored in the
106 | /// zip archive.
107 | ///
108 | ///
109 | ///
110 | /// This compensation is performed only within the context of an
111 | /// ExtractAll. If you call ZipEntry.Extract on a directory
112 | /// entry, the timestamps on directory in the filesystem will reflect the
113 | /// times stored in the zip. If you then call ZipEntry.Extract on
114 | /// a file entry, which is extracted into the directory, the timestamps on
115 | /// the directory will be updated to the current time.
116 | ///
117 | ///
118 | ///
119 | ///
120 | /// This example extracts all the entries in a zip archive file, to the
121 | /// specified target directory. The extraction will overwrite any
122 | /// existing files silently.
123 | ///
124 | ///
125 | /// String TargetDirectory= "unpack";
126 | /// using(ZipFile zip= ZipFile.Read(ZipFileToExtract))
127 | /// {
128 | /// zip.ExtractExistingFile= ExtractExistingFileAction.OverwriteSilently;
129 | /// zip.ExtractAll(TargetDirectory);
130 | /// }
131 | ///
132 | ///
133 | ///
134 | /// Dim TargetDirectory As String = "unpack"
135 | /// Using zip As ZipFile = ZipFile.Read(ZipFileToExtract)
136 | /// zip.ExtractExistingFile= ExtractExistingFileAction.OverwriteSilently
137 | /// zip.ExtractAll(TargetDirectory)
138 | /// End Using
139 | ///
140 | ///
141 | ///
142 | ///
143 | ///
144 | ///
145 | ///
146 | /// The path to which the contents of the zipfile will be extracted.
147 | /// The path can be relative or fully-qualified.
148 | ///
149 | ///
150 | public void ExtractAll(string path)
151 | {
152 | _InternalExtractAll(path, true);
153 | }
154 |
155 |
156 |
157 | ///
158 | /// Extracts all of the items in the zip archive, to the specified path in the
159 | /// filesystem, using the specified behavior when extraction would overwrite an
160 | /// existing file.
161 | ///
162 | ///
163 | ///
164 | ///
165 | ///
166 | /// This method will extract all entries in the ZipFile to the specified
167 | /// path. For an extraction that would overwrite an existing file, the behavior
168 | /// is dictated by , which overrides any
169 | /// setting you may have made on individual ZipEntry instances.
170 | ///
171 | ///
172 | ///
173 | /// The action to take when an extract would overwrite an existing file
174 | /// applies to all entries. If you want to set this on a per-entry basis,
175 | /// then you must use or one of the similar methods.
177 | ///
178 | ///
179 | ///
180 | /// Calling this method is equivalent to setting the property and then calling .
183 | ///
184 | ///
185 | ///
186 | /// This method will send verbose output messages to the
187 | /// , if it is set on the ZipFile instance.
188 | ///
189 | ///
190 | ///
191 | ///
192 | /// This example extracts all the entries in a zip archive file, to the
193 | /// specified target directory. It does not overwrite any existing files.
194 | ///
195 | /// String TargetDirectory= "c:\\unpack";
196 | /// using(ZipFile zip= ZipFile.Read(ZipFileToExtract))
197 | /// {
198 | /// zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.DontOverwrite);
199 | /// }
200 | ///
201 | ///
202 | ///
203 | /// Dim TargetDirectory As String = "c:\unpack"
204 | /// Using zip As ZipFile = ZipFile.Read(ZipFileToExtract)
205 | /// zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.DontOverwrite)
206 | /// End Using
207 | ///
208 | ///
209 | ///
210 | ///
211 | /// The path to which the contents of the zipfile will be extracted.
212 | /// The path can be relative or fully-qualified.
213 | ///
214 | ///
215 | ///
216 | /// The action to take if extraction would overwrite an existing file.
217 | ///
218 | ///
219 | public void ExtractAll(string path, ExtractExistingFileAction extractExistingFile)
220 | {
221 | ExtractExistingFile = extractExistingFile;
222 | _InternalExtractAll(path, true);
223 | }
224 |
225 |
226 | private void _InternalExtractAll(string path, bool overrideExtractExistingProperty)
227 | {
228 | bool header = Verbose;
229 | _inExtractAll = true;
230 | try
231 | {
232 | OnExtractAllStarted(path);
233 |
234 | int n = 0;
235 | foreach (ZipEntry e in _entries.Values)
236 | {
237 | if (header)
238 | {
239 | StatusMessageTextWriter.WriteLine("\n{1,-22} {2,-8} {3,4} {4,-8} {0}",
240 | "Name", "Modified", "Size", "Ratio", "Packed");
241 | StatusMessageTextWriter.WriteLine(new System.String('-', 72));
242 | header = false;
243 | }
244 | if (Verbose)
245 | {
246 | StatusMessageTextWriter.WriteLine("{1,-22} {2,-8} {3,4:F0}% {4,-8} {0}",
247 | e.FileName,
248 | e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
249 | e.UncompressedSize,
250 | e.CompressionRatio,
251 | e.CompressedSize);
252 | if (!String.IsNullOrEmpty(e.Comment))
253 | StatusMessageTextWriter.WriteLine(" Comment: {0}", e.Comment);
254 | }
255 | e.Password = _Password; // this may be null
256 | OnExtractEntry(n, true, e, path);
257 | if (overrideExtractExistingProperty)
258 | e.ExtractExistingFile = this.ExtractExistingFile;
259 | e.Extract(path);
260 | n++;
261 | OnExtractEntry(n, false, e, path);
262 | if (_extractOperationCanceled)
263 | break;
264 | }
265 |
266 | if (!_extractOperationCanceled)
267 | {
268 | // workitem 8264:
269 | // now, set times on directory entries, again.
270 | // The problem is, extracting a file changes the times on the parent
271 | // directory. So after all files have been extracted, we have to
272 | // run through the directories again.
273 | foreach (ZipEntry e in _entries.Values)
274 | {
275 | // check if it is a directory
276 | if ((e.IsDirectory) || (e.FileName.EndsWith("/")))
277 | {
278 | string outputFile = (e.FileName.StartsWith("/"))
279 | ? Path.Combine(path, e.FileName.Substring(1))
280 | : Path.Combine(path, e.FileName);
281 |
282 | e._SetTimes(outputFile, false);
283 | }
284 | }
285 | OnExtractAllCompleted(path);
286 | }
287 |
288 | }
289 | finally
290 | {
291 |
292 | _inExtractAll = false;
293 | }
294 | }
295 |
296 |
297 | }
298 | }
299 |
--------------------------------------------------------------------------------
/Zip/ZipFile.SaveSelfExtractor.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r2d2rigo/dotnetzip-for-unity/b6e3951d18a9d28f7ef329c2065b284bd869451a/Zip/ZipFile.SaveSelfExtractor.cs
--------------------------------------------------------------------------------
/Zip/ZipFile.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/r2d2rigo/dotnetzip-for-unity/b6e3951d18a9d28f7ef329c2065b284bd869451a/Zip/ZipFile.cs
--------------------------------------------------------------------------------
/Zip/ZipFile.x-IEnumerable.cs:
--------------------------------------------------------------------------------
1 | // ZipFile.x-IEnumerable.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2006, 2007, 2008, 2009 Dino Chiesa and Microsoft Corporation.
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2009-December-26 15:13:26>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines smoe methods for IEnumerable support. It is
23 | // particularly important for COM to have these things in a separate module.
24 | //
25 | // ------------------------------------------------------------------
26 |
27 |
28 | namespace Ionic.Zip
29 | {
30 |
31 | // For some weird reason, the method with the DispId(-4) attribute, which is used as
32 | // the _NewEnum() method, and which is required to get enumeration to work from COM
33 | // environments like VBScript and Javascript (etc) must be the LAST MEMBER in the
34 | // source. In the event of Partial classes, it needs to be the last member defined
35 | // in the last source module. The source modules are ordered alphabetically by
36 | // filename. Not sure why this is true. In any case, we put the enumeration stuff
37 | // here in this oddly-named module, for this reason.
38 | //
39 |
40 |
41 |
42 | public partial class ZipFile
43 | {
44 |
45 |
46 |
47 |
48 | ///
49 | /// Generic IEnumerator support, for use of a ZipFile in an enumeration.
50 | ///
51 | ///
52 | ///
53 | /// You probably do not want to call GetEnumerator explicitly. Instead
54 | /// it is implicitly called when you use a loop in C#, or a
55 | /// For Each loop in VB.NET.
56 | ///
57 | ///
58 | ///
59 | /// This example reads a zipfile of a given name, then enumerates the
60 | /// entries in that zip file, and displays the information about each
61 | /// entry on the Console.
62 | ///
63 | /// using (ZipFile zip = ZipFile.Read(zipfile))
64 | /// {
65 | /// bool header = true;
66 | /// foreach (ZipEntry e in zip)
67 | /// {
68 | /// if (header)
69 | /// {
70 | /// System.Console.WriteLine("Zipfile: {0}", zip.Name);
71 | /// System.Console.WriteLine("Version Needed: 0x{0:X2}", e.VersionNeeded);
72 | /// System.Console.WriteLine("BitField: 0x{0:X2}", e.BitField);
73 | /// System.Console.WriteLine("Compression Method: 0x{0:X2}", e.CompressionMethod);
74 | /// System.Console.WriteLine("\n{1,-22} {2,-6} {3,4} {4,-8} {0}",
75 | /// "Filename", "Modified", "Size", "Ratio", "Packed");
76 | /// System.Console.WriteLine(new System.String('-', 72));
77 | /// header = false;
78 | /// }
79 | ///
80 | /// System.Console.WriteLine("{1,-22} {2,-6} {3,4:F0}% {4,-8} {0}",
81 | /// e.FileName,
82 | /// e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
83 | /// e.UncompressedSize,
84 | /// e.CompressionRatio,
85 | /// e.CompressedSize);
86 | ///
87 | /// e.Extract();
88 | /// }
89 | /// }
90 | ///
91 | ///
92 | ///
93 | /// Dim ZipFileToExtract As String = "c:\foo.zip"
94 | /// Using zip As ZipFile = ZipFile.Read(ZipFileToExtract)
95 | /// Dim header As Boolean = True
96 | /// Dim e As ZipEntry
97 | /// For Each e In zip
98 | /// If header Then
99 | /// Console.WriteLine("Zipfile: {0}", zip.Name)
100 | /// Console.WriteLine("Version Needed: 0x{0:X2}", e.VersionNeeded)
101 | /// Console.WriteLine("BitField: 0x{0:X2}", e.BitField)
102 | /// Console.WriteLine("Compression Method: 0x{0:X2}", e.CompressionMethod)
103 | /// Console.WriteLine(ChrW(10) & "{1,-22} {2,-6} {3,4} {4,-8} {0}", _
104 | /// "Filename", "Modified", "Size", "Ratio", "Packed" )
105 | /// Console.WriteLine(New String("-"c, 72))
106 | /// header = False
107 | /// End If
108 | /// Console.WriteLine("{1,-22} {2,-6} {3,4:F0}% {4,-8} {0}", _
109 | /// e.FileName, _
110 | /// e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"), _
111 | /// e.UncompressedSize, _
112 | /// e.CompressionRatio, _
113 | /// e.CompressedSize )
114 | /// e.Extract
115 | /// Next
116 | /// End Using
117 | ///
118 | ///
119 | ///
120 | /// A generic enumerator suitable for use within a foreach loop.
121 | public System.Collections.Generic.IEnumerator GetEnumerator()
122 | {
123 | foreach (ZipEntry e in _entries.Values)
124 | yield return e;
125 | }
126 |
127 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
128 | {
129 | return GetEnumerator();
130 | }
131 |
132 |
133 | ///
134 | /// An IEnumerator, for use of a ZipFile in a foreach construct.
135 | ///
136 | ///
137 | ///
138 | /// This method is included for COM support. An application generally does not call
139 | /// this method directly. It is called implicitly by COM clients when enumerating
140 | /// the entries in the ZipFile instance. In VBScript, this is done with a For Each
141 | /// statement. In Javascript, this is done with new Enumerator(zipfile).
142 | ///
143 | ///
144 | ///
145 | /// The IEnumerator over the entries in the ZipFile.
146 | ///
147 | [System.Runtime.InteropServices.DispId(-4)]
148 | public System.Collections.IEnumerator GetNewEnum() // the name of this method is not significant
149 | {
150 | return GetEnumerator();
151 | }
152 |
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/Zip/ZipSegmentedStream.cs:
--------------------------------------------------------------------------------
1 | // ZipSegmentedStream.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2009-2011 Dino Chiesa.
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2011-July-13 22:25:45>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines logic for zip streams that span disk files.
23 | //
24 | // ------------------------------------------------------------------
25 |
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.IO;
30 |
31 | namespace Ionic.Zip
32 | {
33 | internal class ZipSegmentedStream : System.IO.Stream
34 | {
35 | enum RwMode
36 | {
37 | None = 0,
38 | ReadOnly = 1,
39 | Write = 2,
40 | //Update = 3
41 | }
42 |
43 | private RwMode rwMode;
44 | private bool _exceptionPending; // **see note below
45 | private string _baseName;
46 | private string _baseDir;
47 | //private bool _isDisposed;
48 | private string _currentName;
49 | private string _currentTempName;
50 | private uint _currentDiskNumber;
51 | private uint _maxDiskNumber;
52 | private int _maxSegmentSize;
53 | private System.IO.Stream _innerStream;
54 |
55 | // **Note regarding exceptions:
56 | //
57 | // When ZipSegmentedStream is employed within a using clause,
58 | // which is the typical scenario, and an exception is thrown
59 | // within the scope of the using, Dispose() is invoked
60 | // implicitly before processing the initial exception. If that
61 | // happens, this class sets _exceptionPending to true, and then
62 | // within the Dispose(bool), takes special action as
63 | // appropriate. Need to be careful: any additional exceptions
64 | // will mask the original one.
65 |
66 | private ZipSegmentedStream() : base()
67 | {
68 | _exceptionPending = false;
69 | }
70 |
71 | public static ZipSegmentedStream ForReading(string name,
72 | uint initialDiskNumber,
73 | uint maxDiskNumber)
74 | {
75 | ZipSegmentedStream zss = new ZipSegmentedStream()
76 | {
77 | rwMode = RwMode.ReadOnly,
78 | CurrentSegment = initialDiskNumber,
79 | _maxDiskNumber = maxDiskNumber,
80 | _baseName = name,
81 | };
82 |
83 | // Console.WriteLine("ZSS: ForReading ({0})",
84 | // Path.GetFileName(zss.CurrentName));
85 |
86 | zss._SetReadStream();
87 |
88 | return zss;
89 | }
90 |
91 |
92 | public static ZipSegmentedStream ForWriting(string name, int maxSegmentSize)
93 | {
94 | ZipSegmentedStream zss = new ZipSegmentedStream()
95 | {
96 | rwMode = RwMode.Write,
97 | CurrentSegment = 0,
98 | _baseName = name,
99 | _maxSegmentSize = maxSegmentSize,
100 | _baseDir = Path.GetDirectoryName(name)
101 | };
102 |
103 | // workitem 9522
104 | if (zss._baseDir=="") zss._baseDir=".";
105 |
106 | zss._SetWriteStream(0);
107 |
108 | // Console.WriteLine("ZSS: ForWriting ({0})",
109 | // Path.GetFileName(zss.CurrentName));
110 |
111 | return zss;
112 | }
113 |
114 |
115 | ///
116 | /// Sort-of like a factory method, ForUpdate is used only when
117 | /// the application needs to update the zip entry metadata for
118 | /// a segmented zip file, when the starting segment is earlier
119 | /// than the ending segment, for a particular entry.
120 | ///
121 | ///
122 | ///
123 | /// The update is always contiguous, never rolls over. As a
124 | /// result, this method doesn't need to return a ZSS; it can
125 | /// simply return a FileStream. That's why it's "sort of"
126 | /// like a Factory method.
127 | ///
128 | ///
129 | /// Caller must Close/Dispose the stream object returned by
130 | /// this method.
131 | ///
132 | ///
133 | public static Stream ForUpdate(string name, uint diskNumber)
134 | {
135 | if (diskNumber >= 99)
136 | throw new ArgumentOutOfRangeException("diskNumber");
137 |
138 | string fname =
139 | String.Format("{0}.z{1:D2}",
140 | Path.Combine(Path.GetDirectoryName(name),
141 | Path.GetFileNameWithoutExtension(name)),
142 | diskNumber + 1);
143 |
144 | // Console.WriteLine("ZSS: ForUpdate ({0})",
145 | // Path.GetFileName(fname));
146 |
147 | // This class assumes that the update will not expand the
148 | // size of the segment. Update is used only for an in-place
149 | // update of zip metadata. It never will try to write beyond
150 | // the end of a segment.
151 |
152 | return File.Open(fname,
153 | FileMode.Open,
154 | FileAccess.ReadWrite,
155 | FileShare.None);
156 | }
157 |
158 | public bool ContiguousWrite
159 | {
160 | get;
161 | set;
162 | }
163 |
164 |
165 | public UInt32 CurrentSegment
166 | {
167 | get
168 | {
169 | return _currentDiskNumber;
170 | }
171 | private set
172 | {
173 | _currentDiskNumber = value;
174 | _currentName = null; // it will get updated next time referenced
175 | }
176 | }
177 |
178 | ///
179 | /// Name of the filesystem file corresponding to the current segment.
180 | ///
181 | ///
182 | ///
183 | /// The name is not always the name currently being used in the
184 | /// filesystem. When rwMode is RwMode.Write, the filesystem file has a
185 | /// temporary name until the stream is closed or until the next segment is
186 | /// started.
187 | ///
188 | ///
189 | public String CurrentName
190 | {
191 | get
192 | {
193 | if (_currentName==null)
194 | _currentName = _NameForSegment(CurrentSegment);
195 |
196 | return _currentName;
197 | }
198 | }
199 |
200 |
201 | public String CurrentTempName
202 | {
203 | get
204 | {
205 | return _currentTempName;
206 | }
207 | }
208 |
209 | private string _NameForSegment(uint diskNumber)
210 | {
211 | if (diskNumber >= 99)
212 | {
213 | _exceptionPending = true;
214 | throw new OverflowException("The number of zip segments would exceed 99.");
215 | }
216 |
217 | return String.Format("{0}.z{1:D2}",
218 | Path.Combine(Path.GetDirectoryName(_baseName),
219 | Path.GetFileNameWithoutExtension(_baseName)),
220 | diskNumber + 1);
221 | }
222 |
223 |
224 | // Returns the segment that WILL be current if writing
225 | // a block of the given length.
226 | // This isn't exactly true. It could roll over beyond
227 | // this number.
228 | public UInt32 ComputeSegment(int length)
229 | {
230 | if (_innerStream.Position + length > _maxSegmentSize)
231 | // the block will go AT LEAST into the next segment
232 | return CurrentSegment + 1;
233 |
234 | // it will fit in the current segment
235 | return CurrentSegment;
236 | }
237 |
238 |
239 | public override String ToString()
240 | {
241 | return String.Format("{0}[{1}][{2}], pos=0x{3:X})",
242 | "ZipSegmentedStream", CurrentName,
243 | rwMode.ToString(),
244 | this.Position);
245 | }
246 |
247 |
248 | private void _SetReadStream()
249 | {
250 | if (_innerStream != null)
251 | {
252 | #if NETCF
253 | _innerStream.Close();
254 | #else
255 | _innerStream.Dispose();
256 | #endif
257 | }
258 |
259 | if (CurrentSegment + 1 == _maxDiskNumber)
260 | _currentName = _baseName;
261 |
262 | // Console.WriteLine("ZSS: SRS ({0})",
263 | // Path.GetFileName(CurrentName));
264 |
265 | _innerStream = File.OpenRead(CurrentName);
266 | }
267 |
268 |
269 | ///
270 | /// Read from the stream
271 | ///
272 | /// the buffer to read
273 | /// the offset at which to start
274 | /// the number of bytes to read
275 | /// the number of bytes actually read
276 | public override int Read(byte[] buffer, int offset, int count)
277 | {
278 | if (rwMode != RwMode.ReadOnly)
279 | {
280 | _exceptionPending = true;
281 | throw new InvalidOperationException("Stream Error: Cannot Read.");
282 | }
283 |
284 | int r = _innerStream.Read(buffer, offset, count);
285 | int r1 = r;
286 |
287 | while (r1 != count)
288 | {
289 | if (_innerStream.Position != _innerStream.Length)
290 | {
291 | _exceptionPending = true;
292 | throw new ZipException(String.Format("Read error in file {0}", CurrentName));
293 |
294 | }
295 |
296 | if (CurrentSegment + 1 == _maxDiskNumber)
297 | return r; // no more to read
298 |
299 | CurrentSegment++;
300 | _SetReadStream();
301 | offset += r1;
302 | count -= r1;
303 | r1 = _innerStream.Read(buffer, offset, count);
304 | r += r1;
305 | }
306 | return r;
307 | }
308 |
309 |
310 |
311 | private void _SetWriteStream(uint increment)
312 | {
313 | if (_innerStream != null)
314 | {
315 | #if NETCF
316 | _innerStream.Close();
317 | #else
318 | _innerStream.Dispose();
319 | #endif
320 | if (File.Exists(CurrentName))
321 | File.Delete(CurrentName);
322 | File.Move(_currentTempName, CurrentName);
323 | // Console.WriteLine("ZSS: SWS close ({0})",
324 | // Path.GetFileName(CurrentName));
325 | }
326 |
327 | if (increment > 0)
328 | CurrentSegment += increment;
329 |
330 | SharedUtilities.CreateAndOpenUniqueTempFile(_baseDir,
331 | out _innerStream,
332 | out _currentTempName);
333 |
334 | // Console.WriteLine("ZSS: SWS open ({0})",
335 | // Path.GetFileName(_currentTempName));
336 |
337 | if (CurrentSegment == 0)
338 | _innerStream.Write(BitConverter.GetBytes(ZipConstants.SplitArchiveSignature), 0, 4);
339 | }
340 |
341 |
342 | ///
343 | /// Write to the stream.
344 | ///
345 | /// the buffer from which to write
346 | /// the offset at which to start writing
347 | /// the number of bytes to write
348 | public override void Write(byte[] buffer, int offset, int count)
349 | {
350 | if (rwMode != RwMode.Write)
351 | {
352 | _exceptionPending = true;
353 | throw new InvalidOperationException("Stream Error: Cannot Write.");
354 | }
355 |
356 |
357 | if (ContiguousWrite)
358 | {
359 | // enough space for a contiguous write?
360 | if (_innerStream.Position + count > _maxSegmentSize)
361 | _SetWriteStream(1);
362 | }
363 | else
364 | {
365 | while (_innerStream.Position + count > _maxSegmentSize)
366 | {
367 | int c = unchecked(_maxSegmentSize - (int)_innerStream.Position);
368 | _innerStream.Write(buffer, offset, c);
369 | _SetWriteStream(1);
370 | count -= c;
371 | offset += c;
372 | }
373 | }
374 |
375 | _innerStream.Write(buffer, offset, count);
376 | }
377 |
378 |
379 | public long TruncateBackward(uint diskNumber, long offset)
380 | {
381 | // Console.WriteLine("***ZSS.Trunc to disk {0}", diskNumber);
382 | // Console.WriteLine("***ZSS.Trunc: current disk {0}", CurrentSegment);
383 | if (diskNumber >= 99)
384 | throw new ArgumentOutOfRangeException("diskNumber");
385 |
386 | if (rwMode != RwMode.Write)
387 | {
388 | _exceptionPending = true;
389 | throw new ZipException("bad state.");
390 | }
391 |
392 | // Seek back in the segmented stream to a (maybe) prior segment.
393 |
394 | // Check if it is the same segment. If it is, very simple.
395 | if (diskNumber == CurrentSegment)
396 | {
397 | var x =_innerStream.Seek(offset, SeekOrigin.Begin);
398 | // workitem 10178
399 | Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(_innerStream);
400 | return x;
401 | }
402 |
403 | // Seeking back to a prior segment.
404 | // The current segment and any intervening segments must be removed.
405 | // First, close the current segment, and then remove it.
406 | if (_innerStream != null)
407 | {
408 | #if NETCF
409 | _innerStream.Close();
410 | #else
411 | _innerStream.Dispose();
412 | #endif
413 | if (File.Exists(_currentTempName))
414 | File.Delete(_currentTempName);
415 | }
416 |
417 | // Now, remove intervening segments.
418 | for (uint j= CurrentSegment-1; j > diskNumber; j--)
419 | {
420 | string s = _NameForSegment(j);
421 | // Console.WriteLine("***ZSS.Trunc: removing file {0}", s);
422 | if (File.Exists(s))
423 | File.Delete(s);
424 | }
425 |
426 | // now, open the desired segment. It must exist.
427 | CurrentSegment = diskNumber;
428 |
429 | // get a new temp file, try 3 times:
430 | for (int i = 0; i < 3; i++)
431 | {
432 | try
433 | {
434 | _currentTempName = SharedUtilities.InternalGetTempFileName();
435 | // move the .z0x file back to a temp name
436 | File.Move(CurrentName, _currentTempName);
437 | break; // workitem 12403
438 | }
439 | catch(IOException)
440 | {
441 | if (i == 2) throw;
442 | }
443 | }
444 |
445 | // open it
446 | _innerStream = new FileStream(_currentTempName, FileMode.Open);
447 |
448 | var r = _innerStream.Seek(offset, SeekOrigin.Begin);
449 |
450 | // workitem 10178
451 | Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(_innerStream);
452 |
453 | return r;
454 | }
455 |
456 |
457 |
458 | public override bool CanRead
459 | {
460 | get
461 | {
462 | return (rwMode == RwMode.ReadOnly &&
463 | (_innerStream != null) &&
464 | _innerStream.CanRead);
465 | }
466 | }
467 |
468 |
469 | public override bool CanSeek
470 | {
471 | get
472 | {
473 | return (_innerStream != null) &&
474 | _innerStream.CanSeek;
475 | }
476 | }
477 |
478 |
479 | public override bool CanWrite
480 | {
481 | get
482 | {
483 | return (rwMode == RwMode.Write) &&
484 | (_innerStream != null) &&
485 | _innerStream.CanWrite;
486 | }
487 | }
488 |
489 | public override void Flush()
490 | {
491 | _innerStream.Flush();
492 | }
493 |
494 | public override long Length
495 | {
496 | get
497 | {
498 | return _innerStream.Length;
499 | }
500 | }
501 |
502 | public override long Position
503 | {
504 | get { return _innerStream.Position; }
505 | set { _innerStream.Position = value; }
506 | }
507 |
508 | public override long Seek(long offset, System.IO.SeekOrigin origin)
509 | {
510 | var x = _innerStream.Seek(offset, origin);
511 | // workitem 10178
512 | Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(_innerStream);
513 | return x;
514 | }
515 |
516 | public override void SetLength(long value)
517 | {
518 | if (rwMode != RwMode.Write)
519 | {
520 | _exceptionPending = true;
521 | throw new InvalidOperationException();
522 | }
523 | _innerStream.SetLength(value);
524 | }
525 |
526 |
527 | protected override void Dispose(bool disposing)
528 | {
529 | // this gets called by Stream.Close()
530 |
531 | // if (_isDisposed) return;
532 | // _isDisposed = true;
533 | //Console.WriteLine("Dispose (mode={0})\n", rwMode.ToString());
534 |
535 | try
536 | {
537 | if (_innerStream != null)
538 | {
539 | #if NETCF
540 | _innerStream.Close();
541 | #else
542 | _innerStream.Dispose();
543 | #endif
544 | //_innerStream = null;
545 | if (rwMode == RwMode.Write)
546 | {
547 | if (_exceptionPending)
548 | {
549 | // possibly could try to clean up all the
550 | // temp files created so far...
551 | }
552 | else
553 | {
554 | // // move the final temp file to the .zNN name
555 | // if (File.Exists(CurrentName))
556 | // File.Delete(CurrentName);
557 | // if (File.Exists(_currentTempName))
558 | // File.Move(_currentTempName, CurrentName);
559 | }
560 | }
561 | }
562 | }
563 | finally
564 | {
565 | base.Dispose(disposing);
566 | }
567 | }
568 |
569 | }
570 |
571 | }
--------------------------------------------------------------------------------
/Zlib/LICENSE.jzlib.txt:
--------------------------------------------------------------------------------
1 | The ZLIB library, available as Ionic.Zlib.dll or as part of DotNetZip,
2 | is a ported-then-modified version of jzlib. The following applies to jzlib:
3 |
4 | JZlib 0.0.* were released under the GNU LGPL license. Later, we have switched
5 | over to a BSD-style license.
6 |
7 | ------------------------------------------------------------------------------
8 | Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
9 |
10 | Redistribution and use in source and binary forms, with or without
11 | modification, are permitted provided that the following conditions are met:
12 |
13 | 1. Redistributions of source code must retain the above copyright notice,
14 | this list of conditions and the following disclaimer.
15 |
16 | 2. Redistributions in binary form must reproduce the above copyright
17 | notice, this list of conditions and the following disclaimer in
18 | the documentation and/or other materials provided with the distribution.
19 |
20 | 3. The names of the authors may not be used to endorse or promote products
21 | derived from this software without specific prior written permission.
22 |
23 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
24 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
25 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
26 | INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
27 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
29 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 |
--------------------------------------------------------------------------------
/Zlib/License.zlib.txt:
--------------------------------------------------------------------------------
1 | The ZLIB library, available as Ionic.Zlib.dll or as part of DotNetZip,
2 | is a ported-then-modified version of jzlib, which itself is based on
3 | zlib-1.1.3, the well-known C-language compression library.
4 |
5 | The following notice applies to zlib:
6 |
7 | -----------------------------------------------------------------------
8 |
9 | Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
10 |
11 | The ZLIB software is provided 'as-is', without any express or implied
12 | warranty. In no event will the authors be held liable for any damages
13 | arising from the use of this software.
14 |
15 | Permission is granted to anyone to use this software for any purpose,
16 | including commercial applications, and to alter it and redistribute it
17 | freely, subject to the following restrictions:
18 |
19 | 1. The origin of this software must not be misrepresented; you must not
20 | claim that you wrote the original software. If you use this software
21 | in a product, an acknowledgment in the product documentation would be
22 | appreciated but is not required.
23 | 2. Altered source versions must be plainly marked as such, and must not be
24 | misrepresented as being the original software.
25 | 3. This notice may not be removed or altered from any source distribution.
26 |
27 | Jean-loup Gailly jloup@gzip.org
28 | Mark Adler madler@alumni.caltech.edu
29 |
30 |
31 | -----------------------------------------------------------------------
32 |
--------------------------------------------------------------------------------
/Zlib/Tree.cs:
--------------------------------------------------------------------------------
1 | // Tree.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2009-October-28 13:29:50>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines classes for zlib compression and
23 | // decompression. This code is derived from the jzlib implementation of
24 | // zlib. In keeping with the license for jzlib, the copyright to that
25 | // code is below.
26 | //
27 | // ------------------------------------------------------------------
28 | //
29 | // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
30 | //
31 | // Redistribution and use in source and binary forms, with or without
32 | // modification, are permitted provided that the following conditions are met:
33 | //
34 | // 1. Redistributions of source code must retain the above copyright notice,
35 | // this list of conditions and the following disclaimer.
36 | //
37 | // 2. Redistributions in binary form must reproduce the above copyright
38 | // notice, this list of conditions and the following disclaimer in
39 | // the documentation and/or other materials provided with the distribution.
40 | //
41 | // 3. The names of the authors may not be used to endorse or promote products
42 | // derived from this software without specific prior written permission.
43 | //
44 | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
45 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
46 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
47 | // INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
48 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
50 | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
51 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
52 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
53 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 | //
55 | // -----------------------------------------------------------------------
56 | //
57 | // This program is based on zlib-1.1.3; credit to authors
58 | // Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
59 | // and contributors of zlib.
60 | //
61 | // -----------------------------------------------------------------------
62 |
63 |
64 | using System;
65 |
66 | namespace Ionic.Zlib
67 | {
68 | sealed class Tree
69 | {
70 | private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1);
71 |
72 | // extra bits for each length code
73 | internal static readonly int[] ExtraLengthBits = new int[]
74 | {
75 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
76 | 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
77 | };
78 |
79 | // extra bits for each distance code
80 | internal static readonly int[] ExtraDistanceBits = new int[]
81 | {
82 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
83 | 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13
84 | };
85 |
86 | // extra bits for each bit length code
87 | internal static readonly int[] extra_blbits = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7};
88 |
89 | internal static readonly sbyte[] bl_order = new sbyte[]{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
90 |
91 |
92 | // The lengths of the bit length codes are sent in order of decreasing
93 | // probability, to avoid transmitting the lengths for unused bit
94 | // length codes.
95 |
96 | internal const int Buf_size = 8 * 2;
97 |
98 | // see definition of array dist_code below
99 | //internal const int DIST_CODE_LEN = 512;
100 |
101 | private static readonly sbyte[] _dist_code = new sbyte[]
102 | {
103 | 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
104 | 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
105 | 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
106 | 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
107 | 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
108 | 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
109 | 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
110 | 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
111 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
112 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
113 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
114 | 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
115 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
116 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
117 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
118 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
119 | 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21,
120 | 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
121 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
122 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
123 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
124 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
125 | 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
126 | 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
127 | 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
128 | 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
129 | 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
130 | 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
131 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
132 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
133 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
134 | 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
135 | };
136 |
137 | internal static readonly sbyte[] LengthCode = new sbyte[]
138 | {
139 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11,
140 | 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
141 | 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17,
142 | 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19,
143 | 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
144 | 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
145 | 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
146 | 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
147 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
148 | 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
149 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
150 | 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
151 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
152 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
153 | 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
154 | 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
155 | };
156 |
157 |
158 | internal static readonly int[] LengthBase = new int[]
159 | {
160 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28,
161 | 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0
162 | };
163 |
164 |
165 | internal static readonly int[] DistanceBase = new int[]
166 | {
167 | 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
168 | 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
169 | };
170 |
171 |
172 | ///
173 | /// Map from a distance to a distance code.
174 | ///
175 | ///
176 | /// No side effects. _dist_code[256] and _dist_code[257] are never used.
177 | ///
178 | internal static int DistanceCode(int dist)
179 | {
180 | return (dist < 256)
181 | ? _dist_code[dist]
182 | : _dist_code[256 + SharedUtils.URShift(dist, 7)];
183 | }
184 |
185 | internal short[] dyn_tree; // the dynamic tree
186 | internal int max_code; // largest code with non zero frequency
187 | internal StaticTree staticTree; // the corresponding static tree
188 |
189 | // Compute the optimal bit lengths for a tree and update the total bit length
190 | // for the current block.
191 | // IN assertion: the fields freq and dad are set, heap[heap_max] and
192 | // above are the tree nodes sorted by increasing frequency.
193 | // OUT assertions: the field len is set to the optimal bit length, the
194 | // array bl_count contains the frequencies for each bit length.
195 | // The length opt_len is updated; static_len is also updated if stree is
196 | // not null.
197 | internal void gen_bitlen(DeflateManager s)
198 | {
199 | short[] tree = dyn_tree;
200 | short[] stree = staticTree.treeCodes;
201 | int[] extra = staticTree.extraBits;
202 | int base_Renamed = staticTree.extraBase;
203 | int max_length = staticTree.maxLength;
204 | int h; // heap index
205 | int n, m; // iterate over the tree elements
206 | int bits; // bit length
207 | int xbits; // extra bits
208 | short f; // frequency
209 | int overflow = 0; // number of elements with bit length too large
210 |
211 | for (bits = 0; bits <= InternalConstants.MAX_BITS; bits++)
212 | s.bl_count[bits] = 0;
213 |
214 | // In a first pass, compute the optimal bit lengths (which may
215 | // overflow in the case of the bit length tree).
216 | tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap
217 |
218 | for (h = s.heap_max + 1; h < HEAP_SIZE; h++)
219 | {
220 | n = s.heap[h];
221 | bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
222 | if (bits > max_length)
223 | {
224 | bits = max_length; overflow++;
225 | }
226 | tree[n * 2 + 1] = (short) bits;
227 | // We overwrite tree[n*2+1] which is no longer needed
228 |
229 | if (n > max_code)
230 | continue; // not a leaf node
231 |
232 | s.bl_count[bits]++;
233 | xbits = 0;
234 | if (n >= base_Renamed)
235 | xbits = extra[n - base_Renamed];
236 | f = tree[n * 2];
237 | s.opt_len += f * (bits + xbits);
238 | if (stree != null)
239 | s.static_len += f * (stree[n * 2 + 1] + xbits);
240 | }
241 | if (overflow == 0)
242 | return ;
243 |
244 | // This happens for example on obj2 and pic of the Calgary corpus
245 | // Find the first bit length which could increase:
246 | do
247 | {
248 | bits = max_length - 1;
249 | while (s.bl_count[bits] == 0)
250 | bits--;
251 | s.bl_count[bits]--; // move one leaf down the tree
252 | s.bl_count[bits + 1] = (short) (s.bl_count[bits + 1] + 2); // move one overflow item as its brother
253 | s.bl_count[max_length]--;
254 | // The brother of the overflow item also moves one step up,
255 | // but this does not affect bl_count[max_length]
256 | overflow -= 2;
257 | }
258 | while (overflow > 0);
259 |
260 | for (bits = max_length; bits != 0; bits--)
261 | {
262 | n = s.bl_count[bits];
263 | while (n != 0)
264 | {
265 | m = s.heap[--h];
266 | if (m > max_code)
267 | continue;
268 | if (tree[m * 2 + 1] != bits)
269 | {
270 | s.opt_len = (int) (s.opt_len + ((long) bits - (long) tree[m * 2 + 1]) * (long) tree[m * 2]);
271 | tree[m * 2 + 1] = (short) bits;
272 | }
273 | n--;
274 | }
275 | }
276 | }
277 |
278 | // Construct one Huffman tree and assigns the code bit strings and lengths.
279 | // Update the total bit length for the current block.
280 | // IN assertion: the field freq is set for all tree elements.
281 | // OUT assertions: the fields len and code are set to the optimal bit length
282 | // and corresponding code. The length opt_len is updated; static_len is
283 | // also updated if stree is not null. The field max_code is set.
284 | internal void build_tree(DeflateManager s)
285 | {
286 | short[] tree = dyn_tree;
287 | short[] stree = staticTree.treeCodes;
288 | int elems = staticTree.elems;
289 | int n, m; // iterate over heap elements
290 | int max_code = -1; // largest code with non zero frequency
291 | int node; // new node being created
292 |
293 | // Construct the initial heap, with least frequent element in
294 | // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
295 | // heap[0] is not used.
296 | s.heap_len = 0;
297 | s.heap_max = HEAP_SIZE;
298 |
299 | for (n = 0; n < elems; n++)
300 | {
301 | if (tree[n * 2] != 0)
302 | {
303 | s.heap[++s.heap_len] = max_code = n;
304 | s.depth[n] = 0;
305 | }
306 | else
307 | {
308 | tree[n * 2 + 1] = 0;
309 | }
310 | }
311 |
312 | // The pkzip format requires that at least one distance code exists,
313 | // and that at least one bit should be sent even if there is only one
314 | // possible code. So to avoid special checks later on we force at least
315 | // two codes of non zero frequency.
316 | while (s.heap_len < 2)
317 | {
318 | node = s.heap[++s.heap_len] = (max_code < 2?++max_code:0);
319 | tree[node * 2] = 1;
320 | s.depth[node] = 0;
321 | s.opt_len--;
322 | if (stree != null)
323 | s.static_len -= stree[node * 2 + 1];
324 | // node is 0 or 1 so it does not have extra bits
325 | }
326 | this.max_code = max_code;
327 |
328 | // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
329 | // establish sub-heaps of increasing lengths:
330 |
331 | for (n = s.heap_len / 2; n >= 1; n--)
332 | s.pqdownheap(tree, n);
333 |
334 | // Construct the Huffman tree by repeatedly combining the least two
335 | // frequent nodes.
336 |
337 | node = elems; // next internal node of the tree
338 | do
339 | {
340 | // n = node of least frequency
341 | n = s.heap[1];
342 | s.heap[1] = s.heap[s.heap_len--];
343 | s.pqdownheap(tree, 1);
344 | m = s.heap[1]; // m = node of next least frequency
345 |
346 | s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency
347 | s.heap[--s.heap_max] = m;
348 |
349 | // Create a new node father of n and m
350 | tree[node * 2] = unchecked((short) (tree[n * 2] + tree[m * 2]));
351 | s.depth[node] = (sbyte) (System.Math.Max((byte) s.depth[n], (byte) s.depth[m]) + 1);
352 | tree[n * 2 + 1] = tree[m * 2 + 1] = (short) node;
353 |
354 | // and insert the new node in the heap
355 | s.heap[1] = node++;
356 | s.pqdownheap(tree, 1);
357 | }
358 | while (s.heap_len >= 2);
359 |
360 | s.heap[--s.heap_max] = s.heap[1];
361 |
362 | // At this point, the fields freq and dad are set. We can now
363 | // generate the bit lengths.
364 |
365 | gen_bitlen(s);
366 |
367 | // The field len is now set, we can generate the bit codes
368 | gen_codes(tree, max_code, s.bl_count);
369 | }
370 |
371 | // Generate the codes for a given tree and bit counts (which need not be
372 | // optimal).
373 | // IN assertion: the array bl_count contains the bit length statistics for
374 | // the given tree and the field len is set for all tree elements.
375 | // OUT assertion: the field code is set for all tree elements of non
376 | // zero code length.
377 | internal static void gen_codes(short[] tree, int max_code, short[] bl_count)
378 | {
379 | short[] next_code = new short[InternalConstants.MAX_BITS + 1]; // next code value for each bit length
380 | short code = 0; // running code value
381 | int bits; // bit index
382 | int n; // code index
383 |
384 | // The distribution counts are first used to generate the code values
385 | // without bit reversal.
386 | for (bits = 1; bits <= InternalConstants.MAX_BITS; bits++)
387 | unchecked {
388 | next_code[bits] = code = (short) ((code + bl_count[bits - 1]) << 1);
389 | }
390 |
391 | // Check that the bit counts in bl_count are consistent. The last code
392 | // must be all ones.
393 | //Assert (code + bl_count[MAX_BITS]-1 == (1<>= 1; //SharedUtils.URShift(code, 1);
417 | res <<= 1;
418 | }
419 | while (--len > 0);
420 | return res >> 1;
421 | }
422 | }
423 | }
--------------------------------------------------------------------------------
/Zlib/ZlibConstants.cs:
--------------------------------------------------------------------------------
1 | // ZlibConstants.cs
2 | // ------------------------------------------------------------------
3 | //
4 | // Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
5 | // All rights reserved.
6 | //
7 | // This code module is part of DotNetZip, a zipfile class library.
8 | //
9 | // ------------------------------------------------------------------
10 | //
11 | // This code is licensed under the Microsoft Public License.
12 | // See the file License.txt for the license details.
13 | // More info on: http://dotnetzip.codeplex.com
14 | //
15 | // ------------------------------------------------------------------
16 | //
17 | // last saved (in emacs):
18 | // Time-stamp: <2009-November-03 18:50:19>
19 | //
20 | // ------------------------------------------------------------------
21 | //
22 | // This module defines constants used by the zlib class library. This
23 | // code is derived from the jzlib implementation of zlib, but
24 | // significantly modified. In keeping with the license for jzlib, the
25 | // copyright to that code is included here.
26 | //
27 | // ------------------------------------------------------------------
28 | //
29 | // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
30 | //
31 | // Redistribution and use in source and binary forms, with or without
32 | // modification, are permitted provided that the following conditions are met:
33 | //
34 | // 1. Redistributions of source code must retain the above copyright notice,
35 | // this list of conditions and the following disclaimer.
36 | //
37 | // 2. Redistributions in binary form must reproduce the above copyright
38 | // notice, this list of conditions and the following disclaimer in
39 | // the documentation and/or other materials provided with the distribution.
40 | //
41 | // 3. The names of the authors may not be used to endorse or promote products
42 | // derived from this software without specific prior written permission.
43 | //
44 | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
45 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
46 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
47 | // INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
48 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
50 | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
51 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
52 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
53 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 | //
55 | // -----------------------------------------------------------------------
56 | //
57 | // This program is based on zlib-1.1.3; credit to authors
58 | // Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
59 | // and contributors of zlib.
60 | //
61 | // -----------------------------------------------------------------------
62 |
63 |
64 | using System;
65 |
66 | namespace Ionic.Zlib
67 | {
68 | ///
69 | /// A bunch of constants used in the Zlib interface.
70 | ///
71 | public static class ZlibConstants
72 | {
73 | ///
74 | /// The maximum number of window bits for the Deflate algorithm.
75 | ///
76 | public const int WindowBitsMax = 15; // 32K LZ77 window
77 |
78 | ///
79 | /// The default number of window bits for the Deflate algorithm.
80 | ///
81 | public const int WindowBitsDefault = WindowBitsMax;
82 |
83 | ///
84 | /// indicates everything is A-OK
85 | ///
86 | public const int Z_OK = 0;
87 |
88 | ///
89 | /// Indicates that the last operation reached the end of the stream.
90 | ///
91 | public const int Z_STREAM_END = 1;
92 |
93 | ///
94 | /// The operation ended in need of a dictionary.
95 | ///
96 | public const int Z_NEED_DICT = 2;
97 |
98 | ///
99 | /// There was an error with the stream - not enough data, not open and readable, etc.
100 | ///
101 | public const int Z_STREAM_ERROR = -2;
102 |
103 | ///
104 | /// There was an error with the data - not enough data, bad data, etc.
105 | ///
106 | public const int Z_DATA_ERROR = -3;
107 |
108 | ///
109 | /// There was an error with the working buffer.
110 | ///
111 | public const int Z_BUF_ERROR = -5;
112 |
113 | ///
114 | /// The size of the working buffer used in the ZlibCodec class. Defaults to 8192 bytes.
115 | ///
116 | #if NETCF
117 | public const int WorkingBufferSizeDefault = 8192;
118 | #else
119 | public const int WorkingBufferSizeDefault = 16384;
120 | #endif
121 | ///
122 | /// The minimum size of the working buffer used in the ZlibCodec class. Currently it is 128 bytes.
123 | ///
124 | public const int WorkingBufferSizeMin = 1024;
125 | }
126 |
127 | }
128 |
129 |
--------------------------------------------------------------------------------