[Top][All Lists]
[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;
}
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [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,
Rhys Weatherley <address@hidden> <=
- Prev by Date:
[Dotgnu-pnet-commits] pnetlib/samples ilrun.sh.in,1.6,1.7
- Next by Date:
[Dotgnu-pnet-commits] pnetlib/SharpZipLib/Zip/Compression Deflater.cs, NONE, 1.1 DeflaterConstants.cs, NONE, 1.1 DeflaterEngine.cs, NONE, 1.1 DeflaterHuffman.cs, NONE, 1.1 DeflaterPending.cs, NONE, 1.1 Inflater.cs, NONE, 1.1 InflaterDynHeader.cs, NONE, 1.1 InflaterHuffmanTree.cs, NONE, 1.1 PendingBuffer.cs, NONE, 1.1
- Previous by thread:
[Dotgnu-pnet-commits] pnetlib/samples ilrun.sh.in,1.6,1.7
- Next by thread:
[Dotgnu-pnet-commits] pnetlib/SharpZipLib/Zip/Compression Deflater.cs, NONE, 1.1 DeflaterConstants.cs, NONE, 1.1 DeflaterEngine.cs, NONE, 1.1 DeflaterHuffman.cs, NONE, 1.1 DeflaterPending.cs, NONE, 1.1 Inflater.cs, NONE, 1.1 InflaterDynHeader.cs, NONE, 1.1 InflaterHuffmanTree.cs, NONE, 1.1 PendingBuffer.cs, NONE, 1.1
- Index(es):