Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
CryptoStream.cs
Go to the documentation of this file.
3using System.IO;
7
9
11{
12 private readonly Stream _stream;
13
14 private readonly ICryptoTransform _transform;
15
16 private byte[] _inputBuffer;
17
18 private int _inputBufferIndex;
19
20 private int _inputBlockSize;
21
22 private byte[] _outputBuffer;
23
24 private int _outputBufferIndex;
25
26 private int _outputBlockSize;
27
28 private bool _canRead;
29
30 private bool _canWrite;
31
33
35
36 private readonly bool _leaveOpen;
37
38 public override bool CanRead => _canRead;
39
40 public override bool CanSeek => false;
41
42 public override bool CanWrite => _canWrite;
43
44 public override long Length
45 {
46 get
47 {
49 }
50 }
51
52 public override long Position
53 {
54 get
55 {
57 }
58 set
59 {
61 }
62 }
63
65
66 [MemberNotNull("_lazyAsyncActiveSemaphore")]
68 {
69 [MemberNotNull("_lazyAsyncActiveSemaphore")]
70 get
71 {
72 return LazyInitializer.EnsureInitialized(ref _lazyAsyncActiveSemaphore, () => new SemaphoreSlim(1, 1));
73 }
74 }
75
77 : this(stream, transform, mode, leaveOpen: false)
78 {
79 }
80
81 public CryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode, bool leaveOpen)
82 {
83 if (transform == null)
84 {
85 throw new ArgumentNullException("transform");
86 }
88 _transform = transform;
89 _leaveOpen = leaveOpen;
90 switch (mode)
91 {
92 case CryptoStreamMode.Read:
93 if (!_stream.CanRead)
94 {
96 }
97 _canRead = true;
98 break;
99 case CryptoStreamMode.Write:
100 if (!_stream.CanWrite)
101 {
103 }
104 _canWrite = true;
105 break;
106 default:
108 }
110 _inputBuffer = new byte[_inputBlockSize];
113 }
114
115 public void FlushFinalBlock()
116 {
117 FlushFinalBlockAsync(useAsync: false, default(CancellationToken)).AsTask().GetAwaiter().GetResult();
118 }
119
121 {
122 if (cancellationToken.IsCancellationRequested)
123 {
125 }
126 return FlushFinalBlockAsync(useAsync: true, cancellationToken);
127 }
128
130 {
132 {
134 }
136 if (_canWrite)
137 {
139 if (useAsync)
140 {
141 await _stream.WriteAsync(new ReadOnlyMemory<byte>(array), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
142 }
143 else
144 {
145 _stream.Write(array, 0, array.Length);
146 }
147 }
148 if (_stream is CryptoStream cryptoStream)
149 {
150 if (!cryptoStream.HasFlushedFinalBlock)
151 {
152 await cryptoStream.FlushFinalBlockAsync(useAsync, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
153 }
154 }
155 else if (useAsync)
156 {
157 await _stream.FlushAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
158 }
159 else
160 {
161 _stream.Flush();
162 }
163 if (_inputBuffer != null)
164 {
166 }
167 if (_outputBuffer != null)
168 {
170 }
171 }
172
173 public override void Flush()
174 {
175 if (_canWrite)
176 {
177 _stream.Flush();
178 }
179 }
180
182 {
183 if (GetType() != typeof(CryptoStream))
184 {
185 return base.FlushAsync(cancellationToken);
186 }
187 if (!cancellationToken.IsCancellationRequested)
188 {
189 if (_canWrite)
190 {
192 }
193 return Task.CompletedTask;
194 }
196 }
197
198 public override long Seek(long offset, SeekOrigin origin)
199 {
201 }
202
203 public override void SetLength(long value)
204 {
206 }
207
213
222
224 {
225 await AsyncActiveSemaphore.WaitAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
226 try
227 {
228 return await ReadAsyncCore(buffer, cancellationToken, useAsync: true).ConfigureAwait(continueOnCapturedContext: false);
229 }
230 finally
231 {
233 }
234 }
235
236 public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
237 {
239 }
240
241 public override int EndRead(IAsyncResult asyncResult)
242 {
244 }
245
246 public override int ReadByte()
247 {
248 if (_outputBufferIndex > 1)
249 {
250 byte result = _outputBuffer[0];
253 return result;
254 }
255 return base.ReadByte();
256 }
257
258 public override void WriteByte(byte value)
259 {
261 {
263 }
264 else
265 {
266 base.WriteByte(value);
267 }
268 }
269
270 public override int Read(byte[] buffer, int offset, int count)
271 {
273 return ReadAsyncCore(buffer.AsMemory(offset, count), default(CancellationToken), useAsync: false).GetAwaiter().GetResult();
274 }
275
276 private void CheckReadArguments(byte[] buffer, int offset, int count)
277 {
279 if (!CanRead)
280 {
282 }
283 }
284
286 {
287 while (true)
288 {
289 if (_outputBufferIndex != 0)
290 {
291 int num = Math.Min(_outputBufferIndex, buffer.Length);
292 if (num != 0)
293 {
295 _outputBufferIndex -= num;
296 _outputBuffer.AsSpan(num).CopyTo(_outputBuffer);
298 }
299 return num;
300 }
302 {
303 break;
304 }
305 int num2 = 0;
306 bool flag = false;
307 int num3 = buffer.Length / _outputBlockSize;
309 {
310 int numWholeBlocksInBytes = checked(num3 * _inputBlockSize);
311 byte[] tempInputBuffer = ArrayPool<byte>.Shared.Rent(numWholeBlocksInBytes);
312 try
313 {
314 int num4 = ((!useAsync) ? _stream.Read(tempInputBuffer, _inputBufferIndex, numWholeBlocksInBytes - _inputBufferIndex) : (await _stream.ReadAsync(new Memory<byte>(tempInputBuffer, _inputBufferIndex, numWholeBlocksInBytes - _inputBufferIndex), cancellationToken).ConfigureAwait(continueOnCapturedContext: false)));
315 num2 = num4;
316 flag = num2 == 0;
317 int num5 = _inputBufferIndex + num2;
318 if (num5 >= _inputBlockSize)
319 {
320 Buffer.BlockCopy(_inputBuffer, 0, tempInputBuffer, 0, _inputBufferIndex);
322 num2 += _inputBufferIndex;
323 int num6 = num2 / _inputBlockSize;
324 int num7 = num6 * _inputBlockSize;
325 _inputBufferIndex = num2 - num7;
326 if (_inputBufferIndex != 0)
327 {
328 Buffer.BlockCopy(tempInputBuffer, num7, _inputBuffer, 0, _inputBufferIndex);
329 }
330 int num8;
331 if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)buffer, out ArraySegment<byte> segment))
332 {
333 num8 = _transform.TransformBlock(tempInputBuffer, 0, num7, segment.Array, segment.Offset);
334 }
335 else
336 {
337 byte[] array = ArrayPool<byte>.Shared.Rent(num6 * _outputBlockSize);
338 num8 = num6 * _outputBlockSize;
339 try
340 {
341 num8 = _transform.TransformBlock(tempInputBuffer, 0, num7, array, 0);
342 array.AsSpan(0, num8).CopyTo(buffer.Span);
343 }
344 finally
345 {
348 }
349 }
350 if (num8 != 0)
351 {
352 return num8;
353 }
354 }
355 else
356 {
358 _inputBufferIndex = num5;
359 }
360 }
361 finally
362 {
363 CryptographicOperations.ZeroMemory(new Span<byte>(tempInputBuffer, 0, numWholeBlocksInBytes));
364 ArrayPool<byte>.Shared.Return(tempInputBuffer);
365 }
366 }
367 if (!flag)
368 {
370 {
371 int num9 = ((!useAsync) ? _stream.Read(_inputBuffer, _inputBufferIndex, _inputBlockSize - _inputBufferIndex) : (await _stream.ReadAsync(new Memory<byte>(_inputBuffer, _inputBufferIndex, _inputBlockSize - _inputBufferIndex), cancellationToken).ConfigureAwait(continueOnCapturedContext: false)));
372 num2 = num9;
373 if (num2 <= 0)
374 {
375 break;
376 }
377 _inputBufferIndex += num2;
378 }
379 }
380 if (num2 <= 0)
381 {
385 }
386 else
387 {
389 }
391 }
392 return 0;
393 }
394
400
409
411 {
412 await AsyncActiveSemaphore.WaitAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
413 try
414 {
415 await WriteAsyncCore(buffer, cancellationToken, useAsync: true).ConfigureAwait(continueOnCapturedContext: false);
416 }
417 finally
418 {
420 }
421 }
422
423 public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
424 {
426 }
427
432
433 public override void Write(byte[] buffer, int offset, int count)
434 {
436 WriteAsyncCore(buffer.AsMemory(offset, count), default(CancellationToken), useAsync: false).AsTask().GetAwaiter().GetResult();
437 }
438
439 private void CheckWriteArguments(byte[] buffer, int offset, int count)
440 {
442 if (!CanWrite)
443 {
445 }
446 }
447
449 {
450 int bytesToWrite = buffer.Length;
451 int currentInputIndex = 0;
452 if (_inputBufferIndex > 0)
453 {
455 {
456 buffer.CopyTo(_inputBuffer.AsMemory(_inputBufferIndex));
457 _inputBufferIndex += buffer.Length;
458 return;
459 }
461 currentInputIndex += _inputBlockSize - _inputBufferIndex;
462 bytesToWrite -= _inputBlockSize - _inputBufferIndex;
464 }
466 {
468 if (useAsync)
469 {
470 await _stream.WriteAsync(new ReadOnlyMemory<byte>(_outputBuffer, 0, numOutputBytes2), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
471 }
472 else
473 {
474 _stream.Write(_outputBuffer, 0, numOutputBytes2);
475 }
477 }
478 while (bytesToWrite > 0)
479 {
480 if (bytesToWrite >= _inputBlockSize)
481 {
482 int num = bytesToWrite / _inputBlockSize;
484 {
485 int numWholeBlocksInBytes = num * _inputBlockSize;
486 byte[] tempOutputBuffer = ArrayPool<byte>.Shared.Rent(checked(num * _outputBlockSize));
487 int numOutputBytes2 = 0;
488 try
489 {
490 numOutputBytes2 = TransformBlock(_transform, buffer.Slice(currentInputIndex, numWholeBlocksInBytes), tempOutputBuffer, 0);
491 if (useAsync)
492 {
493 await _stream.WriteAsync(new ReadOnlyMemory<byte>(tempOutputBuffer, 0, numOutputBytes2), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
494 }
495 else
496 {
497 _stream.Write(tempOutputBuffer, 0, numOutputBytes2);
498 }
499 currentInputIndex += numWholeBlocksInBytes;
500 bytesToWrite -= numWholeBlocksInBytes;
501 CryptographicOperations.ZeroMemory(new Span<byte>(tempOutputBuffer, 0, numOutputBytes2));
502 ArrayPool<byte>.Shared.Return(tempOutputBuffer);
503 tempOutputBuffer = null;
504 }
505 catch
506 {
507 CryptographicOperations.ZeroMemory(new Span<byte>(tempOutputBuffer, 0, numOutputBytes2));
508 throw;
509 }
510 }
511 else
512 {
513 int numOutputBytes2 = TransformBlock(_transform, buffer.Slice(currentInputIndex, _inputBlockSize), _outputBuffer, 0);
514 if (useAsync)
515 {
516 await _stream.WriteAsync(new ReadOnlyMemory<byte>(_outputBuffer, 0, numOutputBytes2), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
517 }
518 else
519 {
520 _stream.Write(_outputBuffer, 0, numOutputBytes2);
521 }
522 currentInputIndex += _inputBlockSize;
523 bytesToWrite -= _inputBlockSize;
524 }
525 continue;
526 }
527 buffer.Slice(currentInputIndex, bytesToWrite).CopyTo(_inputBuffer);
528 _inputBufferIndex += bytesToWrite;
529 break;
530 }
531 unsafe static int TransformBlock(ICryptoTransform transform, ReadOnlyMemory<byte> inputBuffer, byte[] outputBuffer, int outputOffset)
532 {
533 if (MemoryMarshal.TryGetArray(inputBuffer, out var segment))
534 {
535 return transform.TransformBlock(segment.Array, segment.Offset, inputBuffer.Length, outputBuffer, outputOffset);
536 }
537 byte[] array = ArrayPool<byte>.Shared.Rent(inputBuffer.Length);
538 int result = 0;
539 fixed (byte* ptr = &array[0])
540 {
541 try
542 {
543 inputBuffer.CopyTo(array);
544 result = transform.TransformBlock(array, 0, inputBuffer.Length, outputBuffer, outputOffset);
545 }
546 finally
547 {
548 CryptographicOperations.ZeroMemory(array.AsSpan(0, inputBuffer.Length));
549 }
550 }
552 array = null;
553 return result;
554 }
555 }
556
557 public unsafe override void CopyTo(Stream destination, int bufferSize)
558 {
560 byte[] array = ArrayPool<byte>.Shared.Rent(bufferSize);
561 fixed (byte* ptr = &array[0])
562 {
563 try
564 {
565 int num;
566 do
567 {
568 num = Read(array, 0, bufferSize);
569 destination.Write(array, 0, num);
570 }
571 while (num > 0);
572 }
573 finally
574 {
575 CryptographicOperations.ZeroMemory(array.AsSpan(0, bufferSize));
576 }
577 }
579 array = null;
580 }
581
583 {
586 }
587
589 {
590 byte[] rentedBuffer = ArrayPool<byte>.Shared.Rent(bufferSize);
591 GCHandle pinHandle = GCHandle.Alloc(rentedBuffer, GCHandleType.Pinned);
592 try
593 {
594 int bytesRead;
595 do
596 {
597 bytesRead = await ReadAsync(rentedBuffer.AsMemory(0, bufferSize), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
598 await destination.WriteAsync(rentedBuffer.AsMemory(0, bytesRead), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
599 }
600 while (bytesRead > 0);
601 }
602 finally
603 {
604 CryptographicOperations.ZeroMemory(rentedBuffer.AsSpan(0, bufferSize));
605 pinHandle.Free();
606 }
607 ArrayPool<byte>.Shared.Return(rentedBuffer);
608 }
609
610 private void CheckCopyToArguments(Stream destination, int bufferSize)
611 {
612 if (destination == null)
613 {
614 throw new ArgumentNullException("destination");
615 }
616 EnsureNotDisposed(destination, "destination");
617 if (!destination.CanWrite)
618 {
620 }
621 if (bufferSize <= 0)
622 {
624 }
625 if (!CanRead)
626 {
628 }
629 }
630
631 private static void EnsureNotDisposed(Stream stream, string objectName)
632 {
633 if (!stream.CanRead && !stream.CanWrite)
634 {
635 throw new ObjectDisposedException(objectName);
636 }
637 }
638
639 public void Clear()
640 {
641 Close();
642 }
643
644 protected override void Dispose(bool disposing)
645 {
646 try
647 {
648 if (disposing)
649 {
651 {
653 }
654 if (!_leaveOpen)
655 {
657 }
658 }
659 }
660 finally
661 {
662 try
663 {
665 if (_inputBuffer != null)
666 {
668 }
669 if (_outputBuffer != null)
670 {
672 }
673 _inputBuffer = null;
674 _outputBuffer = null;
675 _canRead = false;
676 _canWrite = false;
677 }
678 finally
679 {
680 base.Dispose(disposing);
681 }
682 }
683 }
684
685 public override ValueTask DisposeAsync()
686 {
687 if (!(GetType() != typeof(CryptoStream)))
688 {
689 return DisposeAsyncCore();
690 }
691 return base.DisposeAsync();
692 }
693
695 {
696 _ = 1;
697 try
698 {
700 {
701 await FlushFinalBlockAsync(useAsync: true, default(CancellationToken)).ConfigureAwait(continueOnCapturedContext: false);
702 }
703 if (!_leaveOpen)
704 {
705 await _stream.DisposeAsync().ConfigureAwait(continueOnCapturedContext: false);
706 }
707 }
708 finally
709 {
711 if (_inputBuffer != null)
712 {
714 }
715 if (_outputBuffer != null)
716 {
718 }
719 _inputBuffer = null;
720 _outputBuffer = null;
721 _canRead = false;
722 _canWrite = false;
723 }
724 }
725}
static unsafe void Clear(Array array)
Definition Array.cs:755
static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
Definition Buffer.cs:102
static ArrayPool< T > Shared
Definition ArrayPool.cs:7
Task FlushAsync()
Definition Stream.cs:669
static void ValidateBufferArguments(byte[] buffer, int offset, int count)
Definition Stream.cs:1044
virtual void Close()
Definition Stream.cs:644
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 byte Min(byte val1, byte val2)
Definition Math.cs:912
static string ArgumentOutOfRange_NeedPosNum
Definition SR.cs:20
static string Cryptography_CryptoStream_FlushFinalBlockTwice
Definition SR.cs:32
static string Argument_InvalidValue
Definition SR.cs:24
static string Argument_StreamNotWritable
Definition SR.cs:878
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string NotSupported_UnseekableStream
Definition SR.cs:26
static string NotSupported_UnwritableStream
Definition SR.cs:30
static string Argument_StreamNotReadable
Definition SR.cs:876
static string NotSupported_UnreadableStream
Definition SR.cs:32
Definition SR.cs:7
async ValueTask WriteAsyncInternal(ReadOnlyMemory< byte > buffer, CancellationToken cancellationToken=default(CancellationToken))
override void Write(byte[] buffer, int offset, int count)
async ValueTask< int > ReadAsyncCore(Memory< byte > buffer, CancellationToken cancellationToken, bool useAsync)
override Task< int > ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
ValueTask FlushFinalBlockAsync(CancellationToken cancellationToken=default(CancellationToken))
CryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode, bool leaveOpen)
override ValueTask< int > ReadAsync(Memory< byte > buffer, CancellationToken cancellationToken=default(CancellationToken))
override Task FlushAsync(CancellationToken cancellationToken)
override int Read(byte[] buffer, int offset, int count)
override long Seek(long offset, SeekOrigin origin)
void CheckReadArguments(byte[] buffer, int offset, int count)
override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state)
readonly ICryptoTransform _transform
CryptoStream(Stream stream, ICryptoTransform transform, CryptoStreamMode mode)
void CheckCopyToArguments(Stream destination, int bufferSize)
void CheckWriteArguments(byte[] buffer, int offset, int count)
static void EnsureNotDisposed(Stream stream, string objectName)
async ValueTask< int > ReadAsyncInternal(Memory< byte > buffer, CancellationToken cancellationToken=default(CancellationToken))
async ValueTask FlushFinalBlockAsync(bool useAsync, CancellationToken cancellationToken)
override void EndWrite(IAsyncResult asyncResult)
async ValueTask WriteAsyncCore(ReadOnlyMemory< byte > buffer, CancellationToken cancellationToken, bool useAsync)
override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
override int EndRead(IAsyncResult asyncResult)
unsafe override void CopyTo(Stream destination, int bufferSize)
override ValueTask WriteAsync(ReadOnlyMemory< byte > buffer, CancellationToken cancellationToken=default(CancellationToken))
override void Dispose(bool disposing)
async Task CopyToAsyncInternal(Stream destination, int bufferSize, CancellationToken cancellationToken)
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
byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
void CopyTo(Memory< T > destination)
void CopyTo(Span< T > destination)
static GCHandle Alloc(object? value)
Definition GCHandle.cs:81
static ValueTask FromCanceled(CancellationToken cancellationToken)
Definition ValueTask.cs:180
ConfiguredValueTaskAwaitable ConfigureAwait(bool continueOnCapturedContext)
Definition ValueTask.cs:312
static ValueTask FromException(Exception exception)
Definition ValueTask.cs:190
ValueTaskAwaiter GetAwaiter()
Definition ValueTask.cs:306