You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

309 lines
8.6 KiB

namespace com.hitrust.util.Zip.Compression.Streams
{
using com.hitrust.util;
using com.hitrust.util.Checksums;
using com.hitrust.util.Zip.Compression;
using System;
using System.IO;
public class InflaterInputStream : Stream
{
protected Stream baseInputStream;
protected byte[] buf;
protected byte[] cryptbuffer;
protected long csize;
protected Inflater inf;
private bool isStreamOwner;
private uint[] keys;
protected int len;
private byte[] onebytebuffer;
private int readChunkSize;
public InflaterInputStream(Stream baseInputStream) : this(baseInputStream, new Inflater(), 0x1000)
{
}
public InflaterInputStream(Stream baseInputStream, Inflater inf) : this(baseInputStream, inf, 0x1000)
{
}
public InflaterInputStream(Stream baseInputStream, Inflater inflater, int bufferSize)
{
this.onebytebuffer = new byte[1];
this.isStreamOwner = true;
this.readChunkSize = 0;
this.cryptbuffer = null;
this.keys = null;
if (baseInputStream == null)
{
throw new ArgumentNullException("InflaterInputStream baseInputStream is null");
}
if (inflater == null)
{
throw new ArgumentNullException("InflaterInputStream Inflater is null");
}
if (bufferSize <= 0)
{
throw new ArgumentOutOfRangeException("bufferSize");
}
this.baseInputStream = baseInputStream;
this.inf = inflater;
this.buf = new byte[bufferSize];
if (baseInputStream.CanSeek)
{
this.len = (int) baseInputStream.Length;
}
else
{
this.len = 0;
}
}
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
throw new NotSupportedException("InflaterInputStream BeginWrite not supported");
}
public override void Close()
{
if (this.isStreamOwner)
{
this.baseInputStream.Close();
}
}
protected void DecryptBlock(byte[] buf, int off, int len)
{
for (int i = off; i < (off + len); i++)
{
byte[] buffer;
IntPtr ptr;
(buffer = buf)[(int) (ptr = (IntPtr) i)] = (byte) (buffer[(int) ptr] ^ this.DecryptByte());
this.UpdateKeys(buf[i]);
}
}
protected byte DecryptByte()
{
uint num = (this.keys[2] & 0xffff) | 2;
return (byte) ((num * (num ^ 1)) >> 8);
}
protected void Fill()
{
this.FillInputBuffer();
if (this.keys != null)
{
this.DecryptBlock(this.buf, 0, this.len);
}
if (this.len <= 0)
{
throw new SharpZipBaseException("Deflated stream ends early.");
}
this.inf.SetInput(this.buf, 0, this.len);
}
protected void FillInputBuffer()
{
if (this.readChunkSize <= 0)
{
this.len = this.baseInputStream.Read(this.buf, 0, this.buf.Length);
}
else
{
this.len = this.baseInputStream.Read(this.buf, 0, this.readChunkSize);
}
}
public override void Flush()
{
this.baseInputStream.Flush();
}
protected void InitializePassword(string password)
{
this.keys = new uint[] { 0x12345678, 0x23456789, 0x34567890 };
for (int i = 0; i < password.Length; i++)
{
this.UpdateKeys((byte) password[i]);
}
}
public override int Read(byte[] b, int off, int len)
{
while (true)
{
int num;
try
{
num = this.inf.Inflate(b, off, len);
}
catch (Exception exception)
{
throw new SharpZipBaseException(exception.ToString());
}
if (num > 0)
{
return num;
}
if (this.inf.IsNeedingDictionary)
{
throw new SharpZipBaseException("Need a dictionary");
}
if (this.inf.IsFinished)
{
return 0;
}
if (!this.inf.IsNeedingInput)
{
throw new InvalidOperationException("Don't know what to do");
}
this.Fill();
}
}
public override int ReadByte()
{
if (this.Read(this.onebytebuffer, 0, 1) > 0)
{
return (this.onebytebuffer[0] & 0xff);
}
return -1;
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException("Seek not supported");
}
public override void SetLength(long val)
{
throw new NotSupportedException("InflaterInputStream SetLength not supported");
}
public long Skip(long n)
{
if (n <= 0L)
{
throw new ArgumentOutOfRangeException("n");
}
if (this.baseInputStream.CanSeek)
{
this.baseInputStream.Seek(n, SeekOrigin.Current);
return n;
}
int num = 0x800;
if (n < num)
{
num = (int) n;
}
byte[] buffer = new byte[num];
return (long) this.baseInputStream.Read(buffer, 0, buffer.Length);
}
protected void StopDecrypting()
{
this.keys = null;
this.cryptbuffer = null;
}
protected void UpdateKeys(byte ch)
{
this.keys[0] = Crc32.ComputeCrc32(this.keys[0], ch);
this.keys[1] += (byte) this.keys[0];
this.keys[1] = (this.keys[1] * 0x8088405) + 1;
this.keys[2] = Crc32.ComputeCrc32(this.keys[2], (byte) (this.keys[1] >> 0x18));
}
public override void Write(byte[] array, int offset, int count)
{
throw new NotSupportedException("InflaterInputStream Write not supported");
}
public override void WriteByte(byte val)
{
throw new NotSupportedException("InflaterInputStream WriteByte not supported");
}
public virtual int Available
{
get
{
if (!this.inf.IsFinished)
{
return 1;
}
return 0;
}
}
protected int BufferReadSize
{
get
{
return this.readChunkSize;
}
set
{
this.readChunkSize = value;
}
}
public override bool CanRead
{
get
{
return this.baseInputStream.CanRead;
}
}
public override bool CanSeek
{
get
{
return false;
}
}
public override bool CanWrite
{
get
{
return false;
}
}
public bool IsStreamOwner
{
get
{
return this.isStreamOwner;
}
set
{
this.isStreamOwner = value;
}
}
public override long Length
{
get
{
return (long) this.len;
}
}
public override long Position
{
get
{
return this.baseInputStream.Position;
}
set
{
throw new NotSupportedException("InflaterInputStream Position not supported");
}
}
}
}