dotgnu-pnet-commits
[Top][All Lists]
Advanced

[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);
                }
        }
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]