Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
FileStreamHelpers.cs
Go to the documentation of this file.
8
10
11internal static class FileStreamHelpers
12{
14 {
15 private static readonly Action s_sentinel = delegate
16 {
17 };
18
19 internal unsafe static readonly IOCompletionCallback s_callback = IOCallback;
20
21 internal readonly SafeFileHandle _fileHandle;
22
23 internal long _position;
24
26
27 internal Action _continuation;
28
29 internal uint _errorCode;
30
31 internal uint _numBytes;
32
33 internal object CancellationLock => this;
34
35 public bool IsCompleted => (object)_continuation == s_sentinel;
36
38 {
39 _fileHandle = fileHandle;
40 }
41
42 internal void ResetForNextOperation()
43 {
44 _continuation = null;
45 _errorCode = 0u;
46 _numBytes = 0u;
47 }
48
56
57 internal void MarkCompleted()
58 {
60 }
61
63 {
64 return this;
65 }
66
67 public void GetResult()
68 {
69 }
70
71 public void OnCompleted(Action continuation)
72 {
74 }
75
76 public void UnsafeOnCompleted(Action continuation)
77 {
79 {
81 }
82 }
83 }
84
85 private static int s_cachedSerializationSwitch;
86
87 internal static bool UseNet5CompatStrategy { get; } = AppContextConfigHelper.GetBooleanConfig("System.IO.UseNet5CompatFileStream", "DOTNET_SYSTEM_IO_USENET5COMPATFILESTREAM");
88
89
95
97 {
99 return WrapIfDerivedType(fileStream, strategy);
100 }
101
103 {
104 if (bufferSize <= 1)
105 {
106 return strategy;
107 }
108 return new BufferedFileStreamStrategy(strategy, bufferSize);
109 }
110
112 {
113 if (!(fileStream.GetType() == typeof(FileStream)))
114 {
115 return new DerivedFileStreamStrategy(fileStream, strategy);
116 }
117 return strategy;
118 }
119
120 internal static bool IsIoRelatedException(Exception e)
121 {
123 {
124 if (e is ArgumentException)
125 {
126 return !(e is ArgumentNullException);
127 }
128 return false;
129 }
130 return true;
131 }
132
133 internal static void ValidateArguments(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, long preallocationSize)
134 {
135 if (path == null)
136 {
137 throw new ArgumentNullException("path", SR.ArgumentNull_Path);
138 }
139 if (path.Length == 0)
140 {
141 throw new ArgumentException(SR.Argument_EmptyPath, "path");
142 }
143 FileShare fileShare = share & ~FileShare.Inheritable;
144 string text = null;
146 {
147 text = "mode";
148 }
150 {
151 text = "access";
152 }
153 else if ((fileShare < FileShare.None) || fileShare > (FileShare.ReadWrite | FileShare.Delete))
154 {
155 text = "share";
156 }
157 if (text != null)
158 {
160 }
161 if (options != 0 && (options & (FileOptions)67092479) != 0)
162 {
164 }
165 if (bufferSize < 0)
166 {
168 }
169 else if (preallocationSize < 0)
170 {
172 }
173 if ((access & FileAccess.Write) == 0 && (mode == FileMode.Truncate || mode == FileMode.CreateNew || mode == FileMode.Create || mode == FileMode.Append))
174 {
176 }
177 if ((access & FileAccess.Read) != 0 && mode == FileMode.Append)
178 {
180 }
181 if (preallocationSize > 0)
182 {
184 }
186 }
187
189 {
190 if ((access & FileAccess.Write) == 0)
191 {
193 }
194 if (mode != FileMode.Create && mode != FileMode.CreateNew)
195 {
197 }
198 }
199
201 {
202 if ((access & FileAccess.Write) == FileAccess.Write)
203 {
205 }
206 }
207
216
218 {
219 if ((options & FileOptions.Asynchronous) == 0)
220 {
221 return new SyncWindowsFileStreamStrategy(path, mode, access, share, options, preallocationSize);
222 }
223 return new AsyncWindowsFileStreamStrategy(path, mode, access, share, options, preallocationSize);
224 }
225
226 internal static void FlushToDisk(SafeFileHandle handle)
227 {
229 {
231 }
232 }
233
246
248 {
250 }
251
253 {
255 if (lastPInvokeError == 6)
256 {
257 handle.Dispose();
258 }
259 return lastPInvokeError;
260 }
261
262 internal static void Lock(SafeFileHandle handle, bool canWrite, long position, long length)
263 {
264 int offsetLow = (int)position;
265 int offsetHigh = (int)(position >> 32);
266 int countLow = (int)length;
267 int countHigh = (int)(length >> 32);
269 {
271 }
272 }
273
274 internal static void Unlock(SafeFileHandle handle, long position, long length)
275 {
276 int offsetLow = (int)position;
277 int offsetHigh = (int)(position >> 32);
278 int countLow = (int)length;
279 int countHigh = (int)(length >> 32);
281 {
283 }
284 }
285
293
307
309 {
310 int numBytesRead = 0;
311 int num;
312 fixed (byte* bytes2 = &MemoryMarshal.GetReference(bytes))
313 {
315 }
316 if (num == 0)
317 {
319 return -1;
320 }
321 errorCode = 0;
322 return numBytesRead;
323 }
324
326 {
328 if (canSeek)
329 {
331 }
335 try
336 {
337 if (cancellationToken.CanBeCanceled)
338 {
339 cancellationReg = cancellationToken.UnsafeRegister(delegate(object s)
340 {
342 lock (asyncCopyToAwaitable.CancellationLock)
343 {
344 if (asyncCopyToAwaitable._nativeOverlapped != null)
345 {
347 }
348 }
349 }, readAwaitable);
350 }
351 while (true)
352 {
353 cancellationToken.ThrowIfCancellationRequested();
354 readAwaitable.ResetForNextOperation();
355 try
356 {
357 readAwaitable._nativeOverlapped = handle.ThreadPoolBinding.AllocateNativeOverlapped(awaitableOverlapped);
358 if (canSeek)
359 {
360 readAwaitable._nativeOverlapped->OffsetLow = (int)readAwaitable._position;
361 readAwaitable._nativeOverlapped->OffsetHigh = (int)(readAwaitable._position >> 32);
362 }
363 if (ReadFileNative(handle, copyBuffer, readAwaitable._nativeOverlapped, out var errorCode) < 0)
364 {
365 switch (errorCode)
366 {
367 case 38:
368 case 109:
369 readAwaitable.MarkCompleted();
370 break;
371 default:
373 case 997:
374 break;
375 }
376 }
378 switch (readAwaitable._errorCode)
379 {
380 case 995u:
381 throw new OperationCanceledException(cancellationToken.IsCancellationRequested ? cancellationToken : new CancellationToken(canceled: true));
382 default:
383 throw Win32Marshal.GetExceptionForWin32Error((int)readAwaitable._errorCode, handle.Path);
384 case 0u:
385 case 38u:
386 case 109u:
387 {
388 int numBytes = (int)readAwaitable._numBytes;
389 if (numBytes == 0)
390 {
391 return;
392 }
393 if (canSeek)
394 {
396 }
397 break;
398 }
399 }
400 }
401 finally
402 {
404 lock (readAwaitable.CancellationLock)
405 {
406 nativeOverlapped = readAwaitable._nativeOverlapped;
408 }
409 if (nativeOverlapped != null)
410 {
411 handle.ThreadPoolBinding.FreeNativeOverlapped(nativeOverlapped);
412 }
413 }
414 await destination.WriteAsync(new ReadOnlyMemory<byte>(copyBuffer, 0, (int)readAwaitable._numBytes), cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
415 }
416 }
417 finally
418 {
419 cancellationReg.Dispose();
420 awaitableOverlapped.Dispose();
422 }
423 }
424}
static unsafe int ReadFile(IntPtr handle, byte *bytes, int numBytesToRead, out int numBytesRead, IntPtr mustBeZero)
static unsafe bool CancelIoEx(SafeHandle handle, NativeOverlapped *lpOverlapped)
static bool UnlockFile(SafeFileHandle handle, int offsetLow, int offsetHigh, int countLow, int countHigh)
static bool SetFilePointerEx(SafeFileHandle hFile, long liDistanceToMove, out long lpNewFilePointer, uint dwMoveMethod)
static unsafe bool SetFileInformationByHandle(SafeFileHandle hFile, int FileInformationClass, void *lpFileInformation, uint dwBufferSize)
static bool LockFile(SafeFileHandle handle, int offsetLow, int offsetHigh, int countLow, int countHigh)
static bool FlushFileBuffers(SafeHandle hHandle)
static bool GetBooleanConfig(string configName, bool defaultValue)
static ArrayPool< T > Shared
Definition ArrayPool.cs:7
static unsafe readonly IOCompletionCallback s_callback
static unsafe void IOCallback(uint errorCode, uint numBytes, NativeOverlapped *pOVERLAP)
static unsafe async Task AsyncModeCopyToAsync(SafeFileHandle handle, bool canSeek, long filePosition, Stream destination, int bufferSize, CancellationToken cancellationToken)
static unsafe bool TrySetFileLength(SafeFileHandle handle, long length, out int errorCode)
static void ValidateArguments(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, long preallocationSize)
static FileStreamStrategy ChooseStrategy(FileStream fileStream, SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync)
static FileStreamStrategy ChooseStrategyCore(string path, FileMode mode, FileAccess access, FileShare share, FileOptions options, long preallocationSize)
static FileStreamStrategy WrapIfDerivedType(FileStream fileStream, FileStreamStrategy strategy)
static int GetLastWin32ErrorAndDisposeHandleIfInvalid(SafeFileHandle handle)
static unsafe int ReadFileNative(SafeFileHandle handle, Span< byte > bytes, NativeOverlapped *overlapped, out int errorCode)
static void SerializationGuard(FileAccess access)
static void SetFileLength(SafeFileHandle handle, long length)
static void Lock(SafeFileHandle handle, bool canWrite, long position, long length)
static void Unlock(SafeFileHandle handle, long position, long length)
static void FlushToDisk(SafeFileHandle handle)
static OSFileStreamStrategy ChooseStrategyCore(SafeFileHandle handle, FileAccess access, bool isAsync)
static long Seek(SafeFileHandle handle, long offset, SeekOrigin origin, bool closeInvalidHandle=false)
static void ThrowInvalidArgument(SafeFileHandle handle)
static FileStreamStrategy EnableBufferingIfNeeded(FileStreamStrategy strategy, int bufferSize)
static FileStreamStrategy ChooseStrategy(FileStream fileStream, string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, long preallocationSize)
static void ValidateArgumentsForPreallocation(FileMode mode, FileAccess access)
static bool IsIoRelatedException(Exception e)
static Exception GetExceptionForLastWin32Error(string path="")
static Exception GetExceptionForWin32Error(int errorCode, string path="")
static string ArgumentOutOfRange_Enum
Definition SR.cs:18
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string ArgumentNull_Path
Definition SR.cs:954
static string Argument_InvalidFileModeAndAccessCombo
Definition SR.cs:686
static string ArgumentOutOfRange_FileLengthTooBig
Definition SR.cs:1014
static string Argument_InvalidPreallocateAccess
Definition SR.cs:636
static string Argument_EmptyPath
Definition SR.cs:38
static string Argument_InvalidPreallocateMode
Definition SR.cs:638
static string Argument_InvalidAppendMode
Definition SR.cs:634
Definition SR.cs:7
static int CompareExchange(ref int location1, int value, int comparand)
static Task Run(Action action)
Definition Task.cs:3395
static unsafe? object GetNativeOverlappedState(NativeOverlapped *overlapped)
static void ThrowArgumentOutOfRangeException_NeedNonNegNum(string paramName)
unsafe delegate void IOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped *pOVERLAP)
static readonly IntPtr Zero
Definition IntPtr.cs:18