using System; using ICSharpCode.SharpZipLib.Checksums; namespace ICSharpCode.SharpZipLib.Zip.Compression { // Token: 0x02000042 RID: 66 public class DeflaterEngine : DeflaterConstants { // Token: 0x0600028E RID: 654 RVA: 0x0000D36C File Offset: 0x0000C36C public DeflaterEngine(DeflaterPending pending) { this.pending = pending; this.huffman = new DeflaterHuffman(pending); this.adler = new Adler32(); this.window = new byte[65536]; this.head = new short[32768]; this.prev = new short[32768]; this.blockStart = (this.strstart = 1); } // Token: 0x0600028F RID: 655 RVA: 0x0000D3E0 File Offset: 0x0000C3E0 public bool Deflate(bool flush, bool finish) { for (;;) { this.FillWindow(); bool flag = flush && this.inputOff == this.inputEnd; bool flag2; switch (this.compressionFunction) { case 0: flag2 = this.DeflateStored(flag, finish); goto IL_62; case 1: flag2 = this.DeflateFast(flag, finish); goto IL_62; case 2: flag2 = this.DeflateSlow(flag, finish); goto IL_62; } break; IL_62: if (!this.pending.IsFlushed || !flag2) { return flag2; } } throw new InvalidOperationException("unknown compressionFunction"); } // Token: 0x06000290 RID: 656 RVA: 0x0000D460 File Offset: 0x0000C460 public void SetInput(byte[] buffer, int offset, int count) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset"); } if (count < 0) { throw new ArgumentOutOfRangeException("count"); } if (this.inputOff < this.inputEnd) { throw new InvalidOperationException("Old input was not completely processed"); } int num = offset + count; if (offset > num || num > buffer.Length) { throw new ArgumentOutOfRangeException("count"); } this.inputBuf = buffer; this.inputOff = offset; this.inputEnd = num; } // Token: 0x06000291 RID: 657 RVA: 0x0000D4E0 File Offset: 0x0000C4E0 public bool NeedsInput() { return this.inputEnd == this.inputOff; } // Token: 0x06000292 RID: 658 RVA: 0x0000D4F0 File Offset: 0x0000C4F0 public void SetDictionary(byte[] buffer, int offset, int length) { this.adler.Update(buffer, offset, length); if (length < 3) { return; } if (length > 32506) { offset += length - 32506; length = 32506; } Array.Copy(buffer, offset, this.window, this.strstart, length); this.UpdateHash(); length--; while (--length > 0) { this.InsertString(); this.strstart++; } this.strstart += 2; this.blockStart = this.strstart; } // Token: 0x06000293 RID: 659 RVA: 0x0000D584 File Offset: 0x0000C584 public void Reset() { this.huffman.Reset(); this.adler.Reset(); this.blockStart = (this.strstart = 1); this.lookahead = 0; this.totalIn = 0L; this.prevAvailable = false; this.matchLen = 2; for (int i = 0; i < 32768; i++) { this.head[i] = 0; } for (int j = 0; j < 32768; j++) { this.prev[j] = 0; } } // Token: 0x06000294 RID: 660 RVA: 0x0000D606 File Offset: 0x0000C606 public void ResetAdler() { this.adler.Reset(); } // Token: 0x17000091 RID: 145 // (get) Token: 0x06000295 RID: 661 RVA: 0x0000D613 File Offset: 0x0000C613 public int Adler { get { return (int)this.adler.Value; } } // Token: 0x17000092 RID: 146 // (get) Token: 0x06000296 RID: 662 RVA: 0x0000D621 File Offset: 0x0000C621 public long TotalIn { get { return this.totalIn; } } // Token: 0x17000093 RID: 147 // (get) Token: 0x06000297 RID: 663 RVA: 0x0000D629 File Offset: 0x0000C629 // (set) Token: 0x06000298 RID: 664 RVA: 0x0000D631 File Offset: 0x0000C631 public DeflateStrategy Strategy { get { return this.strategy; } set { this.strategy = value; } } // Token: 0x06000299 RID: 665 RVA: 0x0000D63C File Offset: 0x0000C63C public void SetLevel(int level) { if (level < 0 || level > 9) { throw new ArgumentOutOfRangeException("level"); } this.goodLength = DeflaterConstants.GOOD_LENGTH[level]; this.max_lazy = DeflaterConstants.MAX_LAZY[level]; this.niceLength = DeflaterConstants.NICE_LENGTH[level]; this.max_chain = DeflaterConstants.MAX_CHAIN[level]; if (DeflaterConstants.COMPR_FUNC[level] != this.compressionFunction) { switch (this.compressionFunction) { case 0: if (this.strstart > this.blockStart) { this.huffman.FlushStoredBlock(this.window, this.blockStart, this.strstart - this.blockStart, false); this.blockStart = this.strstart; } this.UpdateHash(); break; case 1: if (this.strstart > this.blockStart) { this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, false); this.blockStart = this.strstart; } break; case 2: if (this.prevAvailable) { this.huffman.TallyLit((int)(this.window[this.strstart - 1] & byte.MaxValue)); } if (this.strstart > this.blockStart) { this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, false); this.blockStart = this.strstart; } this.prevAvailable = false; this.matchLen = 2; break; } this.compressionFunction = DeflaterConstants.COMPR_FUNC[level]; } } // Token: 0x0600029A RID: 666 RVA: 0x0000D7D4 File Offset: 0x0000C7D4 public void FillWindow() { if (this.strstart >= 65274) { this.SlideWindow(); } while (this.lookahead < 262 && this.inputOff < this.inputEnd) { int num = 65536 - this.lookahead - this.strstart; if (num > this.inputEnd - this.inputOff) { num = this.inputEnd - this.inputOff; } Array.Copy(this.inputBuf, this.inputOff, this.window, this.strstart + this.lookahead, num); this.adler.Update(this.inputBuf, this.inputOff, num); this.inputOff += num; this.totalIn += (long)num; this.lookahead += num; } if (this.lookahead >= 3) { this.UpdateHash(); } } // Token: 0x0600029B RID: 667 RVA: 0x0000D8C3 File Offset: 0x0000C8C3 private void UpdateHash() { this.ins_h = ((int)this.window[this.strstart] << 5) ^ (int)this.window[this.strstart + 1]; } // Token: 0x0600029C RID: 668 RVA: 0x0000D8EC File Offset: 0x0000C8EC private int InsertString() { int num = ((this.ins_h << 5) ^ (int)this.window[this.strstart + 2]) & 32767; short num2 = (this.prev[this.strstart & 32767] = this.head[num]); this.head[num] = (short)this.strstart; this.ins_h = num; return (int)num2 & 65535; } // Token: 0x0600029D RID: 669 RVA: 0x0000D954 File Offset: 0x0000C954 private void SlideWindow() { Array.Copy(this.window, 32768, this.window, 0, 32768); this.matchStart -= 32768; this.strstart -= 32768; this.blockStart -= 32768; for (int i = 0; i < 32768; i++) { int num = (int)this.head[i] & 65535; this.head[i] = (short)((num >= 32768) ? (num - 32768) : 0); } for (int j = 0; j < 32768; j++) { int num2 = (int)this.prev[j] & 65535; this.prev[j] = (short)((num2 >= 32768) ? (num2 - 32768) : 0); } } // Token: 0x0600029E RID: 670 RVA: 0x0000DA28 File Offset: 0x0000CA28 private bool FindLongestMatch(int curMatch) { int num = this.max_chain; int num2 = this.niceLength; short[] array = this.prev; int num3 = this.strstart; int num4 = this.strstart + this.matchLen; int num5 = Math.Max(this.matchLen, 2); int num6 = Math.Max(this.strstart - 32506, 0); int num7 = this.strstart + 258 - 1; byte b = this.window[num4 - 1]; byte b2 = this.window[num4]; if (num5 >= this.goodLength) { num >>= 2; } if (num2 > this.lookahead) { num2 = this.lookahead; } do { if (this.window[curMatch + num5] == b2 && this.window[curMatch + num5 - 1] == b && this.window[curMatch] == this.window[num3] && this.window[curMatch + 1] == this.window[num3 + 1]) { int num8 = curMatch + 2; num3 += 2; while (this.window[++num3] == this.window[++num8] && this.window[++num3] == this.window[++num8] && this.window[++num3] == this.window[++num8] && this.window[++num3] == this.window[++num8] && this.window[++num3] == this.window[++num8] && this.window[++num3] == this.window[++num8] && this.window[++num3] == this.window[++num8] && this.window[++num3] == this.window[++num8] && num3 < num7) { } if (num3 > num4) { this.matchStart = curMatch; num4 = num3; num5 = num3 - this.strstart; if (num5 >= num2) { break; } b = this.window[num4 - 1]; b2 = this.window[num4]; } num3 = this.strstart; } } while ((curMatch = (int)array[curMatch & 32767] & 65535) > num6 && --num != 0); this.matchLen = Math.Min(num5, this.lookahead); return this.matchLen >= 3; } // Token: 0x0600029F RID: 671 RVA: 0x0000DC94 File Offset: 0x0000CC94 private bool DeflateStored(bool flush, bool finish) { if (!flush && this.lookahead == 0) { return false; } this.strstart += this.lookahead; this.lookahead = 0; int num = this.strstart - this.blockStart; if (num >= DeflaterConstants.MAX_BLOCK_SIZE || (this.blockStart < 32768 && num >= 32506) || flush) { bool flag = finish; if (num > DeflaterConstants.MAX_BLOCK_SIZE) { num = DeflaterConstants.MAX_BLOCK_SIZE; flag = false; } this.huffman.FlushStoredBlock(this.window, this.blockStart, num, flag); this.blockStart += num; return !flag; } return true; } // Token: 0x060002A0 RID: 672 RVA: 0x0000DD38 File Offset: 0x0000CD38 private bool DeflateFast(bool flush, bool finish) { if (this.lookahead < 262 && !flush) { return false; } while (this.lookahead >= 262 || flush) { if (this.lookahead == 0) { this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, finish); this.blockStart = this.strstart; return false; } if (this.strstart > 65274) { this.SlideWindow(); } int num; if (this.lookahead >= 3 && (num = this.InsertString()) != 0 && this.strategy != DeflateStrategy.HuffmanOnly && this.strstart - num <= 32506 && this.FindLongestMatch(num)) { bool flag = this.huffman.TallyDist(this.strstart - this.matchStart, this.matchLen); this.lookahead -= this.matchLen; if (this.matchLen <= this.max_lazy && this.lookahead >= 3) { while (--this.matchLen > 0) { this.strstart++; this.InsertString(); } this.strstart++; } else { this.strstart += this.matchLen; if (this.lookahead >= 2) { this.UpdateHash(); } } this.matchLen = 2; if (!flag) { continue; } } else { this.huffman.TallyLit((int)(this.window[this.strstart] & byte.MaxValue)); this.strstart++; this.lookahead--; } if (this.huffman.IsFull()) { bool flag2 = finish && this.lookahead == 0; this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, flag2); this.blockStart = this.strstart; return !flag2; } } return true; } // Token: 0x060002A1 RID: 673 RVA: 0x0000DF48 File Offset: 0x0000CF48 private bool DeflateSlow(bool flush, bool finish) { if (this.lookahead < 262 && !flush) { return false; } while (this.lookahead >= 262 || flush) { if (this.lookahead == 0) { if (this.prevAvailable) { this.huffman.TallyLit((int)(this.window[this.strstart - 1] & byte.MaxValue)); } this.prevAvailable = false; this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, finish); this.blockStart = this.strstart; return false; } if (this.strstart >= 65274) { this.SlideWindow(); } int num = this.matchStart; int num2 = this.matchLen; if (this.lookahead >= 3) { int num3 = this.InsertString(); if (this.strategy != DeflateStrategy.HuffmanOnly && num3 != 0 && this.strstart - num3 <= 32506 && this.FindLongestMatch(num3) && this.matchLen <= 5 && (this.strategy == DeflateStrategy.Filtered || (this.matchLen == 3 && this.strstart - this.matchStart > 4096))) { this.matchLen = 2; } } if (num2 >= 3 && this.matchLen <= num2) { this.huffman.TallyDist(this.strstart - 1 - num, num2); num2 -= 2; do { this.strstart++; this.lookahead--; if (this.lookahead >= 3) { this.InsertString(); } } while (--num2 > 0); this.strstart++; this.lookahead--; this.prevAvailable = false; this.matchLen = 2; } else { if (this.prevAvailable) { this.huffman.TallyLit((int)(this.window[this.strstart - 1] & byte.MaxValue)); } this.prevAvailable = true; this.strstart++; this.lookahead--; } if (this.huffman.IsFull()) { int num4 = this.strstart - this.blockStart; if (this.prevAvailable) { num4--; } bool flag = finish && this.lookahead == 0 && !this.prevAvailable; this.huffman.FlushBlock(this.window, this.blockStart, num4, flag); this.blockStart += num4; return !flag; } } return true; } // Token: 0x0400018E RID: 398 private const int TooFar = 4096; // Token: 0x0400018F RID: 399 private int ins_h; // Token: 0x04000190 RID: 400 private short[] head; // Token: 0x04000191 RID: 401 private short[] prev; // Token: 0x04000192 RID: 402 private int matchStart; // Token: 0x04000193 RID: 403 private int matchLen; // Token: 0x04000194 RID: 404 private bool prevAvailable; // Token: 0x04000195 RID: 405 private int blockStart; // Token: 0x04000196 RID: 406 private int strstart; // Token: 0x04000197 RID: 407 private int lookahead; // Token: 0x04000198 RID: 408 private byte[] window; // Token: 0x04000199 RID: 409 private DeflateStrategy strategy; // Token: 0x0400019A RID: 410 private int max_chain; // Token: 0x0400019B RID: 411 private int max_lazy; // Token: 0x0400019C RID: 412 private int niceLength; // Token: 0x0400019D RID: 413 private int goodLength; // Token: 0x0400019E RID: 414 private int compressionFunction; // Token: 0x0400019F RID: 415 private byte[] inputBuf; // Token: 0x040001A0 RID: 416 private long totalIn; // Token: 0x040001A1 RID: 417 private int inputOff; // Token: 0x040001A2 RID: 418 private int inputEnd; // Token: 0x040001A3 RID: 419 private DeflaterPending pending; // Token: 0x040001A4 RID: 420 private DeflaterHuffman huffman; // Token: 0x040001A5 RID: 421 private Adler32 adler; } }