using System; using System.IO; namespace ICSharpCode.SharpZipLib.LZW { // Token: 0x02000030 RID: 48 public class LzwInputStream : Stream { // Token: 0x17000043 RID: 67 // (get) Token: 0x0600015B RID: 347 RVA: 0x0000919F File Offset: 0x0000819F // (set) Token: 0x0600015C RID: 348 RVA: 0x000091A7 File Offset: 0x000081A7 public bool IsStreamOwner { get { return this.isStreamOwner; } set { this.isStreamOwner = value; } } // Token: 0x0600015D RID: 349 RVA: 0x000091B0 File Offset: 0x000081B0 public LzwInputStream(Stream baseInputStream) { this.baseInputStream = baseInputStream; } // Token: 0x0600015E RID: 350 RVA: 0x00009200 File Offset: 0x00008200 public override int ReadByte() { int num = this.Read(this.one, 0, 1); if (num == 1) { return (int)(this.one[0] & byte.MaxValue); } return -1; } // Token: 0x0600015F RID: 351 RVA: 0x00009230 File Offset: 0x00008230 public override int Read(byte[] buffer, int offset, int count) { if (!this.headerParsed) { this.ParseHeader(); } if (this.eof) { return -1; } int num = offset; int[] array = this.tabPrefix; byte[] array2 = this.tabSuffix; byte[] array3 = this.stack; int num2 = this.nBits; int num3 = this.maxCode; int num4 = this.maxMaxCode; int num5 = this.bitMask; int num6 = this.oldCode; byte b = this.finChar; int num7 = this.stackP; int num8 = this.freeEnt; byte[] array4 = this.data; int i = this.bitPos; int num9 = array3.Length - num7; if (num9 > 0) { int num10 = ((num9 >= count) ? count : num9); Array.Copy(array3, num7, buffer, offset, num10); offset += num10; count -= num10; num7 += num10; } if (count == 0) { this.stackP = num7; return offset - num; } int j; for (;;) { IL_C6: if (this.end < 64) { this.Fill(); } int num11 = ((this.got > 0) ? (this.end - this.end % num2 << 3) : ((this.end << 3) - (num2 - 1))); while (i < num11) { if (count == 0) { goto Block_8; } if (num8 > num3) { int num12 = num2 << 3; i = i - 1 + num12 - (i - 1 + num12) % num12; num2++; num3 = ((num2 == this.maxBits) ? num4 : ((1 << num2) - 1)); num5 = (1 << num2) - 1; i = this.ResetBuf(i); goto IL_C6; } int num13 = i >> 3; j = (((int)(array4[num13] & byte.MaxValue) | ((int)(array4[num13 + 1] & byte.MaxValue) << 8) | ((int)(array4[num13 + 2] & byte.MaxValue) << 16)) >> (i & 7)) & num5; i += num2; if (num6 == -1) { if (j >= 256) { goto Block_12; } b = (byte)(num6 = j); buffer[offset++] = b; count--; } else { if (j == 256 && this.blockMode) { Array.Copy(this.zeros, 0, array, 0, this.zeros.Length); num8 = 256; int num14 = num2 << 3; i = i - 1 + num14 - (i - 1 + num14) % num14; num2 = 9; num3 = (1 << num2) - 1; num5 = num3; i = this.ResetBuf(i); goto IL_C6; } int num15 = j; num7 = array3.Length; if (j >= num8) { if (j > num8) { goto Block_16; } array3[--num7] = b; j = num6; } while (j >= 256) { array3[--num7] = array2[j]; j = array[j]; } b = array2[j]; buffer[offset++] = b; count--; num9 = array3.Length - num7; int num16 = ((num9 >= count) ? count : num9); Array.Copy(array3, num7, buffer, offset, num16); offset += num16; count -= num16; num7 += num16; if (num8 < num4) { array[num8] = num6; array2[num8] = b; num8++; } num6 = num15; if (count == 0) { goto Block_20; } } } i = this.ResetBuf(i); if (this.got <= 0) { goto Block_22; } } Block_8: this.nBits = num2; this.maxCode = num3; this.maxMaxCode = num4; this.bitMask = num5; this.oldCode = num6; this.finChar = b; this.stackP = num7; this.freeEnt = num8; this.bitPos = i; return offset - num; Block_12: throw new LzwException("corrupt input: " + j + " > 255"); Block_16: throw new LzwException(string.Concat(new object[] { "corrupt input: code=", j, ", freeEnt=", num8 })); Block_20: this.nBits = num2; this.maxCode = num3; this.bitMask = num5; this.oldCode = num6; this.finChar = b; this.stackP = num7; this.freeEnt = num8; this.bitPos = i; return offset - num; Block_22: this.nBits = num2; this.maxCode = num3; this.bitMask = num5; this.oldCode = num6; this.finChar = b; this.stackP = num7; this.freeEnt = num8; this.bitPos = i; this.eof = true; return offset - num; } // Token: 0x06000160 RID: 352 RVA: 0x00009678 File Offset: 0x00008678 private int ResetBuf(int bitPosition) { int num = bitPosition >> 3; Array.Copy(this.data, num, this.data, 0, this.end - num); this.end -= num; return 0; } // Token: 0x06000161 RID: 353 RVA: 0x000096B4 File Offset: 0x000086B4 private void Fill() { this.got = this.baseInputStream.Read(this.data, this.end, this.data.Length - 1 - this.end); if (this.got > 0) { this.end += this.got; } } // Token: 0x06000162 RID: 354 RVA: 0x0000970C File Offset: 0x0000870C private void ParseHeader() { this.headerParsed = true; byte[] array = new byte[3]; int num = this.baseInputStream.Read(array, 0, array.Length); if (num < 0) { throw new LzwException("Failed to read LZW header"); } if (array[0] != 31 || array[1] != 157) { throw new LzwException(string.Format("Wrong LZW header. Magic bytes don't match. 0x{0:x2} 0x{1:x2}", array[0], array[1])); } this.blockMode = (array[2] & 128) > 0; this.maxBits = (int)(array[2] & 31); if (this.maxBits > 16) { throw new LzwException(string.Concat(new object[] { "Stream compressed with ", this.maxBits, " bits, but decompression can only handle ", 16, " bits." })); } if ((array[2] & 96) > 0) { throw new LzwException("Unsupported bits set in the header."); } this.maxMaxCode = 1 << this.maxBits; this.nBits = 9; this.maxCode = (1 << this.nBits) - 1; this.bitMask = this.maxCode; this.oldCode = -1; this.finChar = 0; this.freeEnt = (this.blockMode ? 257 : 256); this.tabPrefix = new int[1 << this.maxBits]; this.tabSuffix = new byte[1 << this.maxBits]; this.stack = new byte[1 << this.maxBits]; this.stackP = this.stack.Length; for (int i = 255; i >= 0; i--) { this.tabSuffix[i] = (byte)i; } } // Token: 0x17000044 RID: 68 // (get) Token: 0x06000163 RID: 355 RVA: 0x000098C1 File Offset: 0x000088C1 public override bool CanRead { get { return this.baseInputStream.CanRead; } } // Token: 0x17000045 RID: 69 // (get) Token: 0x06000164 RID: 356 RVA: 0x000098CE File Offset: 0x000088CE public override bool CanSeek { get { return false; } } // Token: 0x17000046 RID: 70 // (get) Token: 0x06000165 RID: 357 RVA: 0x000098D1 File Offset: 0x000088D1 public override bool CanWrite { get { return false; } } // Token: 0x17000047 RID: 71 // (get) Token: 0x06000166 RID: 358 RVA: 0x000098D4 File Offset: 0x000088D4 public override long Length { get { return (long)this.got; } } // Token: 0x17000048 RID: 72 // (get) Token: 0x06000167 RID: 359 RVA: 0x000098DD File Offset: 0x000088DD // (set) Token: 0x06000168 RID: 360 RVA: 0x000098EA File Offset: 0x000088EA public override long Position { get { return this.baseInputStream.Position; } set { throw new NotSupportedException("InflaterInputStream Position not supported"); } } // Token: 0x06000169 RID: 361 RVA: 0x000098F6 File Offset: 0x000088F6 public override void Flush() { this.baseInputStream.Flush(); } // Token: 0x0600016A RID: 362 RVA: 0x00009903 File Offset: 0x00008903 public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException("Seek not supported"); } // Token: 0x0600016B RID: 363 RVA: 0x0000990F File Offset: 0x0000890F public override void SetLength(long value) { throw new NotSupportedException("InflaterInputStream SetLength not supported"); } // Token: 0x0600016C RID: 364 RVA: 0x0000991B File Offset: 0x0000891B public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException("InflaterInputStream Write not supported"); } // Token: 0x0600016D RID: 365 RVA: 0x00009927 File Offset: 0x00008927 public override void WriteByte(byte value) { throw new NotSupportedException("InflaterInputStream WriteByte not supported"); } // Token: 0x0600016E RID: 366 RVA: 0x00009933 File Offset: 0x00008933 public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { throw new NotSupportedException("InflaterInputStream BeginWrite not supported"); } // Token: 0x0600016F RID: 367 RVA: 0x0000993F File Offset: 0x0000893F public override void Close() { if (!this.isClosed) { this.isClosed = true; if (this.isStreamOwner) { this.baseInputStream.Close(); } } } // Token: 0x040000C5 RID: 197 private const int TBL_CLEAR = 256; // Token: 0x040000C6 RID: 198 private const int TBL_FIRST = 257; // Token: 0x040000C7 RID: 199 private const int EXTRA = 64; // Token: 0x040000C8 RID: 200 private Stream baseInputStream; // Token: 0x040000C9 RID: 201 private bool isStreamOwner = true; // Token: 0x040000CA RID: 202 private bool isClosed; // Token: 0x040000CB RID: 203 private readonly byte[] one = new byte[1]; // Token: 0x040000CC RID: 204 private bool headerParsed; // Token: 0x040000CD RID: 205 private int[] tabPrefix; // Token: 0x040000CE RID: 206 private byte[] tabSuffix; // Token: 0x040000CF RID: 207 private readonly int[] zeros = new int[256]; // Token: 0x040000D0 RID: 208 private byte[] stack; // Token: 0x040000D1 RID: 209 private bool blockMode; // Token: 0x040000D2 RID: 210 private int nBits; // Token: 0x040000D3 RID: 211 private int maxBits; // Token: 0x040000D4 RID: 212 private int maxMaxCode; // Token: 0x040000D5 RID: 213 private int maxCode; // Token: 0x040000D6 RID: 214 private int bitMask; // Token: 0x040000D7 RID: 215 private int oldCode; // Token: 0x040000D8 RID: 216 private byte finChar; // Token: 0x040000D9 RID: 217 private int stackP; // Token: 0x040000DA RID: 218 private int freeEnt; // Token: 0x040000DB RID: 219 private readonly byte[] data = new byte[8192]; // Token: 0x040000DC RID: 220 private int bitPos; // Token: 0x040000DD RID: 221 private int end; // Token: 0x040000DE RID: 222 private int got; // Token: 0x040000DF RID: 223 private bool eof; } }