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/Compression/Streams Deflat


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] pnetlib/SharpZipLib/Zip/Compression/Streams DeflaterOutputStream.cs, NONE, 1.1 InflaterInputStream.cs, NONE, 1.1 OutputWindow.cs, NONE, 1.1 StreamManipulator.cs, NONE, 1.1
Date: Wed, 08 Oct 2003 07:37:07 +0000

Update of /cvsroot/dotgnu-pnet/pnetlib/SharpZipLib/Zip/Compression/Streams
In directory subversions:/tmp/cvs-serv5756/SharpZipLib/Zip/Compression/Streams

Added Files:
        DeflaterOutputStream.cs InflaterInputStream.cs OutputWindow.cs 
        StreamManipulator.cs 
Log Message:


Add the "SharpZipLib" directory to pnetlib, which is a port of
SharpDevelop's compression handling library.


--- NEW FILE: DeflaterOutputStream.cs ---
// DeflaterOutputStream.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 ICSharpCode.SharpZipLib.Zip.Compression;

namespace ICSharpCode.SharpZipLib.Zip.Compression.Streams 
{

        /// <summary>
        /// This is a special FilterOutputStream deflating the bytes that are
        /// written through it.  It uses the Deflater for deflating.
        /// 
        /// authors of the original java version : Tom Tromey, Jochen Hoenicke 
        /// </summary>
        public class DeflaterOutputStream : Stream
        {
                /// <summary>
                /// This buffer is used temporarily to retrieve the bytes from 
the
                /// deflater and write them to the underlying output stream.
                /// </summary>
                protected byte[] buf;
                
                /// <summary>
                /// The deflater which is used to deflate the stream.
                /// </summary>
                protected Deflater def;
                
                /// <summary>
                /// base stream the deflater depends on.
                /// </summary>
                protected Stream baseOutputStream;
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override bool CanRead 
                {
                        get 
                        {
                                return baseOutputStream.CanRead;
                        }
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override bool CanSeek 
                {
                        get 
                        {
                                return baseOutputStream.CanSeek;
                        }
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override bool CanWrite 
                {
                        get 
                        {
                                return baseOutputStream.CanWrite;
                        }
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override long Length 
                {
                        get 
                        {
                                return baseOutputStream.Length;
                        }
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override long Position 
                {
                        get 
                        {
                                return baseOutputStream.Position;
                        }
                        set 
                        {
                                baseOutputStream.Position = value;
                        }
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override long Seek(long offset, SeekOrigin origin)
                {
                        return baseOutputStream.Seek(offset, origin);
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override void SetLength(long val)
                {
                        baseOutputStream.SetLength(val);
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override int ReadByte()
                {
                        return baseOutputStream.ReadByte();
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override int Read(byte[] b, int off, int len)
                {
                        return baseOutputStream.Read(b, off, len);
                }
                
                
                /// <summary>
                /// Deflates everything in the def's input buffers.  This will 
call
                /// <code>def.deflate()</code> until all bytes from the input 
buffers
                /// are processed.
                /// </summary>
                protected void deflate()
                {
                        while (!def.IsNeedingInput) 
                        {
                                int len = def.Deflate(buf, 0, buf.Length);
                                
                                //      System.err.println("DOS deflated " + 
len + " baseOutputStream of " + buf.length);
                                if (len <= 0) 
                                {
                                        break;
                                }
                                baseOutputStream.Write(buf, 0, len);
                        }
                        
                        if (!def.IsNeedingInput) 
                        {
                                throw new ApplicationException("Can't deflate 
all input?");
                        }
                }
                
                /// <summary>
                /// Creates a new DeflaterOutputStream with a default Deflater 
and default buffer size.
                /// </summary>
                /// <param name="baseOutputStream">
                /// the output stream where deflated output should be written.
                /// </param>
                public DeflaterOutputStream(Stream baseOutputStream) : 
this(baseOutputStream, new Deflater(), 512)
                {
                        
                }
                
                /// <summary>
                /// Creates a new DeflaterOutputStream with the given Deflater 
and
                /// default buffer size.
                /// </summary>
                /// <param name="baseOutputStream">
                /// the output stream where deflated output should be written.
                /// </param>
                /// <param name="defl">
                /// the underlying deflater.
                /// </param>
                public DeflaterOutputStream(Stream baseOutputStream, Deflater 
defl) :this(baseOutputStream, defl, 512)
                {
                }
                
                /// <summary>
                /// Creates a new DeflaterOutputStream with the given Deflater 
and
                /// buffer size.
                /// </summary>
                /// <param name="baseOutputStream">
                /// the output stream where deflated output should be written.
                /// </param>
                /// <param name="defl">
                /// the underlying deflater.
                /// </param>
                /// <param name="bufsize">
                /// the buffer size.
                /// </param>
                /// <exception cref="System.InvalidOperationException">
                /// if bufsize isn't positive.
                /// </exception>
                public DeflaterOutputStream(Stream baseOutputStream, Deflater 
defl, int bufsize)
                {
                        this.baseOutputStream = baseOutputStream;
                        if (bufsize <= 0) 
                        {
                                throw new InvalidOperationException("bufsize <= 
0");
                        }
                        buf = new byte[bufsize];
                        def = defl;
                }
                
                /// <summary>
                /// Flushes the stream by calling flush() on the deflater and 
then
                /// on the underlying stream.  This ensures that all bytes are
                /// flushed.
                /// </summary>
                public override void Flush()
                {
                        def.Flush();
                        deflate();
                        baseOutputStream.Flush();
                }
                
                /// <summary>
                /// Finishes the stream by calling finish() on the deflater. 
                /// </summary>
                public virtual void Finish()
                {
                        def.Finish();
                        while (!def.IsFinished) 
                        {
                                int len = def.Deflate(buf, 0, buf.Length);
                                if (len <= 0) 
                                {
                                        break;
                                }
                                baseOutputStream.Write(buf, 0, len);
                        }
                        if (!def.IsFinished) 
                        {
                                throw new ApplicationException("Can't deflate 
all input?");
                        }
                        baseOutputStream.Flush();
                }
                
                /// <summary>
                /// Calls finish () and closes the stream.
                /// </summary>
                public override void Close()
                {
                        Finish();
                        baseOutputStream.Close();
                }
                
                /// <summary>
                /// Writes a single byte to the compressed output stream.
                /// </summary>
                /// <param name="bval">
                /// the byte value.
                /// </param>
                public override void WriteByte(byte bval)
                {
                        byte[] b = new byte[1];
                        b[0] = (byte) bval;
                        Write(b, 0, 1);
                }
                
                /// <summary>
                /// Writes a len bytes from an array to the compressed stream.
                /// </summary>
                /// <param name="buf">
                /// the byte array.
                /// </param>
                /// <param name="off">
                /// the offset into the byte array where to start.
                /// </param>
                /// <param name="len">
                /// the number of bytes to write.
                /// </param>
                public override void Write(byte[] buf, int off, int len)
                {
                        //    System.err.println("DOS with off " + off + " and 
len " + len);
                        def.SetInput(buf, off, len);
                        deflate();
                }
                
        }
}

--- NEW FILE: StreamManipulator.cs ---
// StreamManipulator.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.Compression.Streams 
{
        
        /// <summary>
        /// This class allows us to retrieve a specified amount of bits from
        /// the input buffer, as well as copy big byte blocks.
        ///
        /// It uses an int buffer to store up to 31 bits for direct
        /// manipulation.  This guarantees that we can get at least 16 bits,
        /// but we only need at most 15, so this is all safe.
        ///
        /// There are some optimizations in this class, for example, you must
        /// never peek more then 8 bits more than needed, and you must first
        /// peek bits before you may drop them.  This is not a general purpose
        /// class but optimized for the behaviour of the Inflater.
        ///
        /// authors of the original java version : John Leuner, Jochen Hoenicke
        /// </summary>
        public class StreamManipulator
        {
                private byte[] window;
                private int window_start = 0;
                private int window_end = 0;
                
                private uint buffer = 0;
                private int bits_in_buffer = 0;
                
                /// <summary>
                /// Get the next n bits but don't increase input pointer.  n 
must be
                /// less or equal 16 and if you if this call succeeds, you must 
drop
                /// at least n-8 bits in the next call.
                /// </summary>
                /// <returns>
                /// the value of the bits, or -1 if not enough bits available.  
*/
                /// </returns>
                public int PeekBits(int n)
                {
                        if (bits_in_buffer < n) 
                        {
                                if (window_start == window_end) 
                                {
                                        return -1;
                                }
                                buffer |= (uint)((window[window_start++] & 0xff 
|
                                        (window[window_start++] & 0xff) << 8) 
<< bits_in_buffer);
                                bits_in_buffer += 16;
                        }
                        return (int)(buffer & ((1 << n) - 1));
                }
                
                /// <summary>
                /// Drops the next n bits from the input.  You should have 
called peekBits
                /// with a bigger or equal n before, to make sure that enough 
bits are in
                /// the bit buffer.
                /// </summary>
                public void DropBits(int n)
                {
                        buffer >>= n;
                        bits_in_buffer -= n;
                }
                
                /// <summary>
                /// Gets the next n bits and increases input pointer.  This is 
equivalent
                /// to peekBits followed by dropBits, except for correct error 
handling.
                /// </summary>
                /// <returns>
                /// the value of the bits, or -1 if not enough bits available.
                /// </returns>
                public int GetBits(int n)
                {
                        int bits = PeekBits(n);
                        if (bits >= 0) 
                        {
                                DropBits(n);
                        }
                        return bits;
                }
                
                /// <summary>
                /// Gets the number of bits available in the bit buffer.  This 
must be
                /// only called when a previous peekBits() returned -1.
                /// </summary>
                /// <returns>
                /// the number of bits available.
                /// </returns>
                public int AvailableBits 
                {
                        get 
                        {
                                return bits_in_buffer;
                        }
                }
                
                /// <summary>
                /// Gets the number of bytes available.
                /// </summary>
                /// <returns>
                /// the number of bytes available.
                /// </returns>
                public int AvailableBytes 
                {
                        get 
                        {
                                return window_end - window_start + 
(bits_in_buffer >> 3);
                        }
                }
                
                /// <summary>
                /// Skips to the next byte boundary.
                /// </summary>
                public void SkipToByteBoundary()
                {
                        buffer >>= (bits_in_buffer & 7);
                        bits_in_buffer &= ~7;
                }
                
                public bool IsNeedingInput 
                {
                        get 
                        {
                                return window_start == window_end;
                        }
                }
                
                /// <summary>
                /// Copies length bytes from input buffer to output buffer 
starting
                /// at output[offset].  You have to make sure, that the buffer 
is
                /// byte aligned.  If not enough bytes are available, copies 
fewer
                /// bytes.
                /// </summary>
                /// <param name="output">
                /// the buffer.
                /// </param>
                /// <param name="offset">
                /// the offset in the buffer.
                /// </param>
                /// <param name="length">
                /// the length to copy, 0 is allowed.
                /// </param>
                /// <returns>
                /// the number of bytes copied, 0 if no byte is available.
                /// </returns>
                public int CopyBytes(byte[] output, int offset, int length)
                {
                        if (length < 0) 
                        {
                                throw new ArgumentOutOfRangeException("length 
negative");
                        }
                        if ((bits_in_buffer & 7) != 0)   
                        {
                                /* bits_in_buffer may only be 0 or 8 */
                                throw new InvalidOperationException("Bit buffer 
is not aligned!");
                        }
                        
                        int count = 0;
                        while (bits_in_buffer > 0 && length > 0) 
                        {
                                output[offset++] = (byte) buffer;
                                buffer >>= 8;
                                bits_in_buffer -= 8;
                                length--;
                                count++;
                        }
                        if (length == 0) 
                        {
                                return count;
                        }
                        
                        int avail = window_end - window_start;
                        if (length > avail) 
                        {
                                length = avail;
                        }
                        System.Array.Copy(window, window_start, output, offset, 
length);
                        window_start += length;
                        
                        if (((window_start - window_end) & 1) != 0) 
                        {
                                /* We always want an even number of bytes in 
input, see peekBits */
                                buffer = (uint)(window[window_start++] & 0xff);
                                bits_in_buffer = 8;
                        }
                        return count + length;
                }
                
                public StreamManipulator()
                {
                }
                
                public void Reset()
                {
                        buffer = (uint)(window_start = window_end = 
bits_in_buffer = 0);
                }
                
                public void SetInput(byte[] buf, int off, int len)
                {
                        if (window_start < window_end) 
                        {
                                throw new InvalidOperationException("Old input 
was not completely processed");
                        }
                        
                        int end = off + len;
                        
                        /* We want to throw an ArrayIndexOutOfBoundsException 
early.  The
                        * check is very tricky: it also handles integer wrap 
around.
                        */
                        if (0 > off || off > end || end > buf.Length) 
                        {
                                throw new ArgumentOutOfRangeException();
                        }
                        
                        if ((len & 1) != 0) 
                        {
                                /* We always want an even number of bytes in 
input, see peekBits */
                                buffer |= (uint)((buf[off++] & 0xff) << 
bits_in_buffer);
                                bits_in_buffer += 8;
                        }
                        
                        window = buf;
                        window_start = off;
                        window_end = end;
                }
        }
}

--- NEW FILE: InflaterInputStream.cs ---
// InflaterInputStream.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 ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Checksums;

namespace ICSharpCode.SharpZipLib.Zip.Compression.Streams 
{
        
        /// <summary>
        /// This filter stream is used to decompress data compressed 
baseInputStream the "deflate"
        /// format. The "deflate" format is described baseInputStream RFC 1951.
        ///
        /// This stream may form the basis for other decompression filters, such
        /// as the <code>GzipInputStream</code>.
        ///
        /// author of the original java version : John Leuner
        /// </summary>
        public class InflaterInputStream : Stream
        {
                //Variables
                
                /// <summary>
                /// Decompressor for this filter
                /// </summary>
                protected Inflater inf;
                
                /// <summary>
                /// Byte array used as a buffer
                /// </summary>
                protected byte[] buf;
                
                /// <summary>
                /// Size of buffer
                /// </summary>
                protected int len;
                
                //We just use this if we are decoding one byte at a time with 
the read() call
                private byte[] onebytebuffer = new byte[1];
                
                /// <summary>
                /// base stream the inflater depends on.
                /// </summary>
                protected Stream baseInputStream;
                
                protected long csize;
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override bool CanRead {
                        get {
                                return baseInputStream.CanRead;
                        }
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override bool CanSeek {
                        get {
                                return baseInputStream.CanSeek;
                        }
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override bool CanWrite {
                        get {
                                return baseInputStream.CanWrite;
                        }
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override long Length {
                        get {
                                return len;
                        }
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override long Position {
                        get {
                                return baseInputStream.Position;
                        }
                        set {
                                baseInputStream.Position = value;
                        }
                }
                
                /// <summary>
                /// Flushes the baseInputStream
                /// </summary>
                public override void Flush()
                {
                        baseInputStream.Flush();
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override long Seek(long offset, SeekOrigin origin)
                {
                        return baseInputStream.Seek(offset, origin);
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override void SetLength(long val)
                {
                        baseInputStream.SetLength(val);
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override void Write(byte[] array, int offset, int count)
                {
                        baseInputStream.Write(array, offset, count);
                }
                
                /// <summary>
                /// I needed to implement the abstract member.
                /// </summary>
                public override void WriteByte(byte val)
                {
                        baseInputStream.WriteByte(val);
                }
                
                //Constructors
                
                /// <summary>
                /// Create an InflaterInputStream with the default decompresseor
                /// and a default buffer size.
                /// </summary>
                /// <param name = "baseInputStream">
                /// the InputStream to read bytes from
                /// </param>
                public InflaterInputStream(Stream baseInputStream) : 
this(baseInputStream, new Inflater(), 4096)
                {
                        
                }
                
                /// <summary>
                /// Create an InflaterInputStream with the specified 
decompresseor
                /// and a default buffer size.
                /// </summary>
                /// <param name = "baseInputStream">
                /// the InputStream to read bytes from
                /// </param>
                /// <param name = "inf">
                /// the decompressor used to decompress data read from 
baseInputStream
                /// </param>
                public InflaterInputStream(Stream baseInputStream, Inflater 
inf) : this(baseInputStream, inf, 4096)
                {
                }
                
                /// <summary>
                /// Create an InflaterInputStream with the specified 
decompresseor
                /// and a specified buffer size.
                /// </summary>
                /// <param name = "baseInputStream">
                /// the InputStream to read bytes from
                /// </param>
                /// <param name = "inf">
                /// the decompressor used to decompress data read from 
baseInputStream
                /// </param>
                /// <param name = "size">
                /// size of the buffer to use
                /// </param>
                public InflaterInputStream(Stream baseInputStream, Inflater 
inf, int size)
                {
                        this.baseInputStream = baseInputStream;
                        this.inf = inf;
                        try {
                                this.len = (int)baseInputStream.Length;
                        } catch (Exception) { 
                                // the stream may not support .Length
                                this.len = 0;
                        }
                        
                        if (size <= 0) {
                                throw new ArgumentOutOfRangeException("size <= 
0");
                        }
                        
                        buf = new byte[size]; //Create the buffer
                }
                
                //Methods
                
                /// <summary>
                /// Returns 0 once the end of the stream (EOF) has been reached.
                /// Otherwise returns 1.
                /// </summary>
                public virtual int Available {
                        get {
                                return inf.IsFinished ? 0 : 1;
                        }
                }
                
                /// <summary>
                /// Closes the input stream
                /// </summary>
                public override void Close()
                {
                        baseInputStream.Close();
                }
                
                /// <summary>
                /// Fills the buffer with more data to decompress.
                /// </summary>
                protected void Fill()
                {
                        len = baseInputStream.Read(buf, 0, buf.Length);
                        // decrypting crypted data
                        if (cryptbuffer != null) {
                                DecryptBlock(buf, 0, 
System.Math.Min((int)(csize - inf.TotalIn), buf.Length));
                        }
                        
                        if (len <= 0) {
                                throw new ApplicationException("Deflated stream 
ends early.");
                        }
                        inf.SetInput(buf, 0, len);
                }
                
                /// <summary>
                /// Reads one byte of decompressed data.
                ///
                /// The byte is baseInputStream the lower 8 bits of the int.
                /// </summary>
                public override int ReadByte()
                {
                        int nread = Read(onebytebuffer, 0, 1); //read one byte
                        if (nread > 0) {
                                return onebytebuffer[0] & 0xff;
                        }
                        return -1;
                }
                
                /// <summary>
                /// Decompresses data into the byte array
                /// </summary>
                /// <param name ="b">
                /// the array to read and decompress data into
                /// </param>
                /// <param name ="off">
                /// the offset indicating where the data should be placed
                /// </param>
                /// <param name ="len">
                /// the number of bytes to decompress
                /// </param>
                public override int Read(byte[] b, int off, int len)
                {
                        for (;;) {
                                int count;
                                try {
                                        count = inf.Inflate(b, off, len);
                                } catch (Exception e) {
                                        throw new ZipException(e.ToString());
                                }
                                
                                if (count > 0) {
                                        return count;
                                }
                                
                                if (inf.IsNeedingDictionary) {
                                        throw new ZipException("Need a 
dictionary");
                                } else if (inf.IsFinished) {
                                        return 0;
                                } else if (inf.IsNeedingInput) {
                                        Fill();
                                } else {
                                        throw new 
InvalidOperationException("Don't know what to do");
                                }
                        }
                }
                
                /// <summary>
                /// Skip specified number of bytes of uncompressed data
                /// </summary>
                /// <param name ="n">
                /// number of bytes to skip
                /// </param>
                public long Skip(long n)
                {
                        if (n < 0) {
                                throw new ArgumentOutOfRangeException("n");
                        }
                        int len = 2048;
                        if (n < len) {
                                len = (int) n;
                        }
                        byte[] tmp = new byte[len];
                        return (long)baseInputStream.Read(tmp, 0, tmp.Length);
                }
                
#region Encryption stuff
                protected byte[] cryptbuffer = null;
                
                uint[] keys = null;
                protected byte DecryptByte()
                {
                        uint temp = ((keys[2] & 0xFFFF) | 2);
                        return (byte)((temp * (temp ^ 1)) >> 8);
                }
                
                protected void DecryptBlock(byte[] buf, int off, int len)
                {
                        for (int i = off; i < off + len; ++i) {
                                buf[i] ^= DecryptByte();
                                UpdateKeys(buf[i]);
                        }
                }
                
                protected void InitializePassword(string password)
                {
                        keys = new uint[] {
                                0x12345678, 
                                0x23456789, 
                                0x34567890
                        };
                        for (int i = 0; i < password.Length; ++i) {
                                UpdateKeys((byte)password[i]);
                        }
                }
                
                uint ComputeCrc32(uint oldCrc, byte bval)
                {
                        return (uint)(Crc32.CrcTable[(oldCrc ^ bval) & 0xFF] ^ 
(oldCrc >> 8));
                }
                
                protected void UpdateKeys(byte ch)
                {
                        keys[0] = ComputeCrc32(keys[0], ch);
                        keys[1] = keys[1] + (byte)keys[0];
                        keys[1] = keys[1] * 134775813 + 1;
                        keys[2] = ComputeCrc32(keys[2], (byte)(keys[1] >> 24));
                }
#endregion
        }
}

--- NEW FILE: OutputWindow.cs ---
// OutputWindow.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.Compression.Streams 
{
        
        /// <summary>
        /// Contains the output from the Inflation process.
        /// We need to have a window so that we can refer backwards into the 
output stream
        /// to repeat stuff.
        ///
        /// author of the original java version : John Leuner
        /// </summary>
        public class OutputWindow
        {
                private static int WINDOW_SIZE = 1 << 15;
                private static int WINDOW_MASK = WINDOW_SIZE - 1;
                
                private byte[] window = new byte[WINDOW_SIZE]; //The window is 
2^15 bytes
                private int window_end  = 0;
                private int window_filled = 0;
                
                public void Write(int abyte)
                {
                        if (window_filled++ == WINDOW_SIZE) 
                        {
                                throw new InvalidOperationException("Window 
full");
                        }
                        window[window_end++] = (byte) abyte;
                        window_end &= WINDOW_MASK;
                }
                
                
                private void SlowRepeat(int rep_start, int len, int dist)
                {
                        while (len-- > 0) 
                        {
                                window[window_end++] = window[rep_start++];
                                window_end &= WINDOW_MASK;
                                rep_start &= WINDOW_MASK;
                        }
                }
                
                public void Repeat(int len, int dist)
                {
                        if ((window_filled += len) > WINDOW_SIZE) 
                        {
                                throw new InvalidOperationException("Window 
full");
                        }
                        
                        int rep_start = (window_end - dist) & WINDOW_MASK;
                        int border = WINDOW_SIZE - len;
                        if (rep_start <= border && window_end < border) 
                        {
                                if (len <= dist) 
                                {
                                        System.Array.Copy(window, rep_start, 
window, window_end, len);
                                        window_end += len;
                                }                               
                                else 
                                {
                                        /* We have to copy manually, since the 
repeat pattern overlaps.
                                        */
                                        while (len-- > 0) 
                                        {
                                                window[window_end++] = 
window[rep_start++];
                                        }
                                }
                        } 
                        else 
                        {
                                SlowRepeat(rep_start, len, dist);
                        }
                }
                
                public int CopyStored(StreamManipulator input, int len)
                {
                        len = Math.Min(Math.Min(len, WINDOW_SIZE - 
window_filled), input.AvailableBytes);
                        int copied;
                        
                        int tailLen = WINDOW_SIZE - window_end;
                        if (len > tailLen) 
                        {
                                copied = input.CopyBytes(window, window_end, 
tailLen);
                                if (copied == tailLen) 
                                {
                                        copied += input.CopyBytes(window, 0, 
len - tailLen);
                                }
                        } 
                        else 
                        {
                                copied = input.CopyBytes(window, window_end, 
len);
                        }
                        
                        window_end = (window_end + copied) & WINDOW_MASK;
                        window_filled += copied;
                        return copied;
                }
                
                public void CopyDict(byte[] dict, int offset, int len)
                {
                        if (window_filled > 0) 
                        {
                                throw new InvalidOperationException();
                        }
                        
                        if (len > WINDOW_SIZE) 
                        {
                                offset += len - WINDOW_SIZE;
                                len = WINDOW_SIZE;
                        }
                        System.Array.Copy(dict, offset, window, 0, len);
                        window_end = len & WINDOW_MASK;
                }
                
                public int GetFreeSpace()
                {
                        return WINDOW_SIZE - window_filled;
                }
                
                public int GetAvailable()
                {
                        return window_filled;
                }
                
                public int CopyOutput(byte[] output, int offset, int len)
                {
                        int copy_end = window_end;
                        if (len > window_filled) 
                        {
                                len = window_filled;
                        } 
                        else 
                        {
                                copy_end = (window_end - window_filled + len) & 
WINDOW_MASK;
                        }
                        
                        int copied = len;
                        int tailLen = len - copy_end;
                        
                        if (tailLen > 0) 
                        {
                                System.Array.Copy(window, WINDOW_SIZE - tailLen,
                                        output, offset, tailLen);
                                offset += tailLen;
                                len = copy_end;
                        }
                        System.Array.Copy(window, copy_end - len, output, 
offset, len);
                        window_filled -= copied;
                        if (window_filled < 0) 
                        {
                                throw new InvalidOperationException();
                        }
                        return copied;
                }
                
                public void Reset()
                {
                        window_filled = window_end = 0;
                }
        }
}





reply via email to

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