632 lines
14 KiB
C#
632 lines
14 KiB
C#
using System;
|
|
using ICSharpCode.SharpZipLib.Checksums;
|
|
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
|
|
|
|
namespace ICSharpCode.SharpZipLib.Zip.Compression
|
|
{
|
|
// Token: 0x02000047 RID: 71
|
|
public class Inflater
|
|
{
|
|
// Token: 0x060002C9 RID: 713 RVA: 0x0000F5A2 File Offset: 0x0000E5A2
|
|
public Inflater()
|
|
: this(false)
|
|
{
|
|
}
|
|
|
|
// Token: 0x060002CA RID: 714 RVA: 0x0000F5AB File Offset: 0x0000E5AB
|
|
public Inflater(bool noHeader)
|
|
{
|
|
this.noHeader = noHeader;
|
|
this.adler = new Adler32();
|
|
this.input = new StreamManipulator();
|
|
this.outputWindow = new OutputWindow();
|
|
this.mode = (noHeader ? 2 : 0);
|
|
}
|
|
|
|
// Token: 0x060002CB RID: 715 RVA: 0x0000F5E8 File Offset: 0x0000E5E8
|
|
public void Reset()
|
|
{
|
|
this.mode = (this.noHeader ? 2 : 0);
|
|
this.totalIn = 0L;
|
|
this.totalOut = 0L;
|
|
this.input.Reset();
|
|
this.outputWindow.Reset();
|
|
this.dynHeader = null;
|
|
this.litlenTree = null;
|
|
this.distTree = null;
|
|
this.isLastBlock = false;
|
|
this.adler.Reset();
|
|
}
|
|
|
|
// Token: 0x060002CC RID: 716 RVA: 0x0000F654 File Offset: 0x0000E654
|
|
private bool DecodeHeader()
|
|
{
|
|
int num = this.input.PeekBits(16);
|
|
if (num < 0)
|
|
{
|
|
return false;
|
|
}
|
|
this.input.DropBits(16);
|
|
num = ((num << 8) | (num >> 8)) & 65535;
|
|
if (num % 31 != 0)
|
|
{
|
|
throw new SharpZipBaseException("Header checksum illegal");
|
|
}
|
|
if ((num & 3840) != 2048)
|
|
{
|
|
throw new SharpZipBaseException("Compression Method unknown");
|
|
}
|
|
if ((num & 32) == 0)
|
|
{
|
|
this.mode = 2;
|
|
}
|
|
else
|
|
{
|
|
this.mode = 1;
|
|
this.neededBits = 32;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Token: 0x060002CD RID: 717 RVA: 0x0000F6DC File Offset: 0x0000E6DC
|
|
private bool DecodeDict()
|
|
{
|
|
while (this.neededBits > 0)
|
|
{
|
|
int num = this.input.PeekBits(8);
|
|
if (num < 0)
|
|
{
|
|
return false;
|
|
}
|
|
this.input.DropBits(8);
|
|
this.readAdler = (this.readAdler << 8) | num;
|
|
this.neededBits -= 8;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Token: 0x060002CE RID: 718 RVA: 0x0000F734 File Offset: 0x0000E734
|
|
private bool DecodeHuffman()
|
|
{
|
|
int i = this.outputWindow.GetFreeSpace();
|
|
while (i >= 258)
|
|
{
|
|
int num;
|
|
switch (this.mode)
|
|
{
|
|
case 7:
|
|
while (((num = this.litlenTree.GetSymbol(this.input)) & -256) == 0)
|
|
{
|
|
this.outputWindow.Write(num);
|
|
if (--i < 258)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
if (num >= 257)
|
|
{
|
|
try
|
|
{
|
|
this.repLength = Inflater.CPLENS[num - 257];
|
|
this.neededBits = Inflater.CPLEXT[num - 257];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new SharpZipBaseException("Illegal rep length code");
|
|
}
|
|
goto IL_C5;
|
|
}
|
|
if (num < 0)
|
|
{
|
|
return false;
|
|
}
|
|
this.distTree = null;
|
|
this.litlenTree = null;
|
|
this.mode = 2;
|
|
return true;
|
|
case 8:
|
|
goto IL_C5;
|
|
case 9:
|
|
goto IL_114;
|
|
case 10:
|
|
break;
|
|
default:
|
|
throw new SharpZipBaseException("Inflater unknown mode");
|
|
}
|
|
IL_154:
|
|
if (this.neededBits > 0)
|
|
{
|
|
this.mode = 10;
|
|
int num2 = this.input.PeekBits(this.neededBits);
|
|
if (num2 < 0)
|
|
{
|
|
return false;
|
|
}
|
|
this.input.DropBits(this.neededBits);
|
|
this.repDist += num2;
|
|
}
|
|
this.outputWindow.Repeat(this.repLength, this.repDist);
|
|
i -= this.repLength;
|
|
this.mode = 7;
|
|
continue;
|
|
IL_114:
|
|
num = this.distTree.GetSymbol(this.input);
|
|
if (num < 0)
|
|
{
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
this.repDist = Inflater.CPDIST[num];
|
|
this.neededBits = Inflater.CPDEXT[num];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new SharpZipBaseException("Illegal rep dist code");
|
|
}
|
|
goto IL_154;
|
|
IL_C5:
|
|
if (this.neededBits > 0)
|
|
{
|
|
this.mode = 8;
|
|
int num3 = this.input.PeekBits(this.neededBits);
|
|
if (num3 < 0)
|
|
{
|
|
return false;
|
|
}
|
|
this.input.DropBits(this.neededBits);
|
|
this.repLength += num3;
|
|
}
|
|
this.mode = 9;
|
|
goto IL_114;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Token: 0x060002CF RID: 719 RVA: 0x0000F93C File Offset: 0x0000E93C
|
|
private bool DecodeChksum()
|
|
{
|
|
while (this.neededBits > 0)
|
|
{
|
|
int num = this.input.PeekBits(8);
|
|
if (num < 0)
|
|
{
|
|
return false;
|
|
}
|
|
this.input.DropBits(8);
|
|
this.readAdler = (this.readAdler << 8) | num;
|
|
this.neededBits -= 8;
|
|
}
|
|
if ((int)this.adler.Value != this.readAdler)
|
|
{
|
|
throw new SharpZipBaseException(string.Concat(new object[]
|
|
{
|
|
"Adler chksum doesn't match: ",
|
|
(int)this.adler.Value,
|
|
" vs. ",
|
|
this.readAdler
|
|
}));
|
|
}
|
|
this.mode = 12;
|
|
return false;
|
|
}
|
|
|
|
// Token: 0x060002D0 RID: 720 RVA: 0x0000F9F4 File Offset: 0x0000E9F4
|
|
private bool Decode()
|
|
{
|
|
switch (this.mode)
|
|
{
|
|
case 0:
|
|
return this.DecodeHeader();
|
|
case 1:
|
|
return this.DecodeDict();
|
|
case 2:
|
|
if (this.isLastBlock)
|
|
{
|
|
if (this.noHeader)
|
|
{
|
|
this.mode = 12;
|
|
return false;
|
|
}
|
|
this.input.SkipToByteBoundary();
|
|
this.neededBits = 32;
|
|
this.mode = 11;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
int num = this.input.PeekBits(3);
|
|
if (num < 0)
|
|
{
|
|
return false;
|
|
}
|
|
this.input.DropBits(3);
|
|
if ((num & 1) != 0)
|
|
{
|
|
this.isLastBlock = true;
|
|
}
|
|
switch (num >> 1)
|
|
{
|
|
case 0:
|
|
this.input.SkipToByteBoundary();
|
|
this.mode = 3;
|
|
break;
|
|
case 1:
|
|
this.litlenTree = InflaterHuffmanTree.defLitLenTree;
|
|
this.distTree = InflaterHuffmanTree.defDistTree;
|
|
this.mode = 7;
|
|
break;
|
|
case 2:
|
|
this.dynHeader = new InflaterDynHeader();
|
|
this.mode = 6;
|
|
break;
|
|
default:
|
|
throw new SharpZipBaseException("Unknown block type " + num);
|
|
}
|
|
return true;
|
|
}
|
|
break;
|
|
case 3:
|
|
if ((this.uncomprLen = this.input.PeekBits(16)) < 0)
|
|
{
|
|
return false;
|
|
}
|
|
this.input.DropBits(16);
|
|
this.mode = 4;
|
|
break;
|
|
case 4:
|
|
break;
|
|
case 5:
|
|
goto IL_1A9;
|
|
case 6:
|
|
if (!this.dynHeader.Decode(this.input))
|
|
{
|
|
return false;
|
|
}
|
|
this.litlenTree = this.dynHeader.BuildLitLenTree();
|
|
this.distTree = this.dynHeader.BuildDistTree();
|
|
this.mode = 7;
|
|
goto IL_22D;
|
|
case 7:
|
|
case 8:
|
|
case 9:
|
|
case 10:
|
|
goto IL_22D;
|
|
case 11:
|
|
return this.DecodeChksum();
|
|
case 12:
|
|
return false;
|
|
default:
|
|
throw new SharpZipBaseException("Inflater.Decode unknown mode");
|
|
}
|
|
int num2 = this.input.PeekBits(16);
|
|
if (num2 < 0)
|
|
{
|
|
return false;
|
|
}
|
|
this.input.DropBits(16);
|
|
if (num2 != (this.uncomprLen ^ 65535))
|
|
{
|
|
throw new SharpZipBaseException("broken uncompressed block");
|
|
}
|
|
this.mode = 5;
|
|
IL_1A9:
|
|
int num3 = this.outputWindow.CopyStored(this.input, this.uncomprLen);
|
|
this.uncomprLen -= num3;
|
|
if (this.uncomprLen == 0)
|
|
{
|
|
this.mode = 2;
|
|
return true;
|
|
}
|
|
return !this.input.IsNeedingInput;
|
|
IL_22D:
|
|
return this.DecodeHuffman();
|
|
}
|
|
|
|
// Token: 0x060002D1 RID: 721 RVA: 0x0000FC41 File Offset: 0x0000EC41
|
|
public void SetDictionary(byte[] buffer)
|
|
{
|
|
this.SetDictionary(buffer, 0, buffer.Length);
|
|
}
|
|
|
|
// Token: 0x060002D2 RID: 722 RVA: 0x0000FC50 File Offset: 0x0000EC50
|
|
public void SetDictionary(byte[] buffer, int index, int count)
|
|
{
|
|
if (buffer == null)
|
|
{
|
|
throw new ArgumentNullException("buffer");
|
|
}
|
|
if (index < 0)
|
|
{
|
|
throw new ArgumentOutOfRangeException("index");
|
|
}
|
|
if (count < 0)
|
|
{
|
|
throw new ArgumentOutOfRangeException("count");
|
|
}
|
|
if (!this.IsNeedingDictionary)
|
|
{
|
|
throw new InvalidOperationException("Dictionary is not needed");
|
|
}
|
|
this.adler.Update(buffer, index, count);
|
|
if ((int)this.adler.Value != this.readAdler)
|
|
{
|
|
throw new SharpZipBaseException("Wrong adler checksum");
|
|
}
|
|
this.adler.Reset();
|
|
this.outputWindow.CopyDict(buffer, index, count);
|
|
this.mode = 2;
|
|
}
|
|
|
|
// Token: 0x060002D3 RID: 723 RVA: 0x0000FCE9 File Offset: 0x0000ECE9
|
|
public void SetInput(byte[] buffer)
|
|
{
|
|
this.SetInput(buffer, 0, buffer.Length);
|
|
}
|
|
|
|
// Token: 0x060002D4 RID: 724 RVA: 0x0000FCF6 File Offset: 0x0000ECF6
|
|
public void SetInput(byte[] buffer, int index, int count)
|
|
{
|
|
this.input.SetInput(buffer, index, count);
|
|
this.totalIn += (long)count;
|
|
}
|
|
|
|
// Token: 0x060002D5 RID: 725 RVA: 0x0000FD15 File Offset: 0x0000ED15
|
|
public int Inflate(byte[] buffer)
|
|
{
|
|
if (buffer == null)
|
|
{
|
|
throw new ArgumentNullException("buffer");
|
|
}
|
|
return this.Inflate(buffer, 0, buffer.Length);
|
|
}
|
|
|
|
// Token: 0x060002D6 RID: 726 RVA: 0x0000FD30 File Offset: 0x0000ED30
|
|
public int Inflate(byte[] buffer, int offset, int count)
|
|
{
|
|
if (buffer == null)
|
|
{
|
|
throw new ArgumentNullException("buffer");
|
|
}
|
|
if (count < 0)
|
|
{
|
|
throw new ArgumentOutOfRangeException("count", "count cannot be negative");
|
|
}
|
|
if (offset < 0)
|
|
{
|
|
throw new ArgumentOutOfRangeException("offset", "offset cannot be negative");
|
|
}
|
|
if (offset + count > buffer.Length)
|
|
{
|
|
throw new ArgumentException("count exceeds buffer bounds");
|
|
}
|
|
if (count == 0)
|
|
{
|
|
if (!this.IsFinished)
|
|
{
|
|
this.Decode();
|
|
}
|
|
return 0;
|
|
}
|
|
int num = 0;
|
|
for (;;)
|
|
{
|
|
if (this.mode != 11)
|
|
{
|
|
int num2 = this.outputWindow.CopyOutput(buffer, offset, count);
|
|
if (num2 > 0)
|
|
{
|
|
this.adler.Update(buffer, offset, num2);
|
|
offset += num2;
|
|
num += num2;
|
|
this.totalOut += (long)num2;
|
|
count -= num2;
|
|
if (count == 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!this.Decode() && (this.outputWindow.GetAvailable() <= 0 || this.mode == 11))
|
|
{
|
|
return num;
|
|
}
|
|
}
|
|
return num;
|
|
}
|
|
|
|
// Token: 0x17000096 RID: 150
|
|
// (get) Token: 0x060002D7 RID: 727 RVA: 0x0000FE0A File Offset: 0x0000EE0A
|
|
public bool IsNeedingInput
|
|
{
|
|
get
|
|
{
|
|
return this.input.IsNeedingInput;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000097 RID: 151
|
|
// (get) Token: 0x060002D8 RID: 728 RVA: 0x0000FE17 File Offset: 0x0000EE17
|
|
public bool IsNeedingDictionary
|
|
{
|
|
get
|
|
{
|
|
return this.mode == 1 && this.neededBits == 0;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000098 RID: 152
|
|
// (get) Token: 0x060002D9 RID: 729 RVA: 0x0000FE2D File Offset: 0x0000EE2D
|
|
public bool IsFinished
|
|
{
|
|
get
|
|
{
|
|
return this.mode == 12 && this.outputWindow.GetAvailable() == 0;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000099 RID: 153
|
|
// (get) Token: 0x060002DA RID: 730 RVA: 0x0000FE49 File Offset: 0x0000EE49
|
|
public int Adler
|
|
{
|
|
get
|
|
{
|
|
if (!this.IsNeedingDictionary)
|
|
{
|
|
return (int)this.adler.Value;
|
|
}
|
|
return this.readAdler;
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700009A RID: 154
|
|
// (get) Token: 0x060002DB RID: 731 RVA: 0x0000FE66 File Offset: 0x0000EE66
|
|
public long TotalOut
|
|
{
|
|
get
|
|
{
|
|
return this.totalOut;
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700009B RID: 155
|
|
// (get) Token: 0x060002DC RID: 732 RVA: 0x0000FE6E File Offset: 0x0000EE6E
|
|
public long TotalIn
|
|
{
|
|
get
|
|
{
|
|
return this.totalIn - (long)this.RemainingInput;
|
|
}
|
|
}
|
|
|
|
// Token: 0x1700009C RID: 156
|
|
// (get) Token: 0x060002DD RID: 733 RVA: 0x0000FE7E File Offset: 0x0000EE7E
|
|
public int RemainingInput
|
|
{
|
|
get
|
|
{
|
|
return this.input.AvailableBytes;
|
|
}
|
|
}
|
|
|
|
// Token: 0x040001C9 RID: 457
|
|
private const int DECODE_HEADER = 0;
|
|
|
|
// Token: 0x040001CA RID: 458
|
|
private const int DECODE_DICT = 1;
|
|
|
|
// Token: 0x040001CB RID: 459
|
|
private const int DECODE_BLOCKS = 2;
|
|
|
|
// Token: 0x040001CC RID: 460
|
|
private const int DECODE_STORED_LEN1 = 3;
|
|
|
|
// Token: 0x040001CD RID: 461
|
|
private const int DECODE_STORED_LEN2 = 4;
|
|
|
|
// Token: 0x040001CE RID: 462
|
|
private const int DECODE_STORED = 5;
|
|
|
|
// Token: 0x040001CF RID: 463
|
|
private const int DECODE_DYN_HEADER = 6;
|
|
|
|
// Token: 0x040001D0 RID: 464
|
|
private const int DECODE_HUFFMAN = 7;
|
|
|
|
// Token: 0x040001D1 RID: 465
|
|
private const int DECODE_HUFFMAN_LENBITS = 8;
|
|
|
|
// Token: 0x040001D2 RID: 466
|
|
private const int DECODE_HUFFMAN_DIST = 9;
|
|
|
|
// Token: 0x040001D3 RID: 467
|
|
private const int DECODE_HUFFMAN_DISTBITS = 10;
|
|
|
|
// Token: 0x040001D4 RID: 468
|
|
private const int DECODE_CHKSUM = 11;
|
|
|
|
// Token: 0x040001D5 RID: 469
|
|
private const int FINISHED = 12;
|
|
|
|
// Token: 0x040001D6 RID: 470
|
|
private static readonly int[] CPLENS = new int[]
|
|
{
|
|
3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
|
|
15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
|
|
67, 83, 99, 115, 131, 163, 195, 227, 258
|
|
};
|
|
|
|
// Token: 0x040001D7 RID: 471
|
|
private static readonly int[] CPLEXT = new int[]
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
|
|
4, 4, 4, 4, 5, 5, 5, 5, 0
|
|
};
|
|
|
|
// Token: 0x040001D8 RID: 472
|
|
private static readonly int[] CPDIST = new int[]
|
|
{
|
|
1, 2, 3, 4, 5, 7, 9, 13, 17, 25,
|
|
33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
|
|
1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
|
|
};
|
|
|
|
// Token: 0x040001D9 RID: 473
|
|
private static readonly int[] CPDEXT = new int[]
|
|
{
|
|
0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
|
|
4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
|
|
9, 9, 10, 10, 11, 11, 12, 12, 13, 13
|
|
};
|
|
|
|
// Token: 0x040001DA RID: 474
|
|
private int mode;
|
|
|
|
// Token: 0x040001DB RID: 475
|
|
private int readAdler;
|
|
|
|
// Token: 0x040001DC RID: 476
|
|
private int neededBits;
|
|
|
|
// Token: 0x040001DD RID: 477
|
|
private int repLength;
|
|
|
|
// Token: 0x040001DE RID: 478
|
|
private int repDist;
|
|
|
|
// Token: 0x040001DF RID: 479
|
|
private int uncomprLen;
|
|
|
|
// Token: 0x040001E0 RID: 480
|
|
private bool isLastBlock;
|
|
|
|
// Token: 0x040001E1 RID: 481
|
|
private long totalOut;
|
|
|
|
// Token: 0x040001E2 RID: 482
|
|
private long totalIn;
|
|
|
|
// Token: 0x040001E3 RID: 483
|
|
private bool noHeader;
|
|
|
|
// Token: 0x040001E4 RID: 484
|
|
private StreamManipulator input;
|
|
|
|
// Token: 0x040001E5 RID: 485
|
|
private OutputWindow outputWindow;
|
|
|
|
// Token: 0x040001E6 RID: 486
|
|
private InflaterDynHeader dynHeader;
|
|
|
|
// Token: 0x040001E7 RID: 487
|
|
private InflaterHuffmanTree litlenTree;
|
|
|
|
// Token: 0x040001E8 RID: 488
|
|
private InflaterHuffmanTree distTree;
|
|
|
|
// Token: 0x040001E9 RID: 489
|
|
private Adler32 adler;
|
|
}
|
|
}
|