Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
BufferedFileStreamStrategy.cs
Go to the documentation of this file.
8
10
12{
13 [StructLayout(LayoutKind.Auto)]
14 [CompilerGenerated]
16 {
18
20
22
24
26
28
30
32
34
36
37 private void MoveNext()
38 {
39 int num = _003C_003E1__state;
40 BufferedFileStreamStrategy bufferedFileStreamStrategy = _003C_003E4__this;
41 int result;
42 try
43 {
45 if (num != 0)
46 {
47 if ((uint)(num - 1) <= 2u)
48 {
49 goto IL_007d;
50 }
51 awaiter = semaphoreLockTask.ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
52 if (!awaiter.IsCompleted)
53 {
54 num = (_003C_003E1__state = 0);
55 _003C_003Eu__1 = awaiter;
56 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);
57 return;
58 }
59 }
60 else
61 {
62 awaiter = _003C_003Eu__1;
64 num = (_003C_003E1__state = -1);
65 }
66 awaiter.GetResult();
67 goto IL_007d;
68 IL_007d:
69 try
70 {
74 int result2;
75 int num2;
76 switch (num)
77 {
78 default:
79 num2 = 0;
81 if (bufferedFileStreamStrategy._readLen - bufferedFileStreamStrategy._readPos <= 0)
82 {
83 goto IL_0146;
84 }
85 num2 = Math.Min(buffer.Length, bufferedFileStreamStrategy._readLen - bufferedFileStreamStrategy._readPos);
86 if (num2 > 0)
87 {
88 bufferedFileStreamStrategy._buffer.AsSpan(bufferedFileStreamStrategy._readPos, num2).CopyTo(buffer.Span);
89 bufferedFileStreamStrategy._readPos += num2;
90 }
91 if (num2 != buffer.Length)
92 {
93 if (num2 > 0)
94 {
95 buffer = buffer.Slice(num2);
97 }
98 goto IL_0146;
99 }
100 result = num2;
101 goto end_IL_007d;
102 case 1:
103 awaiter4 = _003C_003Eu__2;
105 num = (_003C_003E1__state = -1);
106 goto IL_01e6;
107 case 2:
108 awaiter3 = _003C_003Eu__3;
109 _003C_003Eu__3 = default(ConfiguredValueTaskAwaitable<int>.ConfiguredValueTaskAwaiter);
110 num = (_003C_003E1__state = -1);
111 goto IL_0280;
112 case 3:
113 {
114 awaiter2 = _003C_003Eu__3;
115 _003C_003Eu__3 = default(ConfiguredValueTaskAwaitable<int>.ConfiguredValueTaskAwaiter);
116 num = (_003C_003E1__state = -1);
117 break;
118 }
119 IL_0280:
120 result2 = awaiter3.GetResult();
121 result = result2 + _003CbytesAlreadySatisfied_003E5__2;
122 goto end_IL_007d;
123 IL_0146:
124 bufferedFileStreamStrategy._readPos = (bufferedFileStreamStrategy._readLen = 0);
125 if (bufferedFileStreamStrategy._writePos > 0)
126 {
127 awaiter4 = bufferedFileStreamStrategy._strategy.WriteAsync(new ReadOnlyMemory<byte>(bufferedFileStreamStrategy._buffer, 0, bufferedFileStreamStrategy._writePos), cancellationToken).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
128 if (!awaiter4.IsCompleted)
129 {
130 num = (_003C_003E1__state = 1);
131 _003C_003Eu__2 = awaiter4;
132 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter4, ref this);
133 return;
134 }
135 goto IL_01e6;
136 }
137 goto IL_01f4;
138 IL_01e6:
139 awaiter4.GetResult();
140 bufferedFileStreamStrategy._writePos = 0;
141 goto IL_01f4;
142 IL_01f4:
143 if (buffer.Length >= bufferedFileStreamStrategy._bufferSize)
144 {
145 awaiter3 = bufferedFileStreamStrategy._strategy.ReadAsync(buffer, cancellationToken).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
146 if (!awaiter3.IsCompleted)
147 {
148 num = (_003C_003E1__state = 2);
149 _003C_003Eu__3 = awaiter3;
150 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter3, ref this);
151 return;
152 }
153 goto IL_0280;
154 }
155 bufferedFileStreamStrategy.EnsureBufferAllocated();
156 awaiter2 = bufferedFileStreamStrategy._strategy.ReadAsync(new Memory<byte>(bufferedFileStreamStrategy._buffer, 0, bufferedFileStreamStrategy._bufferSize), cancellationToken).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
157 if (!awaiter2.IsCompleted)
158 {
159 num = (_003C_003E1__state = 3);
160 _003C_003Eu__3 = awaiter2;
161 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref this);
162 return;
163 }
164 break;
165 }
166 int result3 = awaiter2.GetResult();
167 bufferedFileStreamStrategy._readLen = result3;
168 num2 = Math.Min(bufferedFileStreamStrategy._readLen, buffer.Length);
169 bufferedFileStreamStrategy._buffer.AsSpan(0, num2).CopyTo(buffer.Span);
170 bufferedFileStreamStrategy._readPos += num2;
172 end_IL_007d:;
173 }
174 finally
175 {
176 if (num < 0)
177 {
178 bufferedFileStreamStrategy._asyncActiveSemaphore.Release();
179 }
180 }
181 }
182 catch (Exception exception)
183 {
186 return;
187 }
190 }
191
193 {
194 //ILSpy generated this explicit interface implementation from .override directive in MoveNext
195 this.MoveNext();
196 }
197
198 [DebuggerHidden]
203
205 {
206 //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
207 this.SetStateMachine(stateMachine);
208 }
209 }
210
211 [StructLayout(LayoutKind.Auto)]
212 [CompilerGenerated]
214 {
216
218
220
222
224
226
228
230
231 private void MoveNext()
232 {
233 int num = _003C_003E1__state;
234 BufferedFileStreamStrategy bufferedFileStreamStrategy = _003C_003E4__this;
235 try
236 {
238 if (num != 0)
239 {
240 if ((uint)(num - 1) <= 1u)
241 {
242 goto IL_007c;
243 }
244 awaiter = semaphoreLockTask.ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
245 if (!awaiter.IsCompleted)
246 {
247 num = (_003C_003E1__state = 0);
248 _003C_003Eu__1 = awaiter;
249 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);
250 return;
251 }
252 }
253 else
254 {
255 awaiter = _003C_003Eu__1;
257 num = (_003C_003E1__state = -1);
258 }
259 awaiter.GetResult();
260 goto IL_007c;
261 IL_007c:
262 try
263 {
265 if (num == 1)
266 {
267 awaiter2 = _003C_003Eu__2;
269 num = (_003C_003E1__state = -1);
270 goto IL_01e1;
271 }
273 if (num == 2)
274 {
275 awaiter3 = _003C_003Eu__2;
277 num = (_003C_003E1__state = -1);
278 goto IL_0278;
279 }
280 if (bufferedFileStreamStrategy._writePos == 0)
281 {
282 bufferedFileStreamStrategy.ClearReadBufferBeforeWrite();
283 }
284 if (bufferedFileStreamStrategy._writePos <= 0)
285 {
286 goto IL_01ef;
287 }
288 int num2 = bufferedFileStreamStrategy._bufferSize - bufferedFileStreamStrategy._writePos;
289 if (num2 <= 0)
290 {
291 goto IL_015f;
292 }
293 ReadOnlySpan<byte> readOnlySpan;
294 if (num2 < source.Length)
295 {
296 readOnlySpan = source.Span;
297 readOnlySpan = readOnlySpan.Slice(0, num2);
298 readOnlySpan.CopyTo(bufferedFileStreamStrategy._buffer.AsSpan(bufferedFileStreamStrategy._writePos));
299 bufferedFileStreamStrategy._writePos += num2;
300 source = source.Slice(num2);
301 goto IL_015f;
302 }
303 readOnlySpan = source.Span;
304 readOnlySpan.CopyTo(bufferedFileStreamStrategy._buffer.AsSpan(bufferedFileStreamStrategy._writePos));
305 bufferedFileStreamStrategy._writePos += source.Length;
306 goto end_IL_007c;
307 IL_0278:
308 awaiter3.GetResult();
309 goto end_IL_007c;
310 IL_015f:
311 awaiter2 = bufferedFileStreamStrategy._strategy.WriteAsync(new ReadOnlyMemory<byte>(bufferedFileStreamStrategy._buffer, 0, bufferedFileStreamStrategy._writePos), cancellationToken).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
312 if (!awaiter2.IsCompleted)
313 {
314 num = (_003C_003E1__state = 1);
315 _003C_003Eu__2 = awaiter2;
316 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref this);
317 return;
318 }
319 goto IL_01e1;
320 IL_01ef:
321 if (source.Length >= bufferedFileStreamStrategy._bufferSize)
322 {
323 awaiter3 = bufferedFileStreamStrategy._strategy.WriteAsync(source, cancellationToken).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter();
324 if (!awaiter3.IsCompleted)
325 {
326 num = (_003C_003E1__state = 2);
327 _003C_003Eu__2 = awaiter3;
328 _003C_003Et__builder.AwaitUnsafeOnCompleted(ref awaiter3, ref this);
329 return;
330 }
331 goto IL_0278;
332 }
333 if (source.Length != 0)
334 {
335 bufferedFileStreamStrategy.EnsureBufferAllocated();
336 readOnlySpan = source.Span;
337 readOnlySpan.CopyTo(bufferedFileStreamStrategy._buffer.AsSpan(bufferedFileStreamStrategy._writePos));
338 bufferedFileStreamStrategy._writePos = source.Length;
339 }
340 goto end_IL_007c;
341 IL_01e1:
342 awaiter2.GetResult();
343 bufferedFileStreamStrategy._writePos = 0;
344 goto IL_01ef;
345 end_IL_007c:;
346 }
347 finally
348 {
349 if (num < 0)
350 {
351 bufferedFileStreamStrategy._asyncActiveSemaphore.Release();
352 }
353 }
354 }
355 catch (Exception exception)
356 {
359 return;
360 }
363 }
364
366 {
367 //ILSpy generated this explicit interface implementation from .override directive in MoveNext
368 this.MoveNext();
369 }
370
371 [DebuggerHidden]
376
378 {
379 //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
380 this.SetStateMachine(stateMachine);
381 }
382 }
383
385
386 private readonly int _bufferSize;
387
388 private byte[] _buffer;
389
390 private int _writePos;
391
392 private int _readPos;
393
394 private int _readLen;
395
397
398 public override bool CanRead => _strategy.CanRead;
399
400 public override bool CanWrite => _strategy.CanWrite;
401
402 public override bool CanSeek => _strategy.CanSeek;
403
404 public override long Length
405 {
406 get
407 {
408 long num = _strategy.Length;
409 if (_writePos > 0 && _strategy.Position + _writePos > num)
410 {
412 }
413 return num;
414 }
415 }
416
417 public override long Position
418 {
419 get
420 {
421 return _strategy.Position + _readPos - _readLen + _writePos;
422 }
423 set
424 {
425 if (_writePos > 0)
426 {
427 FlushWrite();
428 }
429 _readPos = 0;
430 _readLen = 0;
431 _strategy.Position = value;
432 }
433 }
434
435 internal override bool IsAsync => _strategy.IsAsync;
436
437 internal override bool IsClosed => _strategy.IsClosed;
438
439 internal override string Name => _strategy.Name;
440
442 {
443 get
444 {
445 Flush();
447 }
448 }
449
450 internal BufferedFileStreamStrategy(FileStreamStrategy strategy, int bufferSize)
451 {
452 _strategy = strategy;
453 _bufferSize = bufferSize;
454 }
455
457 {
458 try
459 {
460 Dispose(disposing: true);
461 }
463 {
464 }
465 }
466
467 public override async ValueTask DisposeAsync()
468 {
469 _ = 1;
470 try
471 {
472 if (!_strategy.IsClosed)
473 {
474 try
475 {
476 await FlushAsync().ConfigureAwait(continueOnCapturedContext: false);
477 }
478 finally
479 {
480 await _strategy.DisposeAsync().ConfigureAwait(continueOnCapturedContext: false);
481 }
482 }
483 }
484 finally
485 {
486 _writePos = 0;
487 }
488 }
489
490 internal override void DisposeInternal(bool disposing)
491 {
492 Dispose(disposing);
493 }
494
495 protected override void Dispose(bool disposing)
496 {
497 try
498 {
499 if (disposing && !_strategy.IsClosed)
500 {
501 try
502 {
503 Flush();
504 return;
505 }
506 finally
507 {
509 }
510 }
511 }
512 finally
513 {
514 base.Dispose(disposing);
515 _writePos = 0;
516 }
517 }
518
519 public override int Read(byte[] buffer, int offset, int count)
520 {
522 }
523
524 public override int Read(Span<byte> destination)
525 {
527 return ReadSpan(destination, default(ArraySegment<byte>));
528 }
529
531 {
532 bool flag = false;
533 int num = _readLen - _readPos;
534 if (num == 0)
535 {
537 if (_writePos > 0)
538 {
539 FlushWrite();
540 }
541 if (!_strategy.CanSeek || destination.Length >= _bufferSize)
542 {
543 num = ((arraySegment.Array != null) ? _strategy.Read(arraySegment.Array, arraySegment.Offset, arraySegment.Count) : _strategy.Read(destination));
544 _readPos = 0;
545 _readLen = 0;
546 return num;
547 }
550 if (num == 0)
551 {
552 return 0;
553 }
554 flag = num < _bufferSize;
555 _readPos = 0;
556 _readLen = num;
557 }
558 if (num > destination.Length)
559 {
560 num = destination.Length;
561 }
563 _readPos += num;
564 if (_strategy.CanSeek && num < destination.Length && !flag)
565 {
566 int num2 = ((arraySegment.Array != null) ? _strategy.Read(arraySegment.Array, arraySegment.Offset + num, arraySegment.Count - num) : _strategy.Read(destination.Slice(num)));
567 num += num2;
568 _readPos = 0;
569 _readLen = 0;
570 }
571 return num;
572 }
573
574 public override int ReadByte()
575 {
576 if (_readPos == _readLen)
577 {
578 return ReadByteSlow();
579 }
580 return _buffer[_readPos++];
581 }
582
583 private int ReadByteSlow()
584 {
587 if (_writePos > 0)
588 {
589 FlushWrite();
590 }
593 _readPos = 0;
594 if (_readLen == 0)
595 {
596 return -1;
597 }
598 return _buffer[_readPos++];
599 }
600
602 {
604 if (!valueTask.IsCompletedSuccessfully)
605 {
606 return valueTask.AsTask();
607 }
608 return LastSyncCompletedReadTask(valueTask.Result);
609 Task<int> LastSyncCompletedReadTask(int val)
610 {
611 Task<int> lastSyncCompletedReadTask = _lastSyncCompletedReadTask;
612 if (lastSyncCompletedReadTask != null && lastSyncCompletedReadTask.Result == val)
613 {
614 return lastSyncCompletedReadTask;
615 }
616 return _lastSyncCompletedReadTask = Task.FromResult(val);
617 }
618 }
619
621 {
622 if (cancellationToken.IsCancellationRequested)
623 {
625 }
627 if (!_strategy.CanSeek)
628 {
630 }
632 Task task = semaphoreSlim.WaitAsync(cancellationToken);
633 if (task.IsCompletedSuccessfully && _writePos == 0)
634 {
635 bool flag = true;
636 try
637 {
638 if (_readLen == _readPos && buffer.Length >= _bufferSize)
639 {
641 }
642 if (_readLen - _readPos >= buffer.Length)
643 {
644 _buffer.AsSpan(_readPos, buffer.Length).CopyTo(buffer.Span);
645 _readPos += buffer.Length;
646 return new ValueTask<int>(buffer.Length);
647 }
648 flag = false;
649 }
650 finally
651 {
652 if (flag)
653 {
654 semaphoreSlim.Release();
655 }
656 }
657 }
659 }
660
662 {
663 await EnsureAsyncActiveSemaphoreInitialized().WaitAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
664 try
665 {
666 if (_readPos < _readLen)
667 {
668 int num = Math.Min(_readLen - _readPos, destination.Length);
670 _readPos += num;
671 return num;
672 }
673 return await _strategy.ReadAsync(destination, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
674 }
675 finally
676 {
678 }
679 }
680
681 [AsyncStateMachine(typeof(_003CReadAsyncSlowPath_003Ed__39))]
682 [AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder<>))]
684 {
686 stateMachine._003C_003Et__builder = PoolingAsyncValueTaskMethodBuilder<int>.Create();
687 stateMachine._003C_003E4__this = this;
688 stateMachine.semaphoreLockTask = semaphoreLockTask;
689 stateMachine.buffer = buffer;
690 stateMachine.cancellationToken = cancellationToken;
691 stateMachine._003C_003E1__state = -1;
692 stateMachine._003C_003Et__builder.Start(ref stateMachine);
693 return stateMachine._003C_003Et__builder.Task;
694 }
695
696 public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
697 {
699 }
700
701 public override int EndRead(IAsyncResult asyncResult)
702 {
703 return TaskToApm.End<int>(asyncResult);
704 }
705
706 public override void Write(byte[] buffer, int offset, int count)
707 {
709 }
710
711 public override void Write(ReadOnlySpan<byte> buffer)
712 {
715 }
716
718 {
719 if (_writePos == 0)
720 {
723 }
724 if (_writePos > 0)
725 {
726 int num = _bufferSize - _writePos;
727 if (num > 0)
728 {
729 if (num >= source.Length)
730 {
731 source.CopyTo(_buffer.AsSpan(_writePos));
732 _writePos += source.Length;
733 return;
734 }
735 source.Slice(0, num).CopyTo(_buffer.AsSpan(_writePos));
736 _writePos += num;
737 source = source.Slice(num);
738 if (arraySegment.Array != null)
739 {
740 arraySegment = arraySegment.Slice(num);
741 }
742 }
743 FlushWrite();
744 }
745 if (source.Length >= _bufferSize)
746 {
747 if (arraySegment.Array != null)
748 {
749 _strategy.Write(arraySegment.Array, arraySegment.Offset, arraySegment.Count);
750 }
751 else
752 {
754 }
755 }
756 else if (source.Length != 0)
757 {
759 source.CopyTo(_buffer.AsSpan(_writePos));
760 _writePos = source.Length;
761 }
762 }
763
764 public override void WriteByte(byte value)
765 {
766 if (_writePos > 0 && _writePos < _bufferSize - 1)
767 {
769 }
770 else
771 {
773 }
774 }
775
776 private void WriteByteSlow(byte value)
777 {
778 if (_writePos == 0)
779 {
784 }
785 else
786 {
787 FlushWrite();
788 }
790 }
791
793 {
795 }
796
798 {
799 if (cancellationToken.IsCancellationRequested)
800 {
802 }
804 if (!_strategy.CanSeek)
805 {
807 }
809 Task task = semaphoreSlim.WaitAsync(cancellationToken);
810 if (task.IsCompletedSuccessfully && _readPos == _readLen)
811 {
812 bool flag = true;
813 try
814 {
815 if (_writePos == 0 && buffer.Length >= _bufferSize)
816 {
818 }
819 if (_bufferSize - _writePos >= buffer.Length)
820 {
822 buffer.Span.CopyTo(_buffer.AsSpan(_writePos));
823 _writePos += buffer.Length;
824 return default(ValueTask);
825 }
826 flag = false;
827 }
828 finally
829 {
830 if (flag)
831 {
832 semaphoreSlim.Release();
833 }
834 }
835 }
837 }
838
840 {
841 await EnsureAsyncActiveSemaphoreInitialized().WaitAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
842 try
843 {
844 await _strategy.WriteAsync(source, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
845 }
846 finally
847 {
849 }
850 }
851
852 [AsyncStateMachine(typeof(_003CWriteAsyncSlowPath_003Ed__50))]
853 [AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder))]
855 {
857 stateMachine._003C_003Et__builder = PoolingAsyncValueTaskMethodBuilder.Create();
858 stateMachine._003C_003E4__this = this;
859 stateMachine.semaphoreLockTask = semaphoreLockTask;
860 stateMachine.source = source;
861 stateMachine.cancellationToken = cancellationToken;
862 stateMachine._003C_003E1__state = -1;
863 stateMachine._003C_003Et__builder.Start(ref stateMachine);
864 return stateMachine._003C_003Et__builder.Task;
865 }
866
867 public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
868 {
870 }
871
872 public override void EndWrite(IAsyncResult asyncResult)
873 {
875 }
876
877 public override void SetLength(long value)
878 {
879 Flush();
881 }
882
883 public override void Flush()
884 {
885 Flush(flushToDisk: false);
886 }
887
888 internal override void Flush(bool flushToDisk)
889 {
891 if (_writePos > 0 && _strategy.CanWrite)
892 {
893 FlushWrite();
894 }
895 else if (_readPos < _readLen)
896 {
897 if (_strategy.CanSeek)
898 {
899 FlushRead();
900 }
901 }
902 else
903 {
904 _strategy.Flush(flushToDisk);
905 _writePos = (_readPos = (_readLen = 0));
906 }
907 }
908
910 {
911 if (cancellationToken.IsCancellationRequested)
912 {
914 }
917 }
918
920 {
921 await EnsureAsyncActiveSemaphoreInitialized().WaitAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
922 try
923 {
924 if (_writePos > 0)
925 {
926 await _strategy.WriteAsync(new ReadOnlyMemory<byte>(_buffer, 0, _writePos), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
927 _writePos = 0;
928 }
929 else if (_readPos < _readLen && _strategy.CanSeek)
930 {
931 FlushRead();
932 }
933 }
934 finally
935 {
937 }
938 }
939
941 {
944 if (!cancellationToken.IsCancellationRequested)
945 {
946 return CopyToAsyncCore(destination, bufferSize, cancellationToken);
947 }
949 }
950
952 {
953 await EnsureAsyncActiveSemaphoreInitialized().WaitAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
954 try
955 {
956 int num = _readLen - _readPos;
957 if (num > 0)
958 {
959 await destination.WriteAsync(new ReadOnlyMemory<byte>(_buffer, _readPos, num), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
960 _readPos = (_readLen = 0);
961 }
962 else if (_writePos > 0)
963 {
964 await _strategy.WriteAsync(new ReadOnlyMemory<byte>(_buffer, 0, _writePos), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
965 _writePos = 0;
966 }
967 await _strategy.CopyToAsync(destination, bufferSize, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
968 }
969 finally
970 {
972 }
973 }
974
975 public override void CopyTo(Stream destination, int bufferSize)
976 {
979 int num = _readLen - _readPos;
980 if (num > 0)
981 {
982 destination.Write(_buffer, _readPos, num);
983 _readPos = (_readLen = 0);
984 }
985 else if (_writePos > 0)
986 {
987 FlushWrite();
988 }
989 _strategy.CopyTo(destination, bufferSize);
990 }
991
992 public override long Seek(long offset, SeekOrigin origin)
993 {
996 if (_writePos > 0)
997 {
998 FlushWrite();
999 return _strategy.Seek(offset, origin);
1000 }
1001 if (_readLen - _readPos > 0 && origin == SeekOrigin.Current)
1002 {
1004 }
1005 long position = Position;
1006 long num = _strategy.Seek(offset, origin);
1007 long num2 = num - (position - _readPos);
1008 if (0 <= num2 && num2 < _readLen)
1009 {
1010 _readPos = (int)num2;
1012 }
1013 else
1014 {
1015 _readPos = (_readLen = 0);
1016 }
1017 return num;
1018 }
1019
1020 internal override void Lock(long position, long length)
1021 {
1022 _strategy.Lock(position, length);
1023 }
1024
1025 internal override void Unlock(long position, long length)
1026 {
1027 _strategy.Unlock(position, length);
1028 }
1029
1030 private void FlushRead()
1031 {
1032 if (_readPos - _readLen != 0)
1033 {
1035 }
1036 _readPos = 0;
1037 _readLen = 0;
1038 }
1039
1040 private void FlushWrite()
1041 {
1043 _writePos = 0;
1044 }
1045
1047 {
1048 if (_readPos == _readLen)
1049 {
1050 _readPos = (_readLen = 0);
1051 }
1052 else
1053 {
1054 FlushRead();
1055 }
1056 }
1057
1058 private void EnsureNotClosed()
1059 {
1060 if (_strategy.IsClosed)
1061 {
1063 }
1064 }
1065
1066 private void EnsureCanSeek()
1067 {
1068 if (!_strategy.CanSeek)
1069 {
1071 }
1072 }
1073
1074 private void EnsureCanRead()
1075 {
1076 if (!_strategy.CanRead)
1077 {
1079 }
1080 }
1081
1082 private void EnsureCanWrite()
1083 {
1084 if (!_strategy.CanWrite)
1085 {
1087 }
1088 }
1089
1090 [MemberNotNull("_buffer")]
1092 {
1093 if (_buffer == null)
1094 {
1096 }
1097 }
1098
1099 [MethodImpl(MethodImplOptions.NoInlining)]
1100 [MemberNotNull("_buffer")]
1101 private void AllocateBuffer()
1102 {
1103 Interlocked.CompareExchange(ref _buffer, GC.AllocateUninitializedArray<byte>(_bufferSize), null);
1104 }
1105}
Definition GC.cs:8
override void CopyTo(Stream destination, int bufferSize)
override int Read(byte[] buffer, int offset, int count)
void WriteSpan(ReadOnlySpan< byte > source, ArraySegment< byte > arraySegment)
override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
async Task CopyToAsyncCore(Stream destination, int bufferSize, CancellationToken cancellationToken)
override void Write(ReadOnlySpan< byte > buffer)
int ReadSpan(Span< byte > destination, ArraySegment< byte > arraySegment)
override ValueTask< int > ReadAsync(Memory< byte > buffer, CancellationToken cancellationToken=default(CancellationToken))
override long Seek(long offset, SeekOrigin origin)
async ValueTask WriteToNonSeekableAsync(ReadOnlyMemory< byte > source, CancellationToken cancellationToken)
override Task FlushAsync(CancellationToken cancellationToken)
ValueTask WriteAsyncSlowPath(Task semaphoreLockTask, ReadOnlyMemory< byte > source, CancellationToken cancellationToken)
BufferedFileStreamStrategy(FileStreamStrategy strategy, int bufferSize)
override Task< int > ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
override ValueTask WriteAsync(ReadOnlyMemory< byte > buffer, CancellationToken cancellationToken=default(CancellationToken))
ValueTask< int > ReadAsyncSlowPath(Task semaphoreLockTask, Memory< byte > buffer, CancellationToken cancellationToken)
async Task FlushAsyncInternal(CancellationToken cancellationToken)
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)
override void Write(byte[] buffer, int offset, int count)
async ValueTask< int > ReadFromNonSeekableAsync(Memory< byte > destination, CancellationToken cancellationToken)
override void Unlock(long position, long length)
static bool IsIoRelatedException(Exception e)
void Unlock(long position, long length)
void Lock(long position, long length)
Task FlushAsync()
Definition Stream.cs:669
void SetLength(long value)
long Seek(long offset, SeekOrigin origin)
Task WriteAsync(byte[] buffer, int offset, int count)
Definition Stream.cs:914
int Read(byte[] buffer, int offset, int count)
void CopyTo(Stream destination)
Definition Stream.cs:540
void Dispose()
Definition Stream.cs:639
Task< int > ReadAsync(byte[] buffer, int offset, int count)
Definition Stream.cs:762
SemaphoreSlim _asyncActiveSemaphore
Definition Stream.cs:490
void Write(byte[] buffer, int offset, int count)
Task CopyToAsync(Stream destination)
Definition Stream.cs:571
SemaphoreSlim EnsureAsyncActiveSemaphoreInitialized()
Definition Stream.cs:535
virtual ValueTask DisposeAsync()
Definition Stream.cs:654
static byte Min(byte val1, byte val2)
Definition Math.cs:912
static int CompareExchange(ref int location1, int value, int comparand)
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 void ThrowNotSupportedException_UnwritableStream()
static void ThrowNotSupportedException_UnseekableStream()
static void ThrowObjectDisposedException_StreamClosed(string objectName)
static void ThrowNotSupportedException_UnreadableStream()
void SetStateMachine(IAsyncStateMachine stateMachine)
ArraySegment< T > Slice(int index)
ConfiguredValueTaskAwaitable< int >.ConfiguredValueTaskAwaiter _003C_003Eu__3
Memory< T > Slice(int start)
Definition Memory.cs:194
unsafe Span< T > Span
Definition Memory.cs:28
unsafe ReadOnlySpan< T > Span
ReadOnlyMemory< T > Slice(int start)
void CopyTo(Span< T > destination)
ReadOnlySpan< T > Slice(int start)
void CopyTo(Span< T > destination)
Definition Span.cs:224
static ValueTask FromCanceled(CancellationToken cancellationToken)
Definition ValueTask.cs:180
ConfiguredValueTaskAwaitable ConfigureAwait(bool continueOnCapturedContext)
Definition ValueTask.cs:312