Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
BrotliStream.cs
Go to the documentation of this file.
5
7
8public sealed class BrotliStream : Stream
9{
11
13
14 private int _bufferOffset;
15
16 private int _bufferCount;
17
18 private Stream _stream;
19
20 private byte[] _buffer;
21
22 private readonly bool _leaveOpen;
23
24 private readonly CompressionMode _mode;
25
27
29
30 public override bool CanRead
31 {
32 get
33 {
34 if (_mode == CompressionMode.Decompress && _stream != null)
35 {
36 return _stream.CanRead;
37 }
38 return false;
39 }
40 }
41
42 public override bool CanWrite
43 {
44 get
45 {
46 if (_mode == CompressionMode.Compress && _stream != null)
47 {
48 return _stream.CanWrite;
49 }
50 return false;
51 }
52 }
53
54 public override bool CanSeek => false;
55
56 public override long Length
57 {
58 get
59 {
60 throw new NotSupportedException();
61 }
62 }
63
64 public override long Position
65 {
66 get
67 {
68 throw new NotSupportedException();
69 }
70 set
71 {
72 throw new NotSupportedException();
73 }
74 }
75
77
78 public BrotliStream(Stream stream, CompressionLevel compressionLevel)
79 : this(stream, compressionLevel, leaveOpen: false)
80 {
81 }
82
83 public BrotliStream(Stream stream, CompressionLevel compressionLevel, bool leaveOpen)
84 : this(stream, CompressionMode.Compress, leaveOpen)
85 {
87 }
88
89 public override void Write(byte[] buffer, int offset, int count)
90 {
93 }
94
95 public override void WriteByte(byte value)
96 {
97 WriteCore(MemoryMarshal.CreateReadOnlySpan(ref value, 1));
98 }
99
100 public override void Write(ReadOnlySpan<byte> buffer)
101 {
103 }
104
105 internal void WriteCore(ReadOnlySpan<byte> buffer, bool isFinalBlock = false)
106 {
107 if (_mode != CompressionMode.Compress)
108 {
110 }
112 OperationStatus operationStatus = OperationStatus.DestinationTooSmall;
114 while (operationStatus == OperationStatus.DestinationTooSmall)
115 {
116 operationStatus = _encoder.Compress(buffer, destination, out var bytesConsumed, out var bytesWritten, isFinalBlock);
117 if (operationStatus == OperationStatus.InvalidData)
118 {
120 }
121 if (bytesWritten > 0)
122 {
123 _stream.Write(destination.Slice(0, bytesWritten));
124 }
125 if (bytesConsumed > 0)
126 {
127 buffer = buffer.Slice(bytesConsumed);
128 }
129 }
130 }
131
132 public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState)
133 {
134 return System.Threading.Tasks.TaskToApm.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
135 }
136
141
147
162
164 {
166 try
167 {
168 OperationStatus lastResult = OperationStatus.DestinationTooSmall;
169 while (lastResult == OperationStatus.DestinationTooSmall)
170 {
172 int bytesConsumed = 0;
173 int bytesWritten = 0;
174 lastResult = _encoder.Compress(buffer, destination, out bytesConsumed, out bytesWritten, isFinalBlock);
175 if (lastResult == OperationStatus.InvalidData)
176 {
178 }
179 if (bytesConsumed > 0)
180 {
181 buffer = buffer.Slice(bytesConsumed);
182 }
183 if (bytesWritten > 0)
184 {
185 await _stream.WriteAsync(new ReadOnlyMemory<byte>(_buffer, 0, bytesWritten), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
186 }
187 }
188 }
189 finally
190 {
192 }
193 }
194
195 public override void Flush()
196 {
198 if (_mode != CompressionMode.Compress || _encoder._state == null || _encoder._state.IsClosed)
199 {
200 return;
201 }
202 OperationStatus operationStatus = OperationStatus.DestinationTooSmall;
204 while (operationStatus == OperationStatus.DestinationTooSmall)
205 {
206 operationStatus = _encoder.Flush(destination, out var bytesWritten);
207 if (operationStatus == OperationStatus.InvalidData)
208 {
210 }
211 if (bytesWritten > 0)
212 {
213 _stream.Write(destination.Slice(0, bytesWritten));
214 }
215 }
216 _stream.Flush();
217 }
218
220 {
223 if (cancellationToken.IsCancellationRequested)
224 {
226 }
227 if (_mode == CompressionMode.Compress)
228 {
230 }
231 return Task.CompletedTask;
232 }
233
235 {
237 try
238 {
239 if (_encoder._state == null || _encoder._state.IsClosed)
240 {
241 return;
242 }
243 OperationStatus lastResult = OperationStatus.DestinationTooSmall;
244 while (lastResult == OperationStatus.DestinationTooSmall)
245 {
247 int bytesWritten = 0;
248 lastResult = _encoder.Flush(destination, out bytesWritten);
249 if (lastResult == OperationStatus.InvalidData)
250 {
252 }
253 if (bytesWritten > 0)
254 {
255 await _stream.WriteAsync(destination.Slice(0, bytesWritten), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
256 }
257 }
258 await _stream.FlushAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
259 }
260 finally
261 {
263 }
264 }
265
266 public override int Read(byte[] buffer, int offset, int count)
267 {
269 return Read(new Span<byte>(buffer, offset, count));
270 }
271
272 public override int ReadByte()
273 {
274 byte reference = 0;
275 if (Read(MemoryMarshal.CreateSpan(ref reference, 1)) == 0)
276 {
277 return -1;
278 }
279 return reference;
280 }
281
282 public override int Read(Span<byte> buffer)
283 {
284 if (_mode != 0)
285 {
287 }
289 int bytesWritten;
290 while (!TryDecompress(buffer, out bytesWritten))
291 {
292 int num = _stream.Read(_buffer, _bufferCount, _buffer.Length - _bufferCount);
293 if (num <= 0)
294 {
295 break;
296 }
297 _bufferCount += num;
298 if (_bufferCount > _buffer.Length)
299 {
301 }
302 }
303 return bytesWritten;
304 }
305
306 public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState)
307 {
308 return System.Threading.Tasks.TaskToApm.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), asyncCallback, asyncState);
309 }
310
311 public override int EndRead(IAsyncResult asyncResult)
312 {
314 }
315
321
323 {
324 if (_mode != 0)
325 {
327 }
330 if (cancellationToken.IsCancellationRequested)
331 {
333 }
334 return Core(buffer, cancellationToken);
336 {
338 try
339 {
340 int bytesWritten;
341 while (!TryDecompress(buffer.Span, out bytesWritten))
342 {
343 int num = await _stream.ReadAsync(_buffer.AsMemory(_bufferCount), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
344 if (num <= 0)
345 {
346 break;
347 }
348 _bufferCount += num;
349 if (_bufferCount > _buffer.Length)
350 {
352 }
353 }
354 return bytesWritten;
355 }
356 finally
357 {
359 }
360 }
361 }
362
363 private bool TryDecompress(Span<byte> destination, out int bytesWritten)
364 {
365 int bytesConsumed;
366 OperationStatus operationStatus = _decoder.Decompress(new ReadOnlySpan<byte>(_buffer, _bufferOffset, _bufferCount), destination, out bytesConsumed, out bytesWritten);
367 if (operationStatus == OperationStatus.InvalidData)
368 {
370 }
371 if (bytesConsumed != 0)
372 {
373 _bufferOffset += bytesConsumed;
374 _bufferCount -= bytesConsumed;
375 }
376 if (bytesWritten != 0 || operationStatus == OperationStatus.Done)
377 {
378 return true;
379 }
380 if (destination.IsEmpty && _bufferCount != 0)
381 {
382 return true;
383 }
384 if (_bufferCount != 0 && _bufferOffset != 0)
385 {
387 }
388 _bufferOffset = 0;
389 return false;
390 }
391
396
398 : this(stream, mode, leaveOpen: false)
399 {
400 }
401
402 public BrotliStream(Stream stream, CompressionMode mode, bool leaveOpen)
403 {
404 if (stream == null)
405 {
406 throw new ArgumentNullException("stream");
407 }
408 switch (mode)
409 {
410 case CompressionMode.Compress:
411 if (!stream.CanWrite)
412 {
413 throw new ArgumentException(System.SR.Stream_FalseCanWrite, "stream");
414 }
415 break;
416 case CompressionMode.Decompress:
417 if (!stream.CanRead)
418 {
419 throw new ArgumentException(System.SR.Stream_FalseCanRead, "stream");
420 }
421 break;
422 default:
424 }
425 _mode = mode;
426 _stream = stream;
427 _leaveOpen = leaveOpen;
428 _buffer = ArrayPool<byte>.Shared.Rent(65520);
429 }
430
431 private void EnsureNotDisposed()
432 {
433 if (_stream == null)
434 {
436 }
437 }
438
439 protected override void Dispose(bool disposing)
440 {
441 try
442 {
443 if (disposing && _stream != null)
444 {
445 if (_mode == CompressionMode.Compress)
446 {
447 WriteCore(ReadOnlySpan<byte>.Empty, isFinalBlock: true);
448 }
449 if (!_leaveOpen)
450 {
452 }
453 }
454 }
455 finally
456 {
458 base.Dispose(disposing);
459 }
460 }
461
462 public override async ValueTask DisposeAsync()
463 {
464 _ = 1;
465 try
466 {
467 if (_stream != null)
468 {
469 if (_mode == CompressionMode.Compress)
470 {
471 await WriteAsyncMemoryCore(ReadOnlyMemory<byte>.Empty, CancellationToken.None, isFinalBlock: true).ConfigureAwait(continueOnCapturedContext: false);
472 }
473 if (!_leaveOpen)
474 {
475 await _stream.DisposeAsync().ConfigureAwait(continueOnCapturedContext: false);
476 }
477 }
478 }
479 finally
480 {
482 }
483 }
484
486 {
487 _stream = null;
490 byte[] buffer = _buffer;
491 if (buffer != null)
492 {
493 _buffer = null;
495 {
497 }
498 }
499 }
500
501 public override long Seek(long offset, SeekOrigin origin)
502 {
503 throw new NotSupportedException();
504 }
505
506 public override void SetLength(long value)
507 {
508 throw new NotSupportedException();
509 }
510
512 {
514 {
516 }
517 }
518
520 {
522 {
524 }
525 }
526
528 {
530 }
531
532 private static void ThrowInvalidBeginCall()
533 {
535 }
536}
static ArrayPool< T > Shared
Definition ArrayPool.cs:7
override void Dispose(bool disposing)
void WriteCore(ReadOnlySpan< byte > buffer, bool isFinalBlock=false)
override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState)
async Task FlushAsyncCore(CancellationToken cancellationToken)
override Task FlushAsync(CancellationToken cancellationToken)
override ValueTask< int > ReadAsync(Memory< byte > buffer, CancellationToken cancellationToken=default(CancellationToken))
override ValueTask WriteAsync(ReadOnlyMemory< byte > buffer, CancellationToken cancellationToken=default(CancellationToken))
readonly CompressionMode _mode
override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
override void EndWrite(IAsyncResult asyncResult)
async ValueTask WriteAsyncMemoryCore(ReadOnlyMemory< byte > buffer, CancellationToken cancellationToken, bool isFinalBlock=false)
override int Read(Span< byte > buffer)
override int EndRead(IAsyncResult asyncResult)
BrotliStream(Stream stream, CompressionMode mode, bool leaveOpen)
override long Seek(long offset, SeekOrigin origin)
BrotliStream(Stream stream, CompressionLevel compressionLevel, bool leaveOpen)
BrotliStream(Stream stream, CompressionLevel compressionLevel)
BrotliStream(Stream stream, CompressionMode mode)
override void WriteByte(byte value)
override void SetLength(long value)
override int Read(byte[] buffer, int offset, int count)
override Task< int > ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
bool TryDecompress(Span< byte > destination, out int bytesWritten)
override void Write(ReadOnlySpan< byte > buffer)
override void Write(byte[] buffer, int offset, int count)
override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? asyncCallback, object? asyncState)
override async ValueTask DisposeAsync()
static int GetQualityFromCompressionLevel(CompressionLevel level)
Definition BrotliUtils.cs:5
Task FlushAsync()
Definition Stream.cs:669
static void ValidateBufferArguments(byte[] buffer, int offset, int count)
Definition Stream.cs:1044
Task WriteAsync(byte[] buffer, int offset, int count)
Definition Stream.cs:914
int Read(byte[] buffer, int offset, int count)
void Dispose()
Definition Stream.cs:639
Task< int > ReadAsync(byte[] buffer, int offset, int count)
Definition Stream.cs:762
void Write(byte[] buffer, int offset, int count)
virtual ValueTask DisposeAsync()
Definition Stream.cs:654
static string BrotliStream_Compress_UnsupportedOperation
Definition SR.cs:38
static string ObjectDisposed_StreamClosed
Definition SR.cs:20
static string Stream_FalseCanRead
Definition SR.cs:14
static string ArgumentOutOfRange_Enum
Definition SR.cs:18
static string BrotliStream_Decompress_InvalidData
Definition SR.cs:44
static string Stream_FalseCanWrite
Definition SR.cs:16
static string BrotliStream_Compress_InvalidData
Definition SR.cs:40
static string InvalidBeginCall
Definition SR.cs:22
static string BrotliStream_Decompress_UnsupportedOperation
Definition SR.cs:42
static string BrotliStream_Decompress_InvalidStream
Definition SR.cs:46
Definition SR.cs:7
static int Exchange(ref int location1, int value)
static IAsyncResult Begin(Task task, AsyncCallback callback, object state)
Definition TaskToApm.cs:43
static void End(IAsyncResult asyncResult)
Definition TaskToApm.cs:48
new ConfiguredTaskAwaitable< TResult > ConfigureAwait(bool continueOnCapturedContext)
Definition Task.cs:226
static Task FromCanceled(CancellationToken cancellationToken)
Definition Task.cs:3363
static Task CompletedTask
Definition Task.cs:1120
static void Write(ref bool location, bool value)
Definition Volatile.cs:74
unsafe OperationStatus Decompress(ReadOnlySpan< byte > source, Span< byte > destination, out int bytesConsumed, out int bytesWritten)
OperationStatus Flush(Memory< byte > destination, out int bytesWritten)
SafeBrotliEncoderHandle _state
OperationStatus Compress(ReadOnlyMemory< byte > source, Memory< byte > destination, out int bytesConsumed, out int bytesWritten, bool isFinalBlock)
void CopyTo(Span< T > destination)
static ValueTask FromCanceled(CancellationToken cancellationToken)
Definition ValueTask.cs:180
ConfiguredValueTaskAwaitable ConfigureAwait(bool continueOnCapturedContext)
Definition ValueTask.cs:312