Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Inflater.cs
Go to the documentation of this file.
4
6
7internal sealed class Inflater : IDisposable
8{
9 private bool _finished;
10
11 private bool _isDisposed;
12
13 private readonly int _windowBits;
14
16
18
19 private readonly long _uncompressedSize;
20
22
23 private object SyncLock => this;
24
25 private unsafe bool IsInputBufferHandleAllocated => _inputBufferHandle.Pointer != null;
26
27 internal Inflater(int windowBits, long uncompressedSize = -1L)
28 {
29 _finished = false;
30 _isDisposed = false;
31 _windowBits = windowBits;
32 InflateInit(windowBits);
33 _uncompressedSize = uncompressedSize;
34 }
35
36 public bool Finished()
37 {
38 return _finished;
39 }
40
41 public unsafe bool Inflate(out byte b)
42 {
43 fixed (byte* bufPtr = &b)
44 {
45 int num = InflateVerified(bufPtr, 1);
46 return num != 0;
47 }
48 }
49
50 public unsafe int Inflate(byte[] bytes, int offset, int length)
51 {
52 if (length == 0)
53 {
54 return 0;
55 }
56 fixed (byte* ptr = bytes)
57 {
58 return InflateVerified(ptr + offset, length);
59 }
60 }
61
62 public unsafe int Inflate(Span<byte> destination)
63 {
64 if (destination.Length == 0)
65 {
66 return 0;
67 }
68 fixed (byte* bufPtr = &MemoryMarshal.GetReference(destination))
69 {
70 return InflateVerified(bufPtr, destination.Length);
71 }
72 }
73
74 public unsafe int InflateVerified(byte* bufPtr, int length)
75 {
76 try
77 {
78 int bytesRead = 0;
79 if (_uncompressedSize == -1)
80 {
81 ReadOutput(bufPtr, length, out bytesRead);
82 }
84 {
86 ReadOutput(bufPtr, length, out bytesRead);
87 _currentInflatedCount += bytesRead;
88 }
89 else
90 {
91 _finished = true;
92 _zlibStream.AvailIn = 0u;
93 }
94 return bytesRead;
95 }
96 finally
97 {
98 if (_zlibStream.AvailIn == 0 && IsInputBufferHandleAllocated)
99 {
101 }
102 }
103 }
104
105 private unsafe void ReadOutput(byte* bufPtr, int length, out int bytesRead)
106 {
107 if (ReadInflateOutput(bufPtr, length, ZLibNative.FlushCode.NoFlush, out bytesRead) == ZLibNative.ErrorCode.StreamEnd)
108 {
110 {
112 }
113 else
114 {
115 _finished = true;
116 }
117 }
118 }
119
120 private unsafe bool ResetStreamForLeftoverInput()
121 {
122 lock (SyncLock)
123 {
124 IntPtr nextIn = _zlibStream.NextIn;
125 byte* ptr = (byte*)nextIn.ToPointer();
126 uint availIn = _zlibStream.AvailIn;
127 if (*ptr != 31 || (availIn > 1 && ptr[1] != 139))
128 {
129 return true;
130 }
131 _zlibStream.Dispose();
133 _zlibStream.NextIn = nextIn;
134 _zlibStream.AvailIn = availIn;
135 _finished = false;
136 }
137 return false;
138 }
139
140 internal bool IsGzipStream()
141 {
142 if (_windowBits >= 24)
143 {
144 return _windowBits <= 31;
145 }
146 return false;
147 }
148
149 public bool NeedsInput()
150 {
151 return _zlibStream.AvailIn == 0;
152 }
153
154 public void SetInput(byte[] inputBuffer, int startIndex, int count)
155 {
156 SetInput(inputBuffer.AsMemory(startIndex, count));
157 }
158
159 public unsafe void SetInput(ReadOnlyMemory<byte> inputBuffer)
160 {
161 if (inputBuffer.IsEmpty)
162 {
163 return;
164 }
165 lock (SyncLock)
166 {
167 _inputBufferHandle = inputBuffer.Pin();
168 _zlibStream.NextIn = (IntPtr)_inputBufferHandle.Pointer;
169 _zlibStream.AvailIn = (uint)inputBuffer.Length;
170 _finished = false;
171 }
172 }
173
174 private void Dispose(bool disposing)
175 {
176 if (!_isDisposed)
177 {
178 if (disposing)
179 {
180 _zlibStream.Dispose();
181 }
183 {
185 }
186 _isDisposed = true;
187 }
188 }
189
190 public void Dispose()
191 {
192 Dispose(disposing: true);
193 GC.SuppressFinalize(this);
194 }
195
197 {
198 Dispose(disposing: false);
199 }
200
201 [MemberNotNull("_zlibStream")]
202 private void InflateInit(int windowBits)
203 {
204 ZLibNative.ErrorCode errorCode;
205 try
206 {
207 errorCode = ZLibNative.CreateZLibStreamForInflate(out _zlibStream, windowBits);
208 }
209 catch (Exception innerException)
210 {
211 throw new ZLibException(System.SR.ZLibErrorDLLLoadError, innerException);
212 }
213 switch (errorCode)
214 {
215 case ZLibNative.ErrorCode.Ok:
216 break;
217 case ZLibNative.ErrorCode.MemError:
218 throw new ZLibException(System.SR.ZLibErrorNotEnoughMemory, "inflateInit2_", (int)errorCode, _zlibStream.GetErrorMessage());
219 case ZLibNative.ErrorCode.VersionError:
220 throw new ZLibException(System.SR.ZLibErrorVersionMismatch, "inflateInit2_", (int)errorCode, _zlibStream.GetErrorMessage());
221 case ZLibNative.ErrorCode.StreamError:
222 throw new ZLibException(System.SR.ZLibErrorIncorrectInitParameters, "inflateInit2_", (int)errorCode, _zlibStream.GetErrorMessage());
223 default:
224 throw new ZLibException(System.SR.ZLibErrorUnexpected, "inflateInit2_", (int)errorCode, _zlibStream.GetErrorMessage());
225 }
226 }
227
228 private unsafe ZLibNative.ErrorCode ReadInflateOutput(byte* bufPtr, int length, ZLibNative.FlushCode flushCode, out int bytesRead)
229 {
230 lock (SyncLock)
231 {
232 _zlibStream.NextOut = (IntPtr)bufPtr;
233 _zlibStream.AvailOut = (uint)length;
234 ZLibNative.ErrorCode result = Inflate(flushCode);
235 bytesRead = length - (int)_zlibStream.AvailOut;
236 return result;
237 }
238 }
239
241 {
242 ZLibNative.ErrorCode errorCode;
243 try
244 {
245 errorCode = _zlibStream.Inflate(flushCode);
246 }
247 catch (Exception innerException)
248 {
249 throw new ZLibException(System.SR.ZLibErrorDLLLoadError, innerException);
250 }
251 switch (errorCode)
252 {
253 case ZLibNative.ErrorCode.Ok:
254 case ZLibNative.ErrorCode.StreamEnd:
255 return errorCode;
256 case ZLibNative.ErrorCode.BufError:
257 return errorCode;
258 case ZLibNative.ErrorCode.MemError:
259 throw new ZLibException(System.SR.ZLibErrorNotEnoughMemory, "inflate_", (int)errorCode, _zlibStream.GetErrorMessage());
260 case ZLibNative.ErrorCode.DataError:
262 case ZLibNative.ErrorCode.StreamError:
263 throw new ZLibException(System.SR.ZLibErrorInconsistentStream, "inflate_", (int)errorCode, _zlibStream.GetErrorMessage());
264 default:
265 throw new ZLibException(System.SR.ZLibErrorUnexpected, "inflate_", (int)errorCode, _zlibStream.GetErrorMessage());
266 }
267 }
268
270 {
271 lock (SyncLock)
272 {
273 _zlibStream.AvailIn = 0u;
274 _zlibStream.NextIn = ZLibNative.ZNullPtr;
276 }
277 }
278}
static void SuppressFinalize(object obj)
Definition GC.cs:202
Definition GC.cs:8
unsafe void ReadOutput(byte *bufPtr, int length, out int bytesRead)
Definition Inflater.cs:105
readonly long _uncompressedSize
Definition Inflater.cs:19
unsafe int InflateVerified(byte *bufPtr, int length)
Definition Inflater.cs:74
void Dispose(bool disposing)
Definition Inflater.cs:174
unsafe ZLibNative.ErrorCode ReadInflateOutput(byte *bufPtr, int length, ZLibNative.FlushCode flushCode, out int bytesRead)
Definition Inflater.cs:228
Inflater(int windowBits, long uncompressedSize=-1L)
Definition Inflater.cs:27
void SetInput(byte[] inputBuffer, int startIndex, int count)
Definition Inflater.cs:154
MemoryHandle _inputBufferHandle
Definition Inflater.cs:17
unsafe bool Inflate(out byte b)
Definition Inflater.cs:41
unsafe int Inflate(Span< byte > destination)
Definition Inflater.cs:62
ZLibNative.ErrorCode Inflate(ZLibNative.FlushCode flushCode)
Definition Inflater.cs:240
ZLibNative.ZLibStreamHandle _zlibStream
Definition Inflater.cs:15
unsafe bool ResetStreamForLeftoverInput()
Definition Inflater.cs:120
void InflateInit(int windowBits)
Definition Inflater.cs:202
unsafe bool IsInputBufferHandleAllocated
Definition Inflater.cs:25
unsafe int Inflate(byte[] bytes, int offset, int length)
Definition Inflater.cs:50
unsafe void SetInput(ReadOnlyMemory< byte > inputBuffer)
Definition Inflater.cs:159
static ErrorCode CreateZLibStreamForInflate(out ZLibStreamHandle zLibStreamHandle, int windowBits)
static readonly IntPtr ZNullPtr
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static string UnsupportedCompression
Definition SR.cs:122
static string ZLibErrorNotEnoughMemory
Definition SR.cs:46
static string ZLibErrorVersionMismatch
Definition SR.cs:48
static string ZLibErrorDLLLoadError
Definition SR.cs:40
static string ZLibErrorInconsistentStream
Definition SR.cs:42
static string ZLibErrorUnexpected
Definition SR.cs:50
static string ZLibErrorIncorrectInitParameters
Definition SR.cs:44
Definition SR.cs:7
unsafe void * ToPointer()
Definition IntPtr.cs:210
unsafe MemoryHandle Pin()