| /* Copyright 2015 Google Inc. All Rights Reserved. | |
| Distributed under MIT license. | |
| See file LICENSE for detail or copy at https://opensource.org/licenses/MIT | |
| */ | |
| namespace Org.Brotli.Dec | |
| { | |
| internal sealed class State | |
| { | |
| internal int runningState = Org.Brotli.Dec.RunningState.Uninitialized; | |
| internal int nextRunningState; | |
| internal readonly Org.Brotli.Dec.BitReader br = new Org.Brotli.Dec.BitReader(); | |
| internal byte[] ringBuffer; | |
| internal readonly int[] blockTypeTrees = new int[3 * Org.Brotli.Dec.Huffman.HuffmanMaxTableSize]; | |
| internal readonly int[] blockLenTrees = new int[3 * Org.Brotli.Dec.Huffman.HuffmanMaxTableSize]; | |
| internal int metaBlockLength; | |
| internal bool inputEnd; | |
| internal bool isUncompressed; | |
| internal bool isMetadata; | |
| internal readonly Org.Brotli.Dec.HuffmanTreeGroup hGroup0 = new Org.Brotli.Dec.HuffmanTreeGroup(); | |
| internal readonly Org.Brotli.Dec.HuffmanTreeGroup hGroup1 = new Org.Brotli.Dec.HuffmanTreeGroup(); | |
| internal readonly Org.Brotli.Dec.HuffmanTreeGroup hGroup2 = new Org.Brotli.Dec.HuffmanTreeGroup(); | |
| internal readonly int[] blockLength = new int[3]; | |
| internal readonly int[] numBlockTypes = new int[3]; | |
| internal readonly int[] blockTypeRb = new int[6]; | |
| internal readonly int[] distRb = new int[] { 16, 15, 11, 4 }; | |
| internal int pos = 0; | |
| internal int maxDistance = 0; | |
| internal int distRbIdx = 0; | |
| internal bool trivialLiteralContext = false; | |
| internal int literalTreeIndex = 0; | |
| internal int literalTree; | |
| internal int j; | |
| internal int insertLength; | |
| internal byte[] contextModes; | |
| internal byte[] contextMap; | |
| internal int contextMapSlice; | |
| internal int distContextMapSlice; | |
| internal int contextLookupOffset1; | |
| internal int contextLookupOffset2; | |
| internal int treeCommandOffset; | |
| internal int distanceCode; | |
| internal byte[] distContextMap; | |
| internal int numDirectDistanceCodes; | |
| internal int distancePostfixMask; | |
| internal int distancePostfixBits; | |
| internal int distance; | |
| internal int copyLength; | |
| internal int copyDst; | |
| internal int maxBackwardDistance; | |
| internal int maxRingBufferSize; | |
| internal int ringBufferSize = 0; | |
| internal long expectedTotalSize = 0; | |
| internal byte[] customDictionary = new byte[0]; | |
| internal int bytesToIgnore = 0; | |
| internal int outputOffset; | |
| internal int outputLength; | |
| internal int outputUsed; | |
| internal int bytesWritten; | |
| internal int bytesToWrite; | |
| internal byte[] output; | |
| // Current meta-block header information. | |
| // TODO: Update to current spec. | |
| private static int DecodeWindowBits(Org.Brotli.Dec.BitReader br) | |
| { | |
| if (Org.Brotli.Dec.BitReader.ReadBits(br, 1) == 0) | |
| { | |
| return 16; | |
| } | |
| int n = Org.Brotli.Dec.BitReader.ReadBits(br, 3); | |
| if (n != 0) | |
| { | |
| return 17 + n; | |
| } | |
| n = Org.Brotli.Dec.BitReader.ReadBits(br, 3); | |
| if (n != 0) | |
| { | |
| return 8 + n; | |
| } | |
| return 17; | |
| } | |
| /// <summary>Associate input with decoder state.</summary> | |
| /// <param name="state">uninitialized state without associated input</param> | |
| /// <param name="input">compressed data source</param> | |
| internal static void SetInput(Org.Brotli.Dec.State state, System.IO.Stream input) | |
| { | |
| if (state.runningState != Org.Brotli.Dec.RunningState.Uninitialized) | |
| { | |
| throw new System.InvalidOperationException("State MUST be uninitialized"); | |
| } | |
| Org.Brotli.Dec.BitReader.Init(state.br, input); | |
| int windowBits = DecodeWindowBits(state.br); | |
| if (windowBits == 9) | |
| { | |
| /* Reserved case for future expansion. */ | |
| throw new Org.Brotli.Dec.BrotliRuntimeException("Invalid 'windowBits' code"); | |
| } | |
| state.maxRingBufferSize = 1 << windowBits; | |
| state.maxBackwardDistance = state.maxRingBufferSize - 16; | |
| state.runningState = Org.Brotli.Dec.RunningState.BlockStart; | |
| } | |
| /// <exception cref="System.IO.IOException"/> | |
| internal static void Close(Org.Brotli.Dec.State state) | |
| { | |
| if (state.runningState == Org.Brotli.Dec.RunningState.Uninitialized) | |
| { | |
| throw new System.InvalidOperationException("State MUST be initialized"); | |
| } | |
| if (state.runningState == Org.Brotli.Dec.RunningState.Closed) | |
| { | |
| return; | |
| } | |
| state.runningState = Org.Brotli.Dec.RunningState.Closed; | |
| Org.Brotli.Dec.BitReader.Close(state.br); | |
| } | |
| } | |
| } |