Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
RandomAccess.cs
Go to the documentation of this file.
10
11namespace System.IO;
12
13public static class RandomAccess
14{
35
36 private interface IMemoryHandler<T>
37 {
39
41 }
42
43 [StructLayout(LayoutKind.Sequential, Size = 1)]
44 private readonly struct MemoryHandler : IMemoryHandler<Memory<byte>>
45 {
47 {
48 return memory.Length;
49 }
50
52 {
53 return memory.Pin();
54 }
55
57 {
58 return GetLength(in memory);
59 }
60
65 }
66
67 [StructLayout(LayoutKind.Sequential, Size = 1)]
68 private readonly struct ReadOnlyMemoryHandler : IMemoryHandler<ReadOnlyMemory<byte>>
69 {
71 {
72 return memory.Length;
73 }
74
76 {
77 return memory.Pin();
78 }
79
84
89 }
90
92
93 private static readonly int s_cachedPageSize = Environment.SystemPageSize;
94
95 public static long GetLength(SafeFileHandle handle)
96 {
98 return GetFileLength(handle);
99 }
100
106
113
123
134
140
147
157
168
170 {
171 if (handle == null)
172 {
174 }
175 else if (handle.IsInvalid)
176 {
178 }
179 else if (!handle.CanSeek)
180 {
181 if (handle.IsClosed)
182 {
184 }
186 }
187 else if (fileOffset < 0)
188 {
190 }
191 }
192
194 {
195 if (buffers == null)
196 {
198 }
199 }
200
205
210
215
220
230
253
255 {
256 handle.EnsureThreadPoolBindingInitialized();
258 NativeOverlapped* ptr = null;
259 try
260 {
262 fixed (byte* bytes = &MemoryMarshal.GetReference(buffer))
263 {
266 if (num == 997)
267 {
268 callbackResetEvent.WaitOne();
269 num = 0;
270 }
271 if (num == 0)
272 {
275 {
277 }
279 }
280 if (num == 38 || num == 109)
281 {
282 ptr->InternalLow = IntPtr.Zero;
283 return 0;
284 }
286 }
287 }
288 finally
289 {
290 if (ptr != null)
291 {
292 callbackResetEvent.FreeNativeOverlapped(ptr);
293 }
294 callbackResetEvent.Dispose();
295 }
296 }
297
322
324 {
325 if (buffer.IsEmpty)
326 {
327 return;
328 }
329 handle.EnsureThreadPoolBindingInitialized();
331 NativeOverlapped* ptr = null;
332 try
333 {
335 fixed (byte* bytes = &MemoryMarshal.GetReference(buffer))
336 {
339 if (num == 997)
340 {
341 callbackResetEvent.WaitOne();
342 num = 0;
343 }
344 if (num == 0)
345 {
348 {
349 return;
350 }
352 }
353 switch (num)
354 {
355 case 232:
356 break;
357 case 87:
358 throw new IOException(SR.IO_FileTooLong);
359 default:
361 }
362 }
363 }
364 finally
365 {
366 if (ptr != null)
367 {
368 callbackResetEvent.FreeNativeOverlapped(ptr);
369 }
370 callbackResetEvent.Dispose();
371 }
372 }
373
391
393 {
394 handle.EnsureThreadPoolBindingInitialized();
396 int num = 0;
397 try
398 {
400 if (Interop.Kernel32.ReadFile(handle, (byte*)overlappedValueTaskSource._memoryHandle.Pointer, buffer.Length, IntPtr.Zero, ptr) == 0)
401 {
403 switch (num)
404 {
405 case 997:
406 overlappedValueTaskSource.RegisterForCancellation(cancellationToken);
407 break;
408 case 38:
409 case 109:
410 ptr->InternalLow = IntPtr.Zero;
412 return (vts: null, errorCode: 0);
413 default:
415 return (vts: null, errorCode: num);
416 }
417 }
418 }
419 catch
420 {
422 throw;
423 }
424 finally
425 {
426 if (num != 997 && num != 0)
427 {
428 strategy?.OnIncompleteOperation(buffer.Length, 0);
429 }
430 }
431 overlappedValueTaskSource.FinishedScheduling();
433 }
434
452
454 {
455 handle.EnsureThreadPoolBindingInitialized();
457 int num = 0;
458 try
459 {
461 if (Interop.Kernel32.WriteFile(handle, (byte*)overlappedValueTaskSource._memoryHandle.Pointer, buffer.Length, IntPtr.Zero, lpOverlapped) == 0)
462 {
464 switch (num)
465 {
466 case 997:
467 overlappedValueTaskSource.RegisterForCancellation(cancellationToken);
468 break;
469 case 232:
471 return (vts: null, errorCode: 0);
472 default:
474 return (vts: null, errorCode: num);
475 }
476 }
477 }
478 catch
479 {
481 throw;
482 }
483 finally
484 {
485 if (num != 997 && num != 0)
486 {
487 strategy?.OnIncompleteOperation(buffer.Length, 0);
488 }
489 }
490 overlappedValueTaskSource.FinishedScheduling();
492 }
493
495 {
496 long num = 0L;
497 int count = buffers.Count;
498 for (int i = 0; i < count; i++)
499 {
500 Span<byte> span = buffers[i].Span;
501 int num2 = ReadAtOffset(handle, span, fileOffset + num);
502 num += num2;
503 if (num2 != span.Length)
504 {
505 break;
506 }
507 }
508 return num;
509 }
510
512 {
513 int num = 0;
514 int count = buffers.Count;
515 for (int i = 0; i < count; i++)
516 {
519 num += span.Length;
520 }
521 }
522
524 {
525 if (handle.IsAsync)
526 {
527 return (handle.GetFileOptions() & (FileOptions)536870912) != 0;
528 }
529 return false;
530 }
531
533 {
534 int num = s_cachedPageSize;
535 long num2 = num - 1;
536 int count = buffers.Count;
537 handlesToDispose = null;
539 totalBytes = 0;
540 long* ptr = null;
541 bool flag = false;
542 try
543 {
544 long num3 = 0L;
545 for (int i = 0; i < count; i++)
546 {
547 T memory = buffers[i];
548 int length = handler.GetLength(in memory);
549 num3 += length;
550 if (length != num || num3 > int.MaxValue)
551 {
552 return false;
553 }
554 MemoryHandle memoryHandle = handler.Pin(in memory);
555 long num4 = (long)memoryHandle.Pointer;
556 if ((num4 & num2) != 0L)
557 {
558 memoryHandle.Dispose();
559 return false;
560 }
562 if (ptr == null)
563 {
564 ptr = (long*)NativeMemory.Alloc((nuint)count + (nuint)1u, 8u);
565 ptr[count] = 0L;
566 }
567 ptr[i] = num4;
568 }
570 totalBytes = (int)num3;
571 flag = true;
572 return handlesToDispose != null;
573 }
574 finally
575 {
576 if (!flag)
577 {
579 }
580 }
581 }
582
584 {
585 if (handlesToDispose != null)
586 {
588 {
589 memoryHandle.Dispose();
590 }
591 }
592 if (segmentsPtr != IntPtr.Zero)
593 {
595 }
596 }
597
610
622
624 {
625 handle.EnsureThreadPoolBindingInitialized();
627 try
628 {
631 {
634 {
635 case 997:
636 overlappedValueTaskSource.RegisterForCancellation(cancellationToken);
637 break;
638 case 38:
639 case 109:
640 ptr->InternalLow = IntPtr.Zero;
642 return ValueTask.FromResult(0);
643 default:
646 }
647 }
648 }
649 catch
650 {
652 throw;
653 }
654 overlappedValueTaskSource.FinishedScheduling();
656 }
657
659 {
660 long total = 0L;
662 for (int i = 0; i < buffersCount; i++)
663 {
666 total += num;
667 if (num != buffer.Length)
668 {
669 break;
670 }
671 }
672 return total;
673 }
674
687
699
726
737
739 {
740 NativeOverlapped* ptr = threadPoolBinding.AllocateNativeOverlapped(s_callback, resetEvent, null);
741 ptr->OffsetLow = (int)fileOffset;
742 ptr->OffsetHigh = (int)(fileOffset >> 32);
743 ptr->EventHandle = resetEvent.SafeWaitHandle.DangerousGetHandle();
744 return ptr;
745 }
746
748 {
749 NativeOverlapped result = default(NativeOverlapped);
750 if (handle.CanSeek)
751 {
752 result.OffsetLow = (int)fileOffset;
753 result.OffsetHigh = (int)(fileOffset >> 32);
754 }
755 return result;
756 }
757
767}
static unsafe int ReadFile(IntPtr handle, byte *bytes, int numBytesToRead, out int numBytesRead, IntPtr mustBeZero)
static unsafe int WriteFileGather(SafeHandle hFile, long *aSegmentArray, int nNumberOfBytesToWrite, IntPtr lpReserved, NativeOverlapped *lpOverlapped)
static unsafe int WriteFile(IntPtr handle, byte *bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero)
static unsafe int ReadFileScatter(SafeHandle hFile, long *aSegmentArray, int nNumberOfBytesToRead, IntPtr lpReserved, NativeOverlapped *lpOverlapped)
static unsafe bool GetFileInformationByHandleEx(SafeFileHandle hFile, int FileInformationClass, void *lpFileInformation, uint dwBufferSize)
static unsafe bool GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped *lpOverlapped, ref int lpNumberOfBytesTransferred, bool bWait)
static int SystemPageSize
unsafe void FreeNativeOverlapped(NativeOverlapped *pOverlapped)
CallbackResetEvent(ThreadPoolBoundHandle threadPoolBoundHandle)
readonly ThreadPoolBoundHandle _threadPoolBoundHandle
static unsafe void CleanupScatterGatherBuffers(MemoryHandle[] handlesToDispose, IntPtr segmentsPtr)
static Memory< byte > buffer
static async ValueTask WriteGatherAtOffsetMultipleSyscallsAsync(SafeFileHandle handle, IReadOnlyList< ReadOnlyMemory< byte > > buffers, long fileOffset, CancellationToken cancellationToken)
static unsafe void WriteAtOffset(SafeFileHandle handle, ReadOnlySpan< byte > buffer, long fileOffset)
static unsafe int ReadAtOffset(SafeFileHandle handle, Span< byte > buffer, long fileOffset)
static unsafe void WriteSyncUsingAsyncHandle(SafeFileHandle handle, ReadOnlySpan< byte > buffer, long fileOffset)
static async ValueTask WriteGatherAtOffsetSingleSyscallAsync(SafeFileHandle handle, MemoryHandle[] handlesToDispose, IntPtr segmentsPtr, long fileOffset, int totalBytes, CancellationToken cancellationToken)
static unsafe(SafeFileHandle.OverlappedValueTaskSource vts, int errorCode) QueueAsyncReadFile(SafeFileHandle handle
static unsafe int ReadSyncUsingAsyncHandle(SafeFileHandle handle, Span< byte > buffer, long fileOffset)
static async ValueTask< long > ReadScatterAtOffsetMultipleSyscallsAsync(SafeFileHandle handle, IReadOnlyList< Memory< byte > > buffers, long fileOffset, CancellationToken cancellationToken)
static ValueTask ScheduleSyncWriteGatherAtOffsetAsync(SafeFileHandle handle, IReadOnlyList< ReadOnlyMemory< byte > > buffers, long fileOffset, CancellationToken cancellationToken)
static ValueTask< long > ScheduleSyncReadScatterAtOffsetAsync(SafeFileHandle handle, IReadOnlyList< Memory< byte > > buffers, long fileOffset, CancellationToken cancellationToken)
static NativeOverlapped GetNativeOverlappedForSyncHandle(SafeFileHandle handle, long fileOffset)
static async ValueTask< long > ReadScatterAtOffsetSingleSyscallAsync(SafeFileHandle handle, MemoryHandle[] handlesToDispose, IntPtr segmentsPtr, long fileOffset, int totalBytes, CancellationToken cancellationToken)
static unsafe NativeOverlapped * GetNativeOverlappedForAsyncHandle(ThreadPoolBoundHandle threadPoolBinding, long fileOffset, CallbackResetEvent resetEvent)
static ValueTask< long > ReadAsync(SafeFileHandle handle, IReadOnlyList< Memory< byte > > buffers, long fileOffset, CancellationToken cancellationToken=default(CancellationToken))
static Memory< byte > long CancellationToken OSFileStreamStrategy strategy
static unsafe ValueTask WriteFileGatherAsync(SafeFileHandle handle, IntPtr segmentsPtr, int bytesToWrite, long fileOffset, CancellationToken cancellationToken)
static ValueTask WriteAtOffsetAsync(SafeFileHandle handle, ReadOnlyMemory< byte > buffer, long fileOffset, CancellationToken cancellationToken, OSFileStreamStrategy strategy=null)
static ValueTask WriteAsync(SafeFileHandle handle, ReadOnlyMemory< byte > buffer, long fileOffset, CancellationToken cancellationToken=default(CancellationToken))
static void Write(SafeFileHandle handle, IReadOnlyList< ReadOnlyMemory< byte > > buffers, long fileOffset)
static ValueTask WriteAsync(SafeFileHandle handle, IReadOnlyList< ReadOnlyMemory< byte > > buffers, long fileOffset, CancellationToken cancellationToken=default(CancellationToken))
static ValueTask< int > ReadAsync(SafeFileHandle handle, Memory< byte > buffer, long fileOffset, CancellationToken cancellationToken=default(CancellationToken))
static unsafe bool TryPrepareScatterGatherBuffers< T, THandler >(IReadOnlyList< T > buffers, THandler handler, [NotNullWhen(true)] out MemoryHandle[] handlesToDispose, out IntPtr segmentsPtr, out int totalBytes)
static void ValidateInput(SafeFileHandle handle, long fileOffset)
static unsafe long GetFileLength(SafeFileHandle handle)
static ValueTask< long > ReadScatterAtOffsetAsync(SafeFileHandle handle, IReadOnlyList< Memory< byte > > buffers, long fileOffset, CancellationToken cancellationToken)
static void ValidateBuffers< T >(IReadOnlyList< T > buffers)
static ValueTask< int > ReadAtOffsetAsync(SafeFileHandle handle, Memory< byte > buffer, long fileOffset, CancellationToken cancellationToken, OSFileStreamStrategy strategy=null)
static bool CanUseScatterGatherWindowsAPIs(SafeFileHandle handle)
static readonly IOCompletionCallback s_callback
static unsafe IOCompletionCallback AllocateCallback()
static int Read(SafeFileHandle handle, Span< byte > buffer, long fileOffset)
static long GetLength(SafeFileHandle handle)
static void WriteGatherAtOffset(SafeFileHandle handle, IReadOnlyList< ReadOnlyMemory< byte > > buffers, long fileOffset)
static void Write(SafeFileHandle handle, ReadOnlySpan< byte > buffer, long fileOffset)
static long Read(SafeFileHandle handle, IReadOnlyList< Memory< byte > > buffers, long fileOffset)
static Memory< byte > long CancellationToken cancellationToken
static long ReadScatterAtOffset(SafeFileHandle handle, IReadOnlyList< Memory< byte > > buffers, long fileOffset)
static ValueTask WriteGatherAtOffsetAsync(SafeFileHandle handle, IReadOnlyList< ReadOnlyMemory< byte > > buffers, long fileOffset, CancellationToken cancellationToken)
static Memory< byte > long fileOffset
static unsafe ValueTask< int > ReadFileScatterAsync(SafeFileHandle handle, IntPtr segmentsPtr, int bytesToRead, long fileOffset, CancellationToken cancellationToken)
static ValueTask< int > ScheduleSyncReadAtOffsetAsync(SafeFileHandle handle, Memory< byte > buffer, long fileOffset, CancellationToken cancellationToken, OSFileStreamStrategy strategy)
static ValueTask ScheduleSyncWriteAtOffsetAsync(SafeFileHandle handle, ReadOnlyMemory< byte > buffer, long fileOffset, CancellationToken cancellationToken, OSFileStreamStrategy strategy)
static readonly int s_cachedPageSize
static int GetLastWin32ErrorAndDisposeHandleIfInvalid(SafeFileHandle handle)
static Exception GetExceptionForLastWin32Error(string path="")
static Exception GetExceptionForWin32Error(int errorCode, string path="")
static unsafe void Free(void *ptr)
static unsafe void * Alloc(nuint elementCount, nuint elementSize)
static string IO_FileTooLong
Definition SR.cs:1568
Definition SR.cs:7
static int Decrement(ref int location)
unsafe void FreeNativeOverlapped(NativeOverlapped *overlapped)
static unsafe? object GetNativeOverlappedState(NativeOverlapped *overlapped)
static void ThrowArgumentException_InvalidHandle(string paramName)
static void ThrowArgumentOutOfRangeException_NeedNonNegNum(string paramName)
static void ThrowNotSupportedException_UnseekableStream()
static void ThrowArgumentNullException(string name)
static void ThrowObjectDisposedException_FileClosed()
MemoryHandle Pin(in T memory)
unsafe delegate void IOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped *pOVERLAP)
int GetLength(in Memory< byte > memory)
MemoryHandle Pin(in Memory< byte > memory)
int GetLength(in ReadOnlyMemory< byte > memory)
MemoryHandle Pin(in ReadOnlyMemory< byte > memory)
static readonly IntPtr Zero
Definition IntPtr.cs:18
static ValueTask CompletedTask
Definition ValueTask.cs:71
static ValueTask FromCanceled(CancellationToken cancellationToken)
Definition ValueTask.cs:180
static ValueTask FromException(Exception exception)
Definition ValueTask.cs:190