[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Dotgnu-pnet-commits] pnetlib/SharpZipLib/Zip ZipConstants.cs, NONE, 1.
From: |
Rhys Weatherley <address@hidden> |
Subject: |
[Dotgnu-pnet-commits] pnetlib/SharpZipLib/Zip ZipConstants.cs, NONE, 1.1 ZipEntry.cs, NONE, 1.1 ZipFile.cs, NONE, 1.1 ZipInputStream.cs, NONE, 1.1 ZipOutputStream.cs, NONE, 1.1 |
Date: |
Wed, 08 Oct 2003 07:37:07 +0000 |
Update of /cvsroot/dotgnu-pnet/pnetlib/SharpZipLib/Zip
In directory subversions:/tmp/cvs-serv5756/SharpZipLib/Zip
Added Files:
ZipConstants.cs ZipEntry.cs ZipFile.cs ZipInputStream.cs
ZipOutputStream.cs
Log Message:
Add the "SharpZipLib" directory to pnetlib, which is a port of
SharpDevelop's compression handling library.
--- NEW FILE: ZipOutputStream.cs ---
// ZipOutputStream.cs
// Copyright (C) 2001 Mike Krueger
//
// This file was translated from java, it was part of the GNU Classpath
// Copyright (C) 2001 Free Software Foundation, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// Linking this library statically or dynamically with other modules is
// making a combined work based on this library. Thus, the terms and
// conditions of the GNU General Public License cover the whole
// combination.
//
// As a special exception, the copyright holders of this library give you
// permission to link this library with independent modules to produce an
// executable, regardless of the license terms of these independent
// modules, and to copy and distribute the resulting executable under
// terms of your choice, provided that you also meet, for each linked
// independent module, the terms and conditions of the license of that
// module. An independent module is a module which is not derived from
// or based on this library. If you modify this library, you may extend
// this exception to your version of the library, but you are not
// obligated to do so. If you do not wish to do so, delete this
// exception statement from your version.
using System;
using System.IO;
using System.Collections;
using System.Text;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
namespace ICSharpCode.SharpZipLib.Zip
{
/// <summary>
/// This is a FilterOutputStream that writes the files into a zip
/// archive one after another. It has a special method to start a new
/// zip entry. The zip entries contains information about the file name
/// size, compressed size, CRC, etc.
///
/// It includes support for STORED and DEFLATED entries.
/// This class is not thread safe.
///
/// author of the original java version : Jochen Hoenicke
/// </summary>
/// <example> This sample shows how to create a zip file
/// <code>
/// using System;
/// using System.IO;
///
/// using NZlib.Zip;
///
/// class MainClass
/// {
/// public static void Main(string[] args)
/// {
/// string[] filenames = Directory.GetFiles(args[0]);
///
/// ZipOutputStream s = new
ZipOutputStream(File.Create(args[1]));
///
/// s.SetLevel(5); // 0 - store only to 9 - means best
compression
///
/// foreach (string file in filenames) {
/// FileStream fs = File.OpenRead(file);
///
/// byte[] buffer = new byte[fs.Length];
/// fs.Read(buffer, 0, buffer.Length);
///
/// ZipEntry entry = new ZipEntry(file);
///
/// s.PutNextEntry(entry);
///
/// s.Write(buffer, 0, buffer.Length);
///
/// }
///
/// s.Finish();
/// s.Close();
/// }
/// }
/// </code>
/// </example>
public class ZipOutputStream : DeflaterOutputStream
{
private ArrayList entries = new ArrayList();
private Crc32 crc = new Crc32();
private ZipEntry curEntry = null;
private CompressionMethod curMethod;
private int size;
private int offset = 0;
private byte[] zipComment = new byte[0];
private int defaultMethod = DEFLATED;
/// <summary>
/// Our Zip version is hard coded to 1.0 resp. 2.0
/// </summary>
private const int ZIP_STORED_VERSION = 10;
private const int ZIP_DEFLATED_VERSION = 20;
/// <summary>
/// Compression method. This method doesn't compress at all.
/// </summary>
public const int STORED = 0;
/// <summary>
/// Compression method. This method uses the Deflater.
/// </summary>
public const int DEFLATED = 8;
/// <summary>
/// Creates a new Zip output stream, writing a zip archive.
/// </summary>
/// <param name="baseOutputStream">
/// the output stream to which the zip archive is written.
/// </param>
public ZipOutputStream(Stream baseOutputStream) :
base(baseOutputStream, new Deflater(Deflater.DEFAULT_COMPRESSION, true))
{
}
/// <summary>
/// Set the zip file comment.
/// </summary>
/// <param name="comment">
/// the comment.
/// </param>
/// <exception name ="ArgumentException">
/// if UTF8 encoding of comment is longer than 0xffff bytes.
/// </exception>
public void SetComment(string comment)
{
byte[] commentBytes =
ZipConstants.ConvertToArray(comment);
if (commentBytes.Length > 0xffff)
{
throw new ArgumentException("Comment too
long.");
}
zipComment = commentBytes;
}
/// <summary>
/// Sets default compression method. If the Zip entry specifies
/// another method its method takes precedence.
/// </summary>
/// <param name = "method">
/// the method.
/// </param>
/// <exception name = "ArgumentException">
/// if method is not supported.
/// </exception>
public void SetMethod(int method)
{
if (method != STORED && method != DEFLATED) {
throw new ArgumentException("Method not
supported.");
}
defaultMethod = method;
}
/// <summary>
/// Sets default compression level. The new level will be
activated
/// immediately.
/// </summary>
/// <exception cref="System.ArgumentOutOfRangeException">
/// if level is not supported.
/// </exception>
/// <see cref="Deflater"/>
public void SetLevel(int level)
{
def.SetLevel(level);
}
/// <summary>
/// Write an unsigned short in little endian byte order.
/// </summary>
private void WriteLeShort(int value)
{
baseOutputStream.WriteByte((byte)value);
baseOutputStream.WriteByte((byte)(value >> 8));
}
/// <summary>
/// Write an int in little endian byte order.
/// </summary>
private void WriteLeInt(int value)
{
WriteLeShort(value);
WriteLeShort(value >> 16);
}
/// <summary>
/// Write an int in little endian byte order.
/// </summary>
private void WriteLeLong(long value)
{
WriteLeInt((int)value);
WriteLeInt((int)(value >> 32));
}
bool shouldWriteBack = false;
long seekPos = -1;
/// <summary>
/// Starts a new Zip entry. It automatically closes the previous
/// entry if present. If the compression method is stored, the
entry
/// must have a valid size and crc, otherwise all elements
(except
/// name) are optional, but must be correct if present. If the
time
/// is not set in the entry, the current time is used.
/// </summary>
/// <param name="entry">
/// the entry.
/// </param>
/// <exception cref="System.IO.IOException">
/// if an I/O error occured.
/// </exception>
/// <exception cref="System.InvalidOperationException">
/// if stream was finished
/// </exception>
public void PutNextEntry(ZipEntry entry)
{
if (entries == null) {
throw new
InvalidOperationException("ZipOutputStream was finished");
}
CompressionMethod method = entry.CompressionMethod;
int flags = 0;
switch (method) {
case CompressionMethod.Stored:
if (entry.CompressedSize >= 0) {
if (entry.Size < 0) {
entry.Size =
entry.CompressedSize;
} else if (entry.Size !=
entry.CompressedSize) {
throw new
ZipException("Method STORED, but compressed size != size");
}
} else {
entry.CompressedSize =
entry.Size;
}
if (entry.Size < 0) {
throw new ZipException("Method
STORED, but size not set");
} else if (entry.Crc < 0) {
throw new ZipException("Method
STORED, but crc not set");
}
break;
case CompressionMethod.Deflated:
if (entry.CompressedSize < 0 ||
entry.Size < 0 || entry.Crc < 0) {
flags |= 8;
}
break;
}
if (curEntry != null) {
CloseEntry();
}
// if (entry.DosTime < 0) {
// entry.Time =
System.Environment.TickCount;
// }
entry.flags = flags;
entry.offset = offset;
entry.CompressionMethod = (CompressionMethod)method;
curMethod = method;
// Write the local file header
WriteLeInt(ZipConstants.LOCSIG);
// write ZIP version
WriteLeShort(method == CompressionMethod.Stored ?
ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION);
if ((flags & 8) == 0) {
WriteLeShort(flags);
WriteLeShort((byte)method);
WriteLeInt((int)entry.DosTime);
WriteLeInt((int)entry.Crc);
WriteLeInt((int)entry.CompressedSize);
WriteLeInt((int)entry.Size);
} else {
if (baseOutputStream.CanSeek) {
shouldWriteBack = true;
WriteLeShort((short)(flags & ~8));
} else {
shouldWriteBack = false;
WriteLeShort(flags);
}
WriteLeShort((byte)method);
WriteLeInt((int)entry.DosTime);
seekPos = baseOutputStream.Position;
WriteLeInt(0);
WriteLeInt(0);
WriteLeInt(0);
}
byte[] name = ZipConstants.ConvertToArray(entry.Name);
if (name.Length > 0xFFFF) {
throw new ZipException("Name too long.");
}
byte[] extra = entry.ExtraData;
if (extra == null) {
extra = new byte[0];
}
if (extra.Length > 0xFFFF) {
throw new ZipException("Extra data too long.");
}
WriteLeShort(name.Length);
WriteLeShort(extra.Length);
baseOutputStream.Write(name, 0, name.Length);
baseOutputStream.Write(extra, 0, extra.Length);
offset += ZipConstants.LOCHDR + name.Length +
extra.Length;
/* Activate the entry. */
curEntry = entry;
crc.Reset();
if (method == CompressionMethod.Deflated) {
def.Reset();
}
size = 0;
}
/// <summary>
/// Closes the current entry.
/// </summary>
/// <exception cref="System.IO.IOException">
/// if an I/O error occured.
/// </exception>
/// <exception cref="System.InvalidOperationException">
/// if no entry is active.
/// </exception>
public void CloseEntry()
{
if (curEntry == null) {
throw new InvalidOperationException("No open
entry");
}
/* First finish the deflater, if appropriate */
if (curMethod == CompressionMethod.Deflated) {
base.Finish();
}
int csize = curMethod == CompressionMethod.Deflated ?
def.TotalOut : size;
if (curEntry.Size < 0) {
curEntry.Size = size;
} else if (curEntry.Size != size) {
throw new ZipException("size was " + size + ",
but I expected " + curEntry.Size);
}
if (curEntry.CompressedSize < 0) {
curEntry.CompressedSize = csize;
} else if (curEntry.CompressedSize != csize) {
throw new ZipException("compressed size was " +
csize + ", but I expected " + curEntry.CompressedSize);
}
if (curEntry.Crc < 0) {
curEntry.Crc = crc.Value;
} else if (curEntry.Crc != crc.Value) {
throw new ZipException("crc was " + crc.Value +
", but I expected " +
curEntry.Crc);
}
offset += csize;
/* Now write the data descriptor entry if needed. */
if (curMethod == CompressionMethod.Deflated &&
(curEntry.flags & 8) != 0) {
if (shouldWriteBack) {
curEntry.flags &= ~8;
long curPos = baseOutputStream.Position;
baseOutputStream.Seek(seekPos,
SeekOrigin.Begin);
WriteLeInt((int)curEntry.Crc);
WriteLeInt((int)curEntry.CompressedSize);
WriteLeInt((int)curEntry.Size);
baseOutputStream.Seek(curPos,
SeekOrigin.Begin);
shouldWriteBack = false;
} else {
WriteLeInt(ZipConstants.EXTSIG);
WriteLeInt((int)curEntry.Crc);
WriteLeInt((int)curEntry.CompressedSize);
WriteLeInt((int)curEntry.Size);
offset += ZipConstants.EXTHDR;
}
}
entries.Add(curEntry);
curEntry = null;
}
/// <summary>
/// Writes the given buffer to the current entry.
/// </summary>
/// <exception cref="System.IO.IOException">
/// if an I/O error occured.
/// </exception>
/// <exception cref="System.InvalidOperationException">
/// if no entry is active.
/// </exception>
public override void Write(byte[] b, int off, int len)
{
if (curEntry == null) {
throw new InvalidOperationException("No open
entry.");
}
switch (curMethod) {
case CompressionMethod.Deflated:
base.Write(b, off, len);
break;
case CompressionMethod.Stored:
baseOutputStream.Write(b, off, len);
break;
}
crc.Update(b, off, len);
size += len;
}
/// <summary>
/// Finishes the stream. This will write the central directory
at the
/// end of the zip file and flush the stream.
/// </summary>
/// <exception cref="System.IO.IOException">
/// if an I/O error occured.
/// </exception>
public override void Finish()
{
if (entries == null) {
return;
}
if (curEntry != null) {
CloseEntry();
}
int numEntries = 0;
int sizeEntries = 0;
foreach (ZipEntry entry in entries) {
// TODO : check the appnote file for compilance
with the central directory standard
CompressionMethod method =
entry.CompressionMethod;
WriteLeInt(ZipConstants.CENSIG);
WriteLeShort(method == CompressionMethod.Stored
? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION);
WriteLeShort(method == CompressionMethod.Stored
? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION);
if (entry.IsCrypted) {
entry.flags |= 1;
}
WriteLeShort(entry.flags);
WriteLeShort((short)method);
WriteLeInt((int)entry.DosTime);
WriteLeInt((int)entry.Crc);
WriteLeInt((int)entry.CompressedSize);
WriteLeInt((int)entry.Size);
byte[] name =
ZipConstants.ConvertToArray(entry.Name);
if (name.Length > 0xffff) {
throw new ZipException("Name too
long.");
}
byte[] extra = entry.ExtraData;
if (extra == null) {
extra = new byte[0];
}
string strComment = entry.Comment;
byte[] comment = strComment != null ?
ZipConstants.ConvertToArray(strComment) : new byte[0];
if (comment.Length > 0xffff) {
throw new ZipException("Comment too
long.");
}
WriteLeShort(name.Length);
WriteLeShort(extra.Length);
WriteLeShort(comment.Length);
WriteLeShort(0); // disk number
WriteLeShort(0); // internal file attr
WriteLeInt(0); // external file attr
WriteLeInt(entry.offset);
baseOutputStream.Write(name, 0, name.Length);
baseOutputStream.Write(extra, 0,
extra.Length);
baseOutputStream.Write(comment, 0,
comment.Length);
++numEntries;
sizeEntries += ZipConstants.CENHDR +
name.Length + extra.Length + comment.Length;
}
WriteLeInt(ZipConstants.ENDSIG);
WriteLeShort(0); // disk number
WriteLeShort(0); // disk with start of central dir
WriteLeShort(numEntries);
WriteLeShort(numEntries);
WriteLeInt(sizeEntries);
WriteLeInt(offset);
WriteLeShort(zipComment.Length);
baseOutputStream.Write(zipComment, 0,
zipComment.Length);
baseOutputStream.Flush();
entries = null;
}
}
}
--- NEW FILE: ZipInputStream.cs ---
// ZipInputStream.cs
// Copyright (C) 2001 Mike Krueger
//
// This file was translated from java, it was part of the GNU Classpath
// Copyright (C) 2001 Free Software Foundation, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// Linking this library statically or dynamically with other modules is
// making a combined work based on this library. Thus, the terms and
// conditions of the GNU General Public License cover the whole
// combination.
//
// As a special exception, the copyright holders of this library give you
// permission to link this library with independent modules to produce an
// executable, regardless of the license terms of these independent
// modules, and to copy and distribute the resulting executable under
// terms of your choice, provided that you also meet, for each linked
// independent module, the terms and conditions of the license of that
// module. An independent module is a module which is not derived from
// or based on this library. If you modify this library, you may extend
// this exception to your version of the library, but you are not
// obligated to do so. If you do not wish to do so, delete this
// exception statement from your version.
using System;
using System.Text;
using System.IO;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
namespace ICSharpCode.SharpZipLib.Zip
{
/// <summary>
/// This is a FilterInputStream that reads the files baseInputStream an
zip archive
/// one after another. It has a special method to get the zip entry of
/// the next file. The zip entry contains information about the file
name
/// size, compressed size, CRC, etc.
/// It includes support for STORED and DEFLATED entries.
///
/// author of the original java version : Jochen Hoenicke
/// </summary>
/// <example> This sample shows how to read a zip file
/// <code lang="C#">
/// using System;
/// using System.Text;
/// using System.IO;
///
/// using NZlib.Zip;
///
/// class MainClass
/// {
/// public static void Main(string[] args)
/// {
/// ZipInputStream s = new
ZipInputStream(File.OpenRead(args[0]));
///
/// ZipEntry theEntry;
/// while ((theEntry = s.GetNextEntry()) != null) {
/// int size = 2048;
/// byte[] data = new byte[2048];
///
/// Console.Write("Show contents (y/n) ?");
/// if (Console.ReadLine() == "y") {
/// while (true) {
/// size = s.Read(data, 0,
data.Length);
/// if (size > 0) {
/// Console.Write(new
ASCIIEncoding().GetString(data, 0, size));
/// } else {
/// break;
/// }
/// }
/// }
/// }
/// s.Close();
/// }
/// }
/// </code>
/// </example>
public class ZipInputStream : InflaterInputStream
{
Crc32 crc = new Crc32();
ZipEntry entry = null;
long size;
int method;
int flags;
long avail;
string password = null;
public string Password {
get {
return password;
}
set {
password = value;
}
}
/// <summary>
/// Creates a new Zip input stream, reading a zip archive.
/// </summary>
public ZipInputStream(Stream baseInputStream) :
base(baseInputStream, new Inflater(true))
{
}
void FillBuf()
{
avail = len = baseInputStream.Read(buf, 0, buf.Length);
}
int ReadBuf(byte[] outBuf, int offset, int length)
{
if (avail <= 0) {
FillBuf();
if (avail <= 0) {
return -1;
}
}
if (length > avail) {
length = (int)avail;
}
System.Array.Copy(buf, len - (int)avail, outBuf,
offset, length);
avail -= length;
return length;
}
void ReadFully(byte[] outBuf)
{
int off = 0;
int len = outBuf.Length;
while (len > 0) {
int count = ReadBuf(outBuf, off, len);
if (count == -1) {
throw new Exception();
}
off += count;
len -= count;
}
}
int ReadLeByte()
{
if (avail <= 0) {
FillBuf();
if (avail <= 0) {
throw new ZipException("EOF in header");
}
}
return buf[len - avail--] & 0xff;
}
/// <summary>
/// Read an unsigned short baseInputStream little endian byte
order.
/// </summary>
int ReadLeShort()
{
return ReadLeByte() | (ReadLeByte() << 8);
}
/// <summary>
/// Read an int baseInputStream little endian byte order.
/// </summary>
int ReadLeInt()
{
return ReadLeShort() | (ReadLeShort() << 16);
}
/// <summary>
/// Read an int baseInputStream little endian byte order.
/// </summary>
long ReadLeLong()
{
return ReadLeInt() | (ReadLeInt() << 32);
}
/// <summary>
/// Open the next entry from the zip archive, and return its
description.
/// If the previous entry wasn't closed, this method will close
it.
/// </summary>
public ZipEntry GetNextEntry()
{
if (crc == null) {
throw new InvalidOperationException("Closed.");
}
if (entry != null) {
CloseEntry();
}
if (this.cryptbuffer != null) {
if (avail == 0 && inf.RemainingInput != 0) {
avail = inf.RemainingInput - 16;
inf.Reset();
}
baseInputStream.Position -= this.len;
baseInputStream.Read(this.buf, 0, this.len);
}
int header = ReadLeInt();
if (header == ZipConstants.CENSIG) {
/* Central Header reached. */
Close();
return null;
}
if (header != ZipConstants.LOCSIG) {
throw new ZipException("Wrong Local header
signature: 0x" + String.Format("{0:X}", header));
}
short version = (short)ReadLeShort();
flags = ReadLeShort();
method = ReadLeShort();
uint dostime = (uint)ReadLeInt();
int crc2 = ReadLeInt();
csize = ReadLeInt();
size = ReadLeInt();
int nameLen = ReadLeShort();
int extraLen = ReadLeShort();
bool isCrypted = (flags & 1) == 1;
if (method == ZipOutputStream.STORED && (!isCrypted &&
csize != size || (isCrypted && csize - 12 != size))) {
throw new ZipException("Stored, but compressed
!= uncompressed");
}
byte[] buffer = new byte[nameLen];
ReadFully(buffer);
string name = ZipConstants.ConvertToString(buffer);
entry = new ZipEntry(name);
entry.IsCrypted = isCrypted;
entry.Version = (ushort)version;
if (method != 0 && method != 8) {
throw new ZipException("unknown compression
method " + method);
}
entry.CompressionMethod = (CompressionMethod)method;
if ((flags & 8) == 0) {
entry.Crc = crc2 & 0xFFFFFFFFL;
entry.Size = size & 0xFFFFFFFFL;
entry.CompressedSize = csize & 0xFFFFFFFFL;
}
entry.DosTime = dostime;
if (extraLen > 0) {
byte[] extra = new byte[extraLen];
ReadFully(extra);
entry.ExtraData = extra;
}
// test for encryption
if (isCrypted) {
if (password == null) {
throw new ZipException("No password
set.");
}
InitializePassword(password);
cryptbuffer = new byte[12];
ReadFully(cryptbuffer);
//crc.Update(cryptbuffer);
for (int i = 0; i < 12; ++i) {
cryptbuffer[i] ^= DecryptByte();
UpdateKeys(cryptbuffer[i]);
}
//cryptbuffer = cryptbuffer2;
csize -= 12;
} else {
cryptbuffer = null;
}
if (method == ZipOutputStream.DEFLATED && avail > 0) {
System.Array.Copy(buf, len - (int)avail, buf,
0, (int)avail);
len = (int)avail;
avail = 0;
if (isCrypted) {
DecryptBlock(buf, 0,
Math.Min((int)csize, len));
}
inf.SetInput(buf, 0, len);
}
return entry;
}
private void ReadDataDescr()
{
if (ReadLeInt() != ZipConstants.EXTSIG) {
throw new ZipException("Data descriptor
signature not found");
}
entry.Crc = ReadLeInt() & 0xFFFFFFFFL;
csize = ReadLeInt();
size = ReadLeInt();
entry.Size = size & 0xFFFFFFFFL;
entry.CompressedSize = csize & 0xFFFFFFFFL;
}
/// <summary>
/// Closes the current zip entry and moves to the next one.
/// </summary>
public void CloseEntry()
{
if (crc == null) {
throw new InvalidOperationException("Closed.");
}
if (entry == null) {
return;
}
if (method == ZipOutputStream.DEFLATED) {
if ((flags & 8) != 0) {
/* We don't know how much we must skip,
read until end. */
byte[] tmp = new byte[2048];
while (Read(tmp, 0, tmp.Length) > 0)
;
/* read will close this entry */
return;
}
csize -= inf.TotalIn;
avail = inf.RemainingInput;
}
if (avail > csize && csize >= 0) {
avail -= csize;
} else {
csize -= avail;
avail = 0;
while (csize != 0) {
int skipped = (int)base.Skip(csize &
0xFFFFFFFFL);
if (skipped <= 0) {
throw new ZipException("zip
archive ends early.");
}
csize -= skipped;
}
}
size = 0;
crc.Reset();
if (method == ZipOutputStream.DEFLATED) {
inf.Reset();
}
entry = null;
}
public override int Available {
get {
return entry != null ? 1 : 0;
}
}
/// <summary>
/// Reads a byte from the current zip entry.
/// </summary>
/// <returns>
/// the byte or -1 on EOF.
/// </returns>
/// <exception name="System.IO.IOException">
/// IOException if a i/o error occured.
/// </exception>
/// <exception name="ICSharpCode.SharpZipLib.ZipException">
/// ZipException if the deflated stream is corrupted.
/// </exception>
public override int ReadByte()
{
byte[] b = new byte[1];
if (Read(b, 0, 1) <= 0) {
return -1;
}
return b[0] & 0xff;
}
/// <summary>
/// Reads a block of bytes from the current zip entry.
/// </summary>
/// <returns>
/// the number of bytes read (may be smaller, even before EOF),
or -1 on EOF.
/// </returns>
/// <exception name="Exception">
/// IOException if a i/o error occured.
/// ZipException if the deflated stream is corrupted.
/// </exception>
public override int Read(byte[] b, int off, int len)
{
if (crc == null) {
throw new InvalidOperationException("Closed.");
}
if (entry == null) {
return -1;
}
bool finished = false;
switch (method) {
case ZipOutputStream.DEFLATED:
len = base.Read(b, off, len);
if (len <= 0) {
if (!inf.IsFinished) {
throw new
ZipException("Inflater not finished!?");
}
avail = inf.RemainingInput;
if (inf.TotalIn != csize ||
inf.TotalOut != size) {
throw new
ZipException("size mismatch: " + csize + ";" + size + " <-> " + inf.TotalIn +
";" + inf.TotalOut);
}
inf.Reset();
finished = true;
}
break;
case ZipOutputStream.STORED:
if (len > csize && csize >= 0) {
len = (int)csize;
}
len = ReadBuf(b, off, len);
if (len > 0) {
csize -= len;
size -= len;
}
if (csize == 0) {
finished = true;
} else {
if (len < 0) {
throw new
ZipException("EOF in stored block");
}
}
// decrypting crypted data
if (cryptbuffer != null) {
DecryptBlock(b, off,
System.Math.Min((int)(csize - inf.TotalIn), len));
}
break;
}
if (len > 0) {
crc.Update(b, off, len);
}
if (finished) {
if ((flags & 8) != 0) {
ReadDataDescr();
}
// Console.WriteLine("{0:x}",crc.Value &
0xFFFFFFFFL);
// Console.WriteLine(entry.Crc);
if ((crc.Value & 0xFFFFFFFFL) != entry.Crc &&
entry.Crc != -1) {
throw new ZipException("CRC mismatch");
}
crc.Reset();
entry = null;
}
return len;
}
/// <summary>
/// Closes the zip file.
/// </summary>
/// <exception name="Exception">
/// if a i/o error occured.
/// </exception>
public override void Close()
{
base.Close();
crc = null;
entry = null;
}
}
}
--- NEW FILE: ZipFile.cs ---
// ZipFile.cs
// Copyright (C) 2001 Mike Krueger
//
// This file was translated from java, it was part of the GNU Classpath
// Copyright (C) 2001 Free Software Foundation, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// Linking this library statically or dynamically with other modules is
// making a combined work based on this library. Thus, the terms and
// conditions of the GNU General Public License cover the whole
// combination.
//
// As a special exception, the copyright holders of this library give you
// permission to link this library with independent modules to produce an
// executable, regardless of the license terms of these independent
// modules, and to copy and distribute the resulting executable under
// terms of your choice, provided that you also meet, for each linked
// independent module, the terms and conditions of the license of that
// module. An independent module is a module which is not derived from
// or based on this library. If you modify this library, you may extend
// this exception to your version of the library, but you are not
// obligated to do so. If you do not wish to do so, delete this
// exception statement from your version.
using System;
using System.Collections;
using System.IO;
using System.Text;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using ICSharpCode.SharpZipLib.Zip.Compression;
namespace ICSharpCode.SharpZipLib.Zip
{
/// <summary>
/// This class represents a Zip archive. You can ask for the contained
/// entries, or get an input stream for a file entry. The entry is
/// automatically decompressed.
///
/// This class is thread safe: You can open input streams for arbitrary
/// entries in different threads.
///
/// author of the original java version : Jochen Hoenicke
/// </summary>
/// <example>
/// using System;
/// using System.Text;
/// using System.Collections;
/// using System.IO;
///
/// using NZlib.Zip;
///
/// class MainClass
/// {
/// static public void Main(string[] args)
/// {
/// ZipFile zFile = new ZipFile(args[0]);
/// //Console.WriteLine("Listing of : " + zFile.Name);
/// //Console.WriteLine("");
/// //Console.WriteLine("Raw Size Size Date
Time Name");
/// //Console.WriteLine("-------- -------- --------
------ ---------");
/// foreach (ZipEntry e in zFile) {
/// DateTime d = e.DateTime;
/// //Console.WriteLine("{0, -10}{1, -10}{2} {3}
{4}", e.Size, e.CompressedSize,
///
d.ToString("dd-MM-yy"), d.ToString("t"),
///
e.Name);
/// }
/// }
/// }
/// </example>
public class ZipFile : IEnumerable
{
string name;
string comment;
Stream baseStream;
ZipEntry[] entries;
/// <summary>
/// Opens a Zip file with the given name for reading.
/// </summary>
/// <exception name="System.IO.IOException">
/// IOException if a i/o error occured.
/// </exception>
/// <exception name="ICSharpCode.SharpZipLib.ZipException">
/// if the file doesn't contain a valid zip archive.
/// </exception>
public ZipFile(string name) : this(File.OpenRead(name))
{
}
/// <summary>
/// Opens a Zip file reading the given FileStream
/// </summary>
/// <exception name="System.IO.IOException">
/// IOException if a i/o error occured.
/// </exception>
/// <exception name="ICSharpCode.SharpZipLib.ZipException">
/// if the file doesn't contain a valid zip archive.
/// </exception>
public ZipFile(FileStream file)
{
this.baseStream = file;
#if !ECMA_COMPAT
this.name = file.Name;
#endif
ReadEntries();
}
/// <summary>
/// Opens a Zip file reading the given Stream
/// </summary>
/// <exception name="System.IO.IOException">
/// IOException if a i/o error occured.
/// </exception>
/// <exception name="ICSharpCode.SharpZipLib.ZipException">
/// if the file doesn't contain a valid zip archive.
/// </exception>
public ZipFile(Stream baseStream)
{
this.baseStream = baseStream;
this.name = null;
ReadEntries();
}
/// <summary>
/// Read an unsigned short in little endian byte order.
/// </summary>
/// <exception name="System.IO.IOException">
/// if a i/o error occured.
/// </exception>
/// <exception name="System.IO.EndOfStreamException">
/// if the file ends prematurely
/// </exception>
int ReadLeShort()
{
return baseStream.ReadByte() | baseStream.ReadByte() <<
8;
}
/// <summary>
/// Read an int in little endian byte order.
/// </summary>
/// <exception name="System.IO.IOException">
/// if a i/o error occured.
/// </exception>
/// <exception name="System.IO.EndOfStreamException">
/// if the file ends prematurely
/// </exception>
int ReadLeInt()
{
return ReadLeShort() | ReadLeShort() << 16;
}
/// <summary>
/// Read the central directory of a zip file and fill the
entries
/// array. This is called exactly once by the constructors.
/// </summary>
/// <exception name="System.IO.IOException">
/// if a i/o error occured.
/// </exception>
/// <exception name="ICSharpCode.SharpZipLib.ZipException">
/// if the central directory is malformed
/// </exception>
void ReadEntries()
{
/* Search for the End Of Central Directory. When a zip
comment is
* present the directory may start earlier.
* FIXME: This searches the whole file in a very slow
manner if the
* file isn't a zip file.
*/
long pos = baseStream.Length - ZipConstants.ENDHDR;
do {
if (pos < 0) {
throw new ZipException("central
directory not found, probably not a zip file");
}
baseStream.Seek(pos--, SeekOrigin.Begin);
} while (ReadLeInt() != ZipConstants.ENDSIG);
long oldPos = baseStream.Position;
baseStream.Position += ZipConstants.ENDTOT -
ZipConstants.ENDNRD;
if (baseStream.Position - oldPos != ZipConstants.ENDTOT
- ZipConstants.ENDNRD) {
throw new EndOfStreamException();
}
int count = ReadLeShort();
oldPos = baseStream.Position;
baseStream.Position += ZipConstants.ENDOFF -
ZipConstants.ENDSIZ;
if (baseStream.Position - oldPos != ZipConstants.ENDOFF
- ZipConstants.ENDSIZ) {
throw new EndOfStreamException();
}
int centralOffset = ReadLeInt();
// GET COMMENT SIZE (COMES AFTER CENTRALOFFSET)
int commentSize = ReadLeShort();
byte[] zipComment = new byte[commentSize];
baseStream.Read(zipComment, 0, zipComment.Length);
comment = ZipConstants.ConvertToString(zipComment);
entries = new ZipEntry[count];
baseStream.Seek(centralOffset, SeekOrigin.Begin);
for (int i = 0; i < count; i++) {
if (ReadLeInt() != ZipConstants.CENSIG) {
throw new ZipException("Wrong Central
Directory signature");
}
oldPos = baseStream.Position;
baseStream.Position += ZipConstants.CENHOW -
ZipConstants.CENVEM;
if (baseStream.Position - oldPos !=
ZipConstants.CENHOW - ZipConstants.CENVEM) {
throw new EndOfStreamException();
}
int method = ReadLeShort();
int dostime = ReadLeInt();
int crc = ReadLeInt();
int csize = ReadLeInt();
int size = ReadLeInt();
int nameLen = ReadLeShort();
int extraLen = ReadLeShort();
int commentLen = ReadLeShort();
oldPos = baseStream.Position;
baseStream.Position += ZipConstants.CENOFF -
ZipConstants.CENDSK;
if (baseStream.Position - oldPos !=
ZipConstants.CENOFF - ZipConstants.CENDSK) {
throw new EndOfStreamException();
}
int offset = ReadLeInt();
byte[] buffer = new byte[Math.Max(nameLen,
commentLen)];
baseStream.Read(buffer, 0, nameLen);
string name =
ZipConstants.ConvertToString(buffer);
ZipEntry entry = new ZipEntry(name);
entry.CompressionMethod =
(CompressionMethod)method;
entry.Crc = crc & 0xffffffffL;
entry.Size = size & 0xffffffffL;
entry.CompressedSize = csize & 0xffffffffL;
entry.DosTime = (uint)dostime;
if (extraLen > 0) {
byte[] extra = new byte[extraLen];
baseStream.Read(extra, 0, extraLen);
entry.ExtraData = extra;
}
if (commentLen > 0) {
baseStream.Read(buffer, 0, commentLen);
entry.Comment =
ZipConstants.ConvertToString(buffer);
}
entry.zipFileIndex = i;
entry.offset = offset;
entries[i] = entry;
}
}
/// <summary>
/// Closes the ZipFile. This also closes all input streams
given by
/// this class. After this is called, no further method should
be
/// called.
/// </summary>
/// <exception name="System.IO.IOException">
/// if a i/o error occured.
/// </exception>
public void Close()
{
entries = null;
lock(baseStream) {
baseStream.Close();
}
}
/// <summary>
/// Returns an IEnumerator of all Zip entries in this Zip file.
/// </summary>
public IEnumerator GetEnumerator()
{
if (entries == null) {
throw new InvalidOperationException("ZipFile
has closed");
}
return new ZipEntryEnumeration(entries);
}
int GetEntryIndex(string name)
{
for (int i = 0; i < entries.Length; i++) {
if (name.Equals(entries[i].Name)) {
return i;
}
}
return -1;
}
/// <summary>
/// Searches for a zip entry in this archive with the given
name.
/// </summary>
/// <param name="name">
/// the name. May contain directory components separated by
slashes ('/').
/// </param>
/// <returns>
/// the zip entry, or null if no entry with that name exists.
/// </returns>
public ZipEntry GetEntry(string name)
{
if (entries == null) {
throw new InvalidOperationException("ZipFile
has closed");
}
int index = GetEntryIndex(name);
return index >= 0 ? (ZipEntry) entries[index].Clone() :
null;
}
/// <summary>
/// Checks, if the local header of the entry at index i matches
the
/// central directory, and returns the offset to the data.
/// </summary>
/// <returns>
/// the start offset of the (compressed) data.
/// </returns>
/// <exception name="System.IO.IOException">
/// if a i/o error occured.
/// </exception>
/// <exception name="ICSharpCode.SharpZipLib.ZipException">
/// if the local header doesn't match the central directory
header
/// </exception>
long CheckLocalHeader(ZipEntry entry)
{
lock(baseStream) {
baseStream.Seek(entry.offset, SeekOrigin.Begin);
if (ReadLeInt() != ZipConstants.LOCSIG) {
throw new ZipException("Wrong Local
header signature");
}
/* skip version and flags */
long oldPos = baseStream.Position;
baseStream.Position += ZipConstants.LOCHOW -
ZipConstants.LOCVER;
if (baseStream.Position - oldPos !=
ZipConstants.LOCHOW - ZipConstants.LOCVER) {
throw new EndOfStreamException();
}
if (entry.CompressionMethod !=
(CompressionMethod)ReadLeShort()) {
throw new ZipException("Compression
method mismatch");
}
/* Skip time, crc, size and csize */
oldPos = baseStream.Position;
baseStream.Position += ZipConstants.LOCNAM -
ZipConstants.LOCTIM;
if (baseStream.Position - oldPos !=
ZipConstants.LOCNAM - ZipConstants.LOCTIM) {
throw new EndOfStreamException();
}
if (entry.Name.Length != ReadLeShort()) {
throw new ZipException("file name
length mismatch");
}
int extraLen = entry.Name.Length +
ReadLeShort();
return entry.offset + ZipConstants.LOCHDR +
extraLen;
}
}
/// <summary>
/// Creates an input stream reading the given zip entry as
/// uncompressed data. Normally zip entry should be an entry
/// returned by GetEntry().
/// </summary>
/// <returns>
/// the input stream.
/// </returns>
/// <exception name="System.IO.IOException">
/// if a i/o error occured.
/// </exception>
/// <exception name="ICSharpCode.SharpZipLib.ZipException">
/// if the Zip archive is malformed.
/// </exception>
public Stream GetInputStream(ZipEntry entry)
{
if (entries == null) {
throw new InvalidOperationException("ZipFile
has closed");
}
int index = entry.zipFileIndex;
if (index < 0 || index >= entries.Length ||
entries[index].Name != entry.Name) {
index = GetEntryIndex(entry.Name);
if (index < 0) {
throw new IndexOutOfRangeException();
}
}
long start = CheckLocalHeader(entries[index]);
CompressionMethod method =
entries[index].CompressionMethod;
Stream istr = new PartialInputStream(baseStream, start,
entries[index].CompressedSize);
switch (method) {
case CompressionMethod.Stored:
return istr;
case CompressionMethod.Deflated:
return new InflaterInputStream(istr,
new Inflater(true));
default:
throw new ZipException("Unknown
compression method " + method);
}
}
/// <summary>
/// The comment for the whole zip file.
/// </summary>
public string ZipFileComment {
get {
return comment;
}
set {
comment = value;
}
}
/// <summary>
/// Returns the name of this zip file.
/// </summary>
public string Name {
get {
return name;
}
}
/// <summary>
/// Returns the number of entries in this zip file.
/// </summary>
public int Size {
get {
try {
return entries.Length;
} catch (Exception) {
throw new
InvalidOperationException("ZipFile has closed");
}
}
}
class ZipEntryEnumeration : IEnumerator
{
ZipEntry[] array;
int ptr = -1;
public ZipEntryEnumeration(ZipEntry[] arr)
{
array = arr;
}
public object Current {
get {
return array[ptr];
}
}
public void Reset()
{
ptr = -1;
}
public bool MoveNext()
{
return (++ptr < array.Length);
}
}
class PartialInputStream : InflaterInputStream
{
Stream baseStream;
long filepos, end;
public PartialInputStream(Stream baseStream, long
start, long len) : base(baseStream)
{
this.baseStream = baseStream;
filepos = start;
end = start + len;
}
public override int Available
{
get {
long amount = end - filepos;
if (amount > Int32.MaxValue) {
return Int32.MaxValue;
}
return (int) amount;
}
}
public override int ReadByte()
{
if (filepos == end) {
return -1;
}
lock(baseStream) {
baseStream.Seek(filepos++,
SeekOrigin.Begin);
return baseStream.ReadByte();
}
}
public override int Read(byte[] b, int off, int len)
{
if (len > end - filepos) {
len = (int) (end - filepos);
if (len == 0) {
return -1;
}
}
lock(baseStream) {
baseStream.Seek(filepos,
SeekOrigin.Begin);
int count = baseStream.Read(b, off,
len);
if (count > 0) {
filepos += len;
}
return count;
}
}
public long SkipBytes(long amount)
{
if (amount < 0) {
throw new ArgumentOutOfRangeException();
}
if (amount > end - filepos) {
amount = end - filepos;
}
filepos += amount;
return amount;
}
}
}
}
--- NEW FILE: ZipEntry.cs ---
// ZipEntry.cs
// Copyright (C) 2001 Mike Krueger
//
// This file was translated from java, it was part of the GNU Classpath
// Copyright (C) 2001 Free Software Foundation, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// Linking this library statically or dynamically with other modules is
// making a combined work based on this library. Thus, the terms and
// conditions of the GNU General Public License cover the whole
// combination.
//
// As a special exception, the copyright holders of this library give you
// permission to link this library with independent modules to produce an
// executable, regardless of the license terms of these independent
// modules, and to copy and distribute the resulting executable under
// terms of your choice, provided that you also meet, for each linked
// independent module, the terms and conditions of the license of that
// module. An independent module is a module which is not derived from
// or based on this library. If you modify this library, you may extend
// this exception to your version of the library, but you are not
// obligated to do so. If you do not wish to do so, delete this
// exception statement from your version.
using System;
namespace ICSharpCode.SharpZipLib.Zip
{
public enum CompressionMethod
{
Stored = 0,
Deflated = 8,
}
/// <summary>
/// This class represents a member of a zip archive. ZipFile and
/// ZipInputStream will give you instances of this class as information
/// about the members in an archive. On the other hand ZipOutputStream
/// needs an instance of this class to create a new member.
///
/// author of the original java version : Jochen Hoenicke
/// </summary>
public class ZipEntry : ICloneable
{
static int KNOWN_SIZE = 1;
static int KNOWN_CSIZE = 2;
static int KNOWN_CRC = 4;
static int KNOWN_TIME = 8;
string name;
uint size;
ushort version;
uint compressedSize;
uint crc;
uint dosTime;
ushort known = 0;
CompressionMethod method = CompressionMethod.Deflated;
byte[] extra = null;
string comment = null;
bool isCrypted;
public int zipFileIndex = -1; /* used by ZipFile */
public int flags; /* used by ZipOutputStream */
public int offset; /* used by ZipFile and
ZipOutputStream */
/// <summary>
/// Creates a zip entry with the given name.
/// </summary>
/// <param name="name">
/// the name. May include directory components separated by '/'.
/// </param>
public ZipEntry(string name)
{
if (name == null) {
throw new System.ArgumentNullException("name");
}
this.DateTime = System.DateTime.Now;
this.name = name;
}
/// <summary>
/// Creates a copy of the given zip entry.
/// </summary>
/// <param name="e">
/// the entry to copy.
/// </param>
public ZipEntry(ZipEntry e)
{
name = e.name;
known = e.known;
size = e.size;
compressedSize = e.compressedSize;
crc = e.crc;
dosTime = e.dosTime;
method = e.method;
extra = e.extra;
comment = e.comment;
}
public ushort Version {
get {
return version;
}
set {
version = value;
}
}
public uint DosTime {
get {
if ((known & KNOWN_TIME) == 0) {
return 0;
} else {
return dosTime;
}
}
set {
this.dosTime = value;
known |= (ushort)KNOWN_TIME;
}
}
/// <summary>
/// Gets/Sets the time of last modification of the entry.
/// </summary>
public DateTime DateTime {
get {
uint sec = 2 * (dosTime & 0x1f);
uint min = (dosTime >> 5) & 0x3f;
uint hrs = (dosTime >> 11) & 0x1f;
uint day = (dosTime >> 16) & 0x1f;
uint mon = ((dosTime >> 21) & 0xf);
uint year = ((dosTime >> 25) & 0x7f) + 1980; /*
since 1900 */
return new System.DateTime((int)year, (int)mon,
(int)day, (int)hrs, (int)min, (int)sec);
}
set {
DosTime = ((uint)value.Year - 1980 & 0x7f) <<
25 |
((uint)value.Month) << 21 |
((uint)value.Day) << 16 |
((uint)value.Hour) << 11 |
((uint)value.Minute) << 5 |
((uint)value.Second) >> 1;
}
}
/// <summary>
/// Returns the entry name. The path components in the entry
are
/// always separated by slashes ('/').
/// </summary>
public string Name {
get {
return name;
}
}
// /// <summary>
// /// Gets/Sets the time of last modification of
the entry.
// /// </summary>
// /// <returns>
// /// the time of last modification of the entry,
or -1 if unknown.
// /// </returns>
// public long Time {
// get {
// return (known & KNOWN_TIME) !=
0 ? time * 1000L : -1;
// }
// set {
// this.time = (int) (value /
1000L);
// this.known |=
(ushort)KNOWN_TIME;
// }
// }
/// <summary>
/// Gets/Sets the size of the uncompressed data.
/// </summary>
/// <exception cref="System.ArgumentOutOfRangeException">
/// if size is not in 0..0xffffffffL
/// </exception>
/// <returns>
/// the size or -1 if unknown.
/// </returns>
public long Size {
get {
return (known & KNOWN_SIZE) != 0 ? (long)size :
-1L;
}
set {
if (((ulong)value & 0xFFFFFFFF00000000L) != 0) {
throw new
ArgumentOutOfRangeException("size");
}
this.size = (uint)value;
this.known |= (ushort)KNOWN_SIZE;
}
}
/// <summary>
/// Gets/Sets the size of the compressed data.
/// </summary>
/// <exception cref="System.ArgumentOutOfRangeException">
/// if csize is not in 0..0xffffffffL
/// </exception>
/// <returns>
/// the size or -1 if unknown.
/// </returns>
public long CompressedSize {
get {
return (known & KNOWN_CSIZE) != 0 ?
(long)compressedSize : -1L;
}
set {
if (((ulong)value & 0xffffffff00000000L) != 0) {
throw new ArgumentOutOfRangeException();
}
this.compressedSize = (uint)value;
this.known |= (ushort)KNOWN_CSIZE;
}
}
/// <summary>
/// Gets/Sets the crc of the uncompressed data.
/// </summary>
/// <exception cref="System.ArgumentOutOfRangeException">
/// if crc is not in 0..0xffffffffL
/// </exception>
/// <returns>
/// the crc or -1 if unknown.
/// </returns>
public long Crc {
get {
return (known & KNOWN_CRC) != 0 ? crc &
0xffffffffL : -1L;
}
set {
if (((ulong)crc & 0xffffffff00000000L) != 0)
{
throw new Exception();
}
this.crc = (uint)value;
this.known |= (ushort)KNOWN_CRC;
}
}
/// <summary>
/// Gets/Sets the compression method. Only DEFLATED and STORED
are supported.
/// </summary>
/// <exception cref="System.ArgumentOutOfRangeException">
/// if method is not supported.
/// </exception>
/// <returns>
/// the compression method or -1 if unknown.
/// </returns>
/// <see cref="ZipOutputStream.DEFLATED"/>
/// <see cref="ZipOutputStream.STORED"/>
public CompressionMethod CompressionMethod {
get {
return method;
}
set {
this.method = value;
}
}
/// <summary>
/// Gets/Sets the extra data.
/// </summary>
/// <exception cref="System.ArgumentOutOfRangeException">
/// if extra is longer than 0xffff bytes.
/// </exception>
/// <returns>
/// the extra data or null if not set.
/// </returns>
public byte[] ExtraData {
get {
return extra;
}
set {
if (value == null) {
this.extra = null;
return;
}
if (value.Length > 0xffff) {
throw new
System.ArgumentOutOfRangeException();
}
this.extra = value;
try {
int pos = 0;
while (pos < extra.Length) {
int sig = (extra[pos++] & 0xff)
| (extra[pos++] & 0xff) << 8;
int len = (extra[pos++] & 0xff)
| (extra[pos++] & 0xff) << 8;
if (sig == 0x5455) {
/* extended time stamp,
unix format by Rainer Prem <address@hidden> */
int flags = extra[pos];
if ((flags & 1) != 0) {
int iTime =
((extra[pos+1] & 0xff) |
(extra[pos+2] & 0xff) << 8 |
(extra[pos+3] & 0xff) << 16 |
(extra[pos+4] & 0xff) << 24);
DateTime = (new
DateTime ( 1970, 1, 1, 0, 0, 0 ) + new TimeSpan ( 0, 0, 0, iTime, 0
)).ToLocalTime ();
known |=
(ushort)KNOWN_TIME;
}
}
pos += len;
}
} catch (Exception) {
/* be lenient */
return;
}
}
}
/// <summary>
/// Gets/Sets the entry comment.
/// </summary>
/// <exception cref="System.ArgumentOutOfRangeException">
/// if comment is longer than 0xffff.
/// </exception>
/// <returns>
/// the comment or null if not set.
/// </returns>
public string Comment {
get {
return comment;
}
set {
if (value.Length > 0xffff)
{
throw new ArgumentOutOfRangeException();
}
this.comment = value;
}
}
/// <summary>
/// Gets true, if the entry is a directory. This is solely
/// determined by the name, a trailing slash '/' marks a
directory.
/// </summary>
public bool IsDirectory {
get {
int nlen = name.Length;
return nlen > 0 && name[nlen - 1] == '/';
}
}
/// <value>
/// True, if the entry is encrypted.
/// </value>
public bool IsCrypted {
get {
return isCrypted;
}
set {
isCrypted = value;
}
}
/// <summary>
/// Creates a copy of this zip entry.
/// </summary>
public object Clone()
{
return this.MemberwiseClone();
}
/// <summary>
/// Gets the string representation of this ZipEntry. This is
just
/// the name as returned by getName().
/// </summary>
public override string ToString()
{
return name;
}
}
}
--- NEW FILE: ZipConstants.cs ---
// ZipConstants.cs
// Copyright (C) 2001 Mike Krueger
//
// This file was translated from java, it was part of the GNU Classpath
// Copyright (C) 2001 Free Software Foundation, Inc.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// Linking this library statically or dynamically with other modules is
// making a combined work based on this library. Thus, the terms and
// conditions of the GNU General Public License cover the whole
// combination.
//
// As a special exception, the copyright holders of this library give you
// permission to link this library with independent modules to produce an
// executable, regardless of the license terms of these independent
// modules, and to copy and distribute the resulting executable under
// terms of your choice, provided that you also meet, for each linked
// independent module, the terms and conditions of the license of that
// module. An independent module is a module which is not derived from
// or based on this library. If you modify this library, you may extend
// this exception to your version of the library, but you are not
// obligated to do so. If you do not wish to do so, delete this
// exception statement from your version.
using System.Text;
namespace ICSharpCode.SharpZipLib.Zip
{
/// <summary>
/// This class contains constants used for zip.
/// </summary>
public sealed class ZipConstants
{
/* The local file header */
public const int LOCHDR = 30;
public const int LOCSIG = 'P' | ('K' << 8) | (3 << 16) | (4 <<
24);
public const int LOCVER = 4;
public const int LOCFLG = 6;
public const int LOCHOW = 8;
public const int LOCTIM = 10;
public const int LOCCRC = 14;
public const int LOCSIZ = 18;
public const int LOCLEN = 22;
public const int LOCNAM = 26;
public const int LOCEXT = 28;
/* The Data descriptor */
public const int EXTSIG = 'P' | ('K' << 8) | (7 << 16) | (8 <<
24);
public const int EXTHDR = 16;
public const int EXTCRC = 4;
public const int EXTSIZ = 8;
public const int EXTLEN = 12;
/* The central directory file header */
public const int CENSIG = 'P' | ('K' << 8) | (1 << 16) | (2 <<
24);
/* The central directory file header for 64bit ZIP*/
public const int CENSIG64 = 0x06064b50;
public const int CENHDR = 46;
public const int CENVEM = 4;
public const int CENVER = 6;
public const int CENFLG = 8;
public const int CENHOW = 10;
public const int CENTIM = 12;
public const int CENCRC = 16;
public const int CENSIZ = 20;
public const int CENLEN = 24;
public const int CENNAM = 28;
public const int CENEXT = 30;
public const int CENCOM = 32;
public const int CENDSK = 34;
public const int CENATT = 36;
public const int CENATX = 38;
public const int CENOFF = 42;
/* The entries in the end of central directory */
public const int ENDSIG = 'P' | ('K' << 8) | (5 << 16) | (6 <<
24);
public const int ENDHDR = 22;
/* The following two fields are missing in SUN JDK */
public const int ENDNRD = 4;
public const int ENDDCD = 6;
public const int ENDSUB = 8;
public const int ENDTOT = 10;
public const int ENDSIZ = 12;
public const int ENDOFF = 16;
public const int ENDCOM = 20;
/* Using the codepage 1252 doesn't solve the 8bit ASCII problem
:/
any help would be appreciated.
// get encoding for latin characters (like ö, ü, ß or ô)
static Encoding ecp1252 = Encoding.GetEncoding(1252);
*/
public static string ConvertToString(byte[] data)
{
return Encoding.ASCII.GetString(data,0, data.Length);
}
public static byte[] ConvertToArray(string str)
{
return Encoding.ASCII.GetBytes(str);
}
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Dotgnu-pnet-commits] pnetlib/SharpZipLib/Zip ZipConstants.cs, NONE, 1.1 ZipEntry.cs, NONE, 1.1 ZipFile.cs, NONE, 1.1 ZipInputStream.cs, NONE, 1.1 ZipOutputStream.cs, NONE, 1.1,
Rhys Weatherley <address@hidden> <=
- Prev by Date:
[Dotgnu-pnet-commits] pnetlib/SharpZipLib/Zip/Compression Deflater.cs, NONE, 1.1 DeflaterConstants.cs, NONE, 1.1 DeflaterEngine.cs, NONE, 1.1 DeflaterHuffman.cs, NONE, 1.1 DeflaterPending.cs, NONE, 1.1 Inflater.cs, NONE, 1.1 InflaterDynHeader.cs, NONE, 1.1 InflaterHuffmanTree.cs, NONE, 1.1 PendingBuffer.cs, NONE, 1.1
- Next by Date:
[Dotgnu-pnet-commits] pnetlib/SharpZipLib/Tar InvalidHeaderException.cs, NONE, 1.1 TarArchive.cs, NONE, 1.1 TarBuffer.cs, NONE, 1.1 TarEntry.cs, NONE, 1.1 TarHeader.cs, NONE, 1.1 TarInputStream.cs, NONE, 1.1 TarOutputStream.cs, NONE, 1.1
- Previous by thread:
[Dotgnu-pnet-commits] pnetlib/SharpZipLib/Zip/Compression Deflater.cs, NONE, 1.1 DeflaterConstants.cs, NONE, 1.1 DeflaterEngine.cs, NONE, 1.1 DeflaterHuffman.cs, NONE, 1.1 DeflaterPending.cs, NONE, 1.1 Inflater.cs, NONE, 1.1 InflaterDynHeader.cs, NONE, 1.1 InflaterHuffmanTree.cs, NONE, 1.1 PendingBuffer.cs, NONE, 1.1
- Next by thread:
[Dotgnu-pnet-commits] pnetlib/SharpZipLib/Tar InvalidHeaderException.cs, NONE, 1.1 TarArchive.cs, NONE, 1.1 TarBuffer.cs, NONE, 1.1 TarEntry.cs, NONE, 1.1 TarHeader.cs, NONE, 1.1 TarInputStream.cs, NONE, 1.1 TarOutputStream.cs, NONE, 1.1
- Index(es):