xref: /aosp_15_r20/external/brotli/csharp/org/brotli/dec/State.cs (revision f4ee7fba7774faf2a30f13154332c0a06550dbc4)
1 /* Copyright 2015 Google Inc. All Rights Reserved.
2 
3 Distributed under MIT license.
4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5 */
6 namespace Org.Brotli.Dec
7 {
8 	internal sealed class State
9 	{
10 		internal int runningState = Org.Brotli.Dec.RunningState.Uninitialized;
11 
12 		internal int nextRunningState;
13 
14 		internal readonly Org.Brotli.Dec.BitReader br = new Org.Brotli.Dec.BitReader();
15 
16 		internal byte[] ringBuffer;
17 
18 		internal readonly int[] blockTypeTrees = new int[3 * Org.Brotli.Dec.Huffman.HuffmanMaxTableSize];
19 
20 		internal readonly int[] blockLenTrees = new int[3 * Org.Brotli.Dec.Huffman.HuffmanMaxTableSize];
21 
22 		internal int metaBlockLength;
23 
24 		internal bool inputEnd;
25 
26 		internal bool isUncompressed;
27 
28 		internal bool isMetadata;
29 
30 		internal readonly Org.Brotli.Dec.HuffmanTreeGroup hGroup0 = new Org.Brotli.Dec.HuffmanTreeGroup();
31 
32 		internal readonly Org.Brotli.Dec.HuffmanTreeGroup hGroup1 = new Org.Brotli.Dec.HuffmanTreeGroup();
33 
34 		internal readonly Org.Brotli.Dec.HuffmanTreeGroup hGroup2 = new Org.Brotli.Dec.HuffmanTreeGroup();
35 
36 		internal readonly int[] blockLength = new int[3];
37 
38 		internal readonly int[] numBlockTypes = new int[3];
39 
40 		internal readonly int[] blockTypeRb = new int[6];
41 
42 		internal readonly int[] distRb = new int[] { 16, 15, 11, 4 };
43 
44 		internal int pos = 0;
45 
46 		internal int maxDistance = 0;
47 
48 		internal int distRbIdx = 0;
49 
50 		internal bool trivialLiteralContext = false;
51 
52 		internal int literalTreeIndex = 0;
53 
54 		internal int literalTree;
55 
56 		internal int j;
57 
58 		internal int insertLength;
59 
60 		internal byte[] contextModes;
61 
62 		internal byte[] contextMap;
63 
64 		internal int contextMapSlice;
65 
66 		internal int distContextMapSlice;
67 
68 		internal int contextLookupOffset1;
69 
70 		internal int contextLookupOffset2;
71 
72 		internal int treeCommandOffset;
73 
74 		internal int distanceCode;
75 
76 		internal byte[] distContextMap;
77 
78 		internal int numDirectDistanceCodes;
79 
80 		internal int distancePostfixMask;
81 
82 		internal int distancePostfixBits;
83 
84 		internal int distance;
85 
86 		internal int copyLength;
87 
88 		internal int copyDst;
89 
90 		internal int maxBackwardDistance;
91 
92 		internal int maxRingBufferSize;
93 
94 		internal int ringBufferSize = 0;
95 
96 		internal long expectedTotalSize = 0;
97 
98 		internal byte[] customDictionary = new byte[0];
99 
100 		internal int bytesToIgnore = 0;
101 
102 		internal int outputOffset;
103 
104 		internal int outputLength;
105 
106 		internal int outputUsed;
107 
108 		internal int bytesWritten;
109 
110 		internal int bytesToWrite;
111 
112 		internal byte[] output;
113 
114 		// Current meta-block header information.
115 		// TODO: Update to current spec.
DecodeWindowBits(Org.Brotli.Dec.BitReader br)116 		private static int DecodeWindowBits(Org.Brotli.Dec.BitReader br)
117 		{
118 			if (Org.Brotli.Dec.BitReader.ReadBits(br, 1) == 0)
119 			{
120 				return 16;
121 			}
122 			int n = Org.Brotli.Dec.BitReader.ReadBits(br, 3);
123 			if (n != 0)
124 			{
125 				return 17 + n;
126 			}
127 			n = Org.Brotli.Dec.BitReader.ReadBits(br, 3);
128 			if (n != 0)
129 			{
130 				return 8 + n;
131 			}
132 			return 17;
133 		}
134 
135 		/// <summary>Associate input with decoder state.</summary>
136 		/// <param name="state">uninitialized state without associated input</param>
137 		/// <param name="input">compressed data source</param>
SetInput(Org.Brotli.Dec.State state, System.IO.Stream input)138 		internal static void SetInput(Org.Brotli.Dec.State state, System.IO.Stream input)
139 		{
140 			if (state.runningState != Org.Brotli.Dec.RunningState.Uninitialized)
141 			{
142 				throw new System.InvalidOperationException("State MUST be uninitialized");
143 			}
144 			Org.Brotli.Dec.BitReader.Init(state.br, input);
145 			int windowBits = DecodeWindowBits(state.br);
146 			if (windowBits == 9)
147 			{
148 				/* Reserved case for future expansion. */
149 				throw new Org.Brotli.Dec.BrotliRuntimeException("Invalid 'windowBits' code");
150 			}
151 			state.maxRingBufferSize = 1 << windowBits;
152 			state.maxBackwardDistance = state.maxRingBufferSize - 16;
153 			state.runningState = Org.Brotli.Dec.RunningState.BlockStart;
154 		}
155 
156 		/// <exception cref="System.IO.IOException"/>
Close(Org.Brotli.Dec.State state)157 		internal static void Close(Org.Brotli.Dec.State state)
158 		{
159 			if (state.runningState == Org.Brotli.Dec.RunningState.Uninitialized)
160 			{
161 				throw new System.InvalidOperationException("State MUST be initialized");
162 			}
163 			if (state.runningState == Org.Brotli.Dec.RunningState.Closed)
164 			{
165 				return;
166 			}
167 			state.runningState = Org.Brotli.Dec.RunningState.Closed;
168 			Org.Brotli.Dec.BitReader.Close(state.br);
169 		}
170 	}
171 }
172